feat():initial version
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_ADAPTIVE_NODE_POOL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_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/intrusive/set.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/pool_common_alloc.hpp>
|
||||
#include <boost/container/detail/mutex.hpp>
|
||||
#include <boost/container/detail/adaptive_node_pool_impl.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
//!Pooled memory allocator using an smart adaptive pool. Includes
|
||||
//!a reference count but the class does not delete itself, this is
|
||||
//!responsibility of user classes. Node size (NodeSize) and the number of
|
||||
//!nodes allocated per block (NodesPerBlock) are known at compile time.
|
||||
template< std::size_t NodeSize
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t MaxFreeBlocks
|
||||
, std::size_t OverheadPercent
|
||||
>
|
||||
class private_adaptive_node_pool
|
||||
: public private_adaptive_node_pool_impl_ct
|
||||
< fake_segment_manager
|
||||
, MaxFreeBlocks
|
||||
, NodeSize
|
||||
, NodesPerBlock
|
||||
, OverheadPercent
|
||||
, unsigned(OverheadPercent == 0)*::boost::container::adaptive_pool_flag::align_only
|
||||
| ::boost::container::adaptive_pool_flag::size_ordered
|
||||
| ::boost::container::adaptive_pool_flag::address_ordered
|
||||
>
|
||||
{
|
||||
typedef private_adaptive_node_pool_impl_ct
|
||||
< fake_segment_manager
|
||||
, MaxFreeBlocks
|
||||
, NodeSize
|
||||
, NodesPerBlock
|
||||
, OverheadPercent
|
||||
, unsigned(OverheadPercent == 0)*::boost::container::adaptive_pool_flag::align_only
|
||||
| ::boost::container::adaptive_pool_flag::size_ordered
|
||||
| ::boost::container::adaptive_pool_flag::address_ordered
|
||||
> base_t;
|
||||
|
||||
//Non-copyable
|
||||
private_adaptive_node_pool(const private_adaptive_node_pool &);
|
||||
private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
|
||||
|
||||
public:
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
|
||||
//!Constructor. Never throws
|
||||
private_adaptive_node_pool()
|
||||
: base_t(0)
|
||||
{}
|
||||
};
|
||||
|
||||
//!Pooled memory allocator using adaptive pool. Includes
|
||||
//!a reference count but the class does not delete itself, this is
|
||||
//!responsibility of user classes. Node size (NodeSize) and the number of
|
||||
//!nodes allocated per block (NodesPerBlock) are known at compile time
|
||||
template< std::size_t NodeSize
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t MaxFreeBlocks
|
||||
, std::size_t OverheadPercent
|
||||
>
|
||||
class shared_adaptive_node_pool
|
||||
: public private_adaptive_node_pool
|
||||
<NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
|
||||
{
|
||||
private:
|
||||
typedef private_adaptive_node_pool
|
||||
<NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> private_node_allocator_t;
|
||||
public:
|
||||
typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
|
||||
|
||||
//!Constructor. Never throws
|
||||
shared_adaptive_node_pool()
|
||||
: private_node_allocator_t(){}
|
||||
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
||||
~shared_adaptive_node_pool()
|
||||
{}
|
||||
|
||||
//!Allocates array of count elements. Can throw std::bad_alloc
|
||||
void *allocate_node()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_node();
|
||||
}
|
||||
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
||||
void deallocate_node(void *ptr)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_node(ptr);
|
||||
}
|
||||
|
||||
//!Allocates a singly linked list of n nodes ending in null pointer.
|
||||
//!can throw std::bad_alloc
|
||||
void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_nodes(n, chain);
|
||||
}
|
||||
|
||||
void deallocate_nodes(multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_nodes(chain);
|
||||
}
|
||||
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
||||
void deallocate_free_blocks()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_free_blocks();
|
||||
}
|
||||
|
||||
private:
|
||||
default_mutex mutex_;
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 dtl {
|
||||
|
||||
template <typename T>
|
||||
BOOST_CONTAINER_FORCEINLINE T* addressof(T& obj)
|
||||
{
|
||||
return static_cast<T*>(
|
||||
static_cast<void*>(
|
||||
const_cast<char*>(
|
||||
&reinterpret_cast<const volatile char&>(obj)
|
||||
)));
|
||||
}
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
|
||||
@@ -0,0 +1,567 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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/move/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 dtl {
|
||||
|
||||
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;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit move_insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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);
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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);
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_n_copies_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_fill_alloc_n(a, v_, n, p); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const
|
||||
{
|
||||
while (n){
|
||||
--n;
|
||||
*p = v_;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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 &a, Iterator p, size_type n) const
|
||||
{
|
||||
while (n){
|
||||
--n;
|
||||
storage_t v;
|
||||
value_type *vp = reinterpret_cast<value_type *>(v.data);
|
||||
alloc_traits::construct(a, vp);
|
||||
value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
|
||||
*p = ::boost::move(*vp);
|
||||
++p;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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 &a, Iterator p, size_type n) const
|
||||
{
|
||||
if(!is_pod<value_type>::value){
|
||||
while (n){
|
||||
--n;
|
||||
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
|
||||
value_type *vp = reinterpret_cast<value_type *>(v.data);
|
||||
alloc_traits::construct(a, vp, default_init);
|
||||
value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
|
||||
*p = ::boost::move(*vp);
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_copy_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_);
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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;
|
||||
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) );
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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>
|
||||
BOOST_CONTAINER_FORCEINLINE 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>
|
||||
BOOST_CONTAINER_FORCEINLINE 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 dtl {
|
||||
|
||||
#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 dtl {
|
||||
|
||||
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;
|
||||
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
|
||||
: args_(args...)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
|
||||
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
template<std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE 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, boost::movelib::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;
|
||||
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
|
||||
: base_t(::boost::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, size_type n)
|
||||
{ this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
|
||||
template<std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n ==1); (void)n;
|
||||
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
|
||||
value_type *vp = reinterpret_cast<value_type *>(v.data);
|
||||
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>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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 dtl {
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
#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;\
|
||||
\
|
||||
static const bool single_value = true;\
|
||||
\
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
|
||||
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
|
||||
\
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
|
||||
{\
|
||||
BOOST_ASSERT(n == 1); (void)n;\
|
||||
alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
|
||||
}\
|
||||
\
|
||||
BOOST_CONTAINER_FORCEINLINE 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;\
|
||||
\
|
||||
static const bool single_value = true;\
|
||||
\
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
|
||||
: base_t(BOOST_MOVE_FWD##N){}\
|
||||
\
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
|
||||
{\
|
||||
BOOST_ASSERT(n == 1); (void)n;\
|
||||
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\
|
||||
value_type *vp = reinterpret_cast<value_type *>(v.data);\
|
||||
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>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
static const bool single_value = true;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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 dtl {
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
namespace boost { namespace container { namespace dtl {
|
||||
|
||||
template <class T>
|
||||
struct has_single_value
|
||||
{
|
||||
private:
|
||||
struct two {char array_[2];};
|
||||
template<bool Arg> struct wrapper;
|
||||
template <class U> static two test(int, ...);
|
||||
template <class U> static char test(int, const wrapper<U::single_value>*);
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0, 0)) == 1;
|
||||
void dummy(){}
|
||||
};
|
||||
|
||||
template<class InsertionProxy, bool = has_single_value<InsertionProxy>::value>
|
||||
struct is_single_value_proxy_impl
|
||||
{
|
||||
static const bool value = InsertionProxy::single_value;
|
||||
};
|
||||
|
||||
template<class InsertionProxy>
|
||||
struct is_single_value_proxy_impl<InsertionProxy, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class InsertionProxy>
|
||||
struct is_single_value_proxy
|
||||
: is_single_value_proxy_impl<InsertionProxy>
|
||||
{};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace dtl {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
@@ -0,0 +1,157 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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;
|
||||
|
||||
template<class Func>
|
||||
class binder1st
|
||||
{
|
||||
public:
|
||||
typedef typename Func::second_argument_type argument_type;
|
||||
typedef typename Func::result_type result_type;
|
||||
|
||||
binder1st(const Func& func, const typename Func::first_argument_type& arg)
|
||||
: op(func), value(arg)
|
||||
{}
|
||||
|
||||
result_type operator()(const argument_type& arg) const
|
||||
{ return op(value, arg); }
|
||||
|
||||
result_type operator()(argument_type& arg) const
|
||||
{ return op(value, arg); }
|
||||
|
||||
private:
|
||||
Func op;
|
||||
typename Func::first_argument_type value;
|
||||
};
|
||||
|
||||
template<class Func, class T>
|
||||
inline binder1st<Func> bind1st(const Func& func, const T& arg)
|
||||
{ return boost::container::binder1st<Func>(func, arg); }
|
||||
|
||||
template<class Func>
|
||||
class binder2nd
|
||||
{
|
||||
public:
|
||||
typedef typename Func::first_argument_type argument_type;
|
||||
typedef typename Func::result_type result_type;
|
||||
|
||||
binder2nd(const Func& func, const typename Func::second_argument_type& arg)
|
||||
: op(func), value(arg)
|
||||
{}
|
||||
|
||||
result_type operator()(const argument_type& arg) const
|
||||
{ return op(arg, value); }
|
||||
|
||||
result_type operator()(argument_type& arg) const
|
||||
{ return op(arg, value); }
|
||||
|
||||
private:
|
||||
Func op;
|
||||
typename Func::second_argument_type value;
|
||||
};
|
||||
|
||||
template<class Func, class T>
|
||||
inline binder2nd<Func> bind2nd(const Func& func, const T& arg)
|
||||
{
|
||||
return (boost::container::binder2nd<Func>(func, arg));
|
||||
}
|
||||
|
||||
template<class Func>
|
||||
class unary_negate
|
||||
{
|
||||
public:
|
||||
typedef typename Func::argument_type argument_type;
|
||||
typedef typename Func::result_type result_type;
|
||||
|
||||
explicit unary_negate(const Func& func)
|
||||
: m_func(func)
|
||||
{}
|
||||
|
||||
bool operator()(const typename Func::argument_type& arg) const
|
||||
{ return !m_func(arg); }
|
||||
|
||||
private:
|
||||
Func m_func;
|
||||
};
|
||||
|
||||
template<class Func> inline
|
||||
unary_negate<Func> not1(const Func& func)
|
||||
{
|
||||
return boost::container::unary_negate<Func>(func);
|
||||
}
|
||||
|
||||
template<class InputIt, class UnaryPredicate>
|
||||
InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
|
||||
{
|
||||
for (; first != last; ++first) {
|
||||
if (p(*first)) {
|
||||
return first;
|
||||
}
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
template<class InputIt, class ForwardIt, class BinaryPredicate>
|
||||
InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p)
|
||||
{
|
||||
for (; first1 != last1; ++first1) {
|
||||
for (ForwardIt it = first2; it != last2; ++it) {
|
||||
if (p(*first1, *it)) {
|
||||
return first1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return last1;
|
||||
}
|
||||
|
||||
template<class ForwardIt1, class ForwardIt2, class BinaryPredicate>
|
||||
ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1,
|
||||
ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p)
|
||||
{
|
||||
for (; ; ++first1) {
|
||||
ForwardIt1 it = first1;
|
||||
for (ForwardIt2 it2 = first2; ; ++it, ++it2) {
|
||||
if (it2 == last2) {
|
||||
return first1;
|
||||
}
|
||||
if (it == last1) {
|
||||
return last1;
|
||||
}
|
||||
if (!p(*it, *it2)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
|
||||
@@ -0,0 +1,60 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// move
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class AllocatorType>
|
||||
BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
template<class AllocatorType>
|
||||
BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
|
||||
{ boost::adl_move_swap(l, r); }
|
||||
|
||||
template<class AllocatorType>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
template<class AllocatorType>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type)
|
||||
{ l = r; }
|
||||
|
||||
template<class AllocatorType>
|
||||
BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
template<class AllocatorType>
|
||||
BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
|
||||
{ l = ::boost::move(r); }
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
||||
314
install/boost_1_75_0/include/boost/container/detail/alloc_lib.h
Normal file
314
install/boost_1_75_0/include/boost/container/detail/alloc_lib.h
Normal file
@@ -0,0 +1,314 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_ALLOC_LIB_EXT_H
|
||||
#define BOOST_CONTAINER_ALLOC_LIB_EXT_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4127)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!An forward iterator to traverse the elements of a memory chain container.*/
|
||||
typedef struct multialloc_node_impl
|
||||
{
|
||||
struct multialloc_node_impl *next_node_ptr;
|
||||
} boost_cont_memchain_node;
|
||||
|
||||
|
||||
/*!An forward iterator to traverse the elements of a memory chain container.*/
|
||||
typedef struct multialloc_it_impl
|
||||
{
|
||||
boost_cont_memchain_node *node_ptr;
|
||||
} boost_cont_memchain_it;
|
||||
|
||||
/*!Memory chain: A container holding memory portions allocated by boost_cont_multialloc_nodes
|
||||
and boost_cont_multialloc_arrays functions.*/
|
||||
typedef struct boost_cont_memchain_impl
|
||||
{
|
||||
size_t num_mem;
|
||||
boost_cont_memchain_node root_node;
|
||||
boost_cont_memchain_node *last_node_ptr;
|
||||
} boost_cont_memchain;
|
||||
|
||||
/*!Advances the iterator one position so that it points to the next element in the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMIT_NEXT(IT) (IT.node_ptr = IT.node_ptr->next_node_ptr)
|
||||
|
||||
/*!Returns the address of the memory chain currently pointed by the iterator*/
|
||||
#define BOOST_CONTAINER_MEMIT_ADDR(IT) ((void*)IT.node_ptr)
|
||||
|
||||
/*!Initializer for an iterator pointing to the position before the first element*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_BEFORE_BEGIN_IT(PMEMCHAIN) { &((PMEMCHAIN)->root_node) }
|
||||
|
||||
/*!Initializer for an iterator pointing to the first element*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(PMEMCHAIN) {(PMEMCHAIN)->root_node.next_node_ptr }
|
||||
|
||||
/*!Initializer for an iterator pointing to the last element*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_LAST_IT(PMEMCHAIN) {(PMEMCHAIN)->last_node_ptr }
|
||||
|
||||
/*!Initializer for an iterator pointing to one past the last element (end iterator)*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_END_IT(PMEMCHAIN) {(boost_cont_memchain_node *)0 }
|
||||
|
||||
/*!True if IT is the end iterator, false otherwise*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_IS_END_IT(PMEMCHAIN, IT) (!(IT).node_ptr)
|
||||
|
||||
/*!The address of the first memory portion hold by the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(PMEMCHAIN)((void*)((PMEMCHAIN)->root_node.next_node_ptr))
|
||||
|
||||
/*!The address of the last memory portion hold by the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_LASTMEM(PMEMCHAIN) ((void*)((PMEMCHAIN)->last_node_ptr))
|
||||
|
||||
/*!The number of memory portions hold by the memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_SIZE(PMEMCHAIN) ((PMEMCHAIN)->num_mem)
|
||||
|
||||
/*!Initializes the memory chain from the first memory portion, the last memory
|
||||
portion and number of portions obtained from another memory chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_INIT_FROM(PMEMCHAIN, FIRST, LAST, NUM)\
|
||||
(PMEMCHAIN)->last_node_ptr = (boost_cont_memchain_node *)(LAST), \
|
||||
(PMEMCHAIN)->root_node.next_node_ptr = (boost_cont_memchain_node *)(FIRST), \
|
||||
(PMEMCHAIN)->num_mem = (NUM);\
|
||||
/**/
|
||||
|
||||
/*!Default initializes a memory chain. Postconditions: begin iterator is end iterator,
|
||||
the number of portions is zero.*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_INIT(PMEMCHAIN)\
|
||||
((PMEMCHAIN)->root_node.next_node_ptr = 0, (PMEMCHAIN)->last_node_ptr = &((PMEMCHAIN)->root_node), (PMEMCHAIN)->num_mem = 0)\
|
||||
/**/
|
||||
|
||||
/*!True if the memory chain is empty (holds no memory portions*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_EMPTY(PMEMCHAIN)\
|
||||
((PMEMCHAIN)->num_mem == 0)\
|
||||
/**/
|
||||
|
||||
/*!Inserts a new memory portions in the front of the chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(PMEMCHAIN, MEM)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\
|
||||
____chain____->last_node_ptr->next_node_ptr = ____tmp_mem____;\
|
||||
____tmp_mem____->next_node_ptr = 0;\
|
||||
____chain____->last_node_ptr = ____tmp_mem____;\
|
||||
++____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Inserts a new memory portions in the back of the chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_PUSH_FRONT(PMEMCHAIN, MEM)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\
|
||||
boost_cont_memchain *____root____ = &((PMEMCHAIN)->root_node);\
|
||||
if(!____chain____->root_node.next_node_ptr){\
|
||||
____chain____->last_node_ptr = ____tmp_mem____;\
|
||||
}\
|
||||
boost_cont_memchain_node *____old_first____ = ____root____->next_node_ptr;\
|
||||
____tmp_mem____->next_node_ptr = ____old_first____;\
|
||||
____root____->next_node_ptr = ____tmp_mem____;\
|
||||
++____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Erases the memory portion after the portion pointed by BEFORE_IT from the memory chain*/
|
||||
/*!Precondition: BEFORE_IT must be a valid iterator of the memory chain and it can't be the end iterator*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_ERASE_AFTER(PMEMCHAIN, BEFORE_IT)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____prev_node____ = (BEFORE_IT).node_ptr;\
|
||||
boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
|
||||
if(____chain____->last_node_ptr == ____erase_node____){\
|
||||
____chain____->last_node_ptr = &____chain____->root_node;\
|
||||
}\
|
||||
____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
|
||||
--____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Erases the first portion from the memory chain.
|
||||
Precondition: the memory chain must not be empty*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_POP_FRONT(PMEMCHAIN)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____prev_node____ = &____chain____->root_node;\
|
||||
boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
|
||||
if(____chain____->last_node_ptr == ____erase_node____){\
|
||||
____chain____->last_node_ptr = &____chain____->root_node;\
|
||||
}\
|
||||
____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
|
||||
--____chain____->num_mem;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
|
||||
/*
|
||||
#define BOOST_CONTAINER_MEMCHAIN_SPLICE_BACK(PMEMCHAIN, PMEMCHAIN2)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain *____chain2____ = (PMEMCHAIN2);\
|
||||
if(!____chain2____->root_node.next_node_ptr){\
|
||||
break;\
|
||||
}\
|
||||
else if(!____chain____->first_mem){\
|
||||
____chain____->first_mem = ____chain2____->first_mem;\
|
||||
____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
|
||||
____chain____->num_mem = ____chain2____->num_mem;\
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(*____chain2____);\
|
||||
}\
|
||||
else{\
|
||||
____chain____->last_node_ptr->next_node_ptr = ____chain2____->first_mem;\
|
||||
____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
|
||||
____chain____->num_mem += ____chain2____->num_mem;\
|
||||
}\
|
||||
}while(0)\*/
|
||||
/**/
|
||||
|
||||
/*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
|
||||
#define BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER(PMEMCHAIN, BEFORE_IT, FIRST, BEFORELAST, NUM)\
|
||||
do{\
|
||||
boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
||||
boost_cont_memchain_node *____pnode____ = (BEFORE_IT).node_ptr;\
|
||||
boost_cont_memchain_node *____next____ = ____pnode____->next_node_ptr;\
|
||||
boost_cont_memchain_node *____first____ = (boost_cont_memchain_node *)(FIRST);\
|
||||
boost_cont_memchain_node *____blast____ = (boost_cont_memchain_node *)(BEFORELAST);\
|
||||
size_t ____num____ = (NUM);\
|
||||
if(!____num____){\
|
||||
break;\
|
||||
}\
|
||||
if(____pnode____ == ____chain____->last_node_ptr){\
|
||||
____chain____->last_node_ptr = ____blast____;\
|
||||
}\
|
||||
____pnode____->next_node_ptr = ____first____;\
|
||||
____blast____->next_node_ptr = ____next____;\
|
||||
____chain____->num_mem += ____num____;\
|
||||
}while(0)\
|
||||
/**/
|
||||
|
||||
/*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
|
||||
must be contiguous.*/
|
||||
#define BOOST_CONTAINER_DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1))
|
||||
|
||||
/*!Indicates the number of contiguous elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
|
||||
should be selected by those functions.*/
|
||||
#define BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0))
|
||||
|
||||
typedef struct boost_cont_malloc_stats_impl
|
||||
{
|
||||
size_t max_system_bytes;
|
||||
size_t system_bytes;
|
||||
size_t in_use_bytes;
|
||||
} boost_cont_malloc_stats_t;
|
||||
|
||||
typedef unsigned int allocation_type;
|
||||
|
||||
enum
|
||||
{
|
||||
// constants for allocation commands
|
||||
BOOST_CONTAINER_ALLOCATE_NEW = 0X01,
|
||||
BOOST_CONTAINER_EXPAND_FWD = 0X02,
|
||||
BOOST_CONTAINER_EXPAND_BWD = 0X04,
|
||||
BOOST_CONTAINER_SHRINK_IN_PLACE = 0X08,
|
||||
BOOST_CONTAINER_NOTHROW_ALLOCATION = 0X10,
|
||||
// BOOST_CONTAINER_ZERO_MEMORY = 0X20,
|
||||
BOOST_CONTAINER_TRY_SHRINK_IN_PLACE = 0X40,
|
||||
BOOST_CONTAINER_EXPAND_BOTH = BOOST_CONTAINER_EXPAND_FWD | BOOST_CONTAINER_EXPAND_BWD,
|
||||
BOOST_CONTAINER_EXPAND_OR_NEW = BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BOTH
|
||||
};
|
||||
|
||||
//#define BOOST_CONTAINER_DLMALLOC_FOOTERS
|
||||
#ifndef BOOST_CONTAINER_DLMALLOC_FOOTERS
|
||||
enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t) };
|
||||
#else
|
||||
enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)*2 };
|
||||
#endif
|
||||
|
||||
typedef struct boost_cont_command_ret_impl
|
||||
{
|
||||
void *first;
|
||||
int second;
|
||||
}boost_cont_command_ret_t;
|
||||
|
||||
size_t boost_cont_size(const void *p);
|
||||
|
||||
void* boost_cont_malloc(size_t bytes);
|
||||
|
||||
void boost_cont_free(void* mem);
|
||||
|
||||
void* boost_cont_memalign(size_t bytes, size_t alignment);
|
||||
|
||||
int boost_cont_multialloc_nodes
|
||||
(size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain);
|
||||
|
||||
int boost_cont_multialloc_arrays
|
||||
(size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain);
|
||||
|
||||
void boost_cont_multidealloc(boost_cont_memchain *pchain);
|
||||
|
||||
size_t boost_cont_footprint();
|
||||
|
||||
size_t boost_cont_allocated_memory();
|
||||
|
||||
size_t boost_cont_chunksize(const void *p);
|
||||
|
||||
int boost_cont_all_deallocated();
|
||||
|
||||
boost_cont_malloc_stats_t boost_cont_malloc_stats();
|
||||
|
||||
size_t boost_cont_in_use_memory();
|
||||
|
||||
int boost_cont_trim(size_t pad);
|
||||
|
||||
int boost_cont_mallopt(int parameter_number, int parameter_value);
|
||||
|
||||
int boost_cont_grow
|
||||
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received);
|
||||
|
||||
int boost_cont_shrink
|
||||
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit);
|
||||
|
||||
void* boost_cont_alloc
|
||||
(size_t minbytes, size_t preferred_bytes, size_t *received_bytes);
|
||||
|
||||
int boost_cont_malloc_check();
|
||||
|
||||
boost_cont_command_ret_t boost_cont_allocation_command
|
||||
( allocation_type command
|
||||
, size_t sizeof_object
|
||||
, size_t limit_objects
|
||||
, size_t preferred_objects
|
||||
, size_t *received_objects
|
||||
, void *reuse_ptr
|
||||
);
|
||||
|
||||
void *boost_cont_sync_create();
|
||||
|
||||
void boost_cont_sync_destroy(void *sync);
|
||||
|
||||
int boost_cont_sync_lock(void *sync);
|
||||
|
||||
void boost_cont_sync_unlock(void *sync);
|
||||
|
||||
int boost_cont_global_sync_lock();
|
||||
|
||||
void boost_cont_global_sync_unlock();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} //extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
#endif //#define BOOST_CONTAINERDLMALLOC__EXT_H
|
||||
@@ -0,0 +1,58 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
enum allocation_type_v
|
||||
{
|
||||
// constants for allocation commands
|
||||
allocate_new_v = 0x01,
|
||||
expand_fwd_v = 0x02,
|
||||
expand_bwd_v = 0x04,
|
||||
// expand_both = expand_fwd | expand_bwd,
|
||||
// expand_or_new = allocate_new | expand_both,
|
||||
shrink_in_place_v = 0x08,
|
||||
nothrow_allocation_v = 0x10,
|
||||
zero_memory_v = 0x20,
|
||||
try_shrink_in_place_v = 0x40
|
||||
};
|
||||
|
||||
typedef unsigned int allocation_type;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
static const allocation_type allocate_new = (allocation_type)allocate_new_v;
|
||||
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
|
||||
static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
|
||||
static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v;
|
||||
static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
|
||||
static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
|
||||
static const allocation_type zero_memory = (allocation_type)zero_memory_v;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
||||
@@ -0,0 +1,163 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp> //allocator_traits
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
|
||||
#include <boost/container/detail/version_type.hpp> //version_type
|
||||
#include <boost/container/detail/allocation_type.hpp> //allocation_type
|
||||
#include <boost/container/detail/mpl.hpp> //integral_constant
|
||||
#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
|
||||
#include <boost/core/no_exceptions_support.hpp> //BOOST_TRY
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class Allocator, unsigned Version = boost::container::dtl::version<Allocator>::value>
|
||||
struct allocator_version_traits
|
||||
{
|
||||
typedef ::boost::container::dtl::integral_constant
|
||||
<unsigned, Version> alloc_version;
|
||||
|
||||
typedef typename Allocator::multiallocation_chain multiallocation_chain;
|
||||
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
|
||||
//Node allocation interface
|
||||
static pointer allocate_one(Allocator &a)
|
||||
{ return a.allocate_one(); }
|
||||
|
||||
static void deallocate_one(Allocator &a, const pointer &p)
|
||||
{ a.deallocate_one(p); }
|
||||
|
||||
static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
|
||||
{ return a.allocate_individual(n, m); }
|
||||
|
||||
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
|
||||
{ a.deallocate_individual(holder); }
|
||||
|
||||
static pointer allocation_command(Allocator &a, allocation_type command,
|
||||
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
|
||||
{ return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
|
||||
};
|
||||
|
||||
template<class Allocator>
|
||||
struct allocator_version_traits<Allocator, 1>
|
||||
{
|
||||
typedef ::boost::container::dtl::integral_constant
|
||||
<unsigned, 1> alloc_version;
|
||||
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
|
||||
|
||||
typedef typename boost::intrusive::pointer_traits<pointer>::
|
||||
template rebind_pointer<void>::type void_ptr;
|
||||
typedef dtl::basic_multiallocation_chain
|
||||
<void_ptr> multialloc_cached_counted;
|
||||
typedef boost::container::dtl::
|
||||
transform_multiallocation_chain
|
||||
< multialloc_cached_counted, value_type> multiallocation_chain;
|
||||
|
||||
//Node allocation interface
|
||||
static pointer allocate_one(Allocator &a)
|
||||
{ return a.allocate(1); }
|
||||
|
||||
static void deallocate_one(Allocator &a, const pointer &p)
|
||||
{ a.deallocate(p, 1); }
|
||||
|
||||
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
|
||||
{
|
||||
size_type n = holder.size();
|
||||
typename multiallocation_chain::iterator it = holder.begin();
|
||||
while(n){
|
||||
--n;
|
||||
pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
|
||||
++it;
|
||||
a.deallocate(p, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct allocate_individual_rollback
|
||||
{
|
||||
allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
|
||||
: mr_a(a), mp_chain(&chain)
|
||||
{}
|
||||
|
||||
~allocate_individual_rollback()
|
||||
{
|
||||
if(mp_chain)
|
||||
allocator_version_traits::deallocate_individual(mr_a, *mp_chain);
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
mp_chain = 0;
|
||||
}
|
||||
|
||||
Allocator &mr_a;
|
||||
multiallocation_chain * mp_chain;
|
||||
};
|
||||
|
||||
static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
|
||||
{
|
||||
allocate_individual_rollback rollback(a, m);
|
||||
while(n--){
|
||||
m.push_front(a.allocate(1));
|
||||
}
|
||||
rollback.release();
|
||||
}
|
||||
|
||||
static pointer allocation_command(Allocator &a, allocation_type command,
|
||||
size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
|
||||
{
|
||||
pointer ret = pointer();
|
||||
if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
|
||||
throw_logic_error("version 1 allocator without allocate_new flag");
|
||||
}
|
||||
else{
|
||||
BOOST_TRY{
|
||||
ret = a.allocate(prefer_in_recvd_out_size);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
if(!(command & nothrow_allocation)){
|
||||
BOOST_RETHROW
|
||||
}
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
reuse = pointer();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)
|
||||
@@ -0,0 +1,51 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-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_AUTO_LINK_HPP_INCLUDED
|
||||
#define BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//Define BOOST_CONTAINER_DYNAMIC_LINKING which is independent from BOOST_*_NO_LIB
|
||||
//and is needed is some tests that need to disable some checks (like operator new replacements)
|
||||
//that don't work across DLL boundaries
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
||||
# define BOOST_CONTAINER_DYNAMIC_LINKING
|
||||
#endif
|
||||
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_CONTAINER_NO_LIB) && !defined(BOOST_CONTAINER_SOURCE)
|
||||
//
|
||||
// Set the name of our library, this will get undef'ed by auto_link.hpp
|
||||
// once it's done with it:
|
||||
//
|
||||
#define BOOST_LIB_NAME boost_container
|
||||
|
||||
//
|
||||
// If we're importing code from a dll, then tell auto_link.hpp about it:
|
||||
//
|
||||
#if defined(BOOST_CONTAINER_DYNAMIC_LINKING)
|
||||
# define BOOST_DYN_LINK
|
||||
#endif
|
||||
|
||||
//
|
||||
// And include the header that does the work:
|
||||
//
|
||||
#include <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
|
||||
@@ -0,0 +1,140 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_DETAIL_BLOCK_LIST_HEADER
|
||||
#define BOOST_CONTAINER_DETAIL_BLOCK_LIST_HEADER
|
||||
|
||||
#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/container_fwd.hpp>
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/intrusive/circular_list_algorithms.hpp>
|
||||
#include <boost/move/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace pmr {
|
||||
|
||||
struct list_node
|
||||
{
|
||||
list_node *next;
|
||||
list_node *previous;
|
||||
};
|
||||
|
||||
struct list_node_traits
|
||||
{
|
||||
typedef list_node node;
|
||||
typedef list_node* node_ptr;
|
||||
typedef const list_node* const_node_ptr;
|
||||
|
||||
static node_ptr get_next(const_node_ptr n)
|
||||
{ return n->next; }
|
||||
|
||||
static node_ptr get_previous(const_node_ptr n)
|
||||
{ return n->previous; }
|
||||
|
||||
static void set_next(const node_ptr & n, const node_ptr & next)
|
||||
{ n->next = next; }
|
||||
|
||||
static void set_previous(const node_ptr & n, const node_ptr & previous)
|
||||
{ n->previous = previous; }
|
||||
};
|
||||
|
||||
struct block_list_header
|
||||
: public list_node
|
||||
{
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
typedef bi::circular_list_algorithms<list_node_traits> list_algo;
|
||||
|
||||
|
||||
template<class DerivedFromBlockListHeader = block_list_header>
|
||||
class block_list_base
|
||||
{
|
||||
list_node m_list;
|
||||
|
||||
static const std::size_t MaxAlignMinus1 = memory_resource::max_align-1u;
|
||||
|
||||
public:
|
||||
|
||||
static const std::size_t header_size = std::size_t(sizeof(DerivedFromBlockListHeader) + MaxAlignMinus1) & std::size_t(~MaxAlignMinus1);
|
||||
|
||||
explicit block_list_base()
|
||||
{ list_algo::init_header(&m_list); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
block_list_base(const block_list_base&) = delete;
|
||||
block_list_base operator=(const block_list_base&) = delete;
|
||||
#else
|
||||
private:
|
||||
block_list_base (const block_list_base&);
|
||||
block_list_base operator=(const block_list_base&);
|
||||
public:
|
||||
#endif
|
||||
|
||||
~block_list_base()
|
||||
{}
|
||||
|
||||
void *allocate(std::size_t size, memory_resource &mr)
|
||||
{
|
||||
if((size_t(-1) - header_size) < size)
|
||||
throw_bad_alloc();
|
||||
void *p = mr.allocate(size+header_size);
|
||||
block_list_header &mb = *::new((void*)p, boost_container_new_t()) DerivedFromBlockListHeader;
|
||||
mb.size = size+header_size;
|
||||
list_algo::link_after(&m_list, &mb);
|
||||
return (char *)p + header_size;
|
||||
}
|
||||
|
||||
void deallocate(void *p, memory_resource &mr) BOOST_NOEXCEPT
|
||||
{
|
||||
DerivedFromBlockListHeader *pheader = static_cast<DerivedFromBlockListHeader*>
|
||||
(static_cast<void*>((char*)p - header_size));
|
||||
list_algo::unlink(pheader);
|
||||
const std::size_t size = pheader->size;
|
||||
static_cast<DerivedFromBlockListHeader*>(pheader)->~DerivedFromBlockListHeader();
|
||||
mr.deallocate(pheader, size, memory_resource::max_align);
|
||||
}
|
||||
|
||||
void release(memory_resource &mr) BOOST_NOEXCEPT
|
||||
{
|
||||
list_node *n = list_algo::node_traits::get_next(&m_list);
|
||||
while(n != &m_list){
|
||||
DerivedFromBlockListHeader &d = static_cast<DerivedFromBlockListHeader&>(*n);
|
||||
n = list_algo::node_traits::get_next(n);
|
||||
std::size_t size = d.size;
|
||||
d.~DerivedFromBlockListHeader();
|
||||
mr.deallocate(reinterpret_cast<char*>(&d), size, memory_resource::max_align);
|
||||
}
|
||||
list_algo::init_header(&m_list);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace pmr {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_BLOCK_LIST_HEADER
|
||||
@@ -0,0 +1,158 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_DETAIL_BLOCK_SLIST_HEADER
|
||||
#define BOOST_CONTAINER_DETAIL_BLOCK_SLIST_HEADER
|
||||
|
||||
#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/container_fwd.hpp>
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
|
||||
#include <boost/move/detail/type_traits.hpp>
|
||||
#include <boost/intrusive/linear_slist_algorithms.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace pmr {
|
||||
|
||||
struct slist_node
|
||||
{
|
||||
slist_node *next;
|
||||
};
|
||||
|
||||
struct slist_node_traits
|
||||
{
|
||||
typedef slist_node node;
|
||||
typedef slist_node* node_ptr;
|
||||
typedef const slist_node* const_node_ptr;
|
||||
|
||||
static node_ptr get_next(const_node_ptr n)
|
||||
{ return n->next; }
|
||||
|
||||
static void set_next(const node_ptr & n, const node_ptr & next)
|
||||
{ n->next = next; }
|
||||
};
|
||||
|
||||
struct block_slist_header
|
||||
: public slist_node
|
||||
{
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
typedef bi::linear_slist_algorithms<slist_node_traits> slist_algo;
|
||||
|
||||
template<class DerivedFromBlockSlistHeader = block_slist_header>
|
||||
class block_slist_base
|
||||
{
|
||||
slist_node m_slist;
|
||||
|
||||
static const std::size_t MaxAlignMinus1 = memory_resource::max_align-1u;
|
||||
|
||||
public:
|
||||
|
||||
static const std::size_t header_size = std::size_t(sizeof(DerivedFromBlockSlistHeader) + MaxAlignMinus1) & std::size_t(~MaxAlignMinus1);
|
||||
|
||||
explicit block_slist_base()
|
||||
{ slist_algo::init_header(&m_slist); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
block_slist_base(const block_slist_base&) = delete;
|
||||
block_slist_base operator=(const block_slist_base&) = delete;
|
||||
#else
|
||||
private:
|
||||
block_slist_base (const block_slist_base&);
|
||||
block_slist_base operator=(const block_slist_base&);
|
||||
public:
|
||||
#endif
|
||||
|
||||
~block_slist_base()
|
||||
{}
|
||||
|
||||
void *allocate(std::size_t size, memory_resource &mr)
|
||||
{
|
||||
if((size_t(-1) - header_size) < size)
|
||||
throw_bad_alloc();
|
||||
void *p = mr.allocate(size+header_size);
|
||||
block_slist_header &mb = *::new((void*)p, boost_container_new_t()) DerivedFromBlockSlistHeader;
|
||||
mb.size = size+header_size;
|
||||
slist_algo::link_after(&m_slist, &mb);
|
||||
return (char *)p + header_size;
|
||||
}
|
||||
|
||||
void release(memory_resource &mr) BOOST_NOEXCEPT
|
||||
{
|
||||
slist_node *n = slist_algo::node_traits::get_next(&m_slist);
|
||||
while(n){
|
||||
DerivedFromBlockSlistHeader &d = static_cast<DerivedFromBlockSlistHeader&>(*n);
|
||||
n = slist_algo::node_traits::get_next(n);
|
||||
std::size_t size = d.block_slist_header::size;
|
||||
d.~DerivedFromBlockSlistHeader();
|
||||
mr.deallocate(reinterpret_cast<char*>(&d), size, memory_resource::max_align);
|
||||
}
|
||||
slist_algo::init_header(&m_slist);
|
||||
}
|
||||
};
|
||||
|
||||
class block_slist
|
||||
: public block_slist_base<>
|
||||
{
|
||||
memory_resource &m_upstream_rsrc;
|
||||
|
||||
public:
|
||||
|
||||
explicit block_slist(memory_resource &upstream_rsrc)
|
||||
: block_slist_base<>(), m_upstream_rsrc(upstream_rsrc)
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
block_slist(const block_slist&) = delete;
|
||||
block_slist operator=(const block_slist&) = delete;
|
||||
#else
|
||||
private:
|
||||
block_slist (const block_slist&);
|
||||
block_slist operator=(const block_slist&);
|
||||
public:
|
||||
#endif
|
||||
|
||||
~block_slist()
|
||||
{ this->release(); }
|
||||
|
||||
void *allocate(std::size_t size)
|
||||
{ return this->block_slist_base<>::allocate(size, m_upstream_rsrc); }
|
||||
|
||||
void release() BOOST_NOEXCEPT
|
||||
{ return this->block_slist_base<>::release(m_upstream_rsrc); }
|
||||
|
||||
memory_resource& upstream_resource() const BOOST_NOEXCEPT
|
||||
{ return m_upstream_rsrc; }
|
||||
};
|
||||
|
||||
} //namespace pmr {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_BLOCK_SLIST_HEADER
|
||||
@@ -0,0 +1,131 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<class ValueType>
|
||||
class equal_to_value
|
||||
{
|
||||
typedef ValueType value_type;
|
||||
const value_type &t_;
|
||||
|
||||
public:
|
||||
explicit equal_to_value(const value_type &t)
|
||||
: t_(t)
|
||||
{}
|
||||
|
||||
bool operator()(const value_type &t)const
|
||||
{ return t_ == t; }
|
||||
};
|
||||
|
||||
template<class Node, class Pred, class Ret = bool>
|
||||
struct value_to_node_compare
|
||||
: Pred
|
||||
{
|
||||
typedef Pred predicate_type;
|
||||
typedef Node node_type;
|
||||
|
||||
value_to_node_compare()
|
||||
: Pred()
|
||||
{}
|
||||
|
||||
explicit value_to_node_compare(Pred pred)
|
||||
: Pred(pred)
|
||||
{}
|
||||
|
||||
Ret operator()(const Node &a, const Node &b) const
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data(), b.get_data()); }
|
||||
|
||||
Ret operator()(const Node &a) const
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data()); }
|
||||
|
||||
Ret operator()(const Node &a, const Node &b)
|
||||
{ return static_cast<Pred&>(*this)(a.get_data(), b.get_data()); }
|
||||
|
||||
Ret operator()(const Node &a)
|
||||
{ return static_cast<Pred&>(*this)(a.get_data()); }
|
||||
|
||||
predicate_type & predicate() { return static_cast<predicate_type&>(*this); }
|
||||
const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); }
|
||||
};
|
||||
|
||||
template<class KeyPred, class KeyOfValue, class Node, class Ret = bool>
|
||||
struct key_node_pred
|
||||
: public boost::intrusive::detail::ebo_functor_holder<KeyPred>
|
||||
{
|
||||
BOOST_CONTAINER_FORCEINLINE explicit key_node_pred(const KeyPred &comp)
|
||||
: base_t(comp)
|
||||
{}
|
||||
|
||||
typedef boost::intrusive::detail::ebo_functor_holder<KeyPred> base_t;
|
||||
typedef KeyPred key_predicate;
|
||||
typedef KeyOfValue key_of_value;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE static const key_type &key_from(const Node &n)
|
||||
{
|
||||
return key_of_value()(n.get_data());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
BOOST_CONTAINER_FORCEINLINE static const T &
|
||||
key_from(const T &t)
|
||||
{ return t; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const key_predicate &key_pred() const
|
||||
{ return static_cast<const key_predicate &>(*this); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE key_predicate &key_pred()
|
||||
{ return static_cast<key_predicate &>(*this); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const key_type &key) const
|
||||
{ return this->key_pred()(key); }
|
||||
|
||||
template<class U>
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const U &nonkey) const
|
||||
{ return this->key_pred()(this->key_from(nonkey)); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const
|
||||
{ return this->key_pred()(key1, key2); }
|
||||
|
||||
template<class U>
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const U &nonkey2) const
|
||||
{ return this->key_pred()(key1, this->key_from(nonkey2)); }
|
||||
|
||||
template<class U>
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2) const
|
||||
{ return this->key_pred()(this->key_from(nonkey1), key2); }
|
||||
|
||||
template<class U, class V>
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const V &nonkey2) const
|
||||
{ return this->key_pred()(this->key_from(nonkey1), this->key_from(nonkey2)); }
|
||||
};
|
||||
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
||||
@@ -0,0 +1,50 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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 : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
|
||||
#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 : 4706) // assignment within conditional expression
|
||||
#pragma warning (disable : 4710) // function not inlined
|
||||
#pragma warning (disable : 4714) // "function": marked as __forceinline not inlined
|
||||
#pragma warning (disable : 4711) // function selected for automatic inline expansion
|
||||
#pragma warning (disable : 4786) // identifier truncated in debug info
|
||||
#pragma warning (disable : 4996) // "function": was declared deprecated
|
||||
|
||||
#endif //BOOST_MSVC
|
||||
@@ -0,0 +1,13 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#if defined BOOST_MSVC
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//In place construction
|
||||
|
||||
template<class Allocator, class T, class InpIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source)
|
||||
{ boost::container::allocator_traits<Allocator>::construct(a, dest, *source); }
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest);
|
||||
}
|
||||
|
||||
template <class T, class Difference>
|
||||
class default_init_construct_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest, default_init);
|
||||
}
|
||||
|
||||
template <class T, class EmplaceFunctor, class Difference>
|
||||
class emplace_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class EF, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.construct_in_place(a, dest);
|
||||
}
|
||||
|
||||
//Assignment
|
||||
|
||||
template<class DstIt, class InpIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source)
|
||||
{ *dest = *source; }
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
dtl::value_init<U> val;
|
||||
*dest = boost::move(val.get());
|
||||
}
|
||||
|
||||
template <class DstIt, class Difference>
|
||||
class default_init_construct_iterator;
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
U u;
|
||||
*dest = boost::move(u);
|
||||
}
|
||||
|
||||
template <class T, class EmplaceFunctor, class Difference>
|
||||
class emplace_iterator;
|
||||
|
||||
template<class DstIt, class U, class EF, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.assign_in_place(dest);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/container_rebind.hpp>
|
||||
#include <boost/container/detail/is_container.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class AllocatorOrContainer, class ToType, bool = is_container<AllocatorOrContainer>::value>
|
||||
struct container_or_allocator_rebind_impl
|
||||
: container_rebind<AllocatorOrContainer, ToType>
|
||||
{};
|
||||
|
||||
template<class AllocatorOrContainer, class ToType>
|
||||
struct container_or_allocator_rebind_impl<AllocatorOrContainer, ToType, false>
|
||||
: allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc<ToType>
|
||||
{};
|
||||
|
||||
template<class ToType>
|
||||
struct container_or_allocator_rebind_impl<void, ToType, false>
|
||||
: real_allocator<ToType, void>
|
||||
{};
|
||||
|
||||
template<class AllocatorOrContainer, class ToType>
|
||||
struct container_or_allocator_rebind
|
||||
: container_or_allocator_rebind_impl<AllocatorOrContainer, ToType>
|
||||
{};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
||||
@@ -0,0 +1,163 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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_CONTAINER_REBIND_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template <class Cont, class U>
|
||||
struct container_rebind;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <template <class, class, class...> class Cont, typename V, typename A, class... An, class U>
|
||||
struct container_rebind<Cont<V, A, An...>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, An...> type;
|
||||
};
|
||||
|
||||
//Needed for non-conforming compilers like GCC 4.3
|
||||
template <template <class, class> class Cont, typename V, typename A, class U>
|
||||
struct container_rebind<Cont<V, A>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type> type;
|
||||
};
|
||||
|
||||
template <template <class> class Cont, typename V, class U>
|
||||
struct container_rebind<Cont<V>, U>
|
||||
{
|
||||
typedef Cont<U> type;
|
||||
};
|
||||
|
||||
#else //C++03 compilers
|
||||
|
||||
template <template <class> class Cont //0arg
|
||||
, typename V
|
||||
, class U>
|
||||
struct container_rebind<Cont<V>, U>
|
||||
{
|
||||
typedef Cont<U> type;
|
||||
};
|
||||
|
||||
template <template <class, class> class Cont //0arg
|
||||
, typename V, typename A
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class> class Cont //1arg
|
||||
, typename V, typename A, class P0
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class> class Cont //2arg
|
||||
, typename V, typename A, class P0, class P1
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class, class> class Cont //3arg
|
||||
, typename V, typename A, class P0, class P1, class P2
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class, class, class> class Cont //4arg
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class, class, class, class> class Cont //5arg
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class, class, class, class, class> class Cont //6arg
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class, class, class, class, class, class> class Cont //7arg
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class, class, class, class, class, class, class> class Cont //8arg
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type;
|
||||
};
|
||||
|
||||
template <template <class, class, class, class, class, class, class, class, class, class, class> class Cont //9arg
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
|
||||
, class U>
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U>
|
||||
{
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type;
|
||||
};
|
||||
|
||||
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//for small_vector,static_vector
|
||||
|
||||
template <typename V, std::size_t N, typename A, typename O, class U>
|
||||
struct container_rebind<small_vector<V, N, A, O>, U>
|
||||
{
|
||||
typedef small_vector<U, N, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, O> type;
|
||||
};
|
||||
|
||||
template <typename V, std::size_t N, typename O, class U>
|
||||
struct container_rebind<static_vector<V, N, O>, U>
|
||||
{
|
||||
typedef static_vector<U, N, O> type;
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,447 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
//!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 dtl::integral_constant<unsigned,
|
||||
boost::container::dtl::
|
||||
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 dtl::integral_constant<unsigned,
|
||||
boost::container::dtl::
|
||||
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, boost::movelib::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;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE scoped_destructor_n(pointer p, Allocator& a, size_type n)
|
||||
: m_p(p), m_a(a), m_n(n)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void release()
|
||||
{ m_p = 0; m_n = 0; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size(size_type inc)
|
||||
{ m_n += inc; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(size_type inc)
|
||||
{ m_n += inc; m_p -= inc; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void shrink_forward(size_type inc)
|
||||
{ m_n -= inc; m_p += inc; }
|
||||
|
||||
~scoped_destructor_n()
|
||||
{
|
||||
if(m_n){
|
||||
value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
|
||||
do {
|
||||
--m_n;
|
||||
AllocTraits::destroy(m_a, raw_ptr);
|
||||
++raw_ptr;
|
||||
} while(m_n);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_n(pointer, Allocator&, size_type)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size(size_type)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(size_type)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void shrink_forward(size_type)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void release()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//!A deleter for scoped_ptr that destroys
|
||||
//!an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_destructor_range
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
typedef typename AllocTraits::pointer pointer;
|
||||
typedef typename AllocTraits::value_type value_type;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE scoped_destructor_range(pointer p, pointer e, Allocator& a)
|
||||
: m_p(p), m_e(e), m_a(a)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void release()
|
||||
{ m_p = pointer(); m_e = pointer(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void set_end(pointer e)
|
||||
{ m_e = e; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void set_begin(pointer b)
|
||||
{ m_p = b; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void set_range(pointer b, pointer e)
|
||||
{ m_p = b; m_e = e; }
|
||||
|
||||
~scoped_destructor_range()
|
||||
{
|
||||
while(m_p != m_e){
|
||||
value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
|
||||
AllocTraits::destroy(m_a, raw_ptr);
|
||||
++m_p;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
pointer m_p;
|
||||
pointer m_e;
|
||||
Allocator & m_a;
|
||||
};
|
||||
|
||||
//!A deleter for scoped_ptr that destroys
|
||||
//!an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct null_scoped_destructor_range
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
typedef typename AllocTraits::pointer pointer;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_range(pointer, pointer, Allocator&)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void release()
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void set_end(pointer)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void set_begin(pointer)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void set_range(pointer, pointer)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template<class Allocator>
|
||||
class scoped_destructor
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
public:
|
||||
typedef typename Allocator::value_type value_type;
|
||||
BOOST_CONTAINER_FORCEINLINE scoped_destructor(Allocator &a, value_type *pv)
|
||||
: pv_(pv), a_(a)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE ~scoped_destructor()
|
||||
{
|
||||
if(pv_){
|
||||
AllocTraits::destroy(a_, pv_);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void release()
|
||||
{ pv_ = 0; }
|
||||
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; }
|
||||
|
||||
private:
|
||||
value_type *pv_;
|
||||
Allocator &a_;
|
||||
};
|
||||
|
||||
|
||||
template<class Allocator, class Value = typename Allocator::value_type>
|
||||
class value_destructor
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
public:
|
||||
typedef Value value_type;
|
||||
BOOST_CONTAINER_FORCEINLINE value_destructor(Allocator &a, value_type &rv)
|
||||
: rv_(rv), a_(a)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE ~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 dtl::integral_constant<unsigned,
|
||||
boost::container::dtl::
|
||||
version<Allocator>::value> alloc_version;
|
||||
|
||||
private:
|
||||
Allocator & a_;
|
||||
|
||||
private:
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_1)
|
||||
{ AllocTraits::deallocate(a_,p, 1); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_2)
|
||||
{ a_.deallocate_one(p); }
|
||||
|
||||
public:
|
||||
BOOST_CONTAINER_FORCEINLINE explicit allocator_destroyer(Allocator &a)
|
||||
: a_(a)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(const pointer &p)
|
||||
{
|
||||
AllocTraits::destroy(a_, boost::movelib::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:
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
|
||||
: a_(a), c_(c)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(const typename Allocator::pointer &p)
|
||||
{
|
||||
allocator_traits<Allocator>::destroy(a_, boost::movelib::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:
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_multialloc_chain_node_deallocator(Allocator &a)
|
||||
: a_(a), c_()
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE chain_builder get_chain_builder()
|
||||
{ return chain_builder(a_, c_); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE ~allocator_multialloc_chain_node_deallocator()
|
||||
{
|
||||
a_.deallocate_individual(c_);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP
|
||||
@@ -0,0 +1,461 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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 dtl {
|
||||
|
||||
|
||||
// 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
|
||||
>
|
||||
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
|
||||
< void
|
||||
, dtl::is_not_pair<T>
|
||||
, dtl::not_< uses_allocator<T, typename remove_cvref<ArgAlloc>::type > >
|
||||
>::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
|
||||
>
|
||||
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
|
||||
< void
|
||||
, dtl::is_not_pair<T>
|
||||
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
|
||||
, 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
|
||||
>
|
||||
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
|
||||
< void
|
||||
, dtl::is_not_pair<T>
|
||||
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
|
||||
, dtl::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 >\
|
||||
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
|
||||
< void\
|
||||
, dtl::is_not_pair<T>\
|
||||
, dtl::not_<uses_allocator<T, typename remove_cvref<ArgAlloc>::type> >\
|
||||
>::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 >\
|
||||
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
|
||||
< void\
|
||||
, dtl::is_not_pair<T>\
|
||||
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
|
||||
, 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 >\
|
||||
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
|
||||
< void\
|
||||
, dtl::is_not_pair<T>\
|
||||
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
|
||||
, dtl::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 dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void >::type)
|
||||
dispatch_uses_allocator
|
||||
( ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p)
|
||||
{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first));
|
||||
BOOST_TRY{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second));
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, class Pair, class U, class V>
|
||||
BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void>::type)
|
||||
dispatch_uses_allocator
|
||||
( ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
||||
{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<U>(x));
|
||||
BOOST_TRY{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<V>(y));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, class Pair, class Pair2>
|
||||
BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void >::type)
|
||||
dispatch_uses_allocator
|
||||
(ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p, Pair2& x)
|
||||
{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, x.first, x.second); }
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, class Pair, class Pair2>
|
||||
typename dtl::enable_if_and
|
||||
< void
|
||||
, dtl::is_pair<Pair>
|
||||
, dtl::not_<boost::move_detail::is_reference<Pair2> > >::type //This is needed for MSVC10 and ambiguous overloads
|
||||
dispatch_uses_allocator
|
||||
(ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p, BOOST_RV_REF_BEG Pair2 BOOST_RV_REF_END x)
|
||||
{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second)); }
|
||||
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair \
|
||||
, template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
|
||||
dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
|
||||
, BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
|
||||
{\
|
||||
(void)p; (void)q;\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_TMPL_GET##N);\
|
||||
BOOST_TRY{\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_TMPL_GETQ##M);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
|
||||
|
||||
//piecewise construction from Std Tuple
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair
|
||||
, template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
|
||||
void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair
|
||||
, Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
|
||||
{
|
||||
(void)t1; (void)t2;
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->first), ::boost::forward<Args1>(get<Indexes1>(t1))...);
|
||||
BOOST_TRY{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->second), ::boost::forward<Args2>(get<Indexes2>(t2))...);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair
|
||||
, template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
|
||||
dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t
|
||||
, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
{
|
||||
(dispatch_uses_allocator_index)( construct_alloc, arg_alloc, pair, t1, t2
|
||||
, typename build_number_seq<sizeof...(Args1)>::type()
|
||||
, typename build_number_seq<sizeof...(Args2)>::type());
|
||||
}
|
||||
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
|
||||
//MSVC 2010 tuple implementation
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair\
|
||||
, template<class, class, class, class, class, class, class, class, class, class> class StdTuple\
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
|
||||
dispatch_uses_allocator(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
|
||||
{\
|
||||
(void)p; (void)q;\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
|
||||
BOOST_TRY{\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
#if _VARIADIC_MAX >= 9
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
|
||||
#else
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
|
||||
#endif
|
||||
|
||||
//MSVC 2012 tuple implementation
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair\
|
||||
, template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
|
||||
dispatch_uses_allocator\
|
||||
( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
|
||||
{\
|
||||
(void)p; (void)q;\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
|
||||
BOOST_TRY{\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
|
||||
|
||||
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, class Pair, class KeyType, class ... Args>
|
||||
typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
|
||||
dispatch_uses_allocator
|
||||
(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args)
|
||||
{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));
|
||||
BOOST_TRY{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<Args>(args)...);
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE(N) \
|
||||
template <typename ConstructAlloc, typename ArgAlloc, class Pair, class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
inline typename dtl::enable_if\
|
||||
< dtl::is_pair<Pair> BOOST_MOVE_I void >::type\
|
||||
dispatch_uses_allocator\
|
||||
(ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, \
|
||||
BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));\
|
||||
BOOST_TRY{\
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE)
|
||||
#undef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE
|
||||
|
||||
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
} //namespace dtl
|
||||
|
||||
}} // namespace boost { namespace container {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
|
||||
103
install/boost_1_75_0/include/boost/container/detail/dlmalloc.hpp
Normal file
103
install/boost_1_75_0/include/boost/container/detail/dlmalloc.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_DETAIL_ALLOC_LIB_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOC_LIB_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/auto_link.hpp>
|
||||
|
||||
#include <boost/container/detail/alloc_lib.h>
|
||||
|
||||
namespace boost{
|
||||
namespace container{
|
||||
|
||||
typedef boost_cont_command_ret_t dlmalloc_command_ret_t;
|
||||
typedef boost_cont_memchain dlmalloc_memchain;
|
||||
typedef boost_cont_memchain_it dlmalloc_memchain_it;
|
||||
typedef boost_cont_malloc_stats_t dlmalloc_malloc_stats_t;
|
||||
|
||||
BOOST_CONTAINER_DECL size_t dlmalloc_size(const void *p);
|
||||
|
||||
BOOST_CONTAINER_DECL void* dlmalloc_malloc(size_t bytes);
|
||||
|
||||
BOOST_CONTAINER_DECL void dlmalloc_free(void* mem);
|
||||
|
||||
BOOST_CONTAINER_DECL void* dlmalloc_memalign(size_t bytes, size_t alignment);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_multialloc_nodes
|
||||
(size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_multialloc_arrays
|
||||
(size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL void dlmalloc_multidealloc(boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL size_t dlmalloc_footprint();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t dlmalloc_allocated_memory();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t dlmalloc_chunksize(const void *p);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_all_deallocated();
|
||||
|
||||
BOOST_CONTAINER_DECL boost_cont_malloc_stats_t dlmalloc_malloc_stats();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t dlmalloc_in_use_memory();
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_trim(size_t pad);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_mallopt(int parameter_number, int parameter_value);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_grow(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_shrink(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit);
|
||||
|
||||
BOOST_CONTAINER_DECL void* dlmalloc_alloc(size_t minbytes, size_t preferred_bytes, size_t *received_bytes);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_malloc_check();
|
||||
|
||||
BOOST_CONTAINER_DECL boost_cont_command_ret_t dlmalloc_allocation_command
|
||||
( allocation_type command
|
||||
, size_t sizeof_object
|
||||
, size_t limit_objects
|
||||
, size_t preferred_objects
|
||||
, size_t *received_objects
|
||||
, void *reuse_ptr
|
||||
);
|
||||
|
||||
BOOST_CONTAINER_DECL int dlmalloc_mallopt(int param_number, int value);
|
||||
|
||||
BOOST_CONTAINER_DECL void *dlmalloc_sync_create();
|
||||
|
||||
BOOST_CONTAINER_DECL void dlmalloc_sync_destroy(void *sync);
|
||||
|
||||
BOOST_CONTAINER_DECL bool dlmalloc_sync_lock(void *sync);
|
||||
|
||||
BOOST_CONTAINER_DECL void dlmalloc_sync_unlock(void *sync);
|
||||
|
||||
BOOST_CONTAINER_DECL bool dlmalloc_global_sync_lock();
|
||||
|
||||
BOOST_CONTAINER_DECL void dlmalloc_global_sync_unlock();
|
||||
|
||||
} //namespace container{
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_ALLOC_LIB_HPP
|
||||
1629
install/boost_1_75_0/include/boost/container/detail/flat_tree.hpp
Normal file
1629
install/boost_1_75_0/include/boost/container/detail/flat_tree.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,96 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-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 was modified from the code posted by Alexandre Courpron in his
|
||||
// article "Interface Detection" in The Code Project:
|
||||
// http://www.codeproject.com/KB/architecture/Detector.aspx
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2007 Alexandre Courpron
|
||||
//
|
||||
// Permission to use, copy, modify, redistribute and sell this software,
|
||||
// provided that this copyright notice appears on all copies of the software.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
|
||||
|
||||
#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>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace function_detector {
|
||||
|
||||
typedef char NotFoundType;
|
||||
struct StaticFunctionType { NotFoundType x [2]; };
|
||||
struct NonStaticFunctionType { NotFoundType x [3]; };
|
||||
|
||||
enum
|
||||
{ NotFound = 0,
|
||||
StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ),
|
||||
NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
|
||||
};
|
||||
|
||||
} //namespace boost {
|
||||
} //namespace container {
|
||||
} //namespace function_detector {
|
||||
|
||||
#define BOOST_CONTAINER_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
|
||||
namespace boost { \
|
||||
namespace container { \
|
||||
namespace function_detector { \
|
||||
template < class T, \
|
||||
class NonStaticType, \
|
||||
class NonStaticConstType, \
|
||||
class StaticType > \
|
||||
class DetectMember_##InstantiationKey_##Identifier { \
|
||||
template < NonStaticType > \
|
||||
struct TestNonStaticNonConst ; \
|
||||
\
|
||||
template < NonStaticConstType > \
|
||||
struct TestNonStaticConst ; \
|
||||
\
|
||||
template < StaticType > \
|
||||
struct TestStatic ; \
|
||||
\
|
||||
template <class U > \
|
||||
static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
|
||||
\
|
||||
template <class U > \
|
||||
static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
|
||||
\
|
||||
template <class U> \
|
||||
static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
|
||||
\
|
||||
template <class U> \
|
||||
static NotFoundType Test( ... ); \
|
||||
public : \
|
||||
static const int check = NotFound + (sizeof(Test<T>(0, 0)) - sizeof(NotFoundType));\
|
||||
};\
|
||||
}}} //namespace boost::container::function_detector {
|
||||
|
||||
#define BOOST_CONTAINER_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
|
||||
::boost::container::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
|
||||
ReturnType (Class::*)Params,\
|
||||
ReturnType (Class::*)Params const,\
|
||||
ReturnType (*)Params \
|
||||
>::check
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //@ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
|
||||
@@ -0,0 +1,198 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Benedek Thaler 2015-2016
|
||||
// (C) Copyright Ion Gaztanaga 2019-2020. 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://erenon.hu/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_GUARDS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_GUARDS_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/move/core.hpp> // BOOST_MOVABLE_BUT_NOT_COPYABLE
|
||||
|
||||
// move/detail
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace detail {
|
||||
|
||||
class null_construction_guard
|
||||
{
|
||||
public:
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template <typename... Args>
|
||||
null_construction_guard(Args&&...) {}
|
||||
|
||||
#else
|
||||
|
||||
#define NULL_CONSTRUCTION_GUARD_CODE(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE null_construction_guard(BOOST_MOVE_UREFANON##N)\
|
||||
{}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(NULL_CONSTRUCTION_GUARD_CODE)
|
||||
#undef NULL_CONSTRUCTION_GUARD_CODE
|
||||
#endif
|
||||
|
||||
void release() {}
|
||||
void extend() {}
|
||||
};
|
||||
|
||||
template <typename Allocator>
|
||||
class construction_guard
|
||||
{
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(construction_guard)
|
||||
|
||||
public:
|
||||
construction_guard()
|
||||
: _alloc_ptr()
|
||||
, _elem_count()
|
||||
, _allocator()
|
||||
{}
|
||||
|
||||
construction_guard(pointer alloc_ptr, Allocator& allocator)
|
||||
:_alloc_ptr(alloc_ptr)
|
||||
, _elem_count(0)
|
||||
, _allocator(&allocator)
|
||||
{}
|
||||
|
||||
construction_guard(BOOST_RV_REF(construction_guard) rhs)
|
||||
:_alloc_ptr(rhs._alloc_ptr)
|
||||
, _elem_count(rhs._elem_count)
|
||||
, _allocator(rhs._allocator)
|
||||
{
|
||||
rhs._elem_count = 0;
|
||||
}
|
||||
|
||||
~construction_guard()
|
||||
{
|
||||
while (_elem_count) {
|
||||
--_elem_count;
|
||||
boost::container::allocator_traits<Allocator>::destroy(*_allocator, _alloc_ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
_elem_count = 0;
|
||||
}
|
||||
|
||||
void extend()
|
||||
{
|
||||
++_elem_count;
|
||||
}
|
||||
|
||||
private:
|
||||
pointer _alloc_ptr;
|
||||
size_type _elem_count;
|
||||
Allocator* _allocator;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Has two ranges
|
||||
*
|
||||
* On success, destroys the first range (src),
|
||||
* on failure, destroys the second range (dst).
|
||||
*
|
||||
* Can be used when copying/moving a range
|
||||
*/
|
||||
template <class Allocator>
|
||||
class nand_construction_guard
|
||||
{
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
|
||||
construction_guard<Allocator> _src;
|
||||
construction_guard<Allocator> _dst;
|
||||
bool _dst_released;
|
||||
|
||||
public:
|
||||
nand_construction_guard()
|
||||
: _src()
|
||||
, _dst()
|
||||
, _dst_released(false)
|
||||
{}
|
||||
|
||||
nand_construction_guard( pointer src, Allocator& src_alloc
|
||||
, pointer dst, Allocator& dst_alloc)
|
||||
:_src(src, src_alloc),
|
||||
_dst(dst, dst_alloc),
|
||||
_dst_released(false)
|
||||
{}
|
||||
|
||||
void extend()
|
||||
{
|
||||
_src.extend();
|
||||
_dst.extend();
|
||||
}
|
||||
|
||||
void release() // on success
|
||||
{
|
||||
_dst.release();
|
||||
_dst_released = true;
|
||||
}
|
||||
|
||||
~nand_construction_guard()
|
||||
{
|
||||
if (! _dst_released) { _src.release(); }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Allocator>
|
||||
class allocation_guard
|
||||
{
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(allocation_guard)
|
||||
|
||||
public:
|
||||
allocation_guard(pointer alloc_ptr, size_type alloc_size, Allocator& allocator)
|
||||
:_alloc_ptr(alloc_ptr),
|
||||
_alloc_size(alloc_size),
|
||||
_allocator(allocator)
|
||||
{}
|
||||
|
||||
~allocation_guard()
|
||||
{
|
||||
if (_alloc_ptr)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::deallocate(_allocator, _alloc_ptr, _alloc_size);
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
_alloc_ptr = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
pointer _alloc_ptr;
|
||||
size_type _alloc_size;
|
||||
Allocator& _allocator;
|
||||
};
|
||||
|
||||
}}} // namespace boost::container::detail
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_DETAIL_GUARDS_HPP
|
||||
@@ -0,0 +1,62 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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_IS_CONTAINER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//empty
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME empty
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
//size
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME size
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template <class Container>
|
||||
struct is_container
|
||||
{
|
||||
static const bool value =
|
||||
boost::container::is_container_detail::
|
||||
has_member_function_callable_with_size <const Container>::value &&
|
||||
boost::container::is_container_detail::
|
||||
has_member_function_callable_with_empty<const Container>::value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_container<void>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
||||
@@ -0,0 +1,72 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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_IS_CONTIGUOUS_CONTAINER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//data
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME data
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_contiguous_container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
//back_free_capacity
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME back_free_capacity
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace back_free_capacity_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template <class Container>
|
||||
struct is_contiguous_container
|
||||
{
|
||||
static const bool value =
|
||||
boost::container::is_contiguous_container_detail::
|
||||
has_member_function_callable_with_data<Container>::value &&
|
||||
boost::container::is_contiguous_container_detail::
|
||||
has_member_function_callable_with_data<const Container>::value;
|
||||
};
|
||||
|
||||
|
||||
template < class Container
|
||||
, bool = boost::container::back_free_capacity_detail::
|
||||
has_member_function_callable_with_back_free_capacity<const Container>::value>
|
||||
struct back_free_capacity
|
||||
{
|
||||
static typename Container::size_type get(const Container &c)
|
||||
{ return c.back_free_capacity(); }
|
||||
};
|
||||
|
||||
template < class Container>
|
||||
struct back_free_capacity<Container, false>
|
||||
{
|
||||
static typename Container::size_type get(const Container &c)
|
||||
{ return c.capacity() - c.size(); }
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2016-2016. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template <class ForwardIterator, class Pred>
|
||||
bool is_sorted (ForwardIterator first, ForwardIterator last, Pred pred)
|
||||
{
|
||||
if(first != last){
|
||||
ForwardIterator next = first;
|
||||
while (++next != last){
|
||||
if(pred(*next, *first))
|
||||
return false;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ForwardIterator, class Pred>
|
||||
bool is_sorted_and_unique (ForwardIterator first, ForwardIterator last, Pred pred)
|
||||
{
|
||||
if(first != last){
|
||||
ForwardIterator next = first;
|
||||
while (++next != last){
|
||||
if(!pred(*first, *next))
|
||||
return false;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
||||
@@ -0,0 +1,86 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/container/detail/mpl.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;
|
||||
|
||||
template <class Container>
|
||||
class back_emplacer
|
||||
{
|
||||
private:
|
||||
Container& container;
|
||||
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
back_emplacer(Container& x)
|
||||
: container(x)
|
||||
{}
|
||||
|
||||
template<class U>
|
||||
back_emplacer& operator=(BOOST_FWD_REF(U) value)
|
||||
{
|
||||
container.emplace_back(boost::forward<U>(value));
|
||||
return *this;
|
||||
}
|
||||
back_emplacer& operator*() { return *this; }
|
||||
back_emplacer& operator++() { return *this; }
|
||||
back_emplacer& operator++(int){ return *this; }
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
|
||||
|
||||
template<class InputIterator>
|
||||
using it_based_non_const_first_type_t = typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type;
|
||||
|
||||
template<class InputIterator>
|
||||
using it_based_const_first_type_t = const typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type;
|
||||
|
||||
template<class InputIterator>
|
||||
using it_based_second_type_t = typename iterator_traits<InputIterator>::value_type::second_type;
|
||||
|
||||
template<class InputIterator>
|
||||
using it_based_value_type_t = typename iterator_traits<InputIterator>::value_type;
|
||||
|
||||
#endif
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
@@ -0,0 +1,33 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_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/move/detail/iterator_to_raw_pointer.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
using ::boost::movelib::iterator_to_raw_pointer;
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
|
||||
@@ -0,0 +1,891 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/intrusive/detail/reverse_iterator.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#else
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#endif
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class constant_iterator
|
||||
: public ::boost::container::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef constant_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
BOOST_CONTAINER_FORCEINLINE explicit constant_iterator(const T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator++(int)
|
||||
{
|
||||
constant_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator--(int)
|
||||
{
|
||||
constant_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(Difference off) const
|
||||
{
|
||||
constant_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(Difference off, const constant_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const T& operator[] (Difference ) const
|
||||
{ return dereference(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const T* operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
private:
|
||||
const T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
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
|
||||
{ return *m_ptr; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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:
|
||||
BOOST_CONTAINER_FORCEINLINE explicit value_init_construct_iterator(Difference range_size)
|
||||
: m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator()
|
||||
: m_num(0){}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator++(int)
|
||||
{
|
||||
value_init_construct_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator--(int)
|
||||
{
|
||||
value_init_construct_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator+(Difference off) const
|
||||
{
|
||||
value_init_construct_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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;
|
||||
|
||||
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 n)
|
||||
{ m_num -= n; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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:
|
||||
BOOST_CONTAINER_FORCEINLINE explicit default_init_construct_iterator(Difference range_size)
|
||||
: m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator()
|
||||
: m_num(0){}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator++(int)
|
||||
{
|
||||
default_init_construct_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator--(int)
|
||||
{
|
||||
default_init_construct_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator+(Difference off) const
|
||||
{
|
||||
default_init_construct_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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;
|
||||
|
||||
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 n)
|
||||
{ m_num -= n; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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:
|
||||
BOOST_CONTAINER_FORCEINLINE explicit repeat_iterator(T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
BOOST_CONTAINER_FORCEINLINE repeat_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator++(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator--()
|
||||
{ increment(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator--(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
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 operator- (const this_type& i, const this_type& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator+(Difference off) const
|
||||
{
|
||||
this_type other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend this_type operator+(Difference off, const this_type& right)
|
||||
{ return right + off; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE T& operator[] (Difference ) const
|
||||
{ return dereference(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE T *operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
private:
|
||||
T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
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 T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator++(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE 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; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator+(difference_type off) const
|
||||
{
|
||||
this_type other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right)
|
||||
{ return right + off; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
private:
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
||||
//So comment them to catch bad uses
|
||||
const T& operator*() const;
|
||||
const T& operator[](difference_type) const;
|
||||
const T* operator->() const;
|
||||
|
||||
public:
|
||||
template<class Allocator>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* ptr)
|
||||
{ (*m_pe)(a, ptr); }
|
||||
|
||||
template<class DestIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DestIt dest)
|
||||
{ (*m_pe)(dest); }
|
||||
|
||||
private:
|
||||
difference_type m_num;
|
||||
EmplaceFunctor * m_pe;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void increment()
|
||||
{ --m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(difference_type n)
|
||||
{ m_num -= n; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const
|
||||
{ return difference_type(m_num - other.m_num); }
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class ...Args>
|
||||
struct emplace_functor
|
||||
{
|
||||
typedef typename dtl::build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE emplace_functor(BOOST_FWD_REF(Args)... args)
|
||||
: args_(args...)
|
||||
{}
|
||||
|
||||
template<class Allocator, class T>
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)
|
||||
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
|
||||
|
||||
template<class DestIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)
|
||||
{ emplace_functor::inplace_impl(dest, index_tuple_t()); }
|
||||
|
||||
private:
|
||||
template<class Allocator, class T, std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const dtl::index_tuple<IdxPack...>&)
|
||||
{
|
||||
allocator_traits<Allocator>::construct
|
||||
(a, ptr, ::boost::forward<Args>(dtl::get<IdxPack>(args_))...);
|
||||
}
|
||||
|
||||
template<class DestIt, std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const dtl::index_tuple<IdxPack...>&)
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;
|
||||
value_type && tmp= value_type(::boost::forward<Args>(dtl::get<IdxPack>(args_))...);
|
||||
*dest = ::boost::move(tmp);
|
||||
}
|
||||
|
||||
dtl::tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
template<class ...Args>
|
||||
struct emplace_functor_type
|
||||
{
|
||||
typedef emplace_functor<Args...> type;
|
||||
};
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//Partial specializations cannot match argument list for primary template, so add an extra argument
|
||||
template <BOOST_MOVE_CLASSDFLT9, class Dummy = void>
|
||||
struct emplace_functor_type;
|
||||
|
||||
#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
struct emplace_functor##N\
|
||||
{\
|
||||
BOOST_CONTAINER_FORCEINLINE explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
|
||||
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
|
||||
\
|
||||
template<class Allocator, class T>\
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)\
|
||||
{ allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
|
||||
\
|
||||
template<class DestIt>\
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)\
|
||||
{\
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\
|
||||
BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), dtl::value_init<value_type> tmp) ;\
|
||||
*dest = ::boost::move(const_cast<value_type &>(BOOST_MOVE_IF(N, tmp, tmp.get())));\
|
||||
}\
|
||||
\
|
||||
BOOST_MOVE_MREF##N\
|
||||
};\
|
||||
\
|
||||
template <BOOST_MOVE_CLASS##N>\
|
||||
struct emplace_functor_type<BOOST_MOVE_TARG##N>\
|
||||
{\
|
||||
typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\
|
||||
};\
|
||||
//
|
||||
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
|
||||
|
||||
#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
|
||||
|
||||
#endif
|
||||
|
||||
namespace dtl {
|
||||
|
||||
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;
|
||||
class nat
|
||||
{
|
||||
public:
|
||||
IIterator get() const
|
||||
{ return IIterator(); }
|
||||
};
|
||||
typedef typename dtl::if_c< IsConst
|
||||
, iterator_from_iiterator<IIterator, false>
|
||||
, nat>::type nonconst_iterator;
|
||||
|
||||
public:
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
typedef typename types_t::difference_type difference_type;
|
||||
typedef typename types_t::iterator_category iterator_category;
|
||||
typedef typename types_t::value_type value_type;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator()
|
||||
: m_iit()
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_iit(iit)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_iit(other.get())
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const nonconst_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_iit(other.get())
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator=(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ m_iit = other.get(); return *this; }
|
||||
|
||||
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 dtl {
|
||||
|
||||
using ::boost::intrusive::reverse_iterator;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
@@ -0,0 +1,177 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Stephen Cleary 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2007-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 file is a slightly modified file from Boost.Pool
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_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 <climits>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
// Greatest common divisor and least common multiple
|
||||
|
||||
//
|
||||
// gcd is an algorithm that calculates the greatest common divisor of two
|
||||
// integers, using Euclid's algorithm.
|
||||
//
|
||||
// Pre: A > 0 && B > 0
|
||||
// Recommended: A > B
|
||||
template <typename Integer>
|
||||
inline Integer gcd(Integer A, Integer B)
|
||||
{
|
||||
do
|
||||
{
|
||||
const Integer tmp(B);
|
||||
B = A % B;
|
||||
A = tmp;
|
||||
} while (B != 0);
|
||||
|
||||
return A;
|
||||
}
|
||||
|
||||
//
|
||||
// lcm is an algorithm that calculates the least common multiple of two
|
||||
// integers.
|
||||
//
|
||||
// Pre: A > 0 && B > 0
|
||||
// Recommended: A > B
|
||||
template <typename Integer>
|
||||
inline Integer lcm(const Integer & A, const Integer & B)
|
||||
{
|
||||
Integer ret = A;
|
||||
ret /= gcd(A, B);
|
||||
ret *= B;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline Integer log2_ceil(const Integer & A)
|
||||
{
|
||||
Integer i = 0;
|
||||
Integer power_of_2 = 1;
|
||||
|
||||
while(power_of_2 < A){
|
||||
power_of_2 <<= 1;
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline Integer upper_power_of_2(const Integer & A)
|
||||
{
|
||||
Integer power_of_2 = 1;
|
||||
|
||||
while(power_of_2 < A){
|
||||
power_of_2 <<= 1;
|
||||
}
|
||||
return power_of_2;
|
||||
}
|
||||
|
||||
template <typename Integer, bool Loop = true>
|
||||
struct upper_power_of_2_loop_ct
|
||||
{
|
||||
|
||||
template <Integer I, Integer P>
|
||||
struct apply
|
||||
{
|
||||
static const Integer value =
|
||||
upper_power_of_2_loop_ct<Integer, (I > P*2)>::template apply<I, P*2>::value;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Integer>
|
||||
struct upper_power_of_2_loop_ct<Integer, false>
|
||||
{
|
||||
template <Integer I, Integer P>
|
||||
struct apply
|
||||
{
|
||||
static const Integer value = P;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Integer, Integer I>
|
||||
struct upper_power_of_2_ct
|
||||
{
|
||||
static const Integer value = upper_power_of_2_loop_ct<Integer, (I > 1)>::template apply<I, 2>::value;
|
||||
};
|
||||
|
||||
//This function uses binary search to discover the
|
||||
//highest set bit of the integer
|
||||
inline std::size_t floor_log2 (std::size_t x)
|
||||
{
|
||||
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
|
||||
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
|
||||
BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
|
||||
|
||||
std::size_t n = x;
|
||||
std::size_t log2 = 0;
|
||||
|
||||
for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
|
||||
std::size_t tmp = n >> shift;
|
||||
if (tmp)
|
||||
log2 += shift, n = tmp;
|
||||
}
|
||||
|
||||
return log2;
|
||||
}
|
||||
|
||||
template<std::size_t I1, std::size_t I2>
|
||||
struct gcd_ct
|
||||
{
|
||||
static const std::size_t Max = I1 > I2 ? I1 : I2;
|
||||
static const std::size_t Min = I1 < I2 ? I1 : I2;
|
||||
static const std::size_t value = gcd_ct<Min, Max % Min>::value;
|
||||
};
|
||||
|
||||
template<std::size_t I1>
|
||||
struct gcd_ct<I1, 0>
|
||||
{
|
||||
static const std::size_t value = I1;
|
||||
};
|
||||
|
||||
template<std::size_t I1>
|
||||
struct gcd_ct<0, I1>
|
||||
{
|
||||
static const std::size_t value = I1;
|
||||
};
|
||||
|
||||
template<std::size_t I1, std::size_t I2>
|
||||
struct lcm_ct
|
||||
{
|
||||
static const std::size_t value = I1 * I2 / gcd_ct<I1, I2>::value;
|
||||
};
|
||||
|
||||
} // namespace dtl
|
||||
} // namespace container
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif
|
||||
@@ -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 dtl {
|
||||
|
||||
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 dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
|
||||
@@ -0,0 +1,32 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
||||
#
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
#
|
||||
#//Try to avoid including <string>, as it's quite big
|
||||
#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
|
||||
#include <iosfwd> //Dinkum libraries for MSVC define std::char_traits there
|
||||
#elif defined(BOOST_GNU_STDLIB)
|
||||
#include <bits/char_traits.h>
|
||||
#else
|
||||
#include <string> //Fallback
|
||||
#endif
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
||||
144
install/boost_1_75_0/include/boost/container/detail/mpl.hpp
Normal file
144
install/boost_1_75_0/include/boost/container/detail/mpl.hpp
Normal file
@@ -0,0 +1,144 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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 dtl {
|
||||
|
||||
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;
|
||||
using boost::move_detail::remove_const;
|
||||
|
||||
template <class FirstType>
|
||||
struct select1st
|
||||
{
|
||||
typedef FirstType type;
|
||||
|
||||
template<class T>
|
||||
BOOST_CONTAINER_FORCEINLINE const type& operator()(const T& x) const
|
||||
{ return x.first; }
|
||||
|
||||
template<class T>
|
||||
BOOST_CONTAINER_FORCEINLINE type& operator()(T& x)
|
||||
{ return const_cast<type&>(x.first); }
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct void_t { typedef void type; };
|
||||
|
||||
template <class T, class=void>
|
||||
struct is_transparent_base
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_transparent_base<T, typename void_t<typename T::is_transparent>::type>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_transparent
|
||||
: is_transparent_base<T>
|
||||
{};
|
||||
|
||||
template <typename C, class /*Dummy*/, typename R>
|
||||
struct enable_if_transparent
|
||||
: boost::move_detail::enable_if_c<dtl::is_transparent<C>::value, R>
|
||||
{};
|
||||
|
||||
#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
|
||||
|
||||
// void_t (void_t for C++11)
|
||||
template<typename...> using variadic_void_t = void;
|
||||
|
||||
// Trait to detect Allocator-like types.
|
||||
template<typename Allocator, typename = void>
|
||||
struct is_allocator
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T&& ctad_declval();
|
||||
|
||||
template<typename Allocator>
|
||||
struct is_allocator < Allocator,
|
||||
variadic_void_t< typename Allocator::value_type
|
||||
, decltype(ctad_declval<Allocator&>().allocate(size_t{})) >>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using require_allocator_t = typename enable_if_c<is_allocator<T>::value, T>::type;
|
||||
|
||||
template<class T>
|
||||
using require_nonallocator_t = typename enable_if_c<!is_allocator<T>::value, T>::type;
|
||||
|
||||
#endif
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
// container
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
// container/detail
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/transform_iterator.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
// intrusive
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
// move
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class VoidPointer>
|
||||
class basic_multiallocation_chain
|
||||
{
|
||||
private:
|
||||
typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
|
||||
,bi::link_mode<bi::normal_link>
|
||||
> node;
|
||||
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<VoidPointer>::template rebind_pointer<char>::type char_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<char_ptr>::difference_type difference_type;
|
||||
|
||||
typedef bi::slist< node
|
||||
, bi::linear<true>
|
||||
, bi::cache_last<true>
|
||||
, bi::size_type<typename boost::container::dtl::make_unsigned<difference_type>::type>
|
||||
> slist_impl_t;
|
||||
slist_impl_t slist_impl_;
|
||||
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<node_ptr> node_ptr_traits;
|
||||
|
||||
static node & to_node(const VoidPointer &p)
|
||||
{ return *static_cast<node*>(static_cast<void*>(boost::movelib::to_raw_pointer(p))); }
|
||||
|
||||
static VoidPointer from_node(node &n)
|
||||
{ return node_ptr_traits::pointer_to(n); }
|
||||
|
||||
static node_ptr to_node_ptr(const VoidPointer &p)
|
||||
{ return node_ptr_traits::static_cast_from(p); }
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
|
||||
|
||||
public:
|
||||
|
||||
typedef VoidPointer void_pointer;
|
||||
typedef typename slist_impl_t::iterator iterator;
|
||||
typedef typename slist_impl_t::size_type size_type;
|
||||
|
||||
basic_multiallocation_chain()
|
||||
: slist_impl_()
|
||||
{}
|
||||
|
||||
basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n)
|
||||
: slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n)
|
||||
{}
|
||||
|
||||
basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
|
||||
: slist_impl_(::boost::move(other.slist_impl_))
|
||||
{}
|
||||
|
||||
basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
|
||||
{
|
||||
slist_impl_ = ::boost::move(other.slist_impl_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{ return slist_impl_.empty(); }
|
||||
|
||||
size_type size() const
|
||||
{ return slist_impl_.size(); }
|
||||
|
||||
iterator before_begin()
|
||||
{ return slist_impl_.before_begin(); }
|
||||
|
||||
iterator begin()
|
||||
{ return slist_impl_.begin(); }
|
||||
|
||||
iterator end()
|
||||
{ return slist_impl_.end(); }
|
||||
|
||||
iterator last()
|
||||
{ return slist_impl_.last(); }
|
||||
|
||||
void clear()
|
||||
{ slist_impl_.clear(); }
|
||||
|
||||
iterator insert_after(iterator it, void_pointer m)
|
||||
{ return slist_impl_.insert_after(it, to_node(m)); }
|
||||
|
||||
void push_front(const void_pointer &m)
|
||||
{ return slist_impl_.push_front(to_node(m)); }
|
||||
|
||||
void push_back(const void_pointer &m)
|
||||
{ return slist_impl_.push_back(to_node(m)); }
|
||||
|
||||
void_pointer pop_front()
|
||||
{
|
||||
node & n = slist_impl_.front();
|
||||
void_pointer ret = from_node(n);
|
||||
slist_impl_.pop_front();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); }
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_); }
|
||||
|
||||
void erase_after(iterator before_b, iterator e, size_type n)
|
||||
{ slist_impl_.erase_after(before_b, e, n); }
|
||||
|
||||
void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units)
|
||||
{
|
||||
typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits;
|
||||
char_ptr elem = char_pointer_traits::static_cast_from(b);
|
||||
if(num_units){
|
||||
char_ptr prev_elem = elem;
|
||||
elem += unit_bytes;
|
||||
for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){
|
||||
::new (boost::movelib::to_raw_pointer(prev_elem), boost_container_new_t()) void_pointer(elem);
|
||||
prev_elem = elem;
|
||||
}
|
||||
slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n)
|
||||
{ slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); }
|
||||
|
||||
void swap(basic_multiallocation_chain &x)
|
||||
{ slist_impl_.swap(x.slist_impl_); }
|
||||
|
||||
static iterator iterator_to(const void_pointer &p)
|
||||
{ return slist_impl_t::s_iterator_to(to_node(p)); }
|
||||
|
||||
std::pair<void_pointer, void_pointer> extract_data()
|
||||
{
|
||||
if(BOOST_LIKELY(!slist_impl_.empty())){
|
||||
std::pair<void_pointer, void_pointer> ret
|
||||
(slist_impl_.begin().operator->()
|
||||
,slist_impl_.last().operator->());
|
||||
slist_impl_.clear();
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
return std::pair<void_pointer, void_pointer>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct cast_functor
|
||||
{
|
||||
typedef typename dtl::add_reference<T>::type result_type;
|
||||
template<class U>
|
||||
result_type operator()(U &ptr) const
|
||||
{ return *static_cast<T*>(static_cast<void*>(&ptr)); }
|
||||
};
|
||||
|
||||
template<class MultiallocationChain, class T>
|
||||
class transform_multiallocation_chain
|
||||
: public MultiallocationChain
|
||||
{
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
|
||||
//transform_multiallocation_chain(const transform_multiallocation_chain &);
|
||||
//transform_multiallocation_chain & operator=(const transform_multiallocation_chain &);
|
||||
|
||||
typedef typename MultiallocationChain::void_pointer void_pointer;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_pointer> void_pointer_traits;
|
||||
typedef typename void_pointer_traits::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<pointer> pointer_traits;
|
||||
|
||||
static pointer cast(const void_pointer &p)
|
||||
{ return pointer_traits::static_cast_from(p); }
|
||||
|
||||
public:
|
||||
typedef transform_iterator
|
||||
< typename MultiallocationChain::iterator
|
||||
, dtl::cast_functor <T> > iterator;
|
||||
typedef typename MultiallocationChain::size_type size_type;
|
||||
|
||||
transform_multiallocation_chain()
|
||||
: MultiallocationChain()
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
|
||||
: MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
|
||||
: MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
|
||||
{
|
||||
return static_cast<MultiallocationChain&>
|
||||
(this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other))));
|
||||
}
|
||||
|
||||
void push_front(const pointer &mem)
|
||||
{ this->MultiallocationChain::push_front(mem); }
|
||||
|
||||
void push_back(const pointer &mem)
|
||||
{ return this->MultiallocationChain::push_back(mem); }
|
||||
|
||||
void swap(transform_multiallocation_chain &other_chain)
|
||||
{ this->MultiallocationChain::swap(other_chain); }
|
||||
|
||||
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
|
||||
{ this->MultiallocationChain::splice_after(after_this.base(), x, before_b.base(), before_e.base(), n); }
|
||||
|
||||
void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n)
|
||||
{ this->MultiallocationChain::incorporate_after(after_this.base(), b, before_e, n); }
|
||||
|
||||
pointer pop_front()
|
||||
{ return cast(this->MultiallocationChain::pop_front()); }
|
||||
|
||||
bool empty() const
|
||||
{ return this->MultiallocationChain::empty(); }
|
||||
|
||||
iterator before_begin()
|
||||
{ return iterator(this->MultiallocationChain::before_begin()); }
|
||||
|
||||
iterator begin()
|
||||
{ return iterator(this->MultiallocationChain::begin()); }
|
||||
|
||||
iterator last()
|
||||
{ return iterator(this->MultiallocationChain::last()); }
|
||||
|
||||
iterator end()
|
||||
{ return iterator(this->MultiallocationChain::end()); }
|
||||
|
||||
size_type size() const
|
||||
{ return this->MultiallocationChain::size(); }
|
||||
|
||||
void clear()
|
||||
{ this->MultiallocationChain::clear(); }
|
||||
|
||||
iterator insert_after(iterator it, pointer m)
|
||||
{ return iterator(this->MultiallocationChain::insert_after(it.base(), m)); }
|
||||
|
||||
static iterator iterator_to(const pointer &p)
|
||||
{ return iterator(MultiallocationChain::iterator_to(p)); }
|
||||
|
||||
std::pair<pointer, pointer> extract_data()
|
||||
{
|
||||
std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data());
|
||||
return std::pair<pointer, pointer>(cast(data.first), cast(data.second));
|
||||
}
|
||||
/*
|
||||
MultiallocationChain &extract_multiallocation_chain()
|
||||
{ return holder_; }*/
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
// namespace dtl {
|
||||
// namespace container {
|
||||
// namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
283
install/boost_1_75_0/include/boost/container/detail/mutex.hpp
Normal file
283
install/boost_1_75_0/include/boost/container/detail/mutex.hpp
Normal file
@@ -0,0 +1,283 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Stephen Cleary 2000
|
||||
// (C) Copyright Ion Gaztanaga 2015-2017.
|
||||
//
|
||||
// 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_MUTEX_HPP
|
||||
#define BOOST_CONTAINER_MUTEX_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//#define BOOST_CONTAINER_NO_MT
|
||||
//#define BOOST_CONTAINER_NO_SPINLOCKS
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
// Extremely Light-Weight wrapper classes for OS thread synchronization
|
||||
|
||||
#define BOOST_MUTEX_HELPER_NONE 0
|
||||
#define BOOST_MUTEX_HELPER_WIN32 1
|
||||
#define BOOST_MUTEX_HELPER_PTHREAD 2
|
||||
#define BOOST_MUTEX_HELPER_SPINLOCKS 3
|
||||
|
||||
#if !defined(BOOST_HAS_THREADS) && !defined(BOOST_NO_MT)
|
||||
# define BOOST_NO_MT
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_MT) || defined(BOOST_CONTAINER_NO_MT)
|
||||
// No multithreading -> make locks into no-ops
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_NONE
|
||||
#else
|
||||
//Taken from dlmalloc
|
||||
#if !defined(BOOST_CONTAINER_NO_SPINLOCKS) && \
|
||||
((defined(__GNUC__) && \
|
||||
((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \
|
||||
defined(__i386__) || defined(__x86_64__))) || \
|
||||
(defined(_MSC_VER) && _MSC_VER>=1310))
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
#include <windows.h>
|
||||
#ifndef BOOST_MUTEX_HELPER
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_WIN32
|
||||
#endif
|
||||
#elif defined(BOOST_HAS_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#if !defined(BOOST_MUTEX_HELPER) && (defined(_POSIX_THREADS) || defined(BOOST_HAS_PTHREADS))
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_PTHREAD
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MUTEX_HELPER
|
||||
#error Unable to determine platform mutex type; #define BOOST_NO_MT to assume single-threaded
|
||||
#endif
|
||||
|
||||
#if BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_NONE
|
||||
//...
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
#if defined(_MSC_VER)
|
||||
#ifndef _M_AMD64
|
||||
/* These are already defined on AMD64 builds */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
long __cdecl _InterlockedCompareExchange(long volatile *Dest, long Exchange, long Comp);
|
||||
long __cdecl _InterlockedExchange(long volatile *Target, long Value);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* _M_AMD64 */
|
||||
#pragma intrinsic (_InterlockedCompareExchange)
|
||||
#pragma intrinsic (_InterlockedExchange)
|
||||
#define interlockedcompareexchange _InterlockedCompareExchange
|
||||
#define interlockedexchange _InterlockedExchange
|
||||
#elif defined(WIN32) && defined(__GNUC__)
|
||||
#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
|
||||
#define interlockedexchange __sync_lock_test_and_set
|
||||
#endif /* Win32 */
|
||||
|
||||
/* First, define CAS_LOCK and CLEAR_LOCK on ints */
|
||||
/* Note CAS_LOCK defined to return 0 on success */
|
||||
|
||||
#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
|
||||
#define BOOST_CONTAINER_CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1)
|
||||
#define BOOST_CONTAINER_CLEAR_LOCK(sl) __sync_lock_release(sl)
|
||||
|
||||
#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
|
||||
/* Custom spin locks for older gcc on x86 */
|
||||
static inline int boost_container_x86_cas_lock(int *sl) {
|
||||
int ret;
|
||||
int val = 1;
|
||||
int cmp = 0;
|
||||
__asm__ __volatile__ ("lock; cmpxchgl %1, %2"
|
||||
: "=a" (ret)
|
||||
: "r" (val), "m" (*(sl)), "0"(cmp)
|
||||
: "memory", "cc");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void boost_container_x86_clear_lock(int* sl) {
|
||||
assert(*sl != 0);
|
||||
int prev = 0;
|
||||
int ret;
|
||||
__asm__ __volatile__ ("lock; xchgl %0, %1"
|
||||
: "=r" (ret)
|
||||
: "m" (*(sl)), "0"(prev)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define BOOST_CONTAINER_CAS_LOCK(sl) boost_container_x86_cas_lock(sl)
|
||||
#define BOOST_CONTAINER_CLEAR_LOCK(sl) boost_container_x86_clear_lock(sl)
|
||||
|
||||
#else /* Win32 MSC */
|
||||
#define BOOST_CONTAINER_CAS_LOCK(sl) interlockedexchange((long volatile*)sl, (long)1)
|
||||
#define BOOST_CONTAINER_CLEAR_LOCK(sl) interlockedexchange((long volatile*)sl, (long)0)
|
||||
#endif
|
||||
|
||||
/* How to yield for a spin lock */
|
||||
#define SPINS_PER_YIELD 63
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
#define SLEEP_EX_DURATION 50 /* delay for yield/sleep */
|
||||
#define SPIN_LOCK_YIELD SleepEx(SLEEP_EX_DURATION, FALSE)
|
||||
#elif defined (__SVR4) && defined (__sun) /* solaris */
|
||||
#include <thread.h>
|
||||
#define SPIN_LOCK_YIELD thr_yield();
|
||||
#elif !defined(LACKS_SCHED_H)
|
||||
#include <sched.h>
|
||||
#define SPIN_LOCK_YIELD sched_yield();
|
||||
#else
|
||||
#define SPIN_LOCK_YIELD
|
||||
#endif /* ... yield ... */
|
||||
|
||||
#define BOOST_CONTAINER_SPINS_PER_YIELD 63
|
||||
inline int boost_interprocess_spin_acquire_lock(int *sl) {
|
||||
int spins = 0;
|
||||
while (*(volatile int *)sl != 0 ||
|
||||
BOOST_CONTAINER_CAS_LOCK(sl)) {
|
||||
if ((++spins & BOOST_CONTAINER_SPINS_PER_YIELD) == 0) {
|
||||
SPIN_LOCK_YIELD;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#define BOOST_CONTAINER_MLOCK_T int
|
||||
#define BOOST_CONTAINER_TRY_LOCK(sl) !BOOST_CONTAINER_CAS_LOCK(sl)
|
||||
#define BOOST_CONTAINER_RELEASE_LOCK(sl) BOOST_CONTAINER_CLEAR_LOCK(sl)
|
||||
#define BOOST_CONTAINER_ACQUIRE_LOCK(sl) (BOOST_CONTAINER_CAS_LOCK(sl)? boost_interprocess_spin_acquire_lock(sl) : 0)
|
||||
#define BOOST_MOVE_INITIAL_LOCK(sl) (*sl = 0)
|
||||
#define BOOST_CONTAINER_DESTROY_LOCK(sl) (0)
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
|
||||
//
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_PTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
#if BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_NONE
|
||||
class null_mutex
|
||||
{
|
||||
private:
|
||||
null_mutex(const null_mutex &);
|
||||
void operator=(const null_mutex &);
|
||||
|
||||
public:
|
||||
null_mutex() { }
|
||||
|
||||
static void lock() { }
|
||||
static void unlock() { }
|
||||
};
|
||||
|
||||
typedef null_mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
|
||||
class spin_mutex
|
||||
{
|
||||
private:
|
||||
BOOST_CONTAINER_MLOCK_T sl;
|
||||
spin_mutex(const spin_mutex &);
|
||||
void operator=(const spin_mutex &);
|
||||
|
||||
public:
|
||||
spin_mutex() { BOOST_MOVE_INITIAL_LOCK(&sl); }
|
||||
|
||||
void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); }
|
||||
void unlock() { BOOST_CONTAINER_RELEASE_LOCK(&sl); }
|
||||
};
|
||||
typedef spin_mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
|
||||
class mutex
|
||||
{
|
||||
private:
|
||||
CRITICAL_SECTION mtx;
|
||||
|
||||
mutex(const mutex &);
|
||||
void operator=(const mutex &);
|
||||
|
||||
public:
|
||||
mutex()
|
||||
{ InitializeCriticalSection(&mtx); }
|
||||
|
||||
~mutex()
|
||||
{ DeleteCriticalSection(&mtx); }
|
||||
|
||||
void lock()
|
||||
{ EnterCriticalSection(&mtx); }
|
||||
|
||||
void unlock()
|
||||
{ LeaveCriticalSection(&mtx); }
|
||||
};
|
||||
|
||||
typedef mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_PTHREAD
|
||||
class mutex
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
mutex(const mutex &);
|
||||
void operator=(const mutex &);
|
||||
|
||||
public:
|
||||
mutex()
|
||||
{ pthread_mutex_init(&mtx, 0); }
|
||||
|
||||
~mutex()
|
||||
{ pthread_mutex_destroy(&mtx); }
|
||||
|
||||
void lock()
|
||||
{ pthread_mutex_lock(&mtx); }
|
||||
|
||||
void unlock()
|
||||
{ pthread_mutex_unlock(&mtx); }
|
||||
};
|
||||
|
||||
typedef mutex default_mutex;
|
||||
#endif
|
||||
|
||||
template<class Mutex>
|
||||
class scoped_lock
|
||||
{
|
||||
public:
|
||||
scoped_lock(Mutex &m)
|
||||
: m_(m)
|
||||
{ m_.lock(); }
|
||||
~scoped_lock()
|
||||
{ m_.unlock(); }
|
||||
|
||||
private:
|
||||
Mutex &m_;
|
||||
};
|
||||
|
||||
} // namespace dtl
|
||||
} // namespace container
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_MUTEX_HELPER_WIN32
|
||||
#undef BOOST_MUTEX_HELPER_PTHREAD
|
||||
#undef BOOST_MUTEX_HELPER_NONE
|
||||
#undef BOOST_MUTEX_HELPER
|
||||
#undef BOOST_MUTEX_HELPER_SPINLOCKS
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
// container
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/min_max.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<unsigned Minimum, unsigned Numerator, unsigned Denominator>
|
||||
struct grow_factor_ratio
|
||||
{
|
||||
BOOST_STATIC_ASSERT(Numerator > Denominator);
|
||||
BOOST_STATIC_ASSERT(Numerator < 100);
|
||||
BOOST_STATIC_ASSERT(Denominator < 100);
|
||||
BOOST_STATIC_ASSERT(Denominator == 1 || (0 != Numerator % Denominator));
|
||||
|
||||
template<class SizeType>
|
||||
SizeType operator()(const SizeType cur_cap, const SizeType add_min_cap, const SizeType max_cap) const
|
||||
{
|
||||
const SizeType overflow_limit = ((SizeType)-1) / Numerator;
|
||||
|
||||
SizeType new_cap = 0;
|
||||
|
||||
if(cur_cap <= overflow_limit){
|
||||
new_cap = cur_cap * Numerator / Denominator;
|
||||
}
|
||||
else if(Denominator == 1 || (SizeType(new_cap = cur_cap) / Denominator) > overflow_limit){
|
||||
new_cap = (SizeType)-1;
|
||||
}
|
||||
else{
|
||||
new_cap *= Numerator;
|
||||
}
|
||||
return max_value<SizeType>
|
||||
( SizeType(Minimum)
|
||||
, max_value<SizeType>
|
||||
( SizeType(cur_cap+add_min_cap)
|
||||
, min_value<SizeType>(max_cap, new_cap))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
|
||||
struct growth_factor_50
|
||||
: dtl::grow_factor_ratio<0, 3, 2>
|
||||
{};
|
||||
|
||||
struct growth_factor_60
|
||||
: dtl::grow_factor_ratio<0, 8, 5>
|
||||
{};
|
||||
|
||||
struct growth_factor_100
|
||||
: dtl::grow_factor_ratio<0, 2, 1>
|
||||
{};
|
||||
|
||||
template<class SizeType>
|
||||
BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &, SizeType)
|
||||
{}
|
||||
|
||||
template<class SizeType, class SomeStoredSizeType>
|
||||
BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &s, SomeStoredSizeType)
|
||||
{
|
||||
if (s >= SomeStoredSizeType(-1) )
|
||||
s = SomeStoredSizeType(-1);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
|
||||
@@ -0,0 +1,471 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
// container
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/addressof.hpp>
|
||||
#include <boost/container/detail/alloc_helpers.hpp>
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/container/detail/construct_in_place.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
// intrusive
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/options.hpp>
|
||||
// move
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
// other
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_compare)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_equal)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(hasher)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
|
||||
|
||||
template<class Allocator, class ICont>
|
||||
struct node_alloc_holder
|
||||
: public allocator_traits<Allocator>::template
|
||||
portable_rebind_alloc<typename ICont::value_type>::type //NodeAlloc
|
||||
{
|
||||
//If the intrusive container is an associative container, obtain the predicate, which will
|
||||
//be of type node_compare<>. If not an associative container val_compare will be a "nat" type.
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
( boost::container::dtl::
|
||||
, ICont, key_compare, dtl::nat) intrusive_val_compare;
|
||||
//In that case obtain the value predicate from the node predicate via predicate_type
|
||||
//if intrusive_val_compare is node_compare<>, nat otherwise
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
( boost::container::dtl::
|
||||
, intrusive_val_compare
|
||||
, predicate_type, dtl::nat) val_compare;
|
||||
|
||||
//If the intrusive container is a hash container, obtain the predicate, which will
|
||||
//be of type node_compare<>. If not an associative container val_equal will be a "nat" type.
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
(boost::container::dtl::
|
||||
, ICont, key_equal, dtl::nat2) intrusive_val_equal;
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
(boost::container::dtl::
|
||||
, ICont, hasher, dtl::nat3) intrusive_val_hasher;
|
||||
//In that case obtain the value predicate from the node predicate via predicate_type
|
||||
//if intrusive_val_compare is node_compare<>, nat otherwise
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
(boost::container::dtl::
|
||||
, intrusive_val_equal
|
||||
, predicate_type, dtl::nat2) val_equal;
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
(boost::container::dtl::
|
||||
, intrusive_val_hasher
|
||||
, predicate_type, dtl::nat3) val_hasher;
|
||||
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type val_type;
|
||||
typedef ICont intrusive_container;
|
||||
typedef typename ICont::value_type Node;
|
||||
typedef typename allocator_traits_type::template
|
||||
portable_rebind_alloc<Node>::type NodeAlloc;
|
||||
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
|
||||
typedef dtl::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
|
||||
typedef Allocator ValAlloc;
|
||||
typedef typename node_allocator_traits_type::pointer NodePtr;
|
||||
typedef dtl::scoped_deallocator<NodeAlloc> Deallocator;
|
||||
typedef typename node_allocator_traits_type::size_type size_type;
|
||||
typedef typename node_allocator_traits_type::difference_type difference_type;
|
||||
typedef dtl::integral_constant<unsigned,
|
||||
boost::container::dtl::
|
||||
version<NodeAlloc>::value> alloc_version;
|
||||
typedef typename ICont::iterator icont_iterator;
|
||||
typedef typename ICont::const_iterator icont_citerator;
|
||||
typedef allocator_destroyer<NodeAlloc> Destroyer;
|
||||
typedef allocator_traits<NodeAlloc> NodeAllocTraits;
|
||||
typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
|
||||
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
|
||||
|
||||
public:
|
||||
|
||||
//Constructors for sequence containers
|
||||
node_alloc_holder()
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const ValAlloc &a)
|
||||
: NodeAlloc(a)
|
||||
{}
|
||||
|
||||
//Constructors for associative containers
|
||||
node_alloc_holder(const val_compare &c, const ValAlloc &a)
|
||||
: NodeAlloc(a), m_icont(typename ICont::key_compare(c))
|
||||
{}
|
||||
|
||||
node_alloc_holder(const val_hasher &hf, const val_equal &eql, const ValAlloc &a)
|
||||
: NodeAlloc(a)
|
||||
, m_icont(typename ICont::bucket_traits()
|
||||
, typename ICont::hasher(hf)
|
||||
, typename ICont::key_equal(eql))
|
||||
{}
|
||||
|
||||
node_alloc_holder(const val_hasher &hf, const ValAlloc &a)
|
||||
: NodeAlloc(a)
|
||||
, m_icont(typename ICont::bucket_traits()
|
||||
, typename ICont::hasher(hf)
|
||||
, typename ICont::key_equal())
|
||||
{}
|
||||
|
||||
node_alloc_holder(const val_hasher &hf)
|
||||
: m_icont(typename ICont::bucket_traits()
|
||||
, typename ICont::hasher(hf)
|
||||
, typename ICont::key_equal())
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const node_alloc_holder &x)
|
||||
: NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
|
||||
{}
|
||||
|
||||
node_alloc_holder(const node_alloc_holder &x, const val_compare &c)
|
||||
: NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
|
||||
, m_icont(typename ICont::key_compare(c))
|
||||
{}
|
||||
|
||||
node_alloc_holder(const node_alloc_holder &x, const val_hasher &hf, const val_equal &eql)
|
||||
: NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
|
||||
, m_icont( typename ICont::bucket_traits()
|
||||
, typename ICont::hasher(hf)
|
||||
, typename ICont::key_equal(eql))
|
||||
{}
|
||||
|
||||
node_alloc_holder(const val_hasher &hf, const val_equal &eql)
|
||||
: m_icont(typename ICont::bucket_traits()
|
||||
, typename ICont::hasher(hf)
|
||||
, typename ICont::key_equal(eql))
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
|
||||
: NodeAlloc(boost::move(x.node_alloc()))
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
explicit node_alloc_holder(const val_compare &c)
|
||||
: m_icont(typename ICont::key_compare(c))
|
||||
{}
|
||||
|
||||
//helpers for move assignments
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const val_compare &c)
|
||||
: NodeAlloc(boost::move(x.node_alloc())), m_icont(typename ICont::key_compare(c))
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const val_hasher &hf, const val_equal &eql)
|
||||
: NodeAlloc(boost::move(x.node_alloc()))
|
||||
, m_icont( typename ICont::bucket_traits()
|
||||
, typename ICont::hasher(hf)
|
||||
, typename ICont::key_equal(eql))
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
void copy_assign_alloc(const node_alloc_holder &x)
|
||||
{
|
||||
dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag;
|
||||
dtl::assign_alloc( static_cast<NodeAlloc &>(*this)
|
||||
, static_cast<const NodeAlloc &>(x), flag);
|
||||
}
|
||||
|
||||
void move_assign_alloc( node_alloc_holder &x)
|
||||
{
|
||||
dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
|
||||
dtl::move_alloc( static_cast<NodeAlloc &>(*this)
|
||||
, static_cast<NodeAlloc &>(x), flag);
|
||||
}
|
||||
|
||||
~node_alloc_holder()
|
||||
{ this->clear(alloc_version()); }
|
||||
|
||||
size_type max_size() const
|
||||
{ return allocator_traits_type::max_size(this->node_alloc()); }
|
||||
|
||||
NodePtr allocate_one()
|
||||
{ return AllocVersionTraits::allocate_one(this->node_alloc()); }
|
||||
|
||||
void deallocate_one(const NodePtr &p)
|
||||
{ AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class ...Args>
|
||||
NodePtr create_node(Args &&...args)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
BOOST_TRY{
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;
|
||||
allocator_traits<NodeAlloc>::construct
|
||||
(this->node_alloc()
|
||||
, p->get_real_data_ptr(), boost::forward<Args>(args)...);
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
p->destroy_header();
|
||||
this->node_alloc().deallocate(p, 1);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return (p);
|
||||
}
|
||||
|
||||
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
NodePtr create_node(BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
NodePtr p = this->allocate_one();\
|
||||
BOOST_TRY{\
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;\
|
||||
allocator_traits<NodeAlloc>::construct\
|
||||
( this->node_alloc()\
|
||||
, p->get_real_data_ptr()\
|
||||
BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
p->destroy_header();\
|
||||
this->node_alloc().deallocate(p, 1);\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
return (p);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL)
|
||||
#undef BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class It>
|
||||
NodePtr create_node_from_it(const It &it)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
BOOST_TRY{
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;
|
||||
::boost::container::construct_in_place(this->node_alloc(), p->get_real_data_ptr(), it);
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
p->destroy_header();
|
||||
this->node_alloc().deallocate(p, 1);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return (p);
|
||||
}
|
||||
|
||||
template<class KeyConvertible>
|
||||
NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
BOOST_TRY{
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;
|
||||
NodeAlloc &na = this->node_alloc();
|
||||
node_allocator_traits_type::construct
|
||||
(na, dtl::addressof(p->get_real_data().first), boost::forward<KeyConvertible>(key));
|
||||
BOOST_TRY{
|
||||
node_allocator_traits_type::construct(na, dtl::addressof(p->get_real_data().second));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
node_allocator_traits_type::destroy(na, dtl::addressof(p->get_real_data().first));
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
p->destroy_header();
|
||||
this->node_alloc().deallocate(p, 1);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return (p);
|
||||
}
|
||||
|
||||
void destroy_node(const NodePtr &nodep)
|
||||
{
|
||||
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(nodep));
|
||||
this->deallocate_one(nodep);
|
||||
}
|
||||
|
||||
void swap(node_alloc_holder &x)
|
||||
{
|
||||
this->icont().swap(x.icont());
|
||||
dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
|
||||
dtl::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
|
||||
}
|
||||
|
||||
template<class FwdIterator, class Inserter>
|
||||
void allocate_many_and_construct
|
||||
(FwdIterator beg, difference_type n, Inserter inserter)
|
||||
{
|
||||
if(n){
|
||||
typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain_t;
|
||||
|
||||
//Try to allocate memory in a single block
|
||||
typedef typename multiallocation_chain_t::iterator multialloc_iterator_t;
|
||||
multiallocation_chain_t chain;
|
||||
NodeAlloc &nalloc = this->node_alloc();
|
||||
node_allocator_version_traits_type::allocate_individual(nalloc, n, chain);
|
||||
multialloc_iterator_t itbeg = chain.begin();
|
||||
multialloc_iterator_t itlast = chain.last();
|
||||
chain.clear();
|
||||
|
||||
Node *p = 0;
|
||||
BOOST_TRY{
|
||||
Deallocator node_deallocator(NodePtr(), nalloc);
|
||||
dtl::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
|
||||
while(n){
|
||||
--n;
|
||||
p = boost::movelib::iterator_to_raw_pointer(itbeg);
|
||||
++itbeg; //Increment iterator before overwriting pointed memory
|
||||
//This does not throw
|
||||
p = ::new(p, boost_container_new_t()) Node;
|
||||
node_deallocator.set(p);
|
||||
//This can throw
|
||||
boost::container::construct_in_place(nalloc, p->get_real_data_ptr(), beg);
|
||||
sdestructor.set(p);
|
||||
++beg;
|
||||
//This can throw in some containers (predicate might throw).
|
||||
//(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
|
||||
inserter(*p);
|
||||
sdestructor.set(0);
|
||||
}
|
||||
sdestructor.release();
|
||||
node_deallocator.release();
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
p->destroy_header();
|
||||
chain.incorporate_after(chain.last(), &*itbeg, &*itlast, n);
|
||||
node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), chain);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
}
|
||||
|
||||
void clear(version_1)
|
||||
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
|
||||
|
||||
void clear(version_2)
|
||||
{
|
||||
typename NodeAlloc::multiallocation_chain chain;
|
||||
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
|
||||
this->icont().clear_and_dispose(builder);
|
||||
//BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
|
||||
if(!chain.empty())
|
||||
this->node_alloc().deallocate_individual(chain);
|
||||
}
|
||||
|
||||
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
|
||||
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
|
||||
|
||||
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
|
||||
{
|
||||
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
|
||||
NodeAlloc & nalloc = this->node_alloc();
|
||||
multiallocation_chain chain;
|
||||
allocator_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain);
|
||||
icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder);
|
||||
nalloc.deallocate_individual(chain);
|
||||
return ret_it;
|
||||
}
|
||||
|
||||
template<class Key, class Comparator>
|
||||
size_type erase_key(const Key& k, const Comparator &comp, version_1)
|
||||
{ return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
|
||||
|
||||
template<class Key, class Comparator>
|
||||
size_type erase_key(const Key& k, const Comparator &comp, version_2)
|
||||
{
|
||||
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
|
||||
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
|
||||
}
|
||||
|
||||
protected:
|
||||
struct cloner
|
||||
{
|
||||
explicit cloner(node_alloc_holder &holder)
|
||||
: m_holder(holder)
|
||||
{}
|
||||
|
||||
NodePtr operator()(const Node &other) const
|
||||
{ return m_holder.create_node(other.get_real_data()); }
|
||||
|
||||
node_alloc_holder &m_holder;
|
||||
};
|
||||
|
||||
struct move_cloner
|
||||
{
|
||||
move_cloner(node_alloc_holder &holder)
|
||||
: m_holder(holder)
|
||||
{}
|
||||
|
||||
NodePtr operator()(Node &other)
|
||||
{ //Use get_real_data() instead of get_real_data to allow moving const key in [multi]map
|
||||
return m_holder.create_node(::boost::move(other.get_real_data()));
|
||||
}
|
||||
|
||||
node_alloc_holder &m_holder;
|
||||
};
|
||||
|
||||
ICont &non_const_icont() const
|
||||
{ return const_cast<ICont&>(this->m_icont); }
|
||||
|
||||
NodeAlloc &node_alloc()
|
||||
{ return static_cast<NodeAlloc &>(*this); }
|
||||
|
||||
const NodeAlloc &node_alloc() const
|
||||
{ return static_cast<const NodeAlloc &>(*this); }
|
||||
|
||||
public:
|
||||
ICont &icont()
|
||||
{ return this->m_icont; }
|
||||
|
||||
const ICont &icont() const
|
||||
{ return this->m_icont; }
|
||||
|
||||
private:
|
||||
//The intrusive container
|
||||
ICont m_icont;
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
||||
@@ -0,0 +1,157 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_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/mutex.hpp>
|
||||
#include <boost/container/detail/pool_common_alloc.hpp>
|
||||
#include <boost/container/detail/node_pool_impl.hpp>
|
||||
#include <boost/container/detail/mutex.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
//!Pooled memory allocator using single segregated storage. Includes
|
||||
//!a reference count but the class does not delete itself, this is
|
||||
//!responsibility of user classes. Node size (NodeSize) and the number of
|
||||
//!nodes allocated per block (NodesPerBlock) are known at compile time
|
||||
template< std::size_t NodeSize, std::size_t NodesPerBlock >
|
||||
class private_node_pool
|
||||
//Inherit from the implementation to avoid template bloat
|
||||
: public boost::container::dtl::
|
||||
private_node_pool_impl<fake_segment_manager>
|
||||
{
|
||||
typedef boost::container::dtl::
|
||||
private_node_pool_impl<fake_segment_manager> base_t;
|
||||
//Non-copyable
|
||||
private_node_pool(const private_node_pool &);
|
||||
private_node_pool &operator=(const private_node_pool &);
|
||||
|
||||
public:
|
||||
typedef typename base_t::multiallocation_chain multiallocation_chain;
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
private_node_pool()
|
||||
: base_t(0, NodeSize, NodesPerBlock)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
template< std::size_t NodeSize
|
||||
, std::size_t NodesPerBlock
|
||||
>
|
||||
class shared_node_pool
|
||||
: public private_node_pool<NodeSize, NodesPerBlock>
|
||||
{
|
||||
private:
|
||||
typedef private_node_pool<NodeSize, NodesPerBlock> private_node_allocator_t;
|
||||
|
||||
public:
|
||||
typedef typename private_node_allocator_t::free_nodes_t free_nodes_t;
|
||||
typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
shared_node_pool()
|
||||
: private_node_allocator_t(){}
|
||||
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
||||
~shared_node_pool()
|
||||
{}
|
||||
|
||||
//!Allocates array of count elements. Can throw std::bad_alloc
|
||||
void *allocate_node()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_node();
|
||||
}
|
||||
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
||||
void deallocate_node(void *ptr)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_node(ptr);
|
||||
}
|
||||
|
||||
//!Allocates a singly linked list of n nodes ending in null pointer.
|
||||
//!can throw std::bad_alloc
|
||||
void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::allocate_nodes(n, chain);
|
||||
}
|
||||
|
||||
void deallocate_nodes(multiallocation_chain &chain)
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_nodes(chain);
|
||||
}
|
||||
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
||||
void deallocate_free_blocks()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_free_blocks();
|
||||
}
|
||||
|
||||
//!Deallocates all blocks. Never throws
|
||||
void purge_blocks()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
private_node_allocator_t::purge_blocks();
|
||||
}
|
||||
|
||||
std::size_t num_free_nodes()
|
||||
{
|
||||
//-----------------------
|
||||
scoped_lock<default_mutex> guard(mutex_);
|
||||
//-----------------------
|
||||
return private_node_allocator_t::num_free_nodes();
|
||||
}
|
||||
|
||||
private:
|
||||
default_mutex mutex_;
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
|
||||
@@ -0,0 +1,375 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_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/container_fwd.hpp>
|
||||
|
||||
#include <boost/container/detail/math_functions.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/pool_common.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class SegmentManagerBase>
|
||||
class private_node_pool_impl
|
||||
{
|
||||
//Non-copyable
|
||||
private_node_pool_impl();
|
||||
private_node_pool_impl(const private_node_pool_impl &);
|
||||
private_node_pool_impl &operator=(const private_node_pool_impl &);
|
||||
|
||||
//A node object will hold node_t when it's not allocated
|
||||
public:
|
||||
typedef typename SegmentManagerBase::void_pointer void_pointer;
|
||||
typedef typename node_slist<void_pointer>::slist_hook_t slist_hook_t;
|
||||
typedef typename node_slist<void_pointer>::node_t node_t;
|
||||
typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
|
||||
typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
|
||||
typedef typename SegmentManagerBase::size_type size_type;
|
||||
|
||||
private:
|
||||
typedef typename bi::make_slist
|
||||
< node_t, bi::base_hook<slist_hook_t>
|
||||
, bi::linear<true>
|
||||
, bi::constant_time_size<false> >::type blockslist_t;
|
||||
|
||||
static size_type get_rounded_size(size_type orig_size, size_type round_to)
|
||||
{ return ((orig_size-1)/round_to+1)*round_to; }
|
||||
|
||||
public:
|
||||
|
||||
//!Segment manager typedef
|
||||
typedef SegmentManagerBase segment_manager_base_type;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
private_node_pool_impl(segment_manager_base_type *segment_mngr_base, size_type node_size, size_type nodes_per_block)
|
||||
: m_nodes_per_block(nodes_per_block)
|
||||
, m_real_node_size(lcm(node_size, size_type(alignment_of<node_t>::value)))
|
||||
//General purpose allocator
|
||||
, mp_segment_mngr_base(segment_mngr_base)
|
||||
, m_blocklist()
|
||||
, m_freelist()
|
||||
//Debug node count
|
||||
, m_allocated(0)
|
||||
{}
|
||||
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
||||
~private_node_pool_impl()
|
||||
{ this->purge_blocks(); }
|
||||
|
||||
size_type get_real_num_node() const
|
||||
{ return m_nodes_per_block; }
|
||||
|
||||
//!Returns the segment manager. Never throws
|
||||
segment_manager_base_type* get_segment_manager_base()const
|
||||
{ return boost::movelib::to_raw_pointer(mp_segment_mngr_base); }
|
||||
|
||||
void *allocate_node()
|
||||
{ return this->priv_alloc_node(); }
|
||||
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
||||
void deallocate_node(void *ptr)
|
||||
{ this->priv_dealloc_node(ptr); }
|
||||
|
||||
//!Allocates a singly linked list of n nodes ending in null pointer.
|
||||
void allocate_nodes(const size_type n, multiallocation_chain &chain)
|
||||
{
|
||||
//Preallocate all needed blocks to fulfill the request
|
||||
size_type cur_nodes = m_freelist.size();
|
||||
if(cur_nodes < n){
|
||||
this->priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
|
||||
}
|
||||
|
||||
//We just iterate the needed nodes to get the last we'll erase
|
||||
typedef typename free_nodes_t::iterator free_iterator;
|
||||
free_iterator before_last_new_it = m_freelist.before_begin();
|
||||
for(size_type j = 0; j != n; ++j){
|
||||
++before_last_new_it;
|
||||
}
|
||||
|
||||
//Cache the first node of the allocated range before erasing
|
||||
free_iterator first_node(m_freelist.begin());
|
||||
free_iterator last_node (before_last_new_it);
|
||||
|
||||
//Erase the range. Since we already have the distance, this is O(1)
|
||||
m_freelist.erase_after( m_freelist.before_begin()
|
||||
, ++free_iterator(before_last_new_it)
|
||||
, n);
|
||||
|
||||
//Now take the last erased node and just splice it in the end
|
||||
//of the intrusive list that will be traversed by the multialloc iterator.
|
||||
chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
|
||||
m_allocated += n;
|
||||
}
|
||||
|
||||
void deallocate_nodes(multiallocation_chain &chain)
|
||||
{
|
||||
typedef typename multiallocation_chain::iterator iterator;
|
||||
iterator it(chain.begin()), itend(chain.end());
|
||||
while(it != itend){
|
||||
void *pElem = &*it;
|
||||
++it;
|
||||
this->priv_dealloc_node(pElem);
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
||||
void deallocate_free_blocks()
|
||||
{
|
||||
typedef typename free_nodes_t::iterator nodelist_iterator;
|
||||
typename blockslist_t::iterator bit(m_blocklist.before_begin()),
|
||||
it(m_blocklist.begin()),
|
||||
itend(m_blocklist.end());
|
||||
free_nodes_t backup_list;
|
||||
nodelist_iterator backup_list_last = backup_list.before_begin();
|
||||
|
||||
//Execute the algorithm and get an iterator to the last value
|
||||
size_type blocksize = (get_rounded_size)
|
||||
(m_real_node_size*m_nodes_per_block, (size_type) alignment_of<node_t>::value);
|
||||
|
||||
while(it != itend){
|
||||
//Collect all the nodes from the block pointed by it
|
||||
//and push them in the list
|
||||
free_nodes_t free_nodes;
|
||||
nodelist_iterator last_it = free_nodes.before_begin();
|
||||
const void *addr = get_block_from_hook(&*it, blocksize);
|
||||
|
||||
m_freelist.remove_and_dispose_if
|
||||
(is_between(addr, blocksize), push_in_list(free_nodes, last_it));
|
||||
|
||||
//If the number of nodes is equal to m_nodes_per_block
|
||||
//this means that the block can be deallocated
|
||||
if(free_nodes.size() == m_nodes_per_block){
|
||||
//Unlink the nodes
|
||||
free_nodes.clear();
|
||||
it = m_blocklist.erase_after(bit);
|
||||
mp_segment_mngr_base->deallocate((void*)addr);
|
||||
}
|
||||
//Otherwise, insert them in the backup list, since the
|
||||
//next "remove_if" does not need to check them again.
|
||||
else{
|
||||
//Assign the iterator to the last value if necessary
|
||||
if(backup_list.empty() && !m_freelist.empty()){
|
||||
backup_list_last = last_it;
|
||||
}
|
||||
//Transfer nodes. This is constant time.
|
||||
backup_list.splice_after
|
||||
( backup_list.before_begin()
|
||||
, free_nodes
|
||||
, free_nodes.before_begin()
|
||||
, last_it
|
||||
, free_nodes.size());
|
||||
bit = it;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
//We should have removed all the nodes from the free list
|
||||
BOOST_ASSERT(m_freelist.empty());
|
||||
|
||||
//Now pass all the node to the free list again
|
||||
m_freelist.splice_after
|
||||
( m_freelist.before_begin()
|
||||
, backup_list
|
||||
, backup_list.before_begin()
|
||||
, backup_list_last
|
||||
, backup_list.size());
|
||||
}
|
||||
|
||||
size_type num_free_nodes()
|
||||
{ return m_freelist.size(); }
|
||||
|
||||
//!Deallocates all used memory. Precondition: all nodes allocated from this pool should
|
||||
//!already be deallocated. Otherwise, undefined behaviour. Never throws
|
||||
void purge_blocks()
|
||||
{
|
||||
//check for memory leaks
|
||||
BOOST_ASSERT(m_allocated==0);
|
||||
size_type blocksize = (get_rounded_size)
|
||||
(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
|
||||
|
||||
//We iterate though the NodeBlock list to free the memory
|
||||
while(!m_blocklist.empty()){
|
||||
void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
|
||||
m_blocklist.pop_front();
|
||||
mp_segment_mngr_base->deallocate((void*)addr);
|
||||
}
|
||||
//Just clear free node list
|
||||
m_freelist.clear();
|
||||
}
|
||||
|
||||
void swap(private_node_pool_impl &other)
|
||||
{
|
||||
BOOST_ASSERT(m_nodes_per_block == other.m_nodes_per_block);
|
||||
BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
|
||||
std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
|
||||
m_blocklist.swap(other.m_blocklist);
|
||||
m_freelist.swap(other.m_freelist);
|
||||
std::swap(m_allocated, other.m_allocated);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct push_in_list
|
||||
{
|
||||
push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
|
||||
: slist_(l), last_it_(it)
|
||||
{}
|
||||
|
||||
void operator()(typename free_nodes_t::pointer p) const
|
||||
{
|
||||
slist_.push_front(*p);
|
||||
if(slist_.size() == 1){ //Cache last element
|
||||
++last_it_ = slist_.begin();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
free_nodes_t &slist_;
|
||||
typename free_nodes_t::iterator &last_it_;
|
||||
};
|
||||
|
||||
struct is_between
|
||||
{
|
||||
typedef typename free_nodes_t::value_type argument_type;
|
||||
typedef bool result_type;
|
||||
|
||||
is_between(const void *addr, std::size_t size)
|
||||
: beg_(static_cast<const char *>(addr)), end_(beg_+size)
|
||||
{}
|
||||
|
||||
bool operator()(typename free_nodes_t::const_reference v) const
|
||||
{
|
||||
return (beg_ <= reinterpret_cast<const char *>(&v) &&
|
||||
end_ > reinterpret_cast<const char *>(&v));
|
||||
}
|
||||
private:
|
||||
const char * beg_;
|
||||
const char * end_;
|
||||
};
|
||||
|
||||
//!Allocates one node, using single segregated storage algorithm.
|
||||
//!Never throws
|
||||
node_t *priv_alloc_node()
|
||||
{
|
||||
//If there are no free nodes we allocate a new block
|
||||
if (m_freelist.empty())
|
||||
this->priv_alloc_block(1);
|
||||
//We take the first free node
|
||||
node_t *n = (node_t*)&m_freelist.front();
|
||||
m_freelist.pop_front();
|
||||
++m_allocated;
|
||||
return n;
|
||||
}
|
||||
|
||||
//!Deallocates one node, using single segregated storage algorithm.
|
||||
//!Never throws
|
||||
void priv_dealloc_node(void *pElem)
|
||||
{
|
||||
//We put the node at the beginning of the free node list
|
||||
node_t * to_deallocate = static_cast<node_t*>(pElem);
|
||||
m_freelist.push_front(*to_deallocate);
|
||||
BOOST_ASSERT(m_allocated>0);
|
||||
--m_allocated;
|
||||
}
|
||||
|
||||
//!Allocates several blocks of nodes. Can throw
|
||||
void priv_alloc_block(size_type num_blocks)
|
||||
{
|
||||
BOOST_ASSERT(num_blocks > 0);
|
||||
size_type blocksize =
|
||||
(get_rounded_size)(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
|
||||
|
||||
BOOST_TRY{
|
||||
for(size_type i = 0; i != num_blocks; ++i){
|
||||
//We allocate a new NodeBlock and put it as first
|
||||
//element in the free Node list
|
||||
char *pNode = reinterpret_cast<char*>
|
||||
(mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
|
||||
char *pBlock = pNode;
|
||||
m_blocklist.push_front(get_block_hook(pBlock, blocksize));
|
||||
|
||||
//We initialize all Nodes in Node Block to insert
|
||||
//them in the free Node list
|
||||
for(size_type j = 0; j < m_nodes_per_block; ++j, pNode += m_real_node_size){
|
||||
m_freelist.push_front(*new (pNode) node_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//to-do: if possible, an efficient way to deallocate allocated blocks
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
//!Deprecated, use deallocate_free_blocks
|
||||
void deallocate_free_chunks()
|
||||
{ this->deallocate_free_blocks(); }
|
||||
|
||||
//!Deprecated, use purge_blocks
|
||||
void purge_chunks()
|
||||
{ this->purge_blocks(); }
|
||||
|
||||
private:
|
||||
//!Returns a reference to the block hook placed in the end of the block
|
||||
static node_t & get_block_hook (void *block, size_type blocksize)
|
||||
{
|
||||
return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
|
||||
}
|
||||
|
||||
//!Returns the starting address of the block reference to the block hook placed in the end of the block
|
||||
void *get_block_from_hook (node_t *hook, size_type blocksize)
|
||||
{
|
||||
return (reinterpret_cast<char*>(hook) - blocksize);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_pointer>::template rebind_pointer<segment_manager_base_type>::type segment_mngr_base_ptr_t;
|
||||
|
||||
const size_type m_nodes_per_block;
|
||||
const size_type m_real_node_size;
|
||||
segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
|
||||
blockslist_t m_blocklist; //Intrusive container of blocks
|
||||
free_nodes_t m_freelist; //Intrusive container of free nods
|
||||
size_type m_allocated; //Used nodes for debugging
|
||||
};
|
||||
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
679
install/boost_1_75_0/include/boost/container/detail/pair.hpp
Normal file
679
install/boost_1_75_0/include/boost/container/detail/pair.hpp
Normal file
@@ -0,0 +1,679 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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/static_assert.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
# include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#endif
|
||||
#include <boost/move/adl_move_swap.hpp> //swap
|
||||
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace tuples {
|
||||
|
||||
struct null_type;
|
||||
|
||||
template <
|
||||
class T0, class T1, class T2,
|
||||
class T3, class T4, class T5,
|
||||
class T6, class T7, class T8,
|
||||
class T9>
|
||||
class tuple;
|
||||
|
||||
} //namespace tuples {
|
||||
} //namespace boost {
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace pair_impl {
|
||||
|
||||
template <class TupleClass>
|
||||
struct is_boost_tuple
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <
|
||||
class T0, class T1, class T2,
|
||||
class T3, class T4, class T5,
|
||||
class T6, class T7, class T8,
|
||||
class T9>
|
||||
struct is_boost_tuple< boost::tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class Tuple>
|
||||
struct disable_if_boost_tuple
|
||||
: boost::container::dtl::disable_if< is_boost_tuple<Tuple> >
|
||||
{};
|
||||
|
||||
template<class T>
|
||||
struct is_tuple_null
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_tuple_null<boost::tuples::null_type>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
//MSVC 2010 tuple marker
|
||||
namespace std { namespace tr1 { struct _Nil; }}
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
//MSVC 2012 tuple marker
|
||||
namespace std { struct _Nil; }
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <int Dummy = 0>
|
||||
struct std_piecewise_construct_holder
|
||||
{
|
||||
static ::std::piecewise_construct_t *dummy;
|
||||
};
|
||||
|
||||
template <int Dummy>
|
||||
::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy =
|
||||
reinterpret_cast< ::std::piecewise_construct_t *>(0x01234); //Avoid sanitizer errors on references to null pointers
|
||||
|
||||
typedef const std::piecewise_construct_t & piecewise_construct_t;
|
||||
|
||||
struct try_emplace_t{};
|
||||
|
||||
#else
|
||||
|
||||
//! The piecewise_construct_t struct is an empty structure type used as a unique type to
|
||||
//! disambiguate used to disambiguate between different functions that take two tuple arguments.
|
||||
typedef unspecified piecewise_construct_t;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A instance of type
|
||||
//! piecewise_construct_t
|
||||
static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy);
|
||||
|
||||
///@cond
|
||||
|
||||
namespace dtl {
|
||||
|
||||
struct piecewise_construct_use
|
||||
{
|
||||
//Avoid warnings of unused "piecewise_construct"
|
||||
piecewise_construct_use()
|
||||
{ (void)&::boost::container::piecewise_construct; }
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair;
|
||||
|
||||
template <class T>
|
||||
struct is_pair
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_pair< pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_pair< std::pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_not_pair
|
||||
{
|
||||
static const bool value = !is_pair<T>::value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_std_pair
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_std_pair< std::pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
struct pair_nat;
|
||||
|
||||
template<typename T, typename U, typename V>
|
||||
void get(T); //to enable ADL
|
||||
|
||||
///@endcond
|
||||
|
||||
#ifdef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
|
||||
//Libc++, in some versions, has an ABI breakage that needs some
|
||||
//padding in dtl::pair, as "std::pair::first" is not at offset zero.
|
||||
//See: https://reviews.llvm.org/D56357 for more information.
|
||||
//
|
||||
template <class T1, class T2, std::size_t N>
|
||||
struct pair_padding
|
||||
{
|
||||
char padding[N];
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair_padding<T1, T2, 0>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct simple_pair
|
||||
{
|
||||
T1 first;
|
||||
T2 second;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
#ifdef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
|
||||
: pair_padding<T1, T2, sizeof(std::pair<T1, T2>) - sizeof(simple_pair<T1, T2>)>
|
||||
#endif
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(pair)
|
||||
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
|
||||
//Default constructor
|
||||
pair()
|
||||
: first(), second()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
//pair copy assignment
|
||||
pair(const pair& x)
|
||||
: first(x.first), second(x.second)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
//pair move constructor
|
||||
pair(BOOST_RV_REF(pair) p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair(const pair<D, S> &p)
|
||||
: first(p.first), second(p.second)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
//pair from two values
|
||||
pair(const T1 &t1, const T2 &t2)
|
||||
: first(t1)
|
||||
, second(t2)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, 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))
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
//And now compatibility with std::pair
|
||||
pair(const std::pair<T1, T2>& x)
|
||||
: first(x.first), second(x.second)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair(const std::pair<D, S>& p)
|
||||
: first(p.first), second(p.second)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template< class KeyType, class ...Args>
|
||||
pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args)
|
||||
: first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
#else
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(N)\
|
||||
template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
|
||||
pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
|
||||
: first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\
|
||||
{\
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE)
|
||||
#undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
|
||||
|
||||
#endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
pair( piecewise_construct_t\
|
||||
, BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q\
|
||||
, typename dtl::enable_if_c\
|
||||
< pair_impl::is_boost_tuple< BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> >::value &&\
|
||||
!(pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARG##N>::value || pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARGQ##M>::value) \
|
||||
>::type* = 0\
|
||||
)\
|
||||
: first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
|
||||
{ (void)p; (void)q;\
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
|
||||
|
||||
//piecewise construction from variadic tuple (with delegating constructors)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
# if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS)
|
||||
private:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
|
||||
pair(Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
|
||||
: first (::boost::forward<Args1>(get<Indexes1>(t1))...)
|
||||
, second(::boost::forward<Args2>(get<Indexes2>(t2))...)
|
||||
{ (void) t1; (void)t2; }
|
||||
|
||||
public:
|
||||
template< template<class ...> class Tuple, class... Args1, class... Args2
|
||||
, class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
: pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
# else
|
||||
//piecewise construction from variadic tuple (suboptimal, without delegating constructors)
|
||||
private:
|
||||
template<typename T, template<class ...> class Tuple, typename... Args>
|
||||
static T build_from_args(Tuple<Args...>&& t)
|
||||
{ return do_build_from_args<T>(::boost::move(t), typename build_number_seq<sizeof...(Args)>::type()); }
|
||||
|
||||
template<typename T, template<class ...> class Tuple, typename... Args, std::size_t... Indexes>
|
||||
static T do_build_from_args(Tuple<Args...> && t, const index_tuple<Indexes...>&)
|
||||
{ (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...); }
|
||||
|
||||
public:
|
||||
template< template<class ...> class Tuple, class... Args1, class... Args2
|
||||
, class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
: first (build_from_args<first_type> (::boost::move(t1)))
|
||||
, second (build_from_args<second_type>(::boost::move(t2)))
|
||||
{
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
|
||||
}
|
||||
# endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
//MSVC 2010 tuple implementation
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class StdTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
pair( piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
|
||||
{ (void)p; (void)q;\
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
#if _VARIADIC_MAX >= 9
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
|
||||
#else
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
|
||||
#endif
|
||||
|
||||
//MSVC 2012 tuple implementation
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
|
||||
template< template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
pair( piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
|
||||
{ (void)p; (void)q;\
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
|
||||
#endif
|
||||
|
||||
//pair copy assignment
|
||||
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//pair move assignment
|
||||
pair& operator=(BOOST_RV_REF(pair) p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
typename ::boost::container::dtl::disable_if_or
|
||||
< pair &
|
||||
, ::boost::container::dtl::is_same<T1, D>
|
||||
, ::boost::container::dtl::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::dtl::disable_if_or
|
||||
< pair &
|
||||
, ::boost::container::dtl::is_same<T1, D>
|
||||
, ::boost::container::dtl::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 dtl {
|
||||
} //namespace container {
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
template<class T1, class T2>
|
||||
struct has_move_emulation_enabled< ::boost::container::dtl::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::dtl::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class_or_union< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_union;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_union< ::boost::container::dtl::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_union< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_class;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class< ::boost::container::dtl::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
|
||||
//Triviality of pair
|
||||
template<class T>
|
||||
struct is_trivially_copy_constructible;
|
||||
|
||||
template<class A, class B>
|
||||
struct is_trivially_copy_assignable
|
||||
<boost::container::dtl::pair<A,B> >
|
||||
{
|
||||
static const bool value = boost::move_detail::is_trivially_copy_assignable<A>::value &&
|
||||
boost::move_detail::is_trivially_copy_assignable<B>::value ;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_trivially_move_constructible;
|
||||
|
||||
template<class A, class B>
|
||||
struct is_trivially_move_assignable
|
||||
<boost::container::dtl::pair<A,B> >
|
||||
{
|
||||
static const bool value = boost::move_detail::is_trivially_move_assignable<A>::value &&
|
||||
boost::move_detail::is_trivially_move_assignable<B>::value ;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_trivially_copy_assignable;
|
||||
|
||||
template<class A, class B>
|
||||
struct is_trivially_copy_constructible<boost::container::dtl::pair<A,B> >
|
||||
{
|
||||
static const bool value = boost::move_detail::is_trivially_copy_constructible<A>::value &&
|
||||
boost::move_detail::is_trivially_copy_constructible<B>::value ;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_trivially_move_assignable;
|
||||
|
||||
template<class A, class B>
|
||||
struct is_trivially_move_constructible<boost::container::dtl::pair<A,B> >
|
||||
{
|
||||
static const bool value = boost::move_detail::is_trivially_move_constructible<A>::value &&
|
||||
boost::move_detail::is_trivially_move_constructible<B>::value ;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_trivially_destructible;
|
||||
|
||||
template<class A, class B>
|
||||
struct is_trivially_destructible<boost::container::dtl::pair<A,B> >
|
||||
{
|
||||
static const bool value = boost::move_detail::is_trivially_destructible<A>::value &&
|
||||
boost::move_detail::is_trivially_destructible<B>::value ;
|
||||
};
|
||||
|
||||
|
||||
} //namespace move_detail{
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP
|
||||
@@ -0,0 +1,55 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
||||
#define BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_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 {
|
||||
|
||||
template<class Key, class Mapped>
|
||||
struct pair_key_mapped_of_value
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef Mapped mapped_type;
|
||||
|
||||
template<class Pair>
|
||||
const key_type & key_of_value(const Pair &p) const
|
||||
{ return p.first; }
|
||||
|
||||
template<class Pair>
|
||||
const mapped_type & mapped_of_value(const Pair &p) const
|
||||
{ return p.second; }
|
||||
|
||||
template<class Pair>
|
||||
key_type & key_of_value(Pair &p) const
|
||||
{ return const_cast<key_type&>(p.first); }
|
||||
|
||||
template<class Pair>
|
||||
mapped_type & mapped_of_value(Pair &p) const
|
||||
{ return p.second; }
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
struct boost_container_new_t{};
|
||||
|
||||
//avoid including <new>
|
||||
inline void *operator new(std::size_t, void *p, boost_container_new_t)
|
||||
{ return p; }
|
||||
|
||||
inline void operator delete(void *, void *, boost_container_new_t)
|
||||
{}
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_POOL_COMMON_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_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/intrusive/slist.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class VoidPointer>
|
||||
struct node_slist
|
||||
{
|
||||
//This hook will be used to chain the individual nodes
|
||||
typedef typename bi::make_slist_base_hook
|
||||
<bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type slist_hook_t;
|
||||
|
||||
//A node object will hold node_t when it's not allocated
|
||||
typedef slist_hook_t node_t;
|
||||
|
||||
typedef typename bi::make_slist
|
||||
<node_t, bi::linear<true>, bi::cache_last<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_stateless_segment_manager
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
@@ -0,0 +1,102 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_POOL_COMMON_ALLOC_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/container/detail/pool_common.hpp>
|
||||
#include <boost/container/detail/dlmalloc.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost{
|
||||
namespace container{
|
||||
namespace dtl{
|
||||
|
||||
struct node_slist_helper
|
||||
: public boost::container::dtl::node_slist<void*>
|
||||
{};
|
||||
|
||||
struct fake_segment_manager
|
||||
{
|
||||
typedef void * void_pointer;
|
||||
static const std::size_t PayloadPerAllocation = BOOST_CONTAINER_ALLOCATION_PAYLOAD;
|
||||
|
||||
typedef boost::container::dtl::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain;
|
||||
static void deallocate(void_pointer p)
|
||||
{ dlmalloc_free(p); }
|
||||
|
||||
static void deallocate_many(multiallocation_chain &chain)
|
||||
{
|
||||
std::size_t size = chain.size();
|
||||
std::pair<void*, void*> ptrs = chain.extract_data();
|
||||
dlmalloc_memchain dlchain;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&dlchain, ptrs.first, ptrs.second, size);
|
||||
dlmalloc_multidealloc(&dlchain);
|
||||
}
|
||||
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
static void *allocate_aligned(std::size_t nbytes, std::size_t alignment)
|
||||
{
|
||||
void *ret = dlmalloc_memalign(nbytes, alignment);
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *allocate(std::size_t nbytes)
|
||||
{
|
||||
void *ret = dlmalloc_malloc(nbytes);
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace boost{
|
||||
} //namespace container{
|
||||
} //namespace dtl{
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class T>
|
||||
struct is_stateless_segment_manager;
|
||||
|
||||
template<>
|
||||
struct is_stateless_segment_manager
|
||||
<boost::container::dtl::fake_segment_manager>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
|
||||
@@ -0,0 +1,191 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_POOL_RESOURCE_HPP
|
||||
#define BOOST_CONTAINER_POOL_RESOURCE_HPP
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <boost/container/detail/block_list.hpp>
|
||||
#include <boost/container/pmr/pool_options.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace pmr {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
class pool_data_t;
|
||||
|
||||
static const std::size_t pool_options_minimum_max_blocks_per_chunk = 1u;
|
||||
static const std::size_t pool_options_default_max_blocks_per_chunk = 32u;
|
||||
static const std::size_t pool_options_minimum_largest_required_pool_block =
|
||||
memory_resource::max_align > 2*sizeof(void*) ? memory_resource::max_align : 2*sizeof(void*);
|
||||
static const std::size_t pool_options_default_largest_required_pool_block =
|
||||
pool_options_minimum_largest_required_pool_block > 4096u
|
||||
? pool_options_minimum_largest_required_pool_block : 4096u;
|
||||
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
class pool_resource
|
||||
{
|
||||
typedef block_list_base<> block_list_base_t;
|
||||
|
||||
pool_options m_options;
|
||||
memory_resource& m_upstream;
|
||||
block_list_base_t m_oversized_list;
|
||||
pool_data_t *m_pool_data;
|
||||
std::size_t m_pool_count;
|
||||
|
||||
static void priv_limit_option(std::size_t &val, std::size_t min, std::size_t max);
|
||||
static std::size_t priv_pool_index(std::size_t block_size);
|
||||
static std::size_t priv_pool_block(std::size_t index);
|
||||
|
||||
void priv_fix_options();
|
||||
void priv_init_pools();
|
||||
void priv_constructor_body();
|
||||
|
||||
public:
|
||||
|
||||
//! <b>Requires</b>: `upstream` is the address of a valid memory resource.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a pool resource object that will obtain memory
|
||||
//! from upstream whenever the pool resource is unable to satisfy a memory
|
||||
//! request from its own internal data structures. The resulting object will hold
|
||||
//! a copy of upstream, but will not own the resource to which upstream points.
|
||||
//! [ Note: The intention is that calls to upstream->allocate() will be
|
||||
//! substantially fewer than calls to this->allocate() in most cases. - end note
|
||||
//! The behavior of the pooling mechanism is tuned according to the value of
|
||||
//! the opts argument.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless upstream->allocate() throws. It is unspecified if
|
||||
//! or under what conditions this constructor calls upstream->allocate().
|
||||
pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT;
|
||||
|
||||
//! <b>Effects</b>: Same as
|
||||
//! `pool_resource(pool_options(), get_default_resource())`.
|
||||
pool_resource() BOOST_NOEXCEPT;
|
||||
|
||||
//! <b>Effects</b>: Same as
|
||||
//! `pool_resource(pool_options(), upstream)`.
|
||||
explicit pool_resource(memory_resource* upstream) BOOST_NOEXCEPT;
|
||||
|
||||
//! <b>Effects</b>: Same as
|
||||
//! `pool_resource(opts, get_default_resource())`.
|
||||
explicit pool_resource(const pool_options& opts) BOOST_NOEXCEPT;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
pool_resource(const pool_resource&) = delete;
|
||||
pool_resource operator=(const pool_resource&) = delete;
|
||||
#else
|
||||
private:
|
||||
pool_resource (const pool_resource&);
|
||||
pool_resource operator=(const pool_resource&);
|
||||
public:
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Calls
|
||||
//! `this->release()`.
|
||||
virtual ~pool_resource();
|
||||
|
||||
//! <b>Effects</b>: Calls Calls `upstream_resource()->deallocate()` as necessary
|
||||
//! to release all allocated memory. [ Note: memory is released back to
|
||||
//! `upstream_resource()` even if deallocate has not been called for some
|
||||
//! of the allocated blocks. - end note ]
|
||||
void release();
|
||||
|
||||
//! <b>Returns</b>: The value of the upstream argument provided to the
|
||||
//! constructor of this object.
|
||||
memory_resource* upstream_resource() const;
|
||||
|
||||
//! <b>Returns</b>: The options that control the pooling behavior of this resource.
|
||||
//! The values in the returned struct may differ from those supplied to the pool
|
||||
//! resource constructor in that values of zero will be replaced with
|
||||
//! implementation-defined defaults and sizes may be rounded to unspecified granularity.
|
||||
pool_options options() const;
|
||||
|
||||
public: //public so that [un]synchronized_pool_resource can use them
|
||||
|
||||
//! <b>Returns</b>: A pointer to allocated storage with a size of at least `bytes`.
|
||||
//! The size and alignment of the allocated memory shall meet the requirements for
|
||||
//! a class derived from `memory_resource`.
|
||||
//!
|
||||
//! <b>Effects</b>: If the pool selected for a block of size bytes is unable to
|
||||
//! satisfy the memory request from its own internal data structures, it will call
|
||||
//! `upstream_resource()->allocate()` to obtain more memory. If `bytes` is larger
|
||||
//! than that which the largest pool can handle, then memory will be allocated
|
||||
//! using `upstream_resource()->allocate()`.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws.
|
||||
virtual void* do_allocate(std::size_t bytes, std::size_t alignment);
|
||||
|
||||
//! <b>Effects</b>: Return the memory at p to the pool. It is unspecified if or under
|
||||
//! what circumstances this operation will result in a call to
|
||||
//! `upstream_resource()->deallocate()`.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment);
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `this == dynamic_cast<const pool_resource*>(&other)`.
|
||||
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT;
|
||||
|
||||
//Non-standard observers
|
||||
public:
|
||||
//! <b>Returns</b>: The number of pools that will be used in the pool resource.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
std::size_t pool_count() const;
|
||||
|
||||
//! <b>Returns</b>: The index of the pool that will be used to serve the allocation of `bytes`.
|
||||
//! from the pool specified by `pool_index`. Returns `pool_count()` if `bytes` is bigger
|
||||
//! than `options().largest_required_pool_block` (no pool will be used to serve this).
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
std::size_t pool_index(std::size_t bytes) const;
|
||||
|
||||
//! <b>Requires</b>: `pool_idx < pool_index()`
|
||||
//!
|
||||
//! <b>Returns</b>: The number blocks that will be allocated in the next chunk
|
||||
//! from the pool specified by `pool_idx`.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
std::size_t pool_next_blocks_per_chunk(std::size_t pool_idx) const;
|
||||
|
||||
//! <b>Requires</b>: `pool_idx < pool_index()`
|
||||
//!
|
||||
//! <b>Returns</b>: The number of bytes of the block that the specified `pool_idx` pool manages.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
std::size_t pool_block(std::size_t pool_idx) const;
|
||||
|
||||
//! <b>Requires</b>: `pool_idx < pool_index()`
|
||||
//!
|
||||
//! <b>Returns</b>: The number of blocks that the specified `pool_idx` pool has cached
|
||||
//! and will be served without calling the upstream_allocator.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
std::size_t pool_cached_blocks(std::size_t pool_idx) const;
|
||||
};
|
||||
|
||||
} //namespace pmr {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_POOL_RESOURCE_HPP
|
||||
@@ -0,0 +1,121 @@
|
||||
// Copyright (C) 2000 Stephen Cleary
|
||||
// Copyright (C) 2008 Ion Gaztanaga
|
||||
//
|
||||
// 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 for updates, documentation, and revision history.
|
||||
//
|
||||
// This file is a modified file from Boost.Pool
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-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_SINGLETON_DETAIL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_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>
|
||||
|
||||
//
|
||||
// The following helper classes are placeholders for a generic "singleton"
|
||||
// class. The classes below support usage of singletons, including use in
|
||||
// program startup/shutdown code, AS LONG AS there is only one thread
|
||||
// running before main() begins, and only one thread running after main()
|
||||
// exits.
|
||||
//
|
||||
// This class is also limited in that it can only provide singleton usage for
|
||||
// classes with default constructors.
|
||||
//
|
||||
|
||||
// The design of this class is somewhat twisted, but can be followed by the
|
||||
// calling inheritance. Let us assume that there is some user code that
|
||||
// calls "singleton_default<T>::instance()". The following (convoluted)
|
||||
// sequence ensures that the same function will be called before main():
|
||||
// instance() contains a call to create_object.do_nothing()
|
||||
// Thus, object_creator is implicitly instantiated, and create_object
|
||||
// must exist.
|
||||
// Since create_object is a static member, its constructor must be
|
||||
// called before main().
|
||||
// The constructor contains a call to instance(), thus ensuring that
|
||||
// instance() will be called before main().
|
||||
// The first time instance() is called (i.e., before main()) is the
|
||||
// latest point in program execution where the object of type T
|
||||
// can be created.
|
||||
// Thus, any call to instance() will auto-magically result in a call to
|
||||
// instance() before main(), unless already present.
|
||||
// Furthermore, since the instance() function contains the object, instead
|
||||
// of the singleton_default class containing a static instance of the
|
||||
// object, that object is guaranteed to be constructed (at the latest) in
|
||||
// the first call to instance(). This permits calls to instance() from
|
||||
// static code, even if that code is called before the file-scope objects
|
||||
// in this file have been initialized.
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
// T must be: no-throw default constructible and no-throw destructible
|
||||
template <typename T>
|
||||
struct singleton_default
|
||||
{
|
||||
private:
|
||||
struct object_creator
|
||||
{
|
||||
// This constructor does nothing more than ensure that instance()
|
||||
// is called before main() begins, thus creating the static
|
||||
// T object before multithreading race issues can come up.
|
||||
object_creator() { singleton_default<T>::instance(); }
|
||||
inline void do_nothing() const { }
|
||||
};
|
||||
static object_creator create_object;
|
||||
|
||||
singleton_default();
|
||||
|
||||
public:
|
||||
typedef T object_type;
|
||||
|
||||
// If, at any point (in user code), singleton_default<T>::instance()
|
||||
// is called, then the following function is instantiated.
|
||||
static object_type & instance()
|
||||
{
|
||||
// This is the object that we return a reference to.
|
||||
// It is guaranteed to be created before main() begins because of
|
||||
// the next line.
|
||||
static object_type obj;
|
||||
|
||||
// The following line does nothing else than force the instantiation
|
||||
// of singleton_default<T>::create_object, whose constructor is
|
||||
// called before main() begins.
|
||||
create_object.do_nothing();
|
||||
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
typename singleton_default<T>::object_creator
|
||||
singleton_default<T>::create_object;
|
||||
|
||||
} // namespace dtl
|
||||
} // namespace container
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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 T>
|
||||
struct equal_to;
|
||||
|
||||
template<class T1, class T2>
|
||||
struct pair;
|
||||
|
||||
template<class T>
|
||||
struct char_traits;
|
||||
|
||||
struct input_iterator_tag;
|
||||
struct forward_iterator_tag;
|
||||
struct bidirectional_iterator_tag;
|
||||
struct random_access_iterator_tag;
|
||||
|
||||
template<class Container>
|
||||
class insert_iterator;
|
||||
|
||||
struct allocator_arg_t;
|
||||
|
||||
struct piecewise_construct_t;
|
||||
|
||||
BOOST_MOVE_STD_NS_END
|
||||
#include <boost/move/detail/std_ns_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
||||
@@ -0,0 +1,181 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2018-2018. 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/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This code is partially based on the lightweight mutex implemented
|
||||
// by Boost.SmartPtr:
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
// Copyright (c) Microsoft Corporation 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)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
|
||||
#include <pthread.h>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
class thread_mutex
|
||||
{
|
||||
public:
|
||||
thread_mutex()
|
||||
{
|
||||
BOOST_VERIFY(pthread_mutex_init(&m_mut, 0) == 0);
|
||||
}
|
||||
|
||||
~thread_mutex()
|
||||
{
|
||||
BOOST_VERIFY(pthread_mutex_destroy(&m_mut) == 0);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
BOOST_VERIFY(pthread_mutex_lock( &m_mut) == 0);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
BOOST_VERIFY(pthread_mutex_unlock(&m_mut) == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
thread_mutex(thread_mutex const &);
|
||||
thread_mutex & operator=(thread_mutex const &);
|
||||
|
||||
pthread_mutex_t m_mut;
|
||||
};
|
||||
|
||||
} // namespace dtl {
|
||||
} // namespace container {
|
||||
} // namespace boost {
|
||||
|
||||
#else //!BOOST_HAS_PTHREADS (Windows implementation)
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
typedef ::CRITICAL_SECTION win_critical_section;
|
||||
|
||||
} // namespace dtl {
|
||||
} // namespace container {
|
||||
} // namespace boost {
|
||||
|
||||
#else //! BOOST_USE_WINDOWS_H
|
||||
|
||||
struct _RTL_CRITICAL_SECTION_DEBUG;
|
||||
struct _RTL_CRITICAL_SECTION;
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
#ifdef BOOST_PLAT_WINDOWS_UWP
|
||||
extern "C" __declspec(dllimport) int __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
|
||||
#endif
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *);
|
||||
|
||||
struct win_critical_section
|
||||
{
|
||||
struct _RTL_CRITICAL_SECTION_DEBUG * DebugInfo;
|
||||
long LockCount;
|
||||
long RecursionCount;
|
||||
void * OwningThread;
|
||||
void * LockSemaphore;
|
||||
#if defined(_WIN64)
|
||||
unsigned __int64 SpinCount;
|
||||
#else
|
||||
unsigned long SpinCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace dtl {
|
||||
} // namespace container {
|
||||
} // namespace boost {
|
||||
|
||||
#endif //BOOST_USE_WINDOWS_H
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
class thread_mutex
|
||||
{
|
||||
public:
|
||||
thread_mutex()
|
||||
{
|
||||
#ifdef BOOST_PLAT_WINDOWS_UWP
|
||||
(InitializeCriticalSectionEx)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0);
|
||||
#else
|
||||
(InitializeCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
|
||||
#endif
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
(EnterCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
(LeaveCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
|
||||
}
|
||||
|
||||
~thread_mutex()
|
||||
{
|
||||
(DeleteCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
|
||||
}
|
||||
|
||||
private:
|
||||
thread_mutex(thread_mutex const &);
|
||||
thread_mutex & operator=(thread_mutex const &);
|
||||
|
||||
win_critical_section m_crit_sect;
|
||||
};
|
||||
|
||||
} // namespace dtl {
|
||||
} // namespace container {
|
||||
} // namespace boost {
|
||||
|
||||
#endif //BOOST_HAS_PTHREADS
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
|
||||
@@ -0,0 +1,180 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template <class PseudoReference>
|
||||
struct operator_arrow_proxy
|
||||
{
|
||||
operator_arrow_proxy(const PseudoReference &px)
|
||||
: m_value(px)
|
||||
{}
|
||||
|
||||
typedef PseudoReference element_type;
|
||||
|
||||
PseudoReference* operator->() const { return &m_value; }
|
||||
|
||||
mutable PseudoReference m_value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct operator_arrow_proxy<T&>
|
||||
{
|
||||
operator_arrow_proxy(T &px)
|
||||
: m_value(px)
|
||||
{}
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
T* operator->() const { return const_cast<T*>(&m_value); }
|
||||
|
||||
T &m_value;
|
||||
};
|
||||
|
||||
template <class Iterator, class UnaryFunction>
|
||||
class transform_iterator
|
||||
: public UnaryFunction
|
||||
, public boost::container::iterator
|
||||
< typename Iterator::iterator_category
|
||||
, typename dtl::remove_reference<typename UnaryFunction::result_type>::type
|
||||
, typename Iterator::difference_type
|
||||
, operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
, typename UnaryFunction::result_type>
|
||||
{
|
||||
public:
|
||||
explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
|
||||
: UnaryFunction(f), m_it(it)
|
||||
{}
|
||||
|
||||
explicit transform_iterator()
|
||||
: UnaryFunction(), m_it()
|
||||
{}
|
||||
|
||||
//Constructors
|
||||
transform_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
transform_iterator operator++(int)
|
||||
{
|
||||
transform_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
/*
|
||||
friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
*/
|
||||
friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
transform_iterator& operator+=(typename Iterator::difference_type off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
transform_iterator operator+(typename Iterator::difference_type off) const
|
||||
{
|
||||
transform_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
transform_iterator& operator-=(typename Iterator::difference_type off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
transform_iterator operator-(typename Iterator::difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
typename UnaryFunction::result_type operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
operator->() const
|
||||
{ return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
|
||||
|
||||
Iterator & base()
|
||||
{ return m_it; }
|
||||
|
||||
const Iterator & base() const
|
||||
{ return m_it; }
|
||||
|
||||
private:
|
||||
Iterator m_it;
|
||||
|
||||
void increment()
|
||||
{ ++m_it; }
|
||||
|
||||
void decrement()
|
||||
{ --m_it; }
|
||||
|
||||
bool equal(const transform_iterator &other) const
|
||||
{ return m_it == other.m_it; }
|
||||
|
||||
bool less(const transform_iterator &other) const
|
||||
{ return other.m_it < m_it; }
|
||||
|
||||
typename UnaryFunction::result_type dereference() const
|
||||
{ return UnaryFunction::operator()(*m_it); }
|
||||
|
||||
void advance(typename Iterator::difference_type n)
|
||||
{ boost::container::iterator_advance(m_it, n); }
|
||||
|
||||
typename Iterator::difference_type distance_to(const transform_iterator &other)const
|
||||
{ return boost::container::iterator_distance(other.m_it, m_it); }
|
||||
};
|
||||
|
||||
template <class Iterator, class UnaryFunc>
|
||||
transform_iterator<Iterator, UnaryFunc>
|
||||
make_transform_iterator(Iterator it, UnaryFunc fun)
|
||||
{
|
||||
return transform_iterator<Iterator, UnaryFunc>(it, fun);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
1531
install/boost_1_75_0/include/boost/container/detail/tree.hpp
Normal file
1531
install/boost_1_75_0/include/boost/container/detail/tree.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// (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 dtl {
|
||||
|
||||
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::remove_cvref;
|
||||
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::nat2;
|
||||
using ::boost::move_detail::nat3;
|
||||
using ::boost::move_detail::max_align_t;
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Functors for member algorithm defaults
|
||||
template<class ValueType>
|
||||
struct value_less
|
||||
{
|
||||
bool operator()(const ValueType &a, const ValueType &b) const
|
||||
{ return a < b; }
|
||||
};
|
||||
|
||||
template<class ValueType>
|
||||
struct value_equal
|
||||
{
|
||||
bool operator()(const ValueType &a, const ValueType &b) const
|
||||
{ return a == b; }
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
|
||||
@@ -0,0 +1,51 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<class T>
|
||||
struct value_init
|
||||
{
|
||||
value_init()
|
||||
: m_t()
|
||||
{}
|
||||
|
||||
operator T &() { return m_t; }
|
||||
|
||||
T &get() { return m_t; }
|
||||
|
||||
T m_t;
|
||||
};
|
||||
|
||||
} //namespace dtl {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
@@ -0,0 +1,163 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace dtl {
|
||||
|
||||
template<typename... Values>
|
||||
class tuple;
|
||||
|
||||
template<> class tuple<>
|
||||
{};
|
||||
|
||||
template<typename Head, typename... Tail>
|
||||
class tuple<Head, Tail...>
|
||||
: private tuple<Tail...>
|
||||
{
|
||||
typedef tuple<Tail...> inherited;
|
||||
|
||||
public:
|
||||
tuple()
|
||||
: inherited(), m_head()
|
||||
{}
|
||||
|
||||
template<class U, class ...Args>
|
||||
tuple(U &&u, Args && ...args)
|
||||
: inherited(::boost::forward<Args>(args)...), m_head(::boost::forward<U>(u))
|
||||
{}
|
||||
|
||||
// Construct tuple from another tuple.
|
||||
template<typename... VValues>
|
||||
tuple(const tuple<VValues...>& other)
|
||||
: inherited(other.tail()), m_head(other.head())
|
||||
{}
|
||||
|
||||
template<typename... VValues>
|
||||
tuple& operator=(const tuple<VValues...>& other)
|
||||
{
|
||||
m_head = other.head();
|
||||
tail() = other.tail();
|
||||
return this;
|
||||
}
|
||||
|
||||
typename add_reference<Head>::type head() { return m_head; }
|
||||
typename add_reference<const Head>::type head() const { return m_head; }
|
||||
|
||||
inherited& tail() { return *this; }
|
||||
const inherited& tail() const { return *this; }
|
||||
|
||||
protected:
|
||||
Head m_head;
|
||||
};
|
||||
|
||||
|
||||
template<typename... Values>
|
||||
tuple<Values&&...> forward_as_tuple_impl(Values&&... values)
|
||||
{ return tuple<Values&&...>(::boost::forward<Values>(values)...); }
|
||||
|
||||
template<int I, typename Tuple>
|
||||
struct tuple_element;
|
||||
|
||||
template<int I, typename Head, typename... Tail>
|
||||
struct tuple_element<I, tuple<Head, Tail...> >
|
||||
{
|
||||
typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
|
||||
};
|
||||
|
||||
template<typename Head, typename... Tail>
|
||||
struct tuple_element<0, tuple<Head, Tail...> >
|
||||
{
|
||||
typedef Head type;
|
||||
};
|
||||
|
||||
template<int I, typename Tuple>
|
||||
class get_impl;
|
||||
|
||||
template<int I, typename Head, typename... Values>
|
||||
class get_impl<I, tuple<Head, Values...> >
|
||||
{
|
||||
typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
|
||||
typedef get_impl<I-1, tuple<Values...> > Next;
|
||||
|
||||
public:
|
||||
typedef typename add_reference<Element>::type type;
|
||||
typedef typename add_const_reference<Element>::type const_type;
|
||||
static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
||||
static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
||||
};
|
||||
|
||||
template<typename Head, typename... Values>
|
||||
class get_impl<0, tuple<Head, Values...> >
|
||||
{
|
||||
public:
|
||||
typedef typename add_reference<Head>::type type;
|
||||
typedef typename add_const_reference<Head>::type const_type;
|
||||
static type get(tuple<Head, Values...>& t) { return t.head(); }
|
||||
static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
|
||||
};
|
||||
|
||||
template<int I, typename... Values>
|
||||
typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); }
|
||||
|
||||
template<int I, typename... Values>
|
||||
typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); }
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
|
||||
// be used to "unpack" into comma-separated values
|
||||
// in a function call.
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
template<std::size_t...> struct index_tuple{ typedef index_tuple type; };
|
||||
|
||||
template<class S1, class S2> struct concat_index_tuple;
|
||||
|
||||
template<std::size_t... I1, std::size_t... I2>
|
||||
struct concat_index_tuple<index_tuple<I1...>, index_tuple<I2...>>
|
||||
: index_tuple<I1..., (sizeof...(I1)+I2)...>{};
|
||||
|
||||
template<std::size_t N> struct build_number_seq;
|
||||
|
||||
template<std::size_t N>
|
||||
struct build_number_seq
|
||||
: concat_index_tuple<typename build_number_seq<N/2>::type
|
||||
,typename build_number_seq<N - N/2 >::type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<> struct build_number_seq<0> : index_tuple<>{};
|
||||
template<> struct build_number_seq<1> : index_tuple<0>{};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace dtl {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
@@ -0,0 +1,101 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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 dtl {
|
||||
|
||||
template <class T, unsigned V>
|
||||
struct version_type
|
||||
: public dtl::integral_constant<unsigned, V>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
namespace impl{
|
||||
|
||||
template <class T>
|
||||
struct extract_version
|
||||
{
|
||||
typedef typename T::version type;
|
||||
};
|
||||
|
||||
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>::type::value;
|
||||
};
|
||||
|
||||
} //namespace impl
|
||||
|
||||
template <class T>
|
||||
struct version
|
||||
: public dtl::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 dtl {
|
||||
|
||||
typedef dtl::integral_constant<unsigned, 0> version_0;
|
||||
typedef dtl::integral_constant<unsigned, 1> version_1;
|
||||
typedef dtl::integral_constant<unsigned, 2> version_2;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
@@ -0,0 +1,142 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\
|
||||
&& !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
|
||||
#define BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
|
||||
&& (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
|
||||
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC_VERSION)
|
||||
# if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11)
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#elif defined(BOOST_MSVC)
|
||||
# if _MSC_FULL_VER < 180020827
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#elif defined(BOOST_CLANG)
|
||||
# if !__has_feature(cxx_delegating_constructors)
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC) && (_MSC_VER < 1400)
|
||||
#define BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600))
|
||||
#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE
|
||||
#endif
|
||||
|
||||
//Macros for documentation purposes. For code, expands to the argument
|
||||
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
|
||||
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
|
||||
|
||||
//Macros for memset optimization. In most platforms
|
||||
//memsetting pointers and floatings is safe and faster.
|
||||
//
|
||||
//If your platform does not offer these guarantees
|
||||
//define these to value zero.
|
||||
#ifndef BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO
|
||||
#define BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO 1
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_NULL
|
||||
#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL
|
||||
#endif
|
||||
|
||||
#define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2
|
||||
#define BOOST_CONTAINER_I ,
|
||||
#define BOOST_CONTAINER_DOCIGN(T) T
|
||||
#define BOOST_CONTAINER_DOCONLY(T)
|
||||
|
||||
/*
|
||||
we need to import/export our code only if the user has specifically
|
||||
asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
|
||||
libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK
|
||||
if they want just this one to be dynamically liked:
|
||||
*/
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
||||
|
||||
/* export if this is our own source, otherwise import: */
|
||||
#ifdef BOOST_CONTAINER_SOURCE
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_EXPORT
|
||||
#else
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_IMPORT
|
||||
|
||||
#endif /* BOOST_CONTAINER_SOURCE */
|
||||
#else
|
||||
#define BOOST_CONTAINER_DECL
|
||||
#endif /* DYN_LINK */
|
||||
|
||||
//#define BOOST_CONTAINER_DISABLE_FORCEINLINE
|
||||
|
||||
#if defined(BOOST_CONTAINER_DISABLE_FORCEINLINE)
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE)
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
||||
#elif defined(BOOST_MSVC) && defined(_DEBUG)
|
||||
//"__forceinline" and MSVC seems to have some bugs in debug mode
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5)))
|
||||
//Older GCCs have problems with forceinline
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#else
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
||||
#endif
|
||||
|
||||
//#define BOOST_CONTAINER_DISABLE_NOINLINE
|
||||
|
||||
#if defined(BOOST_CONTAINER_DISABLE_NOINLINE)
|
||||
#define BOOST_CONTAINER_NOINLINE
|
||||
#else
|
||||
#define BOOST_CONTAINER_NOINLINE BOOST_NOINLINE
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__has_feature)
|
||||
#define BOOST_CONTAINER_HAS_FEATURE(feature) 0
|
||||
#else
|
||||
#define BOOST_CONTAINER_HAS_FEATURE(feature) __has_feature(feature)
|
||||
#endif
|
||||
|
||||
//Detect address sanitizer
|
||||
#if defined(__SANITIZE_ADDRESS__) || BOOST_CONTAINER_HAS_FEATURE(address_sanitizer)
|
||||
#define BOOST_CONTAINER_ASAN
|
||||
#endif
|
||||
|
||||
|
||||
#if (__cplusplus >= 201703L)
|
||||
//CTAD supported
|
||||
#ifdef __INTEL_COMPILER
|
||||
//Intel compilers do not offer this feature yet
|
||||
#define BOOST_CONTAINER_NO_CXX17_CTAD
|
||||
#endif
|
||||
#else
|
||||
#define BOOST_CONTAINER_NO_CXX17_CTAD
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
Reference in New Issue
Block a user