mirror of
https://github.com/boostorg/container.git
synced 2026-01-30 18:22:44 +01:00
Merge branch 'develop'
This commit is contained in:
390
include/boost/container/adaptive_pool.hpp
Normal file
390
include/boost/container/adaptive_pool.hpp
Normal file
@@ -0,0 +1,390 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_ADAPTIVE_POOL_HPP
|
||||
#define BOOST_CONTAINER_ADAPTIVE_POOL_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/adaptive_node_pool.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/singleton.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//!An STL node allocator that uses a modified DLMalloc as memory
|
||||
//!source.
|
||||
//!
|
||||
//!This node allocator shares a segregated storage between all instances
|
||||
//!of adaptive_pool with equal sizeof(T).
|
||||
//!
|
||||
//!NodesPerBlock is the number of nodes allocated at once when the allocator
|
||||
//!needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks
|
||||
//!that the adaptive node pool will hold. The rest of the totally free blocks will be
|
||||
//!deallocated to the memory manager.
|
||||
//!
|
||||
//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
|
||||
//!(memory usable for nodes / total memory allocated from the memory allocator)
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template < class T
|
||||
, std::size_t NodesPerBlock = ADP_nodes_per_block
|
||||
, std::size_t MaxFreeBlocks = ADP_max_free_blocks
|
||||
, std::size_t OverheadPercent = ADP_overhead_percent
|
||||
>
|
||||
#else
|
||||
template < class T
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t MaxFreeBlocks
|
||||
, std::size_t OverheadPercent
|
||||
, unsigned Version
|
||||
>
|
||||
#endif
|
||||
class adaptive_pool
|
||||
{
|
||||
//!If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
|
||||
//!the allocator offers advanced expand in place and burst allocation capabilities.
|
||||
public:
|
||||
typedef unsigned int allocation_type;
|
||||
typedef adaptive_pool
|
||||
<T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> self_t;
|
||||
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
static const std::size_t max_free_blocks = MaxFreeBlocks;
|
||||
static const std::size_t overhead_percent = OverheadPercent;
|
||||
static const std::size_t real_nodes_per_block = NodesPerBlock;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
BOOST_STATIC_ASSERT((Version <=2));
|
||||
#endif
|
||||
|
||||
public:
|
||||
//-------
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & reference;
|
||||
typedef const typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain_void;
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
<multiallocation_chain_void, T> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains adaptive_pool from
|
||||
//!adaptive_pool
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef adaptive_pool
|
||||
< T2
|
||||
, NodesPerBlock
|
||||
, MaxFreeBlocks
|
||||
, OverheadPercent
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> other;
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
//!Not assignable from related adaptive_pool
|
||||
template<class T2, unsigned Version2, std::size_t N2, std::size_t F2>
|
||||
adaptive_pool& operator=
|
||||
(const adaptive_pool<T2, Version2, N2, F2>&);
|
||||
|
||||
//!Not assignable from other adaptive_pool
|
||||
adaptive_pool& operator=(const adaptive_pool&);
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//!Default constructor
|
||||
adaptive_pool() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from other adaptive_pool.
|
||||
adaptive_pool(const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from related adaptive_pool.
|
||||
template<class T2>
|
||||
adaptive_pool
|
||||
(const adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Destructor
|
||||
~adaptive_pool() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Returns the number of elements that could be allocated.
|
||||
//!Never throws
|
||||
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return size_type(-1)/sizeof(T); }
|
||||
|
||||
//!Allocate memory for an array of count elements.
|
||||
//!Throws std::bad_alloc if there is no enough memory
|
||||
pointer allocate(size_type count, const void * = 0)
|
||||
{
|
||||
if(count > this->max_size())
|
||||
boost::container::throw_bad_alloc();
|
||||
|
||||
if(Version == 1 && count == 1){
|
||||
typedef typename container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return pointer(static_cast<T*>(singleton_t::instance().allocate_node()));
|
||||
}
|
||||
else{
|
||||
return static_cast<pointer>(boost_cont_malloc(count*sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocate allocated memory.
|
||||
//!Never throws
|
||||
void deallocate(const pointer &ptr, size_type count) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
(void)count;
|
||||
if(Version == 1 && count == 1){
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(ptr);
|
||||
}
|
||||
else{
|
||||
boost_cont_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<pointer, bool>
|
||||
allocation_command(allocation_type command,
|
||||
size_type limit_size,
|
||||
size_type preferred_size,
|
||||
size_type &received_size, pointer reuse = pointer())
|
||||
{
|
||||
std::pair<pointer, bool> ret =
|
||||
this->priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
|
||||
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold.
|
||||
size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return boost_cont_size(p); }
|
||||
|
||||
//!Allocates just one object. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
//!Throws bad_alloc if there is no enough memory
|
||||
pointer allocate_one()
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return (pointer)singleton_t::instance().allocate_node();
|
||||
}
|
||||
|
||||
//!Allocates many elements of size == 1.
|
||||
//!Elements must be individually deallocated with deallocate_one()
|
||||
void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().allocate_nodes(num_elements, static_cast<typename shared_pool_t::multiallocation_chain&>(chain));
|
||||
//typename shared_pool_t::multiallocation_chain ch;
|
||||
//singleton_t::instance().allocate_nodes(num_elements, ch);
|
||||
//chain.incorporate_after
|
||||
//(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size());
|
||||
}
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
//!with other functions different from allocate_one(). Never throws
|
||||
void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(p);
|
||||
}
|
||||
|
||||
void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
//typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size());
|
||||
//singleton_t::instance().deallocate_nodes(ch);
|
||||
singleton_t::instance().deallocate_nodes(chain);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size.
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));/*
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));/*
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{/*
|
||||
boost_cont_memchain ch;
|
||||
void *beg(&*chain.begin()), *last(&*chain.last());
|
||||
size_t size(chain.size());
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size);
|
||||
boost_cont_multidealloc(&ch);*/
|
||||
boost_cont_multidealloc(reinterpret_cast<boost_cont_memchain *>(&chain));
|
||||
}
|
||||
|
||||
//!Deallocates all free blocks of the pool
|
||||
static void deallocate_free_blocks() BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_adaptive_node_pool
|
||||
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_free_blocks();
|
||||
}
|
||||
|
||||
//!Swaps allocators. Does not throw. If each allocator is placed in a
|
||||
//!different memory segment, the result is undefined.
|
||||
friend void swap(adaptive_pool &, adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!An allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return true; }
|
||||
|
||||
//!An allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return false; }
|
||||
/*
|
||||
//!Returns address of mutable object.
|
||||
//!Never throws
|
||||
pointer address(reference value) const
|
||||
{ return pointer(boost::addressof(value)); }
|
||||
|
||||
//!Returns address of non mutable object.
|
||||
//!Never throws
|
||||
const_pointer address(const_reference value) const
|
||||
{ return const_pointer(boost::addressof(value)); }
|
||||
|
||||
//!Default construct an object.
|
||||
//!Throws if T's default constructor throws
|
||||
void construct(const pointer &ptr)
|
||||
{ new(ptr) value_type; }
|
||||
|
||||
//!Construct a copy of the passed object.
|
||||
//!Throws if T's copy constructor throws
|
||||
void construct(pointer ptr, const_reference t)
|
||||
{ new(ptr) value_type(t); }
|
||||
|
||||
//!Destroys object. Throws if object's
|
||||
//!destructor throws
|
||||
void destroy(const pointer &ptr)
|
||||
{ (void)ptr; BOOST_ASSERT(ptr); (*ptr).~value_type(); }
|
||||
*/
|
||||
private:
|
||||
std::pair<pointer, bool> priv_allocation_command
|
||||
(allocation_type command, std::size_t limit_size
|
||||
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
|
||||
{
|
||||
boost_cont_command_ret_t ret = {0 , 0};
|
||||
if(limit_size > this->max_size() || preferred_size > this->max_size()){
|
||||
// ret.first = 0;
|
||||
return std::pair<pointer, bool>(pointer(), false);
|
||||
}
|
||||
std::size_t l_size = limit_size*sizeof(T);
|
||||
std::size_t p_size = preferred_size*sizeof(T);
|
||||
std::size_t r_size;
|
||||
{
|
||||
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
|
||||
}
|
||||
received_size = r_size/sizeof(T);
|
||||
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP
|
||||
368
include/boost/container/allocator.hpp
Normal file
368
include/boost/container/allocator.hpp
Normal file
@@ -0,0 +1,368 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template<unsigned Version, unsigned int AllocationDisableMask>
|
||||
class allocator<void, Version, AllocationDisableMask>
|
||||
{
|
||||
typedef allocator<void, Version, AllocationDisableMask> self_t;
|
||||
public:
|
||||
typedef void value_type;
|
||||
typedef void * pointer;
|
||||
typedef const void* const_pointer;
|
||||
typedef int & reference;
|
||||
typedef const int & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains an allocator that allocates
|
||||
//!objects of type T2
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef allocator< T2
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version, AllocationDisableMask
|
||||
#endif
|
||||
> other;
|
||||
};
|
||||
|
||||
//!Default constructor
|
||||
//!Never throws
|
||||
allocator()
|
||||
{}
|
||||
|
||||
//!Constructor from other allocator.
|
||||
//!Never throws
|
||||
allocator(const allocator &)
|
||||
{}
|
||||
|
||||
//!Constructor from related allocator.
|
||||
//!Never throws
|
||||
template<class T2>
|
||||
allocator(const allocator<T2, Version, AllocationDisableMask> &)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!\file
|
||||
//! This class is an extended STL-compatible that offers advanced allocation mechanism
|
||||
//!(in-place expansion, shrinking, burst-allocation...)
|
||||
//!
|
||||
//! This allocator is a wrapper around a modified DLmalloc.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template<class T>
|
||||
#else
|
||||
//! If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
|
||||
//! the allocator offers advanced expand in place and burst allocation capabilities.
|
||||
//
|
||||
//! AllocationDisableMask works only if Version is 2 and it can be an inclusive OR
|
||||
//! of allocation types the user wants to disable.
|
||||
template<class T, unsigned Version, unsigned int AllocationDisableMask>
|
||||
#endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
class allocator
|
||||
{
|
||||
typedef unsigned int allocation_type;
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
//Self type
|
||||
typedef allocator<T, Version, AllocationDisableMask> self_t;
|
||||
|
||||
//Not assignable from related allocator
|
||||
template<class T2, unsigned int Version2, unsigned int AllocationDisableMask2>
|
||||
allocator& operator=(const allocator<T2, Version2, AllocationDisableMask2>&);
|
||||
|
||||
//Not assignable from other allocator
|
||||
allocator& operator=(const allocator&);
|
||||
|
||||
static const unsigned int ForbiddenMask =
|
||||
BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BWD | BOOST_CONTAINER_EXPAND_FWD ;
|
||||
|
||||
//The mask can't disable all the allocation types
|
||||
BOOST_STATIC_ASSERT(( (AllocationDisableMask & ForbiddenMask) != ForbiddenMask ));
|
||||
|
||||
//The mask is only valid for version 2 allocators
|
||||
BOOST_STATIC_ASSERT(( Version != 1 || (AllocationDisableMask == 0) ));
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> void_multiallocation_chain;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
<void_multiallocation_chain, T> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains an allocator that allocates
|
||||
//!objects of type T2
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef allocator<T2, Version, AllocationDisableMask> other;
|
||||
};
|
||||
|
||||
//!Default constructor
|
||||
//!Never throws
|
||||
allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Constructor from other allocator.
|
||||
//!Never throws
|
||||
allocator(const allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Constructor from related allocator.
|
||||
//!Never throws
|
||||
template<class T2>
|
||||
allocator(const allocator<T2
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version, AllocationDisableMask
|
||||
#endif
|
||||
> &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Allocates memory for an array of count elements.
|
||||
//!Throws std::bad_alloc if there is no enough memory
|
||||
//!If Version is 2, this allocated memory can only be deallocated
|
||||
//!with deallocate() or (for Version == 2) deallocate_many()
|
||||
pointer allocate(size_type count, const void * hint= 0)
|
||||
{
|
||||
(void)hint;
|
||||
if(count > this->max_size())
|
||||
boost::container::throw_bad_alloc();
|
||||
void *ret = boost_cont_malloc(count*sizeof(T));
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return static_cast<pointer>(ret);
|
||||
}
|
||||
|
||||
//!Deallocates previously allocated memory.
|
||||
//!Never throws
|
||||
void deallocate(pointer ptr, size_type) BOOST_CONTAINER_NOEXCEPT
|
||||
{ boost_cont_free(ptr); }
|
||||
|
||||
//!Returns the maximum number of elements that could be allocated.
|
||||
//!Never throws
|
||||
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return size_type(-1)/sizeof(T); }
|
||||
|
||||
//!Swaps two allocators, does nothing
|
||||
//!because this allocator is stateless
|
||||
friend void swap(self_t &, self_t &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!An allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const allocator &, const allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return true; }
|
||||
|
||||
//!An allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const allocator &, const allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return false; }
|
||||
|
||||
//!An advanced function that offers in-place expansion shrink to fit and new allocation
|
||||
//!capabilities. Memory allocated with this function can only be deallocated with deallocate()
|
||||
//!or deallocate_many().
|
||||
//!This function is available only with Version == 2
|
||||
std::pair<pointer, bool>
|
||||
allocation_command(allocation_type command,
|
||||
size_type limit_size,
|
||||
size_type preferred_size,
|
||||
size_type &received_size, pointer reuse = pointer())
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
const allocation_type mask(AllocationDisableMask);
|
||||
command &= ~mask;
|
||||
std::pair<pointer, bool> ret =
|
||||
priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
|
||||
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold.
|
||||
//!Memory must not have been allocated with
|
||||
//!allocate_one or allocate_individual.
|
||||
//!This function is available only with Version == 2
|
||||
size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return boost_cont_size(p);
|
||||
}
|
||||
|
||||
//!Allocates just one object. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
//!Throws bad_alloc if there is no enough memory
|
||||
//!This function is available only with Version == 2
|
||||
pointer allocate_one()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return this->allocate(1);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size == 1.
|
||||
//!Elements must be individually deallocated with deallocate_one()
|
||||
//!This function is available only with Version == 2
|
||||
void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
this->allocate_many(1, num_elements, chain);
|
||||
}
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
//!with other functions different from allocate_one() or allocate_individual.
|
||||
//Never throws
|
||||
void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return this->deallocate(p, 1);
|
||||
}
|
||||
|
||||
//!Deallocates memory allocated with allocate_one() or allocate_individual().
|
||||
//!This function is available only with Version == 2
|
||||
void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return this->deallocate_many(chain);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size.
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
//!This function is available only with Version == 2
|
||||
void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));/*
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
//!This function is available only with Version == 2
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after(chain.before_begin()
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
|
||||
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );
|
||||
/*
|
||||
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
|
||||
boost::container::throw_bad_alloc();
|
||||
}*/
|
||||
}
|
||||
|
||||
//!Deallocates several elements allocated by
|
||||
//!allocate_many(), allocate(), or allocation_command().
|
||||
//!This function is available only with Version == 2
|
||||
void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
void *beg(&*chain.begin()), *last(&*chain.last());
|
||||
size_t size(chain.size());
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size);
|
||||
boost_cont_multidealloc(&ch);
|
||||
//boost_cont_multidealloc(reinterpret_cast<boost_cont_memchain *>(&chain));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::pair<pointer, bool> priv_allocation_command
|
||||
(allocation_type command, std::size_t limit_size
|
||||
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
|
||||
{
|
||||
boost_cont_command_ret_t ret = {0 , 0};
|
||||
if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
|
||||
return std::pair<pointer, bool>(pointer(), false);
|
||||
}
|
||||
std::size_t l_size = limit_size*sizeof(T);
|
||||
std::size_t p_size = preferred_size*sizeof(T);
|
||||
std::size_t r_size;
|
||||
{
|
||||
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
|
||||
}
|
||||
received_size = r_size/sizeof(T);
|
||||
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_ALLOCATOR_HPP
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#endif
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -56,7 +56,7 @@ struct is_std_allocator< std::allocator<T> >
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The class template allocator_traits supplies a uniform interface to all allocator types.
|
||||
//! This class is a C++03-compatible implementation of std::allocator_traits
|
||||
@@ -94,29 +94,29 @@ struct allocator_traits
|
||||
//!
|
||||
typedef see_documentation size_type;
|
||||
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
//! type with internal constant static member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_copy_assignment;
|
||||
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
//! type with internal constant static member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_move_assignment;
|
||||
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
//! type with internal constant static member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_swap;
|
||||
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
|
||||
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
|
||||
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
|
||||
//!
|
||||
//! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
|
||||
//! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
|
||||
//! deduced by previously detailed rules.
|
||||
template <class T> using rebind_alloc = see_documentation;
|
||||
|
||||
//! In C++03 compilers `rebind_traits` is a struct derived from
|
||||
//! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
|
||||
//! the allocator deduced by rules explained in `rebind_alloc`.
|
||||
//! In C++03 compilers <code>rebind_traits</code> is a struct derived from
|
||||
//! <code>allocator_traits<OtherAlloc></code>, where <code>OtherAlloc</code> is
|
||||
//! the allocator deduced by rules explained in <code>rebind_alloc</code>.
|
||||
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
|
||||
|
||||
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
|
||||
//! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
|
||||
//! <code>type</code> is an allocator related to Alloc deduced deduced by rules explained in <code>rebind_alloc</code>.
|
||||
template <class T>
|
||||
struct portable_rebind_alloc
|
||||
{ typedef see_documentation type; };
|
||||
@@ -206,19 +206,19 @@ struct allocator_traits
|
||||
{ typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; };
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Returns</b>: `a.allocate(n)`
|
||||
//! <b>Returns</b>: <code>a.allocate(n)</code>
|
||||
//!
|
||||
static pointer allocate(Alloc &a, size_type n)
|
||||
{ return a.allocate(n); }
|
||||
|
||||
//! <b>Returns</b>: `a.deallocate(p, n)`
|
||||
//! <b>Returns</b>: <code>a.deallocate(p, n)</code>
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing
|
||||
static void deallocate(Alloc &a, pointer p, size_type n)
|
||||
{ a.deallocate(p, n); }
|
||||
|
||||
//! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed;
|
||||
//! otherwise, invokes `a.allocate(n)`
|
||||
//! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>a.allocate(n)</code>
|
||||
static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
@@ -228,10 +228,10 @@ struct allocator_traits
|
||||
return allocator_traits::priv_allocate(flag, a, n, p);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed;
|
||||
//! otherwise, invokes `p->~T()`.
|
||||
//! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>p->~T()</code>.
|
||||
template<class T>
|
||||
static void destroy(Alloc &a, T*p)
|
||||
static void destroy(Alloc &a, T*p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef T* destroy_pointer;
|
||||
const bool value = boost::container::container_detail::
|
||||
@@ -241,9 +241,9 @@ struct allocator_traits
|
||||
allocator_traits::priv_destroy(flag, a, p);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: `a.max_size()` if that expression is well-formed; otherwise,
|
||||
//! `numeric_limits<size_type>::max()`.
|
||||
static size_type max_size(const Alloc &a)
|
||||
//! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
|
||||
//! <code>numeric_limits<size_type>::max()</code>.
|
||||
static size_type max_size(const Alloc &a) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_max_size
|
||||
@@ -252,7 +252,7 @@ struct allocator_traits
|
||||
return allocator_traits::priv_max_size(flag, a);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
|
||||
//! <b>Returns</b>: <code>a.select_on_container_copy_construction()</code> if that expression is well-formed;
|
||||
//! otherwise, a.
|
||||
static
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -276,8 +276,8 @@ struct allocator_traits
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
|
||||
//! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
|
||||
//! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
|
||||
template <class T, class ...Args>
|
||||
static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
@@ -285,7 +285,7 @@ struct allocator_traits
|
||||
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
private:
|
||||
static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
|
||||
@@ -295,23 +295,23 @@ struct allocator_traits
|
||||
{ return allocator_traits::allocate(a, n); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(boost::true_type, Alloc &a, T* p)
|
||||
static void priv_destroy(boost::true_type, Alloc &a, T* p) BOOST_CONTAINER_NOEXCEPT
|
||||
{ a.destroy(p); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(boost::false_type, Alloc &, T* p)
|
||||
static void priv_destroy(boost::false_type, Alloc &, T* p) BOOST_CONTAINER_NOEXCEPT
|
||||
{ p->~T(); (void)p; }
|
||||
|
||||
static size_type priv_max_size(boost::true_type, const Alloc &a)
|
||||
static size_type priv_max_size(boost::true_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return a.max_size(); }
|
||||
|
||||
static size_type priv_max_size(boost::false_type, const Alloc &)
|
||||
static size_type priv_max_size(boost::false_type, const Alloc &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return (std::numeric_limits<size_type>::max)(); }
|
||||
|
||||
static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
|
||||
{ return a.select_on_container_copy_construction(); }
|
||||
|
||||
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
|
||||
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return a; }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
@@ -394,7 +394,7 @@ struct allocator_traits
|
||||
{ ::new((void*)p) T; }
|
||||
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,11 +15,37 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares the following containers:
|
||||
//! - boost::container::vector
|
||||
//! - boost::container::stable_vector
|
||||
//! - boost::container::static_vector
|
||||
//! - boost::container::slist
|
||||
//! - boost::container::list
|
||||
//! - boost::container::set
|
||||
//! - boost::container::multiset
|
||||
//! - boost::container::map
|
||||
//! - boost::container::multimap
|
||||
//! - boost::container::flat_set
|
||||
//! - boost::container::flat_multiset
|
||||
//! - boost::container::flat_map
|
||||
//! - boost::container::flat_multimap
|
||||
//! - boost::container::basic_string
|
||||
//! - boost::container::string
|
||||
//! - boost::container::wstring
|
||||
//!
|
||||
//! It forward declares the following allocators:
|
||||
//! - boost::container::allocator
|
||||
//! - boost::container::node_allocator
|
||||
//! - boost::container::adaptive_pool
|
||||
//!
|
||||
//! And finally it defines the following types
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Standard predeclarations
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
@@ -32,13 +58,14 @@ namespace bi = boost::intrusive;
|
||||
|
||||
}}}
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Containers
|
||||
@@ -47,89 +74,146 @@ namespace bi = boost::intrusive;
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//vector class
|
||||
//! Enumeration used to configure ordered associative containers
|
||||
//! with a concrete tree implementation.
|
||||
enum tree_type_enum
|
||||
{
|
||||
red_black_tree,
|
||||
avl_tree,
|
||||
scapegoat_tree,
|
||||
splay_tree
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class vector;
|
||||
|
||||
//vector class
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class stable_vector;
|
||||
|
||||
//vector class
|
||||
template <class T, std::size_t Capacity>
|
||||
class static_vector;
|
||||
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class deque;
|
||||
|
||||
//list class
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class list;
|
||||
|
||||
//slist class
|
||||
template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class slist;
|
||||
|
||||
//set class
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt;
|
||||
|
||||
typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
,class Allocator = std::allocator<Key>
|
||||
,class Options = tree_assoc_defaults >
|
||||
class set;
|
||||
|
||||
//multiset class
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
,class Allocator = std::allocator<Key>
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multiset;
|
||||
|
||||
//map class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class map;
|
||||
|
||||
//multimap class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multimap;
|
||||
|
||||
//flat_set class
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
class flat_set;
|
||||
|
||||
//flat_multiset class
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key> >
|
||||
class flat_multiset;
|
||||
|
||||
//flat_map class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<Key, T> > >
|
||||
class flat_map;
|
||||
|
||||
//flat_multimap class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<Key, T> > >
|
||||
class flat_multimap;
|
||||
|
||||
//basic_string class
|
||||
template <class CharT
|
||||
,class Traits = std::char_traits<CharT>
|
||||
,class Allocator = std::allocator<CharT> >
|
||||
class basic_string;
|
||||
|
||||
typedef basic_string
|
||||
<char
|
||||
,std::char_traits<char>
|
||||
,std::allocator<char> >
|
||||
string;
|
||||
|
||||
typedef basic_string
|
||||
<wchar_t
|
||||
,std::char_traits<wchar_t>
|
||||
,std::allocator<wchar_t> >
|
||||
wstring;
|
||||
|
||||
static const std::size_t ADP_nodes_per_block = 256u;
|
||||
static const std::size_t ADP_max_free_blocks = 2u;
|
||||
static const std::size_t ADP_overhead_percent = 1u;
|
||||
static const std::size_t ADP_only_alignment = 0u;
|
||||
|
||||
template < class T
|
||||
, std::size_t NodesPerBlock = ADP_nodes_per_block
|
||||
, std::size_t MaxFreeBlocks = ADP_max_free_blocks
|
||||
, std::size_t OverheadPercent = ADP_overhead_percent
|
||||
, unsigned Version = 2
|
||||
>
|
||||
class adaptive_pool;
|
||||
|
||||
template < class T
|
||||
, unsigned Version = 2
|
||||
, unsigned int AllocationDisableMask = 0>
|
||||
class allocator;
|
||||
|
||||
static const std::size_t NodeAlloc_nodes_per_block = 256u;
|
||||
|
||||
template
|
||||
< class T
|
||||
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block
|
||||
, std::size_t Version = 2>
|
||||
class node_allocator;
|
||||
|
||||
#else
|
||||
|
||||
//! Default options for tree-based associative containers
|
||||
//! - tree_type<red_black_tree>
|
||||
//! - optimize_size<true>
|
||||
typedef implementation_defined tree_assoc_defaults;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
struct ordered_range_t
|
||||
@@ -149,17 +233,26 @@ struct ordered_unique_range_t
|
||||
//! guaranteed to be ordered and unique
|
||||
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
//! Type used to tag that the inserted values
|
||||
//! should be default initialized
|
||||
struct default_init_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
//! Value used to tag that the inserted values
|
||||
//! should be default initialized
|
||||
static const default_init_t default_init = default_init_t();
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace detail_really_deep_namespace {
|
||||
//! Type used to tag that the inserted values
|
||||
//! should be value initialized
|
||||
struct value_init_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the inserted values
|
||||
//! should be value initialized
|
||||
static const value_init_t value_init = value_init_t();
|
||||
|
||||
namespace container_detail_really_deep_namespace {
|
||||
|
||||
//Otherwise, gcc issues a warning of previously defined
|
||||
//anonymous_instance and unique_instance
|
||||
@@ -175,7 +268,7 @@ struct dummy
|
||||
|
||||
} //detail_really_deep_namespace {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}} //namespace boost { namespace container {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -45,12 +45,8 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator>
|
||||
#endif
|
||||
class deque;
|
||||
|
||||
template <class T>
|
||||
@@ -465,21 +461,24 @@ class deque_base
|
||||
const allocator_type &alloc() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return members_; }
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Deque class
|
||||
//!
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! A double-ended queue is a sequence that supports random access to elements, constant time insertion
|
||||
//! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the deque
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
template <class T, class Allocator>
|
||||
#endif
|
||||
class deque : protected deque_base<Allocator>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
typedef deque_base<Allocator> Base;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
@@ -503,7 +502,7 @@ class deque : protected deque_base<Allocator>
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
private: // Internal typedefs
|
||||
BOOST_COPYABLE_AND_MOVABLE(deque)
|
||||
@@ -512,7 +511,7 @@ class deque : protected deque_base<Allocator>
|
||||
{ return Base::s_buffer_size(); }
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -549,8 +548,8 @@ class deque : protected deque_base<Allocator>
|
||||
explicit deque(size_type n)
|
||||
: Base(n, allocator_type())
|
||||
{
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
proxy.uninitialized_copy_n_and_update(this->begin(), n);
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
|
||||
//deque_base will deallocate in case of exception...
|
||||
}
|
||||
|
||||
@@ -566,8 +565,8 @@ class deque : protected deque_base<Allocator>
|
||||
deque(size_type n, default_init_t)
|
||||
: Base(n, allocator_type())
|
||||
{
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
proxy.uninitialized_copy_n_and_update(this->begin(), n);
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
|
||||
//deque_base will deallocate in case of exception...
|
||||
}
|
||||
|
||||
@@ -978,7 +977,7 @@ class deque : protected deque_base<Allocator>
|
||||
this->priv_erase_last_n(len - new_size);
|
||||
else{
|
||||
const size_type n = new_size - this->size();
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
priv_insert_back_aux_impl(n, proxy);
|
||||
}
|
||||
}
|
||||
@@ -998,7 +997,7 @@ class deque : protected deque_base<Allocator>
|
||||
this->priv_erase_last_n(len - new_size);
|
||||
else{
|
||||
const size_type n = new_size - this->size();
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
|
||||
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
|
||||
priv_insert_back_aux_impl(n, proxy);
|
||||
}
|
||||
}
|
||||
@@ -1155,7 +1154,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
|
||||
this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
|
||||
this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1177,7 +1176,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
|
||||
this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
|
||||
this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1203,7 +1202,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
|
||||
return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward<Args>(args)...));
|
||||
return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1222,10 +1221,10 @@ class deque : protected deque_base<Allocator>
|
||||
priv_push_front_simple_commit(); \
|
||||
} \
|
||||
else{ \
|
||||
container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
||||
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
priv_insert_front_aux_impl(1, proxy); \
|
||||
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
|
||||
priv_insert_front_aux_impl \
|
||||
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -1240,10 +1239,10 @@ class deque : protected deque_base<Allocator>
|
||||
priv_push_back_simple_commit(); \
|
||||
} \
|
||||
else{ \
|
||||
container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
||||
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
priv_insert_back_aux_impl(1, proxy); \
|
||||
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
|
||||
priv_insert_back_aux_impl \
|
||||
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -1260,10 +1259,10 @@ class deque : protected deque_base<Allocator>
|
||||
return (this->end()-1); \
|
||||
} \
|
||||
else{ \
|
||||
container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
|
||||
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
return this->priv_insert_aux_impl(p, 1, proxy); \
|
||||
typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
|
||||
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
|
||||
return this->priv_insert_aux_impl \
|
||||
(p, 1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
|
||||
} \
|
||||
} \
|
||||
//!
|
||||
@@ -1397,7 +1396,7 @@ class deque : protected deque_base<Allocator>
|
||||
#endif
|
||||
)
|
||||
{
|
||||
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first);
|
||||
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
|
||||
return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
|
||||
}
|
||||
#endif
|
||||
@@ -1537,7 +1536,49 @@ class deque : protected deque_base<Allocator>
|
||||
this->members_.m_finish = this->members_.m_start;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const deque& x, const deque& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const deque& x, const deque& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const deque& x, const deque& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const deque& x, const deque& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const deque& x, const deque& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const deque& x, const deque& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(deque& x, deque& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
void priv_erase_last_n(size_type n)
|
||||
@@ -1570,7 +1611,8 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else {
|
||||
return priv_insert_aux_impl
|
||||
(position, (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
|
||||
( position, (size_type)1
|
||||
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1584,7 +1626,8 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
priv_insert_aux_impl
|
||||
(this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
|
||||
( this->cbegin(), (size_type)1
|
||||
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1598,8 +1641,8 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
else{
|
||||
priv_insert_aux_impl
|
||||
(this->cend(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
|
||||
container_detail::insert_copy_proxy<Allocator, iterator> proxy(this->alloc(), x);
|
||||
( this->cend(), (size_type)1
|
||||
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1652,7 +1695,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
|
||||
template<class InsertProxy>
|
||||
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf)
|
||||
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
|
||||
{
|
||||
iterator pos(p.unconst());
|
||||
const size_type pos_n = p - this->cbegin();
|
||||
@@ -1667,7 +1710,7 @@ class deque : protected deque_base<Allocator>
|
||||
const iterator new_start = this->priv_reserve_elements_at_front(n);
|
||||
const iterator old_start = this->members_.m_start;
|
||||
if(!elemsbefore){
|
||||
interf.uninitialized_copy_n_and_update(new_start, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
|
||||
this->members_.m_start = new_start;
|
||||
}
|
||||
else{
|
||||
@@ -1678,17 +1721,17 @@ class deque : protected deque_base<Allocator>
|
||||
(this->alloc(), this->members_.m_start, start_n, new_start);
|
||||
this->members_.m_start = new_start;
|
||||
boost::move(start_n, pos, old_start);
|
||||
interf.copy_n_and_update(pos - n, n);
|
||||
proxy.copy_n_and_update(this->alloc(), pos - n, n);
|
||||
}
|
||||
else {
|
||||
const size_type mid_count = n - elemsbefore;
|
||||
const iterator mid_start = old_start - mid_count;
|
||||
interf.uninitialized_copy_n_and_update(mid_start, mid_count);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
|
||||
this->members_.m_start = mid_start;
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), old_start, pos, new_start);
|
||||
this->members_.m_start = new_start;
|
||||
interf.copy_n_and_update(old_start, elemsbefore);
|
||||
proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1697,7 +1740,7 @@ class deque : protected deque_base<Allocator>
|
||||
const iterator old_finish = this->members_.m_finish;
|
||||
const size_type elemsafter = length - elemsbefore;
|
||||
if(!elemsafter){
|
||||
interf.uninitialized_copy_n_and_update(old_finish, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
|
||||
this->members_.m_finish = new_finish;
|
||||
}
|
||||
else{
|
||||
@@ -1708,15 +1751,15 @@ class deque : protected deque_base<Allocator>
|
||||
(this->alloc(), finish_n, old_finish, old_finish);
|
||||
this->members_.m_finish = new_finish;
|
||||
boost::move_backward(pos, finish_n, old_finish);
|
||||
interf.copy_n_and_update(pos, n);
|
||||
proxy.copy_n_and_update(this->alloc(), pos, n);
|
||||
}
|
||||
else {
|
||||
const size_type raw_gap = n - elemsafter;
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), pos, old_finish, old_finish + raw_gap);
|
||||
BOOST_TRY{
|
||||
interf.copy_n_and_update(pos, elemsafter);
|
||||
interf.uninitialized_copy_n_and_update(old_finish, raw_gap);
|
||||
proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->priv_destroy_range(old_finish, old_finish + elemsafter);
|
||||
@@ -1731,7 +1774,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
|
||||
template <class InsertProxy>
|
||||
iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf)
|
||||
iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
|
||||
{
|
||||
if(!this->members_.m_map){
|
||||
this->priv_initialize_map(0);
|
||||
@@ -1739,20 +1782,20 @@ class deque : protected deque_base<Allocator>
|
||||
|
||||
iterator new_finish = this->priv_reserve_elements_at_back(n);
|
||||
iterator old_finish = this->members_.m_finish;
|
||||
interf.uninitialized_copy_n_and_update(old_finish, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
|
||||
this->members_.m_finish = new_finish;
|
||||
return iterator(this->members_.m_finish - n);
|
||||
}
|
||||
|
||||
template <class InsertProxy>
|
||||
iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf)
|
||||
iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
|
||||
{
|
||||
if(!this->members_.m_map){
|
||||
this->priv_initialize_map(0);
|
||||
}
|
||||
|
||||
iterator new_start = this->priv_reserve_elements_at_front(n);
|
||||
interf.uninitialized_copy_n_and_update(new_start, n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
|
||||
this->members_.m_start = new_start;
|
||||
return new_start;
|
||||
}
|
||||
@@ -1934,45 +1977,12 @@ class deque : protected deque_base<Allocator>
|
||||
this->members_.m_start.priv_set_node(new_nstart);
|
||||
this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
|
||||
}
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
// Nonmember functions.
|
||||
template <class T, class Allocator>
|
||||
inline bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return y < x; }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return !(x < y); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1985,7 +1995,7 @@ struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
|
||||
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
162
include/boost/container/detail/adaptive_node_pool.hpp
Normal file
162
include/boost/container/detail/adaptive_node_pool.hpp
Normal file
@@ -0,0 +1,162 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.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 <cstddef>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<bool AlignOnly>
|
||||
struct select_private_adaptive_node_pool_impl
|
||||
{
|
||||
typedef boost::container::container_detail::
|
||||
private_adaptive_node_pool_impl
|
||||
< fake_segment_manager
|
||||
, unsigned(AlignOnly)*::boost::container::adaptive_pool_flag::align_only
|
||||
| ::boost::container::adaptive_pool_flag::size_ordered | ::boost::container::adaptive_pool_flag::address_ordered
|
||||
> type;
|
||||
};
|
||||
|
||||
//!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 select_private_adaptive_node_pool_impl<(OverheadPercent == 0)>::type
|
||||
{
|
||||
typedef typename select_private_adaptive_node_pool_impl<OverheadPercent == 0>::type base_t;
|
||||
//Non-copyable
|
||||
private_adaptive_node_pool(const private_adaptive_node_pool &);
|
||||
private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
|
||||
|
||||
public:
|
||||
typedef typename base_t::multiallocation_chain multiallocation_chain;
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
|
||||
//!Constructor. Never throws
|
||||
private_adaptive_node_pool()
|
||||
: base_t(0
|
||||
, NodeSize
|
||||
, NodesPerBlock
|
||||
, MaxFreeBlocks
|
||||
, (unsigned char)OverheadPercent)
|
||||
{}
|
||||
};
|
||||
|
||||
//!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 container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,9 +15,10 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,8 +15,373 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <iterator> //std::iterator_traits
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
template<class A, class FwdIt, class Iterator>
|
||||
struct move_insert_range_proxy
|
||||
{
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
explicit move_insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::uninitialized_move_alloc_n_source
|
||||
(a, this->first_, n, p);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
|
||||
}
|
||||
|
||||
FwdIt first_;
|
||||
};
|
||||
|
||||
|
||||
template<class A, class FwdIt, class Iterator>
|
||||
struct insert_range_proxy
|
||||
{
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
explicit insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
|
||||
}
|
||||
|
||||
FwdIt first_;
|
||||
};
|
||||
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_n_copies_proxy
|
||||
{
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
explicit insert_n_copies_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_fill_alloc_n(a, v_, n, p); }
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n) const
|
||||
{ std::fill_n(p, n, v_); }
|
||||
|
||||
const value_type &v_;
|
||||
};
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_value_initialized_n_proxy
|
||||
{
|
||||
typedef ::boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_value_init_alloc_n(a, n, p); }
|
||||
|
||||
void copy_n_and_update(A &, Iterator, size_type) const
|
||||
{ BOOST_ASSERT(false); }
|
||||
};
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_default_initialized_n_proxy
|
||||
{
|
||||
typedef ::boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_default_init_alloc_n(a, n, p); }
|
||||
|
||||
void copy_n_and_update(A &, Iterator, size_type) const
|
||||
{ BOOST_ASSERT(false); }
|
||||
};
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_copy_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
explicit insert_copy_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, container_detail::to_raw_pointer(&*p), v_);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
*p =v_;
|
||||
}
|
||||
|
||||
const value_type &v_;
|
||||
};
|
||||
|
||||
|
||||
template<class A, class Iterator>
|
||||
struct insert_move_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
explicit insert_move_proxy(value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::move(v_)
|
||||
);
|
||||
}
|
||||
|
||||
void copy_n_and_update(A &, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
*p = ::boost::move(v_);
|
||||
}
|
||||
|
||||
value_type &v_;
|
||||
};
|
||||
|
||||
template<class It, class A>
|
||||
insert_move_proxy<A, It> get_insert_value_proxy(BOOST_RV_REF(typename std::iterator_traits<It>::value_type) v)
|
||||
{
|
||||
return insert_move_proxy<A, It>(v);
|
||||
}
|
||||
|
||||
template<class It, class A>
|
||||
insert_copy_proxy<A, It> get_insert_value_proxy(const typename std::iterator_traits<It>::value_type &v)
|
||||
{
|
||||
return insert_copy_proxy<A, It>(v);
|
||||
}
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <typeinfo>
|
||||
//#include <iostream> //For debugging purposes
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class A, class Iterator, class ...Args>
|
||||
struct insert_non_movable_emplace_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
explicit insert_non_movable_emplace_proxy(Args&&... args)
|
||||
: args_(args...)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
template<int ...IdxPack>
|
||||
void priv_uninitialized_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::forward<Args>(get<IdxPack>(this->args_))...
|
||||
);
|
||||
}
|
||||
|
||||
protected:
|
||||
tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
template<class A, class Iterator, class ...Args>
|
||||
struct insert_emplace_proxy
|
||||
: public insert_non_movable_emplace_proxy<A, Iterator, Args...>
|
||||
{
|
||||
typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::size_type size_type;
|
||||
typedef typename base_t::index_tuple_t index_tuple_t;
|
||||
|
||||
explicit insert_emplace_proxy(Args&&... args)
|
||||
: base_t(::boost::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
void copy_n_and_update(A &a, Iterator p, size_type n)
|
||||
{ this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
|
||||
template<int ...IdxPack>
|
||||
void priv_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n ==1); (void)n;
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
|
||||
alloc_traits::construct(a, vp,
|
||||
::boost::forward<Args>(get<IdxPack>(this->args_))...);
|
||||
BOOST_TRY{
|
||||
*p = ::boost::move(*vp);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
alloc_traits::destroy(a, vp);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
alloc_traits::destroy(a, vp);
|
||||
}
|
||||
};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(N) \
|
||||
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
|
||||
struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
{ \
|
||||
typedef boost::container::allocator_traits<A> alloc_traits; \
|
||||
typedef typename alloc_traits::size_type size_type; \
|
||||
typedef typename alloc_traits::value_type value_type; \
|
||||
\
|
||||
explicit BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
BOOST_PP_EXPR_IF(N, :) BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \
|
||||
{} \
|
||||
\
|
||||
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) \
|
||||
{ \
|
||||
BOOST_ASSERT(n == 1); (void)n; \
|
||||
alloc_traits::construct \
|
||||
( a \
|
||||
, container_detail::to_raw_pointer(&*p) \
|
||||
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
|
||||
); \
|
||||
} \
|
||||
\
|
||||
void copy_n_and_update(A &, Iterator, size_type) \
|
||||
{ BOOST_ASSERT(false); } \
|
||||
\
|
||||
protected: \
|
||||
BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
|
||||
}; \
|
||||
\
|
||||
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
|
||||
struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
|
||||
: BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
< A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
|
||||
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \
|
||||
typedef typename base_t::value_type value_type; \
|
||||
typedef typename base_t::size_type size_type; \
|
||||
typedef boost::container::allocator_traits<A> alloc_traits; \
|
||||
\
|
||||
explicit BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
|
||||
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
: base_t(BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
|
||||
{} \
|
||||
\
|
||||
void copy_n_and_update(A &a, Iterator p, size_type n) \
|
||||
{ \
|
||||
BOOST_ASSERT(n == 1); (void)n; \
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||
alloc_traits::construct(a, vp \
|
||||
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
|
||||
BOOST_TRY{ \
|
||||
*p = ::boost::move(*vp); \
|
||||
} \
|
||||
BOOST_CATCH(...){ \
|
||||
alloc_traits::destroy(a, vp); \
|
||||
BOOST_RETHROW \
|
||||
} \
|
||||
BOOST_CATCH_END \
|
||||
alloc_traits::destroy(a, vp); \
|
||||
} \
|
||||
}; \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
/*
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#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/detail/destroyers.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
@@ -391,3 +756,4 @@ struct BOOST_PP_CAT(insert_emplace_proxy_arg, N)
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (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
|
||||
@@ -17,7 +17,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||
|
||||
326
include/boost/container/detail/alloc_lib.h
Normal file
326
include/boost/container/detail/alloc_lib.h
Normal file
@@ -0,0 +1,326 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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)
|
||||
|
||||
/*
|
||||
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 __declspec(dllexport)
|
||||
#else
|
||||
# define BOOST_CONTAINER_DECL __declspec(dllimport)
|
||||
#endif /* BOOST_CONTAINER_SOURCE */
|
||||
#endif /* DYN_LINK */
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* if BOOST_CONTAINER_DECL isn't defined yet define it now: */
|
||||
#ifndef BOOST_CONTAINER_DECL
|
||||
#define BOOST_CONTAINER_DECL
|
||||
#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)\
|
||||
/**/
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_size(const void *p);
|
||||
|
||||
BOOST_CONTAINER_DECL void* boost_cont_malloc(size_t bytes);
|
||||
|
||||
BOOST_CONTAINER_DECL void boost_cont_free(void* mem);
|
||||
|
||||
BOOST_CONTAINER_DECL void* boost_cont_memalign(size_t bytes, size_t alignment);
|
||||
|
||||
/*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
|
||||
must be contiguous.*/
|
||||
#define 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 DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0))
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_multialloc_nodes
|
||||
(size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL 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);
|
||||
|
||||
BOOST_CONTAINER_DECL void boost_cont_multidealloc(boost_cont_memchain *pchain);
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_footprint();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_allocated_memory();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_chunksize(const void *p);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_all_deallocated();
|
||||
|
||||
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;
|
||||
|
||||
BOOST_CONTAINER_DECL boost_cont_malloc_stats_t boost_cont_malloc_stats();
|
||||
|
||||
BOOST_CONTAINER_DECL size_t boost_cont_in_use_memory();
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_trim(size_t pad);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_mallopt
|
||||
(int parameter_number, int parameter_value);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_grow
|
||||
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_shrink
|
||||
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit);
|
||||
|
||||
BOOST_CONTAINER_DECL void* boost_cont_alloc
|
||||
(size_t minbytes, size_t preferred_bytes, size_t *received_bytes);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_malloc_check();
|
||||
|
||||
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_CONTAINERDLMALLOC__FOOTERS
|
||||
#ifndef BOOST_CONTAINERDLMALLOC__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;
|
||||
|
||||
BOOST_CONTAINER_DECL 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
|
||||
);
|
||||
|
||||
BOOST_CONTAINER_DECL int boost_cont_mallopt(int param_number, int value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} //extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
#endif //#define BOOST_CONTAINERDLMALLOC__EXT_H
|
||||
16
include/boost/container/detail/alloc_lib_auto_link.hpp
Normal file
16
include/boost/container/detail/alloc_lib_auto_link.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_BOOST_CONT_EXT_AUTO_LINK_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_BOOST_CONT_EXT_AUTO_LINK_HPP
|
||||
|
||||
#include <boost/container/detail/auto_link.hpp>
|
||||
#include <boost/container/detail/alloc_lib.h>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_BOOST_CONT_EXT_AUTO_LINK_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,13 +15,13 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
enum allocation_type_v
|
||||
{
|
||||
// constants for allocation commands
|
||||
@@ -37,7 +37,7 @@ enum allocation_type_v
|
||||
};
|
||||
|
||||
typedef int allocation_type;
|
||||
/// @endcond
|
||||
#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;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#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
|
||||
|
||||
38
include/boost/container/detail/auto_link.hpp
Normal file
38
include/boost/container/detail/auto_link.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#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_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
||||
# 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
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -18,6 +18,10 @@
|
||||
#define BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifndef _SCL_SECURE_NO_WARNINGS
|
||||
#define BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4702) // unreachable code
|
||||
#pragma warning (disable : 4706) // assignment within conditional expression
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -13,5 +13,9 @@
|
||||
#undef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
|
||||
#undef _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifdef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
|
||||
#undef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
|
||||
#undef _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (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
|
||||
@@ -17,8 +17,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
@@ -231,6 +232,9 @@ struct null_scoped_destructor_n
|
||||
void increment_size_backwards(size_type)
|
||||
{}
|
||||
|
||||
void shrink_forward(size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,7 +15,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
@@ -270,6 +270,9 @@ class flat_tree
|
||||
Compare key_comp() const
|
||||
{ return this->m_data.get_comp(); }
|
||||
|
||||
value_compare value_comp() const
|
||||
{ return this->m_data; }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{ return this->m_data.m_vect.get_allocator(); }
|
||||
|
||||
@@ -526,7 +529,7 @@ class flat_tree
|
||||
this->reserve(this->size()+len);
|
||||
const const_iterator b(this->cbegin());
|
||||
const_iterator pos(b);
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
skips[0u] = 0u;
|
||||
//Loop in burst sizes
|
||||
while(len){
|
||||
@@ -539,7 +542,7 @@ class flat_tree
|
||||
--len;
|
||||
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
|
||||
//Check if already present
|
||||
if(pos != ce && !value_comp(val, *pos)){
|
||||
if(pos != ce && !val_cmp(val, *pos)){
|
||||
if(unique_burst > 0){
|
||||
++skips[unique_burst-1];
|
||||
}
|
||||
@@ -714,6 +717,7 @@ class flat_tree
|
||||
return i;
|
||||
}
|
||||
|
||||
// set operations:
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
std::pair<const_iterator, const_iterator> p = this->equal_range(k);
|
||||
@@ -739,12 +743,44 @@ class flat_tree
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{ return this->priv_equal_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
std::pair<iterator, iterator> lower_bound_range(const key_type& k)
|
||||
{ return this->priv_lower_bound_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
{ return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
size_type capacity() const
|
||||
{ return this->m_data.m_vect.capacity(); }
|
||||
|
||||
void reserve(size_type cnt)
|
||||
{ this->m_data.m_vect.reserve(cnt); }
|
||||
|
||||
friend bool operator==(const flat_tree& x, const flat_tree& y)
|
||||
{
|
||||
return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
friend bool operator<(const flat_tree& x, const flat_tree& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(),
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
friend bool operator!=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
friend bool operator>(const flat_tree& x, const flat_tree& y)
|
||||
{ return y < x; }
|
||||
|
||||
friend bool operator<=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
friend bool operator>=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(flat_tree& x, flat_tree& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
private:
|
||||
struct insert_commit_data
|
||||
{
|
||||
@@ -764,10 +800,10 @@ class flat_tree
|
||||
// insert val before upper_bound(val)
|
||||
// else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
|
||||
if(pos == this->cend() || !value_comp(*pos, val)){
|
||||
if (pos == this->cbegin() || !value_comp(val, pos[-1])){
|
||||
if(pos == this->cend() || !val_cmp(*pos, val)){
|
||||
if (pos == this->cbegin() || !val_cmp(val, pos[-1])){
|
||||
data.position = pos;
|
||||
}
|
||||
else{
|
||||
@@ -784,9 +820,9 @@ class flat_tree
|
||||
bool priv_insert_unique_prepare
|
||||
(const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data)
|
||||
{
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val));
|
||||
return commit_data.position == e || value_comp(val, *commit_data.position);
|
||||
return commit_data.position == e || val_cmp(val, *commit_data.position);
|
||||
}
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
@@ -807,9 +843,9 @@ class flat_tree
|
||||
// insert val after pos
|
||||
//else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &value_comp = this->m_data;
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
const const_iterator cend_it = this->cend();
|
||||
if(pos == cend_it || value_comp(val, *pos)){ //Check if val should go before end
|
||||
if(pos == cend_it || val_cmp(val, *pos)){ //Check if val should go before end
|
||||
const const_iterator cbeg = this->cbegin();
|
||||
commit_data.position = pos;
|
||||
if(pos == cbeg){ //If container is empty then insert it in the beginning
|
||||
@@ -817,10 +853,10 @@ class flat_tree
|
||||
}
|
||||
const_iterator prev(pos);
|
||||
--prev;
|
||||
if(value_comp(*prev, val)){ //If previous element was less, then it should go between prev and pos
|
||||
if(val_cmp(*prev, val)){ //If previous element was less, then it should go between prev and pos
|
||||
return true;
|
||||
}
|
||||
else if(!value_comp(val, *prev)){ //If previous was equal then insertion should fail
|
||||
else if(!val_cmp(val, *prev)){ //If previous was equal then insertion should fail
|
||||
commit_data.position = prev;
|
||||
return false;
|
||||
}
|
||||
@@ -846,7 +882,7 @@ class flat_tree
|
||||
}
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_lower_bound(RanIt first, RanIt last,
|
||||
RanIt priv_lower_bound(RanIt first, const RanIt last,
|
||||
const key_type & key) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
@@ -855,24 +891,23 @@ class flat_tree
|
||||
RanIt middle;
|
||||
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
size_type step = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
middle += step;
|
||||
|
||||
if (key_cmp(key_extract(*middle), key)) {
|
||||
++middle;
|
||||
first = middle;
|
||||
len = len - half - 1;
|
||||
first = ++middle;
|
||||
len -= step + 1;
|
||||
}
|
||||
else{
|
||||
len = step;
|
||||
}
|
||||
else
|
||||
len = half;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_upper_bound(RanIt first, RanIt last,
|
||||
RanIt priv_upper_bound(RanIt first, const RanIt last,
|
||||
const key_type & key) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
@@ -881,16 +916,16 @@ class flat_tree
|
||||
RanIt middle;
|
||||
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
size_type step = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
middle += step;
|
||||
|
||||
if (key_cmp(key, key_extract(*middle))) {
|
||||
len = half;
|
||||
len = step;
|
||||
}
|
||||
else{
|
||||
first = ++middle;
|
||||
len = len - half - 1;
|
||||
len -= step + 1;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
@@ -906,29 +941,41 @@ class flat_tree
|
||||
RanIt middle;
|
||||
|
||||
while (len) {
|
||||
size_type half = len >> 1;
|
||||
size_type step = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
middle += step;
|
||||
|
||||
if (key_cmp(key_extract(*middle), key)){
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
first = ++middle;
|
||||
len -= step + 1;
|
||||
}
|
||||
else if (key_cmp(key, key_extract(*middle))){
|
||||
len = half;
|
||||
len = step;
|
||||
}
|
||||
else {
|
||||
//Middle is equal to key
|
||||
last = first;
|
||||
last += len;
|
||||
first = this->priv_lower_bound(first, middle, key);
|
||||
return std::pair<RanIt, RanIt> (first, this->priv_upper_bound(++middle, last, key));
|
||||
return std::pair<RanIt, RanIt>
|
||||
( this->priv_lower_bound(first, middle, key)
|
||||
, this->priv_upper_bound(++middle, last, key));
|
||||
}
|
||||
}
|
||||
return std::pair<RanIt, RanIt>(first, first);
|
||||
}
|
||||
|
||||
template<class RanIt>
|
||||
std::pair<RanIt, RanIt> priv_lower_bound_range(RanIt first, RanIt last, const key_type& k) const
|
||||
{
|
||||
const Compare &key_cmp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
RanIt lb(this->priv_lower_bound(first, last, k)), ub(lb);
|
||||
if(lb != last && static_cast<difference_type>(!key_cmp(k, key_extract(*lb)))){
|
||||
++ub;
|
||||
}
|
||||
return std::pair<RanIt, RanIt>(lb, ub);
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
void priv_insert_equal_loop(InIt first, InIt last)
|
||||
{
|
||||
@@ -950,62 +997,6 @@ class flat_tree
|
||||
}
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator==(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{
|
||||
return x.size() == y.size() &&
|
||||
std::equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator<(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(),
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator!=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator>(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator<=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline bool
|
||||
operator>=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class A>
|
||||
inline void
|
||||
swap(flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
|
||||
flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012.
|
||||
// (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
|
||||
|
||||
383
include/boost/container/detail/hash_table.hpp
Normal file
383
include/boost/container/detail/hash_table.hpp
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
template <class Value, unsigned int Options = 0, class Hash = hash<Value>, class Pred = equal_to<Value>,
|
||||
class Alloc = allocator<Value> >
|
||||
class hash_set
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Value key_type;
|
||||
typedef key_type value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
|
||||
typedef /unspecified/ iterator;
|
||||
typedef /unspecified/ const_iterator;
|
||||
typedef /unspecified/ local_iterator;
|
||||
typedef /unspecified/ const_local_iterator;
|
||||
|
||||
hash_set()
|
||||
noexcept(
|
||||
is_nothrow_default_constructible<hasher>::value &&
|
||||
is_nothrow_default_constructible<key_equal>::value &&
|
||||
is_nothrow_default_constructible<allocator_type>::value);
|
||||
explicit hash_set(size_type n, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
template <class InputIterator>
|
||||
hash_set(InputIterator f, InputIterator l,
|
||||
size_type n = 0, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
explicit hash_set(const allocator_type&);
|
||||
hash_set(const hash_set&);
|
||||
hash_set(const hash_set&, const Allocator&);
|
||||
hash_set(hash_set&&)
|
||||
noexcept(
|
||||
is_nothrow_move_constructible<hasher>::value &&
|
||||
is_nothrow_move_constructible<key_equal>::value &&
|
||||
is_nothrow_move_constructible<allocator_type>::value);
|
||||
hash_set(hash_set&&, const Allocator&);
|
||||
hash_set(initializer_list<value_type>, size_type n = 0,
|
||||
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
~hash_set();
|
||||
hash_set& operator=(const hash_set&);
|
||||
hash_set& operator=(hash_set&&)
|
||||
noexcept(
|
||||
allocator_type::propagate_on_container_move_assignment::value &&
|
||||
is_nothrow_move_assignable<allocator_type>::value &&
|
||||
is_nothrow_move_assignable<hasher>::value &&
|
||||
is_nothrow_move_assignable<key_equal>::value);
|
||||
hash_set& operator=(initializer_list<value_type>);
|
||||
|
||||
allocator_type get_allocator() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_type size() const noexcept;
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
|
||||
template <class... Args>
|
||||
pair<iterator, bool> emplace(Args&&... args);
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
pair<iterator, bool> insert(value_type&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
iterator insert(const_iterator hint, value_type&& obj);
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last);
|
||||
void insert(initializer_list<value_type>);
|
||||
|
||||
iterator erase(const_iterator position);
|
||||
size_type erase(const key_type& k);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void clear() noexcept;
|
||||
|
||||
void swap(hash_set&)
|
||||
noexcept(
|
||||
(!allocator_type::propagate_on_container_swap::value ||
|
||||
__is_nothrow_swappable<allocator_type>::value) &&
|
||||
__is_nothrow_swappable<hasher>::value &&
|
||||
__is_nothrow_swappable<key_equal>::value);
|
||||
|
||||
hasher hash_function() const;
|
||||
key_equal key_eq() const;
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
size_type count(const key_type& k) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
|
||||
size_type bucket_count() const noexcept;
|
||||
size_type max_bucket_count() const noexcept;
|
||||
|
||||
size_type bucket_size(size_type n) const;
|
||||
size_type bucket(const key_type& k) const;
|
||||
|
||||
local_iterator begin(size_type n);
|
||||
local_iterator end(size_type n);
|
||||
const_local_iterator begin(size_type n) const;
|
||||
const_local_iterator end(size_type n) const;
|
||||
const_local_iterator cbegin(size_type n) const;
|
||||
const_local_iterator cend(size_type n) const;
|
||||
|
||||
float load_factor() const noexcept;
|
||||
float max_load_factor() const noexcept;
|
||||
void max_load_factor(float z);
|
||||
void rehash(size_type n);
|
||||
void reserve(size_type n);
|
||||
};
|
||||
|
||||
template <class Key, class T, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
|
||||
class Alloc = allocator<pair<const Key, T> > >
|
||||
class hash_map
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Key key_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
|
||||
typedef /unspecified/ iterator;
|
||||
typedef /unspecified/ const_iterator;
|
||||
typedef /unspecified/ local_iterator;
|
||||
typedef /unspecified/ const_local_iterator;
|
||||
|
||||
hash_map()
|
||||
noexcept(
|
||||
is_nothrow_default_constructible<hasher>::value &&
|
||||
is_nothrow_default_constructible<key_equal>::value &&
|
||||
is_nothrow_default_constructible<allocator_type>::value);
|
||||
explicit hash_map(size_type n, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
template <class InputIterator>
|
||||
hash_map(InputIterator f, InputIterator l,
|
||||
size_type n = 0, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
explicit hash_map(const allocator_type&);
|
||||
hash_map(const hash_map&);
|
||||
hash_map(const hash_map&, const Allocator&);
|
||||
hash_map(hash_map&&)
|
||||
noexcept(
|
||||
is_nothrow_move_constructible<hasher>::value &&
|
||||
is_nothrow_move_constructible<key_equal>::value &&
|
||||
is_nothrow_move_constructible<allocator_type>::value);
|
||||
hash_map(hash_map&&, const Allocator&);
|
||||
hash_map(initializer_list<value_type>, size_type n = 0,
|
||||
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
~hash_map();
|
||||
hash_map& operator=(const hash_map&);
|
||||
hash_map& operator=(hash_map&&)
|
||||
noexcept(
|
||||
allocator_type::propagate_on_container_move_assignment::value &&
|
||||
is_nothrow_move_assignable<allocator_type>::value &&
|
||||
is_nothrow_move_assignable<hasher>::value &&
|
||||
is_nothrow_move_assignable<key_equal>::value);
|
||||
hash_map& operator=(initializer_list<value_type>);
|
||||
|
||||
allocator_type get_allocator() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_type size() const noexcept;
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
|
||||
template <class... Args>
|
||||
pair<iterator, bool> emplace(Args&&... args);
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
template <class P>
|
||||
pair<iterator, bool> insert(P&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
template <class P>
|
||||
iterator insert(const_iterator hint, P&& obj);
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last);
|
||||
void insert(initializer_list<value_type>);
|
||||
|
||||
iterator erase(const_iterator position);
|
||||
size_type erase(const key_type& k);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void clear() noexcept;
|
||||
|
||||
void swap(hash_map&)
|
||||
noexcept(
|
||||
(!allocator_type::propagate_on_container_swap::value ||
|
||||
__is_nothrow_swappable<allocator_type>::value) &&
|
||||
__is_nothrow_swappable<hasher>::value &&
|
||||
__is_nothrow_swappable<key_equal>::value);
|
||||
|
||||
hasher hash_function() const;
|
||||
key_equal key_eq() const;
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
size_type count(const key_type& k) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
|
||||
mapped_type& operator[](const key_type& k);
|
||||
mapped_type& operator[](key_type&& k);
|
||||
|
||||
mapped_type& at(const key_type& k);
|
||||
const mapped_type& at(const key_type& k) const;
|
||||
|
||||
size_type bucket_count() const noexcept;
|
||||
size_type max_bucket_count() const noexcept;
|
||||
|
||||
size_type bucket_size(size_type n) const;
|
||||
size_type bucket(const key_type& k) const;
|
||||
|
||||
local_iterator begin(size_type n);
|
||||
local_iterator end(size_type n);
|
||||
const_local_iterator begin(size_type n) const;
|
||||
const_local_iterator end(size_type n) const;
|
||||
const_local_iterator cbegin(size_type n) const;
|
||||
const_local_iterator cend(size_type n) const;
|
||||
|
||||
float load_factor() const noexcept;
|
||||
float max_load_factor() const noexcept;
|
||||
void max_load_factor(float z);
|
||||
void rehash(size_type n);
|
||||
void reserve(size_type n);
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
template <class Key, class Value, class KeyOfValue, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
|
||||
class Alloc = allocator<Value> >
|
||||
class hash_table
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Value key_type;
|
||||
typedef key_type value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
|
||||
typedef /unspecified/ iterator;
|
||||
typedef /unspecified/ const_iterator;
|
||||
typedef /unspecified/ local_iterator;
|
||||
typedef /unspecified/ const_local_iterator;
|
||||
|
||||
hash_set()
|
||||
noexcept(
|
||||
is_nothrow_default_constructible<hasher>::value &&
|
||||
is_nothrow_default_constructible<key_equal>::value &&
|
||||
is_nothrow_default_constructible<allocator_type>::value);
|
||||
explicit hash_set(size_type n, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
template <class InputIterator>
|
||||
hash_set(InputIterator f, InputIterator l,
|
||||
size_type n = 0, const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
explicit hash_set(const allocator_type&);
|
||||
hash_set(const hash_set&);
|
||||
hash_set(const hash_set&, const Allocator&);
|
||||
hash_set(hash_set&&)
|
||||
noexcept(
|
||||
is_nothrow_move_constructible<hasher>::value &&
|
||||
is_nothrow_move_constructible<key_equal>::value &&
|
||||
is_nothrow_move_constructible<allocator_type>::value);
|
||||
hash_set(hash_set&&, const Allocator&);
|
||||
hash_set(initializer_list<value_type>, size_type n = 0,
|
||||
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
~hash_set();
|
||||
hash_set& operator=(const hash_set&);
|
||||
hash_set& operator=(hash_set&&)
|
||||
noexcept(
|
||||
allocator_type::propagate_on_container_move_assignment::value &&
|
||||
is_nothrow_move_assignable<allocator_type>::value &&
|
||||
is_nothrow_move_assignable<hasher>::value &&
|
||||
is_nothrow_move_assignable<key_equal>::value);
|
||||
hash_set& operator=(initializer_list<value_type>);
|
||||
|
||||
allocator_type get_allocator() const noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_type size() const noexcept;
|
||||
size_type max_size() const noexcept;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
|
||||
template <class... Args>
|
||||
pair<iterator, bool> emplace(Args&&... args);
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
pair<iterator, bool> insert(value_type&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
iterator insert(const_iterator hint, value_type&& obj);
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last);
|
||||
void insert(initializer_list<value_type>);
|
||||
|
||||
iterator erase(const_iterator position);
|
||||
size_type erase(const key_type& k);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void clear() noexcept;
|
||||
|
||||
void swap(hash_set&)
|
||||
noexcept(
|
||||
(!allocator_type::propagate_on_container_swap::value ||
|
||||
__is_nothrow_swappable<allocator_type>::value) &&
|
||||
__is_nothrow_swappable<hasher>::value &&
|
||||
__is_nothrow_swappable<key_equal>::value);
|
||||
|
||||
hasher hash_function() const;
|
||||
key_equal key_eq() const;
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
size_type count(const key_type& k) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
|
||||
size_type bucket_count() const noexcept;
|
||||
size_type max_bucket_count() const noexcept;
|
||||
|
||||
size_type bucket_size(size_type n) const;
|
||||
size_type bucket(const key_type& k) const;
|
||||
|
||||
local_iterator begin(size_type n);
|
||||
local_iterator end(size_type n);
|
||||
const_local_iterator begin(size_type n) const;
|
||||
const_local_iterator end(size_type n) const;
|
||||
const_local_iterator cbegin(size_type n) const;
|
||||
const_local_iterator cend(size_type n) const;
|
||||
|
||||
float load_factor() const noexcept;
|
||||
float max_load_factor() const noexcept;
|
||||
void max_load_factor(float z);
|
||||
void rehash(size_type n);
|
||||
void reserve(size_type n);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -18,7 +18,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Stephen Cleary 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012.
|
||||
// (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
|
||||
@@ -16,7 +16,9 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <climits>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -17,20 +17,22 @@
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#include <boost/intrusive/detail/memory_util.hpp>
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (2, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME max_size
|
||||
@@ -48,20 +50,19 @@
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME swap
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
|
||||
@@ -73,6 +74,8 @@ BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assig
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(wrapped_value_compare)
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (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
|
||||
@@ -17,6 +17,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
@@ -110,8 +113,10 @@ struct if_
|
||||
|
||||
template <class Pair>
|
||||
struct select1st
|
||||
// : public std::unary_function<Pair, typename Pair::first_type>
|
||||
{
|
||||
typedef Pair argument_type;
|
||||
typedef typename Pair::first_type result_type;
|
||||
|
||||
template<class OtherPair>
|
||||
const typename Pair::first_type& operator()(const OtherPair& x) const
|
||||
{ return x.first; }
|
||||
@@ -123,8 +128,10 @@ struct select1st
|
||||
// identity is an extension: it is not part of the standard.
|
||||
template <class T>
|
||||
struct identity
|
||||
// : public std::unary_function<T,T>
|
||||
{
|
||||
typedef T argument_type;
|
||||
typedef T result_type;
|
||||
|
||||
typedef T type;
|
||||
const T& operator()(const T& x) const
|
||||
{ return x; }
|
||||
@@ -156,5 +163,7 @@ template <> struct unvoid<const void> { struct type { }; };
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -11,7 +11,9 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
278
include/boost/container/detail/mutex.hpp
Normal file
278
include/boost/container/detail/mutex.hpp
Normal file
@@ -0,0 +1,278 @@
|
||||
// Copyright (C) 2000 Stephen Cleary
|
||||
//
|
||||
// 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.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_MUTEX_HPP
|
||||
#define BOOST_CONTAINER_MUTEX_HPP
|
||||
|
||||
//#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 FORCEINLINE 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 FORCEINLINE 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 */
|
||||
#define SPIN_LOCK_YIELD thr_yield();
|
||||
#elif !defined(LACKS_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_CONTAINER_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 container_detail {
|
||||
|
||||
#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_CONTAINER_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 container_detail
|
||||
} // 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
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,7 +15,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <utility>
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/memory_util.hpp>
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
@@ -50,33 +51,44 @@ template<class ValueCompare, class Node>
|
||||
struct node_compare
|
||||
: private ValueCompare
|
||||
{
|
||||
typedef typename ValueCompare::key_type key_type;
|
||||
typedef typename ValueCompare::value_type value_type;
|
||||
typedef typename ValueCompare::key_of_value key_of_value;
|
||||
typedef ValueCompare wrapped_value_compare;
|
||||
typedef typename wrapped_value_compare::key_type key_type;
|
||||
typedef typename wrapped_value_compare::value_type value_type;
|
||||
typedef typename wrapped_value_compare::key_of_value key_of_value;
|
||||
|
||||
explicit node_compare(const ValueCompare &pred)
|
||||
: ValueCompare(pred)
|
||||
explicit node_compare(const wrapped_value_compare &pred)
|
||||
: wrapped_value_compare(pred)
|
||||
{}
|
||||
|
||||
node_compare()
|
||||
: ValueCompare()
|
||||
: wrapped_value_compare()
|
||||
{}
|
||||
|
||||
ValueCompare &value_comp()
|
||||
{ return static_cast<ValueCompare &>(*this); }
|
||||
wrapped_value_compare &value_comp()
|
||||
{ return static_cast<wrapped_value_compare &>(*this); }
|
||||
|
||||
ValueCompare &value_comp() const
|
||||
{ return static_cast<const ValueCompare &>(*this); }
|
||||
wrapped_value_compare &value_comp() const
|
||||
{ return static_cast<const wrapped_value_compare &>(*this); }
|
||||
|
||||
bool operator()(const Node &a, const Node &b) const
|
||||
{ return ValueCompare::operator()(a.get_data(), b.get_data()); }
|
||||
{ return wrapped_value_compare::operator()(a.get_data(), b.get_data()); }
|
||||
};
|
||||
|
||||
template<class A, class ICont, class ValPred = container_detail::nat>
|
||||
template<class A, class ICont>
|
||||
struct node_alloc_holder
|
||||
{
|
||||
//If the intrusive container is an associative container, obtain the predicate, which will
|
||||
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
|
||||
value_compare, container_detail::nat) intrusive_value_compare;
|
||||
//In that case obtain the value predicate from the node predicate via wrapped_value_compare
|
||||
//if intrusive_value_compare is node_compare<>, nat otherwise
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
|
||||
wrapped_value_compare, container_detail::nat) value_compare;
|
||||
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef ICont intrusive_container;
|
||||
typedef typename ICont::value_type Node;
|
||||
typedef typename allocator_traits_type::template
|
||||
portable_rebind_alloc<Node>::type NodeAlloc;
|
||||
@@ -121,20 +133,20 @@ struct node_alloc_holder
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
//Constructors for associative containers
|
||||
explicit node_alloc_holder(const ValAlloc &a, const ValPred &c)
|
||||
explicit node_alloc_holder(const ValAlloc &a, const value_compare &c)
|
||||
: members_(a, c)
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const node_alloc_holder &x, const ValPred &c)
|
||||
explicit node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
|
||||
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const ValPred &c)
|
||||
explicit node_alloc_holder(const value_compare &c)
|
||||
: members_(c)
|
||||
{}
|
||||
|
||||
//helpers for move assignments
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const ValPred &c)
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &c)
|
||||
: members_(boost::move(x.node_alloc()), c)
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
@@ -346,12 +358,12 @@ struct node_alloc_holder
|
||||
{}
|
||||
|
||||
template<class ConvertibleToAlloc>
|
||||
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const ValPred &c)
|
||||
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
|
||||
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
|
||||
, m_icont(typename ICont::value_compare(c))
|
||||
{}
|
||||
|
||||
explicit members_holder(const ValPred &c)
|
||||
explicit members_holder(const value_compare &c)
|
||||
: NodeAlloc()
|
||||
, m_icont(typename ICont::value_compare(c))
|
||||
{}
|
||||
|
||||
157
include/boost/container/detail/node_pool.hpp
Normal file
157
include/boost/container/detail/node_pool.hpp
Normal file
@@ -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
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/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/intrusive/slist.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <functional> //std::unary_function
|
||||
#include <algorithm> //std::swap
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
//!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::container_detail::
|
||||
private_node_pool_impl<fake_segment_manager>
|
||||
{
|
||||
typedef boost::container::container_detail::
|
||||
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 container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,9 +15,10 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
@@ -29,8 +30,6 @@
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional> //std::unary_function
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -251,8 +250,10 @@ class private_node_pool_impl
|
||||
};
|
||||
|
||||
struct is_between
|
||||
: std::unary_function<typename free_nodes_t::value_type, bool>
|
||||
{
|
||||
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)
|
||||
{}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (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
|
||||
@@ -17,7 +17,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -8,14 +8,16 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
#ifndef BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <new>
|
||||
|
||||
|
||||
94
include/boost/container/detail/pool_common_alloc.hpp
Normal file
94
include/boost/container/detail/pool_common_alloc.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#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/alloc_lib.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost{
|
||||
namespace container{
|
||||
namespace container_detail{
|
||||
|
||||
struct node_slist_helper
|
||||
: public boost::container::container_detail::node_slist<void*>
|
||||
{};
|
||||
|
||||
struct fake_segment_manager
|
||||
{
|
||||
typedef void * void_pointer;
|
||||
static const std::size_t PayloadPerAllocation = BOOST_CONTAINER_ALLOCATION_PAYLOAD;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain;
|
||||
static void deallocate(void_pointer p)
|
||||
{ boost_cont_free(p); }
|
||||
|
||||
static void deallocate_many(multiallocation_chain &chain)
|
||||
{
|
||||
std::size_t size = chain.size();
|
||||
std::pair<void*, void*> ptrs = chain.extract_data();
|
||||
boost_cont_memchain dlchain;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&dlchain, ptrs.first, ptrs.second, size);
|
||||
boost_cont_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 = boost_cont_memalign(nbytes, alignment);
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *allocate(std::size_t nbytes)
|
||||
{
|
||||
void *ret = boost_cont_malloc(nbytes);
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace boost{
|
||||
} //namespace container{
|
||||
} //namespace container_detail{
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class T>
|
||||
struct is_stateless_segment_manager;
|
||||
|
||||
template<>
|
||||
struct is_stateless_segment_manager
|
||||
<boost::container::container_detail::fake_segment_manager>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
|
||||
113
include/boost/container/detail/singleton.hpp
Normal file
113
include/boost/container/detail/singleton.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
// 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
|
||||
|
||||
#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 container_detail {
|
||||
|
||||
// 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 container_detail
|
||||
} // namespace container
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -18,8 +18,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -11,15 +11,10 @@
|
||||
#ifndef BOOST_CONTAINER_TREE_HPP
|
||||
#define BOOST_CONTAINER_TREE_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/intrusive/rbtree.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
@@ -28,7 +23,19 @@
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/options.hpp>
|
||||
|
||||
//
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/rbtree.hpp>
|
||||
#include <boost/intrusive/avltree.hpp>
|
||||
#include <boost/intrusive/splaytree.hpp>
|
||||
#include <boost/intrusive/sgtree.hpp>
|
||||
//
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
//
|
||||
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#endif
|
||||
@@ -85,47 +92,78 @@ struct tree_value_compare
|
||||
{ return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
template<class VoidPointer>
|
||||
struct rbtree_hook
|
||||
template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct intrusive_tree_hook;
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::red_black_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
, container_detail::bi::optimize_size<true>
|
||||
, container_detail::bi::optimize_size<OptimizeSize>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::avl_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_avl_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
, container_detail::bi::optimize_size<OptimizeSize>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::scapegoat_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_bs_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::splay_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_bs_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//This trait is used to type-pun std::pair because in C++03
|
||||
//compilers std::pair is useless for C++11 features
|
||||
template<class T>
|
||||
struct rbtree_internal_data_type
|
||||
struct tree_internal_data_type
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct rbtree_internal_data_type< std::pair<T1, T2> >
|
||||
struct tree_internal_data_type< std::pair<T1, T2> >
|
||||
{
|
||||
typedef pair<T1, T2> type;
|
||||
};
|
||||
|
||||
|
||||
//The node to be store in the tree
|
||||
template <class T, class VoidPointer>
|
||||
struct rbtree_node
|
||||
: public rbtree_hook<VoidPointer>::type
|
||||
template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct tree_node
|
||||
: public intrusive_tree_hook<VoidPointer, tree_type_value, OptimizeSize>::type
|
||||
{
|
||||
private:
|
||||
//BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
|
||||
rbtree_node();
|
||||
//BOOST_COPYABLE_AND_MOVABLE(tree_node)
|
||||
tree_node();
|
||||
|
||||
public:
|
||||
typedef typename rbtree_hook<VoidPointer>::type hook_type;
|
||||
|
||||
typedef typename intrusive_tree_hook
|
||||
<VoidPointer, tree_type_value, OptimizeSize>::type hook_type;
|
||||
typedef T value_type;
|
||||
typedef typename rbtree_internal_data_type<T>::type internal_type;
|
||||
typedef typename tree_internal_data_type<T>::type internal_type;
|
||||
|
||||
typedef rbtree_node<T, VoidPointer> node_type;
|
||||
typedef tree_node< T, VoidPointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
|
||||
T &get_data()
|
||||
{
|
||||
@@ -210,52 +248,224 @@ class push_back_functor
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<class A, class ValueCompare>
|
||||
struct intrusive_rbtree_type
|
||||
template< class NodeType, class NodeCompareType
|
||||
, class SizeType, class HookType
|
||||
, boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_dispatch;
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::red_black_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_rbtree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::avl_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_avltree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::scapegoat_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_sgtree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::floating_point<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::splay_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_splaytree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class A, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct intrusive_tree_type
|
||||
{
|
||||
private:
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::void_pointer void_pointer;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::size_type size_type;
|
||||
typedef typename container_detail::rbtree_node
|
||||
<value_type, void_pointer> node_type;
|
||||
typedef typename container_detail::tree_node
|
||||
< value_type, void_pointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
typedef node_compare<ValueCompare, node_type> node_compare_type;
|
||||
typedef typename container_detail::bi::make_rbtree
|
||||
<node_type
|
||||
,container_detail::bi::compare<node_compare_type>
|
||||
,container_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<size_type>
|
||||
>::type container_type;
|
||||
typedef container_type type ;
|
||||
//Deducing the hook type from node_type (e.g. node_type::hook_type) would
|
||||
//provoke an early instantiation of node_type that could ruin recursive
|
||||
//tree definitions, so retype the complete type to avoid any problem.
|
||||
typedef typename intrusive_tree_hook
|
||||
<void_pointer, tree_type_value
|
||||
, OptimizeSize>::type hook_type;
|
||||
public:
|
||||
typedef typename intrusive_tree_dispatch
|
||||
< node_type, node_compare_type
|
||||
, size_type, hook_type
|
||||
, tree_type_value>::type type;
|
||||
};
|
||||
|
||||
//Trait to detect manually rebalanceable tree types
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct is_manually_balanceable
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<> struct is_manually_balanceable<red_black_tree>
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<> struct is_manually_balanceable<avl_tree>
|
||||
{ static const bool value = false; };
|
||||
|
||||
//Proxy traits to implement different operations depending on the
|
||||
//is_manually_balanceable<>::value
|
||||
template< boost::container::tree_type_enum tree_type_value
|
||||
, bool IsManuallyRebalanceable = is_manually_balanceable<tree_type_value>::value>
|
||||
struct intrusive_tree_proxy
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &) {}
|
||||
};
|
||||
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_proxy<tree_type_value, true>
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &c)
|
||||
{ c.rebalance(); }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//This functor will be used with Intrusive clone functions to obtain
|
||||
//already allocated nodes from a intrusive container instead of
|
||||
//allocating new ones. When the intrusive container runs out of nodes
|
||||
//the node holder is used instead.
|
||||
template<class AllocHolder, bool DoMove>
|
||||
class RecyclingCloner
|
||||
{
|
||||
typedef typename AllocHolder::intrusive_container intrusive_container;
|
||||
typedef typename AllocHolder::Node node_type;
|
||||
typedef typename AllocHolder::NodePtr node_ptr_type;
|
||||
|
||||
public:
|
||||
RecyclingCloner(AllocHolder &holder, intrusive_container &itree)
|
||||
: m_holder(holder), m_icont(itree)
|
||||
{}
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<true>)
|
||||
{ p->do_assign(other.m_data); }
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<false>)
|
||||
{ p->do_move_assign(const_cast<node_type &>(other).m_data); }
|
||||
|
||||
node_ptr_type operator()(const node_type &other) const
|
||||
{
|
||||
if(node_ptr_type p = m_icont.unlink_leftmost_without_rebalance()){
|
||||
//First recycle a node (this can't throw)
|
||||
BOOST_TRY{
|
||||
//This can throw
|
||||
this->do_assign(p, other, bool_<DoMove>());
|
||||
return p;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//If there is an exception destroy the whole source
|
||||
m_holder.destroy_node(p);
|
||||
while((p = m_icont.unlink_leftmost_without_rebalance())){
|
||||
m_holder.destroy_node(p);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
AllocHolder &m_holder;
|
||||
intrusive_container &m_icont;
|
||||
};
|
||||
|
||||
template<class KeyValueCompare, class Node>
|
||||
//where KeyValueCompare is tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
|
||||
struct key_node_compare
|
||||
: private KeyValueCompare
|
||||
{
|
||||
explicit key_node_compare(const KeyValueCompare &comp)
|
||||
: KeyValueCompare(comp)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
struct is_node
|
||||
{
|
||||
static const bool value = is_same<T, Node>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<is_node<T>::value, const typename KeyValueCompare::value_type &>::type
|
||||
key_forward(const T &node) const
|
||||
{ return node.get_data(); }
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<!is_node<T>::value, const T &>::type
|
||||
key_forward(const T &key) const
|
||||
{ return key; }
|
||||
|
||||
template<class KeyType, class KeyType2>
|
||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
class rbtree
|
||||
class KeyCompare, class A,
|
||||
class Options = tree_assoc_defaults>
|
||||
class tree
|
||||
: protected container_detail::node_alloc_holder
|
||||
< A
|
||||
, typename container_detail::intrusive_rbtree_type
|
||||
<A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
|
||||
>::type
|
||||
, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
|
||||
, typename container_detail::intrusive_tree_type
|
||||
< A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue> //ValComp
|
||||
, Options::tree_type, Options::optimize_size>::type
|
||||
>
|
||||
{
|
||||
typedef tree_value_compare
|
||||
<Key, Value, KeyCompare, KeyOfValue> ValComp;
|
||||
typedef typename container_detail::intrusive_rbtree_type
|
||||
< A, ValComp>::type Icont;
|
||||
typedef typename container_detail::intrusive_tree_type
|
||||
< A, ValComp, Options::tree_type
|
||||
, Options::optimize_size>::type Icont;
|
||||
typedef container_detail::node_alloc_holder
|
||||
<A, Icont, ValComp> AllocHolder;
|
||||
<A, Icont> AllocHolder;
|
||||
typedef typename AllocHolder::NodePtr NodePtr;
|
||||
typedef rbtree < Key, Value, KeyOfValue
|
||||
, KeyCompare, A> ThisType;
|
||||
typedef tree < Key, Value, KeyOfValue
|
||||
, KeyCompare, A, Options> ThisType;
|
||||
typedef typename AllocHolder::NodeAlloc NodeAlloc;
|
||||
typedef typename AllocHolder::ValAlloc ValAlloc;
|
||||
typedef typename AllocHolder::Node Node;
|
||||
@@ -265,84 +475,9 @@ class rbtree
|
||||
typedef typename AllocHolder::allocator_v1 allocator_v1;
|
||||
typedef typename AllocHolder::allocator_v2 allocator_v2;
|
||||
typedef typename AllocHolder::alloc_version alloc_version;
|
||||
typedef intrusive_tree_proxy<Options::tree_type> intrusive_tree_proxy_t;
|
||||
|
||||
class RecyclingCloner;
|
||||
friend class RecyclingCloner;
|
||||
|
||||
class RecyclingCloner
|
||||
{
|
||||
public:
|
||||
RecyclingCloner(AllocHolder &holder, Icont &irbtree)
|
||||
: m_holder(holder), m_icont(irbtree)
|
||||
{}
|
||||
|
||||
NodePtr operator()(const Node &other) const
|
||||
{
|
||||
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
|
||||
//First recycle a node (this can't throw)
|
||||
BOOST_TRY{
|
||||
//This can throw
|
||||
p->do_assign(other.m_data);
|
||||
return p;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//If there is an exception destroy the whole source
|
||||
m_holder.destroy_node(p);
|
||||
while((p = m_icont.unlink_leftmost_without_rebalance())){
|
||||
m_holder.destroy_node(p);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
AllocHolder &m_holder;
|
||||
Icont &m_icont;
|
||||
};
|
||||
|
||||
class RecyclingMoveCloner;
|
||||
friend class RecyclingMoveCloner;
|
||||
|
||||
class RecyclingMoveCloner
|
||||
{
|
||||
public:
|
||||
RecyclingMoveCloner(AllocHolder &holder, Icont &irbtree)
|
||||
: m_holder(holder), m_icont(irbtree)
|
||||
{}
|
||||
|
||||
NodePtr operator()(const Node &other) const
|
||||
{
|
||||
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
|
||||
//First recycle a node (this can't throw)
|
||||
BOOST_TRY{
|
||||
//This can throw
|
||||
p->do_move_assign(const_cast<Node &>(other).m_data);
|
||||
return p;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//If there is an exception destroy the whole source
|
||||
m_holder.destroy_node(p);
|
||||
while((p = m_icont.unlink_leftmost_without_rebalance())){
|
||||
m_holder.destroy_node(p);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
AllocHolder &m_holder;
|
||||
Icont &m_icont;
|
||||
};
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(rbtree)
|
||||
BOOST_COPYABLE_AND_MOVABLE(tree)
|
||||
|
||||
public:
|
||||
|
||||
@@ -363,45 +498,16 @@ class rbtree
|
||||
allocator_traits<A>::size_type size_type;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::difference_type difference_type;
|
||||
typedef difference_type rbtree_difference_type;
|
||||
typedef pointer rbtree_pointer;
|
||||
typedef const_pointer rbtree_const_pointer;
|
||||
typedef reference rbtree_reference;
|
||||
typedef const_reference rbtree_const_reference;
|
||||
typedef difference_type tree_difference_type;
|
||||
typedef pointer tree_pointer;
|
||||
typedef const_pointer tree_const_pointer;
|
||||
typedef reference tree_reference;
|
||||
typedef const_reference tree_const_reference;
|
||||
typedef NodeAlloc stored_allocator_type;
|
||||
|
||||
private:
|
||||
|
||||
template<class KeyValueCompare>
|
||||
struct key_node_compare
|
||||
: private KeyValueCompare
|
||||
{
|
||||
key_node_compare(const KeyValueCompare &comp)
|
||||
: KeyValueCompare(comp)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
struct is_node
|
||||
{
|
||||
static const bool value = is_same<T, Node>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<is_node<T>::value, const value_type &>::type
|
||||
key_forward(const T &node) const
|
||||
{ return node.get_data(); }
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<!is_node<T>::value, const T &>::type
|
||||
key_forward(const T &key) const
|
||||
{ return key; }
|
||||
|
||||
template<class KeyType, class KeyType2>
|
||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
typedef key_node_compare<value_compare> KeyNodeCompare;
|
||||
typedef key_node_compare<value_compare, Node> KeyNodeCompare;
|
||||
|
||||
public:
|
||||
typedef container_detail::iterator<iiterator, false> iterator;
|
||||
@@ -409,20 +515,20 @@ class rbtree
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
rbtree()
|
||||
tree()
|
||||
: AllocHolder(ValComp(key_compare()))
|
||||
{}
|
||||
|
||||
explicit rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
: AllocHolder(a, ValComp(comp))
|
||||
{}
|
||||
|
||||
explicit rbtree(const allocator_type& a)
|
||||
explicit tree(const allocator_type& a)
|
||||
: AllocHolder(a)
|
||||
{}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
const allocator_type& a
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -450,7 +556,7 @@ class rbtree
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
const allocator_type& a
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -479,7 +585,7 @@ class rbtree
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree( ordered_range_t, InputIterator first, InputIterator last
|
||||
tree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -496,7 +602,7 @@ class rbtree
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree( ordered_range_t, InputIterator first, InputIterator last
|
||||
tree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
@@ -513,25 +619,25 @@ class rbtree
|
||||
, container_detail::push_back_functor<Node, Icont>(this->icont()));
|
||||
}
|
||||
|
||||
rbtree(const rbtree& x)
|
||||
tree(const tree& x)
|
||||
: AllocHolder(x, x.value_comp())
|
||||
{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
rbtree(BOOST_RV_REF(rbtree) x)
|
||||
tree(BOOST_RV_REF(tree) x)
|
||||
: AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.value_comp())
|
||||
{}
|
||||
|
||||
rbtree(const rbtree& x, const allocator_type &a)
|
||||
tree(const tree& x, const allocator_type &a)
|
||||
: AllocHolder(a, x.value_comp())
|
||||
{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
|
||||
tree(BOOST_RV_REF(tree) x, const allocator_type &a)
|
||||
: AllocHolder(a, x.value_comp())
|
||||
{
|
||||
if(this->node_alloc() == x.node_alloc()){
|
||||
@@ -543,10 +649,10 @@ class rbtree
|
||||
}
|
||||
}
|
||||
|
||||
~rbtree()
|
||||
~tree()
|
||||
{} //AllocHolder clears the tree
|
||||
|
||||
rbtree& operator=(BOOST_COPY_ASSIGN_REF(rbtree) x)
|
||||
tree& operator=(BOOST_COPY_ASSIGN_REF(tree) x)
|
||||
{
|
||||
if (&x != this){
|
||||
NodeAlloc &this_alloc = this->get_stored_allocator();
|
||||
@@ -565,7 +671,7 @@ class rbtree
|
||||
//Now recreate the source tree reusing nodes stored by other_tree
|
||||
this->icont().clone_from
|
||||
(x.icont()
|
||||
, RecyclingCloner(*this, other_tree)
|
||||
, RecyclingCloner<AllocHolder, false>(*this, other_tree)
|
||||
, Destroyer(this->node_alloc()));
|
||||
|
||||
//If there are remaining nodes, destroy them
|
||||
@@ -577,7 +683,7 @@ class rbtree
|
||||
return *this;
|
||||
}
|
||||
|
||||
rbtree& operator=(BOOST_RV_REF(rbtree) x)
|
||||
tree& operator=(BOOST_RV_REF(tree) x)
|
||||
{
|
||||
if (&x != this){
|
||||
NodeAlloc &this_alloc = this->get_stored_allocator();
|
||||
@@ -600,7 +706,7 @@ class rbtree
|
||||
//Now recreate the source tree reusing nodes stored by other_tree
|
||||
this->icont().clone_from
|
||||
(x.icont()
|
||||
, RecyclingMoveCloner(*this, other_tree)
|
||||
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
|
||||
, Destroyer(this->node_alloc()));
|
||||
|
||||
//If there are remaining nodes, destroy them
|
||||
@@ -965,7 +1071,8 @@ class rbtree
|
||||
void clear()
|
||||
{ AllocHolder::clear(alloc_version()); }
|
||||
|
||||
// set operations:
|
||||
// search operations. Const and non-const overloads even if no iterator is returned
|
||||
// so splay implementations can to their rebalancing when searching in non-const versions
|
||||
iterator find(const key_type& k)
|
||||
{ return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
@@ -1001,70 +1108,47 @@ class rbtree
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
std::pair<iterator,iterator> lower_bound_range(const key_type& k)
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->icont().lower_bound_range(k, KeyNodeCompare(value_comp()));
|
||||
return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->non_const_icont().lower_bound_range(k, KeyNodeCompare(value_comp()));
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
void rebalance()
|
||||
{ intrusive_tree_proxy_t::rebalance(this->icont()); }
|
||||
|
||||
friend bool operator==(const tree& x, const tree& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
friend bool operator<(const tree& x, const tree& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
friend bool operator!=(const tree& x, const tree& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
friend bool operator>(const tree& x, const tree& y)
|
||||
{ return y < x; }
|
||||
|
||||
friend bool operator<=(const tree& x, const tree& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
friend bool operator>=(const tree& x, const tree& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(tree& x, tree& y)
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator==(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
|
||||
{
|
||||
return x.size() == y.size() &&
|
||||
std::equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator<(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(),
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator!=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator>(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator<=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline bool
|
||||
operator>=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A>
|
||||
inline void
|
||||
swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
/*
|
||||
@@ -1073,7 +1157,7 @@ swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
|
||||
template <class K, class V, class KOV,
|
||||
class C, class A>
|
||||
struct has_trivial_destructor_after_move
|
||||
<boost::container::container_detail::rbtree<K, V, KOV, C, A> >
|
||||
<boost::container::container_detail::tree<K, V, KOV, C, A> >
|
||||
{
|
||||
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (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
|
||||
@@ -19,7 +19,8 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/move/utility.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -11,8 +11,9 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include "workaround.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring> //for ::memcpy
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
@@ -24,6 +25,7 @@
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
@@ -109,25 +111,47 @@ template<class T>
|
||||
const T &min_value(const T &a, const T &b)
|
||||
{ return a < b ? a : b; }
|
||||
|
||||
template <class SizeType>
|
||||
SizeType
|
||||
get_next_capacity(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
|
||||
|
||||
template<class SizeType, NextCapacityOption Option>
|
||||
struct next_capacity_calculator;
|
||||
|
||||
template<class SizeType>
|
||||
struct next_capacity_calculator<SizeType, NextCapacityDouble>
|
||||
{
|
||||
// if (n > max_size - capacity)
|
||||
// throw std::length_error("get_next_capacity");
|
||||
static SizeType get(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{
|
||||
const SizeType remaining = max_size - capacity;
|
||||
if ( remaining < n )
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
|
||||
const SizeType additional = max_value(n, capacity);
|
||||
return ( remaining < additional ) ? max_size : ( capacity + additional );
|
||||
}
|
||||
};
|
||||
|
||||
const SizeType m3 = max_size/3;
|
||||
|
||||
if (capacity < m3)
|
||||
return capacity + max_value(3*(capacity+1)/5, n);
|
||||
template<class SizeType>
|
||||
struct next_capacity_calculator<SizeType, NextCapacity60Percent>
|
||||
{
|
||||
static SizeType get(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{
|
||||
const SizeType remaining = max_size - capacity;
|
||||
if ( remaining < n )
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
|
||||
const SizeType m3 = max_size/3;
|
||||
|
||||
if (capacity < m3*2)
|
||||
return capacity + max_value((capacity+1)/2, n);
|
||||
if (capacity < m3)
|
||||
return capacity + max_value(3*(capacity+1)/5, n);
|
||||
|
||||
return max_size;
|
||||
}
|
||||
if (capacity < m3*2)
|
||||
return capacity + max_value((capacity+1)/2, n);
|
||||
return max_size;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T* to_raw_pointer(T* p)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (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
|
||||
@@ -17,7 +17,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -15,8 +15,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -16,7 +16,8 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#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>
|
||||
@@ -87,6 +88,6 @@ struct version
|
||||
} //namespace container {
|
||||
} //namespace boost{
|
||||
|
||||
#include "config_end.hpp"
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -34,18 +34,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
// Forward declarations of operators == and <, needed for friend declarations.
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_map;
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y);
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y);
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail{
|
||||
|
||||
@@ -62,8 +51,7 @@ static D force_copy(S s)
|
||||
|
||||
} //namespace container_detail{
|
||||
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A flat_map is a kind of associative container that supports unique keys (contains at
|
||||
//! most one of each key value) and provides for fast retrieval of values of another
|
||||
@@ -88,6 +76,12 @@ static D force_copy(S s)
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
@@ -95,7 +89,7 @@ template <class Key, class T, class Compare, class Allocator>
|
||||
#endif
|
||||
class flat_map
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_map)
|
||||
//This is the tree that we should store if pair was movable
|
||||
@@ -129,7 +123,7 @@ class flat_map
|
||||
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
@@ -168,7 +162,11 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_map()
|
||||
: m_flat_tree() {}
|
||||
: m_flat_tree()
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified
|
||||
//! comparison object and allocator.
|
||||
@@ -176,14 +174,20 @@ class flat_map
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_map(const Compare& comp, const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_map(const allocator_type& a)
|
||||
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
//! allocator, and inserts elements from the range [first ,last ).
|
||||
@@ -194,7 +198,10 @@ class flat_map
|
||||
flat_map(InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
|
||||
@@ -210,13 +217,20 @@ class flat_map
|
||||
flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_map(const flat_map& x)
|
||||
: m_flat_tree(x.m_flat_tree) {}
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map.
|
||||
//! Constructs *this using x's resources.
|
||||
@@ -226,14 +240,20 @@ class flat_map
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_map(BOOST_RV_REF(flat_map) x)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_map(const flat_map& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
@@ -241,7 +261,10 @@ class flat_map
|
||||
//! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
|
||||
flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -834,22 +857,57 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
std::pair<iterator,iterator> equal_range(const key_type& x)
|
||||
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
|
||||
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
|
||||
|
||||
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
|
||||
|
||||
/// @cond
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator== (const flat_map<K1, T1, C1, A1>&,
|
||||
const flat_map<K1, T1, C1, A1>&);
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator< (const flat_map<K1, T1, C1, A1>&,
|
||||
const flat_map<K1, T1, C1, A1>&);
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const flat_map& x, const flat_map& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const flat_map& x, const flat_map& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const flat_map& x, const flat_map& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const flat_map& x, const flat_map& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const flat_map& x, const flat_map& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const flat_map& x, const flat_map& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(flat_map& x, flat_map& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
mapped_type &priv_subscript(const key_type& k)
|
||||
{
|
||||
@@ -872,45 +930,10 @@ class flat_map
|
||||
}
|
||||
return (*i).second;
|
||||
}
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree == y.m_flat_tree; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree < y.m_flat_tree; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator!=(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<=(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>=(const flat_map<Key,T,Compare,Allocator>& x,
|
||||
const flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline void swap(flat_map<Key,T,Compare,Allocator>& x,
|
||||
flat_map<Key,T,Compare,Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -924,18 +947,7 @@ struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, All
|
||||
|
||||
namespace container {
|
||||
|
||||
// Forward declaration of operators < and ==, needed for friend declaration.
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_multimap;
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y);
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y);
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A flat_multimap is a kind of associative container that supports equivalent keys
|
||||
//! (possibly containing multiple copies of the same key value) and provides for
|
||||
@@ -960,6 +972,12 @@ inline bool operator<(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
@@ -967,7 +985,7 @@ template <class Key, class T, class Compare, class Allocator>
|
||||
#endif
|
||||
class flat_multimap
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
|
||||
typedef container_detail::flat_tree<Key,
|
||||
@@ -999,7 +1017,7 @@ class flat_multimap
|
||||
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
@@ -1037,7 +1055,11 @@ class flat_multimap
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_multimap()
|
||||
: m_flat_tree() {}
|
||||
: m_flat_tree()
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
|
||||
//! object and allocator.
|
||||
@@ -1046,14 +1068,20 @@ class flat_multimap
|
||||
explicit flat_multimap(const Compare& comp,
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_multimap(const allocator_type& a)
|
||||
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
|
||||
//! and allocator, and inserts elements from the range [first ,last ).
|
||||
@@ -1065,7 +1093,10 @@ class flat_multimap
|
||||
const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
|
||||
//! allocator, and inserts elements from the ordered range [first ,last). This function
|
||||
@@ -1081,13 +1112,20 @@ class flat_multimap
|
||||
const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_multimap.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multimap(const flat_multimap& x)
|
||||
: m_flat_tree(x.m_flat_tree) { }
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
|
||||
//!
|
||||
@@ -1096,14 +1134,20 @@ class flat_multimap
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_multimap(BOOST_RV_REF(flat_multimap) x)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multimap(const flat_multimap& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
@@ -1111,7 +1155,10 @@ class flat_multimap
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{ }
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -1637,54 +1684,52 @@ class flat_multimap
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
|
||||
|
||||
/// @cond
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator== (const flat_multimap<K1, T1, C1, A1>& x,
|
||||
const flat_multimap<K1, T1, C1, A1>& y);
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
template <class K1, class T1, class C1, class A1>
|
||||
friend bool operator< (const flat_multimap<K1, T1, C1, A1>& x,
|
||||
const flat_multimap<K1, T1, C1, A1>& y);
|
||||
/// @endcond
|
||||
};
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator==(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree == y.m_flat_tree; }
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
{ return x.m_flat_tree < y.m_flat_tree; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator!=(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator<=(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline bool operator>=(const flat_multimap<Key,T,Compare,Allocator>& x,
|
||||
const flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
inline void swap(flat_multimap<Key,T,Compare,Allocator>& x, flat_multimap<Key,T,Compare,Allocator>& y)
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(flat_multimap& x, flat_multimap& y)
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1698,7 +1743,7 @@ struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T,
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -47,7 +47,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
namespace container_detail {
|
||||
|
||||
template<class VoidPointer>
|
||||
@@ -99,7 +99,7 @@ struct intrusive_list_type
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A list is a doubly linked list. That is, it is a Sequence that supports both
|
||||
//! forward and backward traversal, and (amortized) constant time insertion and
|
||||
@@ -111,6 +111,9 @@ struct intrusive_list_type
|
||||
//! after a list operation than it did before), but the iterators themselves will
|
||||
//! not be invalidated or made to point to different elements unless that invalidation
|
||||
//! or mutation is explicit.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the list
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
@@ -120,7 +123,7 @@ class list
|
||||
: protected container_detail::node_alloc_holder
|
||||
<Allocator, typename container_detail::intrusive_list_type<Allocator>::type>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef typename
|
||||
container_detail::intrusive_list_type<Allocator>::type Icont;
|
||||
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
|
||||
@@ -167,7 +170,7 @@ class list
|
||||
|
||||
typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
|
||||
typedef container_detail::iterator<typename Icont::iterator, true> const_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -1214,9 +1217,65 @@ class list
|
||||
//!
|
||||
//! <b>Note</b>: Iterators and references are not invalidated
|
||||
void reverse() BOOST_CONTAINER_NOEXCEPT
|
||||
{ this->icont().reverse(); }
|
||||
{ this->icont().reverse(); }
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const list& x, const list& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename list::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2) {
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const list& x, const list& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const list& x, const list& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const list& x, const list& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const list& x, const list& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const list& x, const list& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(list& x, list& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
bool priv_try_shrink(size_type new_size)
|
||||
@@ -1303,66 +1362,11 @@ class list
|
||||
bool operator()(const value_type &a, const value_type &b) const
|
||||
{ return a == b; }
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
};
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator==(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename list<T,Allocator>::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2) {
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<(const list<T,Allocator>& x,
|
||||
const list<T,Allocator>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator!=(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator<=(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool operator>=(const list<T,Allocator>& x, const list<T,Allocator>& y)
|
||||
{
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline void swap(list<T, Allocator>& x, list<T, Allocator>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
} //namespace container {
|
||||
|
||||
@@ -1375,7 +1379,7 @@ struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
|
||||
|
||||
namespace container {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
346
include/boost/container/node_allocator.hpp
Normal file
346
include/boost/container/node_allocator.hpp
Normal file
@@ -0,0 +1,346 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_POOLED_NODE_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/node_pool.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/alloc_lib_auto_link.hpp>
|
||||
#include <boost/container/detail/singleton.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//!An STL node allocator that uses a modified DlMalloc as memory
|
||||
//!source.
|
||||
//!
|
||||
//!This node allocator shares a segregated storage between all instances
|
||||
//!of node_allocator with equal sizeof(T).
|
||||
//!
|
||||
//!NodesPerBlock is the number of nodes allocated at once when the allocator
|
||||
//!runs out of nodes
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template
|
||||
< class T
|
||||
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block>
|
||||
#else
|
||||
template
|
||||
< class T
|
||||
, std::size_t NodesPerBlock
|
||||
, std::size_t Version>
|
||||
#endif
|
||||
class node_allocator
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
|
||||
//! the allocator offers advanced expand in place and burst allocation capabilities.
|
||||
public:
|
||||
typedef unsigned int allocation_type;
|
||||
typedef node_allocator<T, NodesPerBlock, Version> self_t;
|
||||
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
|
||||
BOOST_STATIC_ASSERT((Version <=2));
|
||||
#endif
|
||||
|
||||
public:
|
||||
//-------
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & reference;
|
||||
typedef const typename ::boost::container::
|
||||
container_detail::unvoid<T>::type & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef boost::container::container_detail::
|
||||
version_type<self_t, Version> version;
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef boost::container::container_detail::
|
||||
basic_multiallocation_chain<void*> multiallocation_chain_void;
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
<multiallocation_chain_void, T> multiallocation_chain;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Obtains node_allocator from
|
||||
//!node_allocator
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef node_allocator< T2, NodesPerBlock
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> other;
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
//!Not assignable from related node_allocator
|
||||
template<class T2, std::size_t N2>
|
||||
node_allocator& operator=
|
||||
(const node_allocator<T2, N2>&);
|
||||
|
||||
//!Not assignable from other node_allocator
|
||||
node_allocator& operator=(const node_allocator&);
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
||||
//!Default constructor
|
||||
node_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from other node_allocator.
|
||||
node_allocator(const node_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Copy constructor from related node_allocator.
|
||||
template<class T2>
|
||||
node_allocator
|
||||
(const node_allocator<T2, NodesPerBlock
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, Version
|
||||
#endif
|
||||
> &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Destructor
|
||||
~node_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!Returns the number of elements that could be allocated.
|
||||
//!Never throws
|
||||
size_type max_size() const
|
||||
{ return size_type(-1)/sizeof(T); }
|
||||
|
||||
//!Allocate memory for an array of count elements.
|
||||
//!Throws std::bad_alloc if there is no enough memory
|
||||
pointer allocate(size_type count, const void * = 0)
|
||||
{
|
||||
if(count > this->max_size())
|
||||
boost::container::throw_bad_alloc();
|
||||
|
||||
if(Version == 1 && count == 1){
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return pointer(static_cast<T*>(singleton_t::instance().allocate_node()));
|
||||
}
|
||||
else{
|
||||
void *ret = boost_cont_malloc(count*sizeof(T));
|
||||
if(!ret)
|
||||
boost::container::throw_bad_alloc();
|
||||
return static_cast<pointer>(ret);
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocate allocated memory.
|
||||
//!Never throws
|
||||
void deallocate(const pointer &ptr, size_type count) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
(void)count;
|
||||
if(Version == 1 && count == 1){
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(ptr);
|
||||
}
|
||||
else{
|
||||
boost_cont_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocates all free blocks of the pool
|
||||
static void deallocate_free_blocks() BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_free_blocks();
|
||||
}
|
||||
|
||||
std::pair<pointer, bool>
|
||||
allocation_command(allocation_type command,
|
||||
size_type limit_size,
|
||||
size_type preferred_size,
|
||||
size_type &received_size, pointer reuse = pointer())
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
std::pair<pointer, bool> ret =
|
||||
priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
|
||||
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
|
||||
boost::container::throw_bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold.
|
||||
size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
return boost_cont_size(p);
|
||||
}
|
||||
|
||||
//!Allocates just one object. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
//!Throws bad_alloc if there is no enough memory
|
||||
pointer allocate_one()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
return (pointer)singleton_t::instance().allocate_node();
|
||||
}
|
||||
|
||||
//!Allocates many elements of size == 1.
|
||||
//!Elements must be individually deallocated with deallocate_one()
|
||||
void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
typename shared_pool_t::multiallocation_chain ch;
|
||||
singleton_t::instance().allocate_nodes(num_elements, ch);
|
||||
chain.incorporate_after(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size());
|
||||
}
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
//!with other functions different from allocate_one(). Never throws
|
||||
void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
singleton_t::instance().deallocate_node(p);
|
||||
}
|
||||
|
||||
void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
typedef container_detail::shared_node_pool
|
||||
<sizeof(T), NodesPerBlock> shared_pool_t;
|
||||
typedef container_detail::singleton_default<shared_pool_t> singleton_t;
|
||||
typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size());
|
||||
singleton_t::instance().deallocate_nodes(ch);
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size.
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
|
||||
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after( chain.before_begin()
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, BOOST_CONTAINER_MEMCHAIN_SIZE(&ch));
|
||||
}
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]
|
||||
//!Elements must be individually deallocated with deallocate()
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
boost_cont_memchain ch;
|
||||
boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch);
|
||||
if(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch)){
|
||||
boost::container::throw_bad_alloc();
|
||||
}
|
||||
chain.incorporate_after( chain.before_begin()
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
|
||||
, BOOST_CONTAINER_MEMCHAIN_SIZE(&ch));
|
||||
}
|
||||
|
||||
void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( Version > 1 ));
|
||||
void *first = &*chain.begin();
|
||||
void *last = &*chain.last();
|
||||
size_t num = chain.size();
|
||||
boost_cont_memchain ch;
|
||||
BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, first, last, num);
|
||||
boost_cont_multidealloc(&ch);
|
||||
}
|
||||
|
||||
//!Swaps allocators. Does not throw. If each allocator is placed in a
|
||||
//!different memory segment, the result is undefined.
|
||||
friend void swap(self_t &, self_t &) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
//!An allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const node_allocator &, const node_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return true; }
|
||||
|
||||
//!An allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const node_allocator &, const node_allocator &) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return false; }
|
||||
|
||||
private:
|
||||
std::pair<pointer, bool> priv_allocation_command
|
||||
(allocation_type command, std::size_t limit_size
|
||||
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
|
||||
{
|
||||
boost_cont_command_ret_t ret = {0 , 0};
|
||||
if(limit_size > this->max_size() || preferred_size > this->max_size()){
|
||||
//ret.first = 0;
|
||||
return std::pair<pointer, bool>(pointer(), false);
|
||||
}
|
||||
std::size_t l_size = limit_size*sizeof(T);
|
||||
std::size_t p_size = preferred_size*sizeof(T);
|
||||
std::size_t r_size;
|
||||
{
|
||||
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
|
||||
}
|
||||
received_size = r_size/sizeof(T);
|
||||
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
|
||||
72
include/boost/container/options.hpp
Normal file
72
include/boost/container/options.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
||||
#define BOOST_CONTAINER_OPTIONS_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/intrusive/pack_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt
|
||||
{
|
||||
static const boost::container::tree_type_enum tree_type = TreeType;
|
||||
static const bool optimize_size = OptimizeSize;
|
||||
};
|
||||
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//!This option setter specifies the underlying tree type
|
||||
//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type)
|
||||
|
||||
//!This option setter specifies if node size is optimized
|
||||
//!storing rebalancing data masked into pointers for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
|
||||
|
||||
//! Helper metafunction to combine options into a single type to be used
|
||||
//! by \c boost::container::set, \c boost::container::multiset
|
||||
//! \c boost::container::map and \c boost::container::multimap.
|
||||
//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct tree_assoc_options
|
||||
{
|
||||
/// @cond
|
||||
typedef typename ::boost::intrusive::pack_options
|
||||
< tree_assoc_defaults,
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -46,7 +46,7 @@ namespace boost { namespace container {
|
||||
//! and if T is used in a context where a container must call such a constructor, then the program is
|
||||
//! ill-formed.
|
||||
//!
|
||||
//! [Example:
|
||||
//! <code>
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! class Z {
|
||||
//! public:
|
||||
@@ -64,7 +64,7 @@ namespace boost { namespace container {
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! struct constructible_with_allocator_suffix<Z<T,Allocator> >
|
||||
//! : ::boost::true_type { };
|
||||
//! -- end example]
|
||||
//! </code>
|
||||
//!
|
||||
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
|
||||
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
||||
@@ -90,7 +90,7 @@ struct constructible_with_allocator_suffix
|
||||
//! called with these initial arguments, and if T is used in a context where a container must call such
|
||||
//! a constructor, then the program is ill-formed.
|
||||
//!
|
||||
//! [Example:
|
||||
//! <code>
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! class Y {
|
||||
//! public:
|
||||
@@ -115,7 +115,7 @@ struct constructible_with_allocator_suffix
|
||||
//! struct constructible_with_allocator_prefix<Y<T,Allocator> >
|
||||
//! : ::boost::true_type { };
|
||||
//!
|
||||
//! -- end example]
|
||||
//! </code>
|
||||
//!
|
||||
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
|
||||
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
||||
@@ -130,7 +130,7 @@ struct constructible_with_allocator_prefix
|
||||
: ::boost::false_type
|
||||
{};
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
@@ -159,7 +159,7 @@ struct uses_allocator_imp
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Remark</b>: Automatically detects if T has a nested allocator_type that is convertible from
|
||||
//! Alloc. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may
|
||||
@@ -173,7 +173,7 @@ struct uses_allocator
|
||||
: boost::integral_constant<bool, container_detail::uses_allocator_imp<T, Alloc>::value>
|
||||
{};
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
@@ -675,16 +675,16 @@ class scoped_allocator_adaptor_base
|
||||
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
|
||||
{ l.swap(r); }
|
||||
|
||||
inner_allocator_type& inner_allocator()
|
||||
inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{ return m_inner; }
|
||||
|
||||
inner_allocator_type const& inner_allocator() const
|
||||
inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return m_inner; }
|
||||
|
||||
outer_allocator_type & outer_allocator()
|
||||
outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{ return static_cast<outer_allocator_type&>(*this); }
|
||||
|
||||
const outer_allocator_type &outer_allocator() const
|
||||
const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return static_cast<const outer_allocator_type&>(*this); }
|
||||
|
||||
scoped_allocator_type select_on_container_copy_construction() const
|
||||
@@ -1008,7 +1008,7 @@ class scoped_allocator_adaptor_base
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//Scoped allocator
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -1038,14 +1038,14 @@ class scoped_allocator_adaptor_base
|
||||
//! scoped_allocator_adaptor is derived from the outer allocator type so it can be
|
||||
//! substituted for the outer allocator type in most expressions. -end note]
|
||||
//!
|
||||
//! In the construct member functions, `OUTERMOST(x)` is x if x does not have
|
||||
//! an `outer_allocator()` member function and
|
||||
//! `OUTERMOST(x.outer_allocator())` otherwise; `OUTERMOST_ALLOC_TRAITS(x)` is
|
||||
//! `allocator_traits<decltype(OUTERMOST(x))>`.
|
||||
//! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
|
||||
//! an <code>outer_allocator()</code> member function and
|
||||
//! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
|
||||
//! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
|
||||
//!
|
||||
//! [<b>Note</b>: `OUTERMOST(x)` and
|
||||
//! `OUTERMOST_ALLOC_TRAITS(x)` are recursive operations. It is incumbent upon
|
||||
//! the definition of `outer_allocator()` to ensure that the recursion terminates.
|
||||
//! [<b>Note</b>: <code>OUTERMOST(x)</code> and
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
|
||||
//! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
|
||||
//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
|
||||
template <typename OuterAlloc, typename ...InnerAllocs>
|
||||
class scoped_allocator_adaptor
|
||||
@@ -1076,7 +1076,7 @@ class scoped_allocator_adaptor
|
||||
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
|
||||
|
||||
public:
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef container_detail::scoped_allocator_adaptor_base
|
||||
<OuterAlloc
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -1086,13 +1086,13 @@ class scoped_allocator_adaptor
|
||||
#endif
|
||||
> base_type;
|
||||
typedef typename base_type::internal_type_t internal_type_t;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef OuterAlloc outer_allocator_type;
|
||||
//! Type: For exposition only
|
||||
//!
|
||||
typedef allocator_traits<OuterAlloc> outer_traits_type;
|
||||
//! Type: `scoped_allocator_adaptor<OuterAlloc>` if `sizeof...(InnerAllocs)` is zero; otherwise,
|
||||
//! `scoped_allocator_adaptor<InnerAllocs...>`.
|
||||
//! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
|
||||
//! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
|
||||
typedef typename base_type::inner_allocator_type inner_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef typename outer_traits_type::value_type value_type;
|
||||
@@ -1102,23 +1102,23 @@ class scoped_allocator_adaptor
|
||||
typedef typename outer_traits_type::const_pointer const_pointer;
|
||||
typedef typename outer_traits_type::void_pointer void_pointer;
|
||||
typedef typename outer_traits_type::const_void_pointer const_void_pointer;
|
||||
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value` is
|
||||
//! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
|
||||
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_copy_assignment::value</code> is
|
||||
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
|
||||
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_move_assignment::value` is
|
||||
//! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
|
||||
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_move_assignment::value</code> is
|
||||
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_move_assignment propagate_on_container_move_assignment;
|
||||
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_swap::value` is true for any
|
||||
//! `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
|
||||
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_swap::value</code> is true for any
|
||||
//! <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_swap propagate_on_container_swap;
|
||||
|
||||
//! Type: Rebinds scoped allocator to
|
||||
//! `typedef scoped_allocator_adaptor
|
||||
//! <code>typedef scoped_allocator_adaptor
|
||||
//! < typename outer_traits_type::template portable_rebind_alloc<U>::type
|
||||
//! , InnerAllocs... >`
|
||||
//! , InnerAllocs... ></code>
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
@@ -1224,55 +1224,55 @@ class scoped_allocator_adaptor
|
||||
friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `static_cast<OuterAlloc&>(*this)`.
|
||||
outer_allocator_type & outer_allocator();
|
||||
//! <code>static_cast<OuterAlloc&>(*this)</code>.
|
||||
outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `static_cast<const OuterAlloc&>(*this)`.
|
||||
const outer_allocator_type &outer_allocator() const;
|
||||
//! <code>static_cast<const OuterAlloc&>(*this)</code>.
|
||||
const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
|
||||
inner_allocator_type& inner_allocator();
|
||||
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
||||
inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
|
||||
inner_allocator_type const& inner_allocator() const;
|
||||
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
||||
inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT;
|
||||
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `allocator_traits<OuterAlloc>::max_size(outer_allocator())`.
|
||||
size_type max_size() const
|
||||
//! <code>allocator_traits<OuterAlloc>::max_size(outer_allocator())</code>.
|
||||
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
return outer_traits_type::max_size(this->outer_allocator());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! calls `OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)`.
|
||||
//! calls <code>OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)</code>.
|
||||
template <class T>
|
||||
void destroy(T* p)
|
||||
void destroy(T* p) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
allocator_traits<typename outermost_allocator<OuterAlloc>::type>
|
||||
::destroy(get_outermost_allocator(this->outer_allocator()), p);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)`.
|
||||
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
|
||||
pointer allocate(size_type n)
|
||||
{
|
||||
return outer_traits_type::allocate(this->outer_allocator(), n);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)`.
|
||||
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
|
||||
pointer allocate(size_type n, const_void_pointer hint)
|
||||
{
|
||||
return outer_traits_type::allocate(this->outer_allocator(), n, hint);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! `allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)`.
|
||||
//! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
outer_traits_type::deallocate(this->outer_allocator(), p, n);
|
||||
@@ -1281,45 +1281,45 @@ class scoped_allocator_adaptor
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator
|
||||
//! A in the adaptor is initialized from the result of calling
|
||||
//! `allocator_traits<Allocator>::select_on_container_copy_construction()` on
|
||||
//! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
|
||||
//! the corresponding allocator in *this.
|
||||
scoped_allocator_adaptor select_on_container_copy_construction() const;
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
base_type &base() { return *this; }
|
||||
|
||||
const base_type &base() const { return *this; }
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! 1) If `uses_allocator<T, inner_allocator_type>::value` is false calls
|
||||
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct
|
||||
//! (OUTERMOST(*this), p, std::forward<Args>(args)...)`.
|
||||
//! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct
|
||||
//! (OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
|
||||
//!
|
||||
//! 2) Otherwise, if `uses_allocator<T, inner_allocator_type>::value` is true and
|
||||
//! `is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value` is true, calls
|
||||
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
|
||||
//! inner_allocator(), std::forward<Args>(args)...)`.
|
||||
//! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
|
||||
//! <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value</code> is true, calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
|
||||
//! inner_allocator(), std::forward<Args>(args)...)</code>.
|
||||
//!
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, `is_constructible` can't
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
|
||||
//! be implemented so that condition will be replaced by
|
||||
//! constructible_with_allocator_prefix<T>::value. -end note]
|
||||
//!
|
||||
//! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
|
||||
//! `is_constructible<T, Args..., inner_allocator_type>::value` is true, calls
|
||||
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p,
|
||||
//! std::forward<Args>(args)..., inner_allocator())`.
|
||||
//! <code>is_constructible<T, Args..., inner_allocator_type>::value</code> is true, calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p,
|
||||
//! std::forward<Args>(args)..., inner_allocator())</code>.
|
||||
//!
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, `is_constructible` can't be
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
|
||||
//! implemented so that condition will be replaced by
|
||||
//! `constructible_with_allocator_suffix<T>::value`. -end note]
|
||||
//! <code>constructible_with_allocator_suffix<T>::value</code>. -end note]
|
||||
//!
|
||||
//! 4) Otherwise, the program is ill-formed.
|
||||
//!
|
||||
//! [<b>Note</b>: An error will result if `uses_allocator` evaluates
|
||||
//! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
|
||||
//! to true but the specific constructor does not take an allocator. This definition prevents a silent
|
||||
//! failure to pass an inner allocator to a contained element. -end note]
|
||||
template < typename T, class ...Args>
|
||||
@@ -1395,7 +1395,7 @@ class scoped_allocator_adaptor
|
||||
, BOOST_RV_REF_BEG container_detail::pair<U, V> BOOST_RV_REF_END x)
|
||||
{ this->construct_pair(p, x); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
template <class Pair>
|
||||
void construct_pair(Pair* p)
|
||||
@@ -1463,7 +1463,7 @@ class scoped_allocator_adaptor
|
||||
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
|
||||
{}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <typename OuterA1, typename OuterA2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares boost::container::scoped_allocator_adaptor
|
||||
//! and defines the following types:
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
@@ -25,7 +29,7 @@
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
@@ -55,7 +59,7 @@ class scoped_allocator_adaptor;
|
||||
|
||||
#endif
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The allocator_arg_t struct is an empty structure type used as a unique type to
|
||||
//! disambiguate constructor and function overloading. Specifically, several types
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-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)
|
||||
//
|
||||
@@ -48,7 +48,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class T, class Allocator>
|
||||
class slist;
|
||||
@@ -106,7 +106,7 @@ struct intrusive_slist_type
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! An slist is a singly linked list: a list where each element is linked to the next
|
||||
//! element, but not to the previous element. That is, it is a Sequence that
|
||||
@@ -140,6 +140,9 @@ struct intrusive_slist_type
|
||||
//! possible. If you find that insert_after and erase_after aren't adequate for your
|
||||
//! needs, and that you often need to use insert and erase in the middle of the list,
|
||||
//! then you should probably use list instead of slist.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the list
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
@@ -149,7 +152,7 @@ class slist
|
||||
: protected container_detail::node_alloc_holder
|
||||
<Allocator, typename container_detail::intrusive_slist_type<Allocator>::type>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef typename
|
||||
container_detail::intrusive_slist_type<Allocator>::type Icont;
|
||||
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
|
||||
@@ -195,7 +198,7 @@ class slist
|
||||
BOOST_COPYABLE_AND_MOVABLE(slist)
|
||||
typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
|
||||
typedef container_detail::iterator<typename Icont::iterator, true > const_iterator_impl;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -313,7 +316,7 @@ class slist
|
||||
this->icont().swap(x.icont());
|
||||
}
|
||||
else{
|
||||
this->insert(this->cbegin(), x.begin(), x.end());
|
||||
this->insert_after(this->cbefore_begin(), x.begin(), x.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1423,14 +1426,70 @@ class slist
|
||||
void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
|
||||
{ this->splice(p, static_cast<slist&>(x), first, last); }
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const slist& x, const slist& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename slist<T,Allocator>::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2){
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const slist& x, const slist& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const slist& x, const slist& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const slist& x, const slist& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const slist& x, const slist& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const slist& x, const slist& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(slist& x, slist& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
void priv_push_front (const T &x)
|
||||
{ this->insert(this->cbegin(), x); }
|
||||
{ this->insert_after(this->cbefore_begin(), x); }
|
||||
|
||||
void priv_push_front (BOOST_RV_REF(T) x)
|
||||
{ this->insert(this->cbegin(), ::boost::move(x)); }
|
||||
{ this->insert_after(this->cbefore_begin(), ::boost::move(x)); }
|
||||
|
||||
bool priv_try_shrink(size_type new_size, const_iterator &last_pos)
|
||||
{
|
||||
@@ -1505,63 +1564,12 @@ class slist
|
||||
|
||||
const value_type &m_ref;
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator==(const slist<T,Allocator>& x, const slist<T,Allocator>& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
return false;
|
||||
}
|
||||
typedef typename slist<T,Allocator>::const_iterator const_iterator;
|
||||
const_iterator end1 = x.end();
|
||||
|
||||
const_iterator i1 = x.begin();
|
||||
const_iterator i2 = y.begin();
|
||||
while (i1 != end1 && *i1 == *i2){
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator<(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{
|
||||
return std::lexicographical_compare
|
||||
(sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator!=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return !(sL1 == sL2); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator>(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return sL2 < sL1; }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator<=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return !(sL2 < sL1); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline bool
|
||||
operator>=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
|
||||
{ return !(sL1 < sL2); }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline void swap(slist<T,Allocator>& x, slist<T,Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1574,14 +1582,14 @@ struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
|
||||
|
||||
namespace container {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}} //namespace boost{ namespace container {
|
||||
|
||||
// Specialization of insert_iterator so that insertions will be constant
|
||||
// time rather than linear time.
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//Ummm, I don't like to define things in namespace std, but
|
||||
//there is no other way
|
||||
@@ -1620,7 +1628,7 @@ class insert_iterator<boost::container::slist<T, Allocator> >
|
||||
|
||||
} //namespace std;
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -47,18 +47,18 @@
|
||||
#include <memory>
|
||||
#include <new> //placement new
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
|
||||
//#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
|
||||
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace stable_vector_detail{
|
||||
|
||||
@@ -393,7 +393,7 @@ struct index_traits
|
||||
|
||||
#endif //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector
|
||||
//! drop-in replacement implemented as a node container, offering iterator and reference
|
||||
@@ -426,6 +426,9 @@ struct index_traits
|
||||
//!
|
||||
//! Exception safety: As stable_vector does not internally copy elements around, some
|
||||
//! operations provide stronger exception safety guarantees than in std::vector.
|
||||
//!
|
||||
//! \tparam T The type of object that is stored in the stable_vector
|
||||
//! \tparam Allocator The allocator used for all internal memory management
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class Allocator = std::allocator<T> >
|
||||
#else
|
||||
@@ -433,7 +436,7 @@ template <class T, class Allocator>
|
||||
#endif
|
||||
class stable_vector
|
||||
{
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef boost::intrusive::
|
||||
pointer_traits
|
||||
@@ -504,7 +507,7 @@ class stable_vector
|
||||
typedef stable_vector_detail::iterator
|
||||
< typename allocator_traits<Allocator>::pointer
|
||||
, false> const_iterator_impl;
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////
|
||||
@@ -526,7 +529,7 @@ class stable_vector
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
|
||||
|
||||
///@cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(stable_vector)
|
||||
static const size_type ExtraPointers = index_traits_type::ExtraPointers;
|
||||
@@ -536,7 +539,7 @@ class stable_vector
|
||||
|
||||
class push_back_rollback;
|
||||
friend class push_back_rollback;
|
||||
///@endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -1510,8 +1513,49 @@ class stable_vector
|
||||
void clear() BOOST_CONTAINER_NOEXCEPT
|
||||
{ this->erase(this->cbegin(),this->cend()); }
|
||||
|
||||
/// @cond
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const stable_vector& x, const stable_vector& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const stable_vector& x, const stable_vector& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const stable_vector& x, const stable_vector& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const stable_vector& x, const stable_vector& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const stable_vector& x, const stable_vector& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const stable_vector& x, const stable_vector& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(stable_vector& x, stable_vector& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
class insert_rollback
|
||||
@@ -1836,58 +1880,14 @@ class stable_vector
|
||||
const node_allocator_type &priv_node_alloc() const { return internal_data; }
|
||||
|
||||
index_type index;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator==(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator< (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator!=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return !(x==y);
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator> (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return y<x;
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator>=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return !(x<y);
|
||||
}
|
||||
|
||||
template <typename T,typename Allocator>
|
||||
bool operator<=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
|
||||
{
|
||||
return !(x>y);
|
||||
}
|
||||
|
||||
// specialized algorithms:
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
void swap(stable_vector<T,Allocator>& x,stable_vector<T,Allocator>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#undef STABLE_VECTOR_CHECK_INVARIANT
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<class T, std::size_t N>
|
||||
@@ -61,46 +63,46 @@ class static_storage_allocator
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
/**
|
||||
* @defgroup static_vector_non_member static_vector non-member functions
|
||||
*/
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
/**
|
||||
* @brief A variable-size array container with fixed capacity.
|
||||
*
|
||||
* static_vector is a sequence container like boost::container::vector with contiguous storage that can
|
||||
* change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
|
||||
*
|
||||
* A static_vector is a sequence that supports random access to elements, constant time insertion and
|
||||
* removal of elements at the end, and linear time insertion and removal of elements at the beginning or
|
||||
* in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
|
||||
* because elements are stored within the object itself similarly to an array. However, objects are
|
||||
* initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
|
||||
* all elements on instantiation. The behavior of static_vector enables the use of statically allocated
|
||||
* elements in cases with complex object lifetime requirements that would otherwise not be trivially
|
||||
* possible.
|
||||
*
|
||||
* @par Error Handling
|
||||
* Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
|
||||
* calling throw_bad_alloc() if not enabled.
|
||||
*
|
||||
* std::out_of_range is thrown if out of bound access is performed in `at()` if exceptions are
|
||||
* enabled, throw_out_of_range() if not enabled.
|
||||
*
|
||||
* @tparam Value The type of element that will be stored.
|
||||
* @tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
|
||||
*/
|
||||
//!
|
||||
//!@brief A variable-size array container with fixed capacity.
|
||||
//!
|
||||
//!static_vector is a sequence container like boost::container::vector with contiguous storage that can
|
||||
//!change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
|
||||
//!
|
||||
//!A static_vector is a sequence that supports random access to elements, constant time insertion and
|
||||
//!removal of elements at the end, and linear time insertion and removal of elements at the beginning or
|
||||
//!in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
|
||||
//!because elements are stored within the object itself similarly to an array. However, objects are
|
||||
//!initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
|
||||
//!all elements on instantiation. The behavior of static_vector enables the use of statically allocated
|
||||
//!elements in cases with complex object lifetime requirements that would otherwise not be trivially
|
||||
//!possible.
|
||||
//!
|
||||
//!@par Error Handling
|
||||
//! Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
|
||||
//! calling throw_bad_alloc() if not enabled.
|
||||
//!
|
||||
//! std::out_of_range is thrown if out of bound access is performed in <code>at()</code> if exceptions are
|
||||
//! enabled, throw_out_of_range() if not enabled.
|
||||
//!
|
||||
//!@tparam Value The type of element that will be stored.
|
||||
//!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
|
||||
template <typename Value, std::size_t Capacity>
|
||||
class static_vector
|
||||
: public vector<Value, container_detail::static_storage_allocator<Value, Capacity> >
|
||||
{
|
||||
typedef vector<Value, container_detail::static_storage_allocator<Value, Capacity> > base_t;
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef vector<Value, container_detail::static_storage_allocator<Value, Capacity> > base_t;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(static_vector)
|
||||
BOOST_COPYABLE_AND_MOVABLE(static_vector)
|
||||
|
||||
template<class U, std::size_t OtherCapacity>
|
||||
friend class static_vector;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//! @brief The type of elements stored in the container.
|
||||
typedef typename base_t::value_type value_type;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (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)
|
||||
//
|
||||
@@ -52,7 +52,7 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
namespace container_detail {
|
||||
// ------------------------------------------------------------
|
||||
// Class basic_string_base.
|
||||
@@ -268,7 +268,12 @@ class basic_string_base
|
||||
}
|
||||
|
||||
size_type next_capacity(size_type additional_objects) const
|
||||
{ return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects); }
|
||||
{
|
||||
return next_capacity_calculator
|
||||
<size_type, NextCapacityDouble /*NextCapacity60Percent*/>::
|
||||
get( allocator_traits_type::max_size(this->alloc())
|
||||
, this->priv_storage(), additional_objects );
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
@@ -433,7 +438,7 @@ class basic_string_base
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The basic_string class represents a Sequence of characters. It contains all the
|
||||
//! usual operations of a Sequence, and, additionally, it contains standard string
|
||||
@@ -463,6 +468,10 @@ class basic_string_base
|
||||
//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
|
||||
//! In this implementation, iterators are only invalidated by member functions that
|
||||
//! explicitly change the string's contents.
|
||||
//!
|
||||
//! \tparam CharT The type of character it contains.
|
||||
//! \tparam Traits The Character Traits type, which encapsulates basic character operations
|
||||
//! \tparam Allocator The allocator, used for internal memory management.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> >
|
||||
#else
|
||||
@@ -471,7 +480,7 @@ template <class CharT, class Traits, class Allocator>
|
||||
class basic_string
|
||||
: private container_detail::basic_string_base<Allocator>
|
||||
{
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(basic_string)
|
||||
@@ -483,19 +492,22 @@ class basic_string
|
||||
|
||||
template <class Tr>
|
||||
struct Eq_traits
|
||||
: public std::binary_function<typename Tr::char_type,
|
||||
typename Tr::char_type,
|
||||
bool>
|
||||
{
|
||||
bool operator()(const typename Tr::char_type& x,
|
||||
const typename Tr::char_type& y) const
|
||||
//Compatibility with std::binary_function
|
||||
typedef typename Tr::char_type first_argument_type;
|
||||
typedef typename Tr::char_type second_argument_type;
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(const first_argument_type& x, const second_argument_type& y) const
|
||||
{ return Tr::eq(x, y); }
|
||||
};
|
||||
|
||||
template <class Tr>
|
||||
struct Not_within_traits
|
||||
: public std::unary_function<typename Tr::char_type, bool>
|
||||
{
|
||||
typedef typename Tr::char_type argument_type;
|
||||
typedef bool result_type;
|
||||
|
||||
typedef const typename Tr::char_type* Pointer;
|
||||
const Pointer m_first;
|
||||
const Pointer m_last;
|
||||
@@ -509,7 +521,7 @@ class basic_string
|
||||
std::bind1st(Eq_traits<Tr>(), x)) == m_last;
|
||||
}
|
||||
};
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -533,14 +545,14 @@ class basic_string
|
||||
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
|
||||
static const size_type npos = size_type(-1);
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
typedef constant_iterator<CharT, difference_type> cvalue_iterator;
|
||||
typedef typename base_t::allocator_v1 allocator_v1;
|
||||
typedef typename base_t::allocator_v2 allocator_v2;
|
||||
typedef typename base_t::alloc_version alloc_version;
|
||||
typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public: // Constructor, destructor, assignment.
|
||||
//////////////////////////////////////////////
|
||||
@@ -548,7 +560,7 @@ class basic_string
|
||||
// construct/copy/destroy
|
||||
//
|
||||
//////////////////////////////////////////////
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
struct reserve_t {};
|
||||
|
||||
basic_string(reserve_t, size_type n,
|
||||
@@ -559,7 +571,7 @@ class basic_string
|
||||
, n + 1)
|
||||
{ this->priv_terminate_string(); }
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Effects</b>: Default constructs a basic_string.
|
||||
//!
|
||||
@@ -668,6 +680,15 @@ class basic_string
|
||||
this->assign(n, c);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and is initialized by n default-initialized characters.
|
||||
basic_string(size_type n, default_init_t, const allocator_type& a = allocator_type())
|
||||
: base_t(a, n + 1)
|
||||
{
|
||||
this->priv_size(n);
|
||||
this->priv_terminate_string();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and a range of iterators.
|
||||
template <class InputIterator>
|
||||
@@ -945,6 +966,26 @@ class basic_string
|
||||
void resize(size_type n)
|
||||
{ resize(n, CharT()); }
|
||||
|
||||
|
||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||
//! the size becomes n. New elements are uninitialized.
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
void resize(size_type n, default_init_t)
|
||||
{
|
||||
if (n <= this->size())
|
||||
this->erase(this->begin() + n, this->end());
|
||||
else{
|
||||
this->priv_reserve(n, false);
|
||||
this->priv_size(n);
|
||||
this->priv_terminate_string();
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Number of elements for which memory has been allocated.
|
||||
//! capacity() is always greater than or equal to size().
|
||||
//!
|
||||
@@ -961,29 +1002,7 @@ class basic_string
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation allocation throws
|
||||
void reserve(size_type res_arg)
|
||||
{
|
||||
if (res_arg > this->max_size()){
|
||||
throw_length_error("basic_string::reserve max_size() exceeded");
|
||||
}
|
||||
|
||||
if (this->capacity() < res_arg){
|
||||
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
|
||||
size_type new_cap = this->next_capacity(n);
|
||||
pointer new_start = this->allocation_command
|
||||
(allocate_new, n, new_cap, new_cap).first;
|
||||
size_type new_length = 0;
|
||||
|
||||
const pointer addr = this->priv_addr();
|
||||
new_length += priv_uninitialized_copy
|
||||
(addr, addr + this->priv_size(), new_start);
|
||||
this->priv_construct_null(new_start + new_length);
|
||||
this->deallocate_block();
|
||||
this->is_short(false);
|
||||
this->priv_long_addr(new_start);
|
||||
this->priv_long_size(new_length);
|
||||
this->priv_storage(new_cap);
|
||||
}
|
||||
}
|
||||
{ this->priv_reserve(res_arg); }
|
||||
|
||||
//! <b>Effects</b>: Tries to deallocate the excess of memory created
|
||||
//! with previous allocations. The size of the string is unchanged
|
||||
@@ -1228,6 +1247,20 @@ class basic_string
|
||||
basic_string& assign(size_type n, CharT c)
|
||||
{ return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
|
||||
|
||||
//! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& assign(const CharT* first, const CharT* last)
|
||||
{
|
||||
size_type n = static_cast<size_type>(last - first);
|
||||
this->reserve(n);
|
||||
CharT* ptr = container_detail::to_raw_pointer(this->priv_addr());
|
||||
Traits::copy(ptr, first, n);
|
||||
this->priv_construct_null(ptr + n);
|
||||
this->priv_size(n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
@@ -2296,8 +2329,35 @@ class basic_string
|
||||
int compare(size_type pos1, size_type n1, const CharT* s) const
|
||||
{ return this->compare(pos1, n1, s, Traits::length(s)); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
void priv_reserve(size_type res_arg, const bool null_terminate = true)
|
||||
{
|
||||
if (res_arg > this->max_size()){
|
||||
throw_length_error("basic_string::reserve max_size() exceeded");
|
||||
}
|
||||
|
||||
if (this->capacity() < res_arg){
|
||||
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
|
||||
size_type new_cap = this->next_capacity(n);
|
||||
pointer new_start = this->allocation_command
|
||||
(allocate_new, n, new_cap, new_cap).first;
|
||||
size_type new_length = 0;
|
||||
|
||||
const pointer addr = this->priv_addr();
|
||||
new_length += priv_uninitialized_copy
|
||||
(addr, addr + this->priv_size(), new_start);
|
||||
if(null_terminate){
|
||||
this->priv_construct_null(new_start + new_length);
|
||||
}
|
||||
this->deallocate_block();
|
||||
this->is_short(false);
|
||||
this->priv_long_addr(new_start);
|
||||
this->priv_long_size(new_length);
|
||||
this->priv_storage(new_cap);
|
||||
}
|
||||
}
|
||||
|
||||
static int s_compare(const_pointer f1, const_pointer l1,
|
||||
const_pointer f2, const_pointer l2)
|
||||
{
|
||||
@@ -2431,9 +2491,11 @@ class basic_string
|
||||
return this->priv_replace(first, last, f, l, Category());
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!Typedef for a basic_string of
|
||||
//!narrow characters
|
||||
typedef basic_string
|
||||
@@ -2450,6 +2512,8 @@ typedef basic_string
|
||||
,std::allocator<wchar_t> >
|
||||
wstring;
|
||||
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Non-member functions.
|
||||
|
||||
@@ -2663,7 +2727,7 @@ template <class CharT, class Traits, class Allocator>
|
||||
inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
// I/O.
|
||||
namespace container_detail {
|
||||
|
||||
@@ -2683,7 +2747,7 @@ string_fill(std::basic_ostream<CharT, Traits>& os,
|
||||
}
|
||||
|
||||
} //namespace container_detail {
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
@@ -2814,7 +2878,7 @@ inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator>
|
||||
|
||||
}}
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -2827,7 +2891,7 @@ struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Al
|
||||
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -76,26 +76,82 @@ namespace container {
|
||||
|
||||
#else //defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
//! Exception callback called by Boost.Container when fails to allocate the requested storage space.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::bad_alloc()</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_bad_alloc()
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal arguments out of range.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::out_of_range(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_out_of_range(const char* str)
|
||||
{
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal errors resizing.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::length_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_length_error(const char* str)
|
||||
{
|
||||
throw std::length_error(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors in the internal logical
|
||||
//! of the program, such as violation of logical preconditions or class invariants.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::logic_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_logic_error(const char* str)
|
||||
{
|
||||
throw std::logic_error(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors that can only be detected during runtime.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::runtime_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_runtime_error(const char* str)
|
||||
{
|
||||
throw std::runtime_error(str);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user