Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. 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_CONTAINERS_CONTAINERS_FWD_HPP
#define BOOST_CONTAINERS_CONTAINERS_FWD_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
//////////////////////////////////////////////////////////////////////////////
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
/// @cond
namespace boost{
namespace intrusive{
//Create namespace to avoid compilation errors
}}
namespace boost{ namespace interprocess_container{ namespace containers_detail{
namespace bi = boost::intrusive;
}}}
namespace std {
template <class T>
class allocator;
template <class T>
struct less;
template <class T1, class T2>
struct pair;
template <class CharType>
struct char_traits;
} //namespace std {
/// @endcond
//////////////////////////////////////////////////////////////////////////////
// Containers
//////////////////////////////////////////////////////////////////////////////
#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
namespace boost {
namespace interprocess {
#else
namespace boost {
namespace interprocess_container {
#endif
//vector class
template <class T
,class A = std::allocator<T> >
class vector;
//vector class
template <class T
,class A = std::allocator<T> >
class deque;
//list class
template <class T
,class A = std::allocator<T> >
class list;
//slist class
template <class T
,class Alloc = std::allocator<T> >
class slist;
//set class
template <class T
,class Pred = std::less<T>
,class Alloc = std::allocator<T> >
class set;
//multiset class
template <class T
,class Pred = std::less<T>
,class Alloc = std::allocator<T> >
class multiset;
//map class
template <class Key
,class T
,class Pred = std::less<Key>
,class Alloc = std::allocator<std::pair<const Key, T> > >
class map;
//multimap class
template <class Key
,class T
,class Pred = std::less<Key>
,class Alloc = std::allocator<std::pair<const Key, T> > >
class multimap;
//flat_set class
template <class T
,class Pred = std::less<T>
,class Alloc = std::allocator<T> >
class flat_set;
//flat_multiset class
template <class T
,class Pred = std::less<T>
,class Alloc = std::allocator<T> >
class flat_multiset;
//flat_map class
template <class Key
,class T
,class Pred = std::less<Key>
,class Alloc = std::allocator<std::pair<Key, T> > >
class flat_map;
//flat_multimap class
template <class Key
,class T
,class Pred = std::less<Key>
,class Alloc = std::allocator<std::pair<Key, T> > >
class flat_multimap;
//basic_string class
template <class CharT
,class Traits = std::char_traits<CharT>
,class Alloc = std::allocator<CharT> >
class basic_string;
//string class
typedef basic_string
<char
,std::char_traits<char>
,std::allocator<char> >
string;
}} //namespace boost { namespace interprocess_container {
#endif //#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,386 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2008. 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_CONTAINERS_ADVANCED_INSERT_INT_HPP
#define BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <iterator> //std::iterator_traits
#include <algorithm> //std::copy, std::uninitialized_copy
#include <new> //placement new
#include <cassert>
namespace boost { namespace interprocess_container { namespace containers_detail {
//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
template<class T, class Iterator>
struct advanced_insert_aux_int
{
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
virtual void copy_all_to(Iterator p) = 0;
virtual void uninitialized_copy_all_to(Iterator p) = 0;
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
virtual ~advanced_insert_aux_int() {}
};
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class FwdIt, class Iterator>
struct advanced_insert_aux_proxy
: public advanced_insert_aux_int<T, Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
advanced_insert_aux_proxy(FwdIt first, FwdIt last)
: first_(first), last_(last)
{}
virtual ~advanced_insert_aux_proxy()
{}
virtual void copy_all_to(Iterator p)
{ std::copy(first_, last_, p); }
virtual void uninitialized_copy_all_to(Iterator p)
{ boost::interprocess::uninitialized_copy_or_move(first_, last_, p); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
FwdIt mid = first_;
std::advance(mid, division_count);
if(first_n){
boost::interprocess::uninitialized_copy_or_move(first_, mid, pos);
first_ = mid;
}
else{
boost::interprocess::uninitialized_copy_or_move(mid, last_, pos);
last_ = mid;
}
}
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
FwdIt mid = first_;
std::advance(mid, division_count);
if(first_n){
std::copy(first_, mid, pos);
first_ = mid;
}
else{
std::copy(mid, last_, pos);
last_ = mid;
}
}
FwdIt first_, last_;
};
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class Iterator, class SizeType>
struct default_construct_aux_proxy
: public advanced_insert_aux_int<T, Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
default_construct_aux_proxy(SizeType count)
: count_(count)
{}
void uninitialized_copy_impl(Iterator p, const SizeType n)
{
assert(n <= count_);
Iterator orig_p = p;
SizeType i = 0;
try{
for(; i < n; ++i, ++p){
new(containers_detail::get_pointer(&*p))T();
}
}
catch(...){
while(i--){
containers_detail::get_pointer(&*orig_p++)->~T();
}
throw;
}
count_ -= n;
}
virtual ~default_construct_aux_proxy()
{}
virtual void copy_all_to(Iterator)
{ //This should never be called with any count
assert(count_ == 0);
}
virtual void uninitialized_copy_all_to(Iterator p)
{ this->uninitialized_copy_impl(p, count_); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
SizeType new_count;
if(first_n){
new_count = division_count;
}
else{
assert(difference_type(count_)>= division_count);
new_count = count_ - division_count;
}
this->uninitialized_copy_impl(pos, new_count);
}
virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
{
assert(count_ == 0);
SizeType new_count;
if(first_n){
new_count = division_count;
}
else{
assert(difference_type(count_)>= division_count);
new_count = count_ - division_count;
}
//This function should never called with a count different to zero
assert(new_count == 0);
(void)new_count;
}
SizeType count_;
};
}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#include <boost/interprocess/containers/container/detail/variadic_templates_tools.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <typeinfo>
//#include <iostream> //For debugging purposes
namespace boost {
namespace interprocess_container {
namespace containers_detail {
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class Iterator, class ...Args>
struct advanced_insert_aux_emplace
: public advanced_insert_aux_int<T, Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
advanced_insert_aux_emplace(Args&&... args)
: args_(args...), used_(false)
{}
~advanced_insert_aux_emplace()
{}
virtual void copy_all_to(Iterator p)
{ this->priv_copy_all_to(index_tuple_t(), p); }
virtual void uninitialized_copy_all_to(Iterator p)
{ this->priv_uninitialized_copy_all_to(index_tuple_t(), p); }
virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{ this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{ this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
private:
template<int ...IdxPack>
void priv_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!used_){
T object(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
*p = boost::interprocess::move(object);
used_ = true;
}
}
template<int ...IdxPack>
void priv_uninitialized_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!used_){
new(containers_detail::get_pointer(&*p))T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
used_ = true;
}
}
template<int ...IdxPack>
void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
{
assert(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
new(containers_detail::get_pointer(&*p))T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
used_ = true;
}
}
}
template<int ...IdxPack>
void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
{
assert(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
T object(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
*p = boost::interprocess::move(object);
used_ = true;
}
}
}
tuple<Args&&...> args_;
bool used_;
};
}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
#include <boost/interprocess/containers/container/detail/value_init.hpp>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class Iterator>
struct advanced_insert_aux_emplace
: public advanced_insert_aux_int<T, Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
advanced_insert_aux_emplace()
: used_(false)
{}
~advanced_insert_aux_emplace()
{}
virtual void copy_all_to(Iterator p)
{
if(!used_){
value_init<T>v;
*p = boost::interprocess::move(v.m_t);
used_ = true;
}
}
virtual void uninitialized_copy_all_to(Iterator p)
{
if(!used_){
new(containers_detail::get_pointer(&*p))T();
used_ = true;
}
}
virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{
assert(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
new(containers_detail::get_pointer(&*p))T();
used_ = true;
}
}
}
virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{
assert(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
value_init<T>v;
*p = boost::interprocess::move(v.m_t);
used_ = true;
}
}
}
private:
bool used_;
};
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T, class Iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
: public advanced_insert_aux_int<T, Iterator> \
{ \
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type; \
\
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
: used_(false), BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
\
virtual void copy_all_to(Iterator p) \
{ \
if(!used_){ \
T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
*p = boost::interprocess::move(v); \
used_ = true; \
} \
} \
\
virtual void uninitialized_copy_all_to(Iterator p) \
{ \
if(!used_){ \
new(containers_detail::get_pointer(&*p))T \
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
used_ = true; \
} \
} \
\
virtual void uninitialized_copy_some_and_update \
(Iterator p, difference_type division_count, bool first_n) \
{ \
assert(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!used_){ \
new(containers_detail::get_pointer(&*p))T \
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
used_ = true; \
} \
} \
} \
\
virtual void copy_some_and_update \
(Iterator p, difference_type division_count, bool first_n) \
{ \
assert(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!used_){ \
T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
*p = boost::interprocess::move(v); \
used_ = true; \
} \
} \
} \
\
bool used_; \
BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP

View File

@@ -0,0 +1,215 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008.
//
// 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_CONTAINERS_DETAIL_ALGORITHMS_HPP
#define BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/get_pointer.hpp>
#include <boost/interprocess/containers/container/detail/type_traits.hpp>
#include <boost/interprocess/containers/container/detail/mpl.hpp>
#include <boost/interprocess/containers/container/detail/iterators.hpp>
#include <cstring>
namespace boost {
namespace interprocess_container {
#if !defined(BOOST_HAS_RVALUE_REFS)
template<class T>
struct has_own_construct_from_it
{
static const bool value = false;
};
namespace containers_detail {
template<class T, class InpIt>
inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::true_)
{
T::construct(dest, *source);
}
template<class T, class InpIt>
inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::false_)
{
new((void*)dest)T(*source);
}
} //namespace containers_detail {
template<class T, class InpIt>
inline void construct_in_place(T* dest, InpIt source)
{
typedef containers_detail::bool_<has_own_construct_from_it<T>::value> boolean_t;
containers_detail::construct_in_place_impl(dest, source, boolean_t());
}
#else
template<class T, class InpIt>
inline void construct_in_place(T* dest, InpIt source)
{ ::new((void*)dest)T(*source); }
#endif
template<class T, class U, class D>
inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
{
::new((void*)dest)T();
}
template<class T, class U, class E>
inline void construct_in_place(T *dest, emplace_iterator<U, E> ei)
{
ei.construct_in_place(dest);
}
template<class InIt, class OutIt>
struct optimize_assign
{
static const bool value = false;
};
template<class T>
struct optimize_assign<const T*, T*>
{
static const bool value = boost::has_trivial_assign<T>::value;
};
template<class T>
struct optimize_assign<T*, T*>
: public optimize_assign<const T*, T*>
{};
template<class InIt, class OutIt>
struct optimize_copy
{
static const bool value = false;
};
template<class T>
struct optimize_copy<const T*, T*>
{
static const bool value = boost::has_trivial_copy<T>::value;
};
template<class T>
struct optimize_copy<T*, T*>
: public optimize_copy<const T*, T*>
{};
template<class InIt, class OutIt> inline
OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, containers_detail::bool_<false>)
{
for (; length--; ++dest, ++first)
*dest = *first;
return dest;
}
template<class T> inline
T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
{
std::size_t size = length*sizeof(T);
return (static_cast<T*>(std::memmove(dest, first, size))) + size;
}
template<class InIt, class OutIt> inline
OutIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
{
const bool do_optimized_assign = optimize_assign<InIt, OutIt>::value;
return copy_n_dispatch(first, length, dest, containers_detail::bool_<do_optimized_assign>());
}
template<class InIt, class FwdIt> inline
FwdIt uninitialized_copy_n_dispatch
(InIt first,
typename std::iterator_traits<InIt>::difference_type count,
FwdIt dest, containers_detail::bool_<false>)
{
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
//Save initial destination position
FwdIt dest_init = dest;
typename std::iterator_traits<InIt>::difference_type new_count = count+1;
BOOST_TRY{
//Try to build objects
for (; --new_count; ++dest, ++first){
construct_in_place(containers_detail::get_pointer(&*dest), first);
}
}
BOOST_CATCH(...){
//Call destructors
new_count = count - new_count;
for (; new_count--; ++dest_init){
containers_detail::get_pointer(&*dest_init)->~value_type();
}
BOOST_RETHROW
}
BOOST_CATCH_END
return dest;
}
template<class T> inline
T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
{
std::size_t size = length*sizeof(T);
return (static_cast<T*>(std::memmove(dest, first, size))) + size;
}
template<class InIt, class FwdIt> inline
FwdIt uninitialized_copy_n
(InIt first,
typename std::iterator_traits<InIt>::difference_type count,
FwdIt dest)
{
const bool do_optimized_copy = optimize_copy<InIt, FwdIt>::value;
return uninitialized_copy_n_dispatch(first, count, dest, containers_detail::bool_<do_optimized_copy>());
}
// uninitialized_copy_copy
// Copies [first1, last1) into [result, result + (last1 - first1)), and
// copies [first2, last2) into
// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
template <class InpIt1, class InpIt2, class FwdIt>
FwdIt uninitialized_copy_copy
(InpIt1 first1, InpIt1 last1, InpIt2 first2, InpIt2 last2, FwdIt result)
{
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
FwdIt mid = std::uninitialized_copy(first1, last1, result);
BOOST_TRY {
return std::uninitialized_copy(first2, last2, mid);
}
BOOST_CATCH(...){
for(;result != mid; ++result){
containers_detail::get_pointer(&*result)->~value_type();
}
BOOST_RETHROW
}
BOOST_CATCH_END
}
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP

View File

@@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. 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_CONTAINERS_ALLOCATION_TYPE_HPP
#define BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
namespace boost {
namespace interprocess_container {
/// @cond
enum allocation_type_v
{
// constants for allocation commands
allocate_new_v = 0x01,
expand_fwd_v = 0x02,
expand_bwd_v = 0x04,
// expand_both = expand_fwd | expand_bwd,
// expand_or_new = allocate_new | expand_both,
shrink_in_place_v = 0x08,
nothrow_allocation_v = 0x10,
zero_memory_v = 0x20,
try_shrink_in_place_v = 0x40
};
typedef int allocation_type;
/// @endcond
static const allocation_type allocate_new = (allocation_type)allocate_new_v;
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v;
static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
static const allocation_type zero_memory = (allocation_type)zero_memory_v;
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //BOOST_CONTAINERS_ALLOCATION_TYPE_HPP

View File

@@ -0,0 +1,47 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. 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_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
#define BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
#include <boost/config.hpp>
#endif
#ifdef BOOST_MSVC
#ifndef _CRT_SECURE_NO_DEPRECATE
#define BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#pragma warning (push)
#pragma warning (disable : 4702) // unreachable code
#pragma warning (disable : 4706) // assignment within conditional expression
#pragma warning (disable : 4127) // conditional expression is constant
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
#pragma warning (disable : 4284) // odd return type for operator->
#pragma warning (disable : 4244) // possible loss of data
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
#pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
#pragma warning (disable : 4355) // "this" : used in base member initializer list
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
#pragma warning (disable : 4511) // copy constructor could not be generated
#pragma warning (disable : 4512) // assignment operator could not be generated
#pragma warning (disable : 4514) // unreferenced inline removed
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
#pragma warning (disable : 4710) // function not inlined
#pragma warning (disable : 4711) // function selected for automatic inline expansion
#pragma warning (disable : 4786) // identifier truncated in debug info
#pragma warning (disable : 4996) // "function": was declared deprecated
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
#pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
// with /GR-; unpredictable behavior may result
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible
#endif

View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#if defined BOOST_MSVC
#pragma warning (pop)
#ifdef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
#undef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
#undef _CRT_SECURE_NO_DEPRECATE
#endif
#endif

View File

@@ -0,0 +1,154 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
#define BOOST_CONTAINERS_DESTROYERS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <boost/interprocess/containers/container/detail/version_type.hpp>
#include <boost/interprocess/containers/container/detail/utilities.hpp>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an array of objects using a STL allocator.
template <class Allocator>
struct scoped_array_deallocator
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::size_type size_type;
scoped_array_deallocator(pointer p, Allocator& a, size_type length)
: m_ptr(p), m_alloc(a), m_length(length) {}
~scoped_array_deallocator()
{ if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
void release()
{ m_ptr = 0; }
private:
pointer m_ptr;
Allocator& m_alloc;
size_type m_length;
};
template <class Allocator>
struct null_scoped_array_deallocator
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::size_type size_type;
null_scoped_array_deallocator(pointer, Allocator&, size_type)
{}
void release()
{}
};
//!A deleter for scoped_ptr that destroys
//!an object using a STL allocator.
template <class Allocator>
struct scoped_destructor_n
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::value_type value_type;
typedef typename Allocator::size_type size_type;
pointer m_p;
size_type m_n;
scoped_destructor_n(pointer p, size_type n)
: m_p(p), m_n(n)
{}
void release()
{ m_p = 0; }
void increment_size(size_type inc)
{ m_n += inc; }
~scoped_destructor_n()
{
if(!m_p) return;
value_type *raw_ptr = containers_detail::get_pointer(m_p);
for(std::size_t i = 0; i < m_n; ++i, ++raw_ptr)
raw_ptr->~value_type();
}
};
//!A deleter for scoped_ptr that destroys
//!an object using a STL allocator.
template <class Allocator>
struct null_scoped_destructor_n
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::size_type size_type;
null_scoped_destructor_n(pointer, size_type)
{}
void increment_size(size_type)
{}
void release()
{}
};
template <class A>
class allocator_destroyer
{
typedef typename A::value_type value_type;
typedef containers_detail::integral_constant<unsigned,
boost::interprocess_container::containers_detail::
version<A>::value> alloc_version;
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
private:
A & a_;
private:
void priv_deallocate(const typename A::pointer &p, allocator_v1)
{ a_.deallocate(p, 1); }
void priv_deallocate(const typename A::pointer &p, allocator_v2)
{ a_.deallocate_one(p); }
public:
allocator_destroyer(A &a)
: a_(a)
{}
void operator()(const typename A::pointer &p)
{
containers_detail::get_pointer(p)->~value_type();
priv_deallocate(p, alloc_version());
}
};
} //namespace containers_detail {
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DESTROYERS_HPP

View File

@@ -0,0 +1,837 @@
////////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
// The author or Addison-Welsey Longman make no representations about the
// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
///////////////////////////////////////////////////////////////////////////////
//
// Parts of this file come from AssocVector.h file from Loki library
//
////////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_FLAT_TREE_HPP
#define BOOST_CONTAINERS_FLAT_TREE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <algorithm>
#include <functional>
#include <utility>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/containers/container/detail/utilities.hpp>
#include <boost/interprocess/containers/container/detail/pair.hpp>
#include <boost/interprocess/containers/container/vector.hpp>
#include <boost/interprocess/containers/container/detail/value_init.hpp>
#include <boost/interprocess/containers/container/detail/destroyers.hpp>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
class flat_tree
{
typedef boost::interprocess_container::vector<Value, Alloc> vector_t;
typedef Alloc allocator_t;
public:
class value_compare
: private Compare
{
typedef Value first_argument_type;
typedef Value second_argument_type;
typedef bool return_type;
public:
value_compare(const Compare &pred)
: Compare(pred)
{}
bool operator()(const Value& lhs, const Value& rhs) const
{
KeyOfValue key_extract;
return Compare::operator()(key_extract(lhs), key_extract(rhs));
}
const Compare &get_comp() const
{ return *this; }
Compare &get_comp()
{ return *this; }
};
private:
struct Data
//Inherit from value_compare to do EBO
: public value_compare
{
public:
Data(const Compare &comp,
const vector_t &vect)
: value_compare(comp), m_vect(vect){}
Data(const value_compare &comp,
const vector_t &vect)
: value_compare(comp), m_vect(vect){}
Data(const Compare &comp,
const allocator_t &alloc)
: value_compare(comp), m_vect(alloc){}
public:
vector_t m_vect;
};
Data m_data;
public:
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_tree)
typedef typename vector_t::value_type value_type;
typedef typename vector_t::pointer pointer;
typedef typename vector_t::const_pointer const_pointer;
typedef typename vector_t::reference reference;
typedef typename vector_t::const_reference const_reference;
typedef Key key_type;
typedef Compare key_compare;
typedef typename vector_t::allocator_type allocator_type;
typedef allocator_type stored_allocator_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef typename vector_t::iterator iterator;
typedef typename vector_t::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// allocation/deallocation
flat_tree(const Compare& comp = Compare(),
const allocator_type& a = allocator_type())
: m_data(comp, a)
{ }
flat_tree(const flat_tree& x)
: m_data(x.m_data, x.m_data.m_vect)
{ }
flat_tree(BOOST_INTERPROCESS_RV_REF(flat_tree) x)
: m_data(boost::interprocess::move(x.m_data))
{ }
~flat_tree()
{ }
flat_tree& operator=(const flat_tree& x)
{ m_data = x.m_data; return *this; }
flat_tree& operator=(BOOST_INTERPROCESS_RV_REF(flat_tree) mx)
{ m_data = boost::interprocess::move(mx.m_data); return *this; }
public:
// accessors:
Compare key_comp() const
{ return this->m_data.get_comp(); }
allocator_type get_allocator() const
{ return this->m_data.m_vect.get_allocator(); }
const stored_allocator_type &get_stored_allocator() const
{ return this->m_data.m_vect.get_stored_allocator(); }
stored_allocator_type &get_stored_allocator()
{ return this->m_data.m_vect.get_stored_allocator(); }
iterator begin()
{ return this->m_data.m_vect.begin(); }
const_iterator begin() const
{ return this->cbegin(); }
const_iterator cbegin() const
{ return this->m_data.m_vect.begin(); }
iterator end()
{ return this->m_data.m_vect.end(); }
const_iterator end() const
{ return this->cend(); }
const_iterator cend() const
{ return this->m_data.m_vect.end(); }
reverse_iterator rbegin()
{ return reverse_iterator(this->end()); }
const_reverse_iterator rbegin() const
{ return this->crbegin(); }
const_reverse_iterator crbegin() const
{ return const_reverse_iterator(this->cend()); }
reverse_iterator rend()
{ return reverse_iterator(this->begin()); }
const_reverse_iterator rend() const
{ return this->crend(); }
const_reverse_iterator crend() const
{ return const_reverse_iterator(this->cbegin()); }
bool empty() const
{ return this->m_data.m_vect.empty(); }
size_type size() const
{ return this->m_data.m_vect.size(); }
size_type max_size() const
{ return this->m_data.m_vect.max_size(); }
void swap(flat_tree& other)
{
value_compare& mycomp = this->m_data;
value_compare& othercomp = other.m_data;
containers_detail::do_swap(mycomp, othercomp);
vector_t & myvect = this->m_data.m_vect;
vector_t & othervect = other.m_data.m_vect;
myvect.swap(othervect);
}
public:
// insert/erase
std::pair<iterator,bool> insert_unique(const value_type& val)
{
insert_commit_data data;
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
if(ret.second){
ret.first = priv_insert_commit(data, val);
}
return ret;
}
std::pair<iterator,bool> insert_unique(BOOST_INTERPROCESS_RV_REF(value_type) val)
{
insert_commit_data data;
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::interprocess::move(val));
}
return ret;
}
iterator insert_equal(const value_type& val)
{
iterator i = this->upper_bound(KeyOfValue()(val));
i = this->m_data.m_vect.insert(i, val);
return i;
}
iterator insert_equal(BOOST_INTERPROCESS_RV_REF(value_type) mval)
{
iterator i = this->upper_bound(KeyOfValue()(mval));
i = this->m_data.m_vect.insert(i, boost::interprocess::move(mval));
return i;
}
iterator insert_unique(const_iterator pos, const value_type& val)
{
insert_commit_data data;
std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, val, data);
if(ret.second){
ret.first = priv_insert_commit(data, val);
}
return ret.first;
}
iterator insert_unique(const_iterator pos, BOOST_INTERPROCESS_RV_REF(value_type) mval)
{
insert_commit_data data;
std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::interprocess::move(mval));
}
return ret.first;
}
iterator insert_equal(const_iterator pos, const value_type& val)
{
insert_commit_data data;
priv_insert_equal_prepare(pos, val, data);
return priv_insert_commit(data, val);
}
iterator insert_equal(const_iterator pos, BOOST_INTERPROCESS_RV_REF(value_type) mval)
{
insert_commit_data data;
priv_insert_equal_prepare(pos, mval, data);
return priv_insert_commit(data, boost::interprocess::move(mval));
}
template <class InIt>
void insert_unique(InIt first, InIt last)
{
for ( ; first != last; ++first)
this->insert_unique(*first);
}
template <class InIt>
void insert_equal(InIt first, InIt last)
{
typedef typename
std::iterator_traits<InIt>::iterator_category ItCat;
priv_insert_equal(first, last, ItCat());
}
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
template <class... Args>
iterator emplace_unique(Args&&... args)
{
value_type val(boost::interprocess::forward<Args>(args)...);
insert_commit_data data;
std::pair<iterator,bool> ret =
priv_insert_unique_prepare(val, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
}
return ret.first;
}
template <class... Args>
iterator emplace_hint_unique(const_iterator hint, Args&&... args)
{
value_type val(boost::interprocess::forward<Args>(args)...);
insert_commit_data data;
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
}
return ret.first;
}
template <class... Args>
iterator emplace_equal(Args&&... args)
{
value_type val(boost::interprocess::forward<Args>(args)...);
iterator i = this->upper_bound(KeyOfValue()(val));
i = this->m_data.m_vect.insert(i, boost::interprocess::move<value_type>(val));
return i;
}
template <class... Args>
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
{
value_type val(boost::interprocess::forward<Args>(args)...);
insert_commit_data data;
priv_insert_equal_prepare(hint, val, data);
return priv_insert_commit(data, boost::interprocess::move<value_type>(val));
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
iterator emplace_unique()
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
insert_commit_data data;
std::pair<iterator,bool> ret =
priv_insert_unique_prepare(val, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
}
return ret.first;
}
iterator emplace_hint_unique(const_iterator hint)
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
insert_commit_data data;
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
}
return ret.first;
}
iterator emplace_equal()
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
iterator i = this->upper_bound(KeyOfValue()(val));
i = this->m_data.m_vect.insert(i, boost::interprocess::move<value_type>(val));
return i;
}
iterator emplace_hint_equal(const_iterator hint)
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
insert_commit_data data;
priv_insert_equal_prepare(hint, val, data);
return priv_insert_commit(data, boost::interprocess::move<value_type>(val));
}
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
insert_commit_data data; \
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
if(ret.second){ \
ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val)); \
} \
return ret.first; \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint_unique(const_iterator hint, \
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
insert_commit_data data; \
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
if(ret.second){ \
ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val)); \
} \
return ret.first; \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
iterator i = this->upper_bound(KeyOfValue()(val)); \
i = this->m_data.m_vect.insert(i, boost::interprocess::move<value_type>(val)); \
return i; \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint_equal(const_iterator hint, \
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
insert_commit_data data; \
priv_insert_equal_prepare(hint, val, data); \
return priv_insert_commit(data, boost::interprocess::move<value_type>(val)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
iterator erase(const_iterator position)
{ return this->m_data.m_vect.erase(position); }
size_type erase(const key_type& k)
{
std::pair<iterator,iterator > itp = this->equal_range(k);
size_type ret = static_cast<size_type>(itp.second-itp.first);
if (ret){
this->m_data.m_vect.erase(itp.first, itp.second);
}
return ret;
}
iterator erase(const_iterator first, const_iterator last)
{ return this->m_data.m_vect.erase(first, last); }
void clear()
{ this->m_data.m_vect.clear(); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
// with previous allocations. The size of the vector is unchanged
//!
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to size().
void shrink_to_fit()
{ this->m_data.m_vect.shrink_to_fit(); }
// set operations:
iterator find(const key_type& k)
{
const Compare &key_comp = this->m_data.get_comp();
iterator i = this->lower_bound(k);
if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
i = this->end();
}
return i;
}
const_iterator find(const key_type& k) const
{
const Compare &key_comp = this->m_data.get_comp();
const_iterator i = this->lower_bound(k);
if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
i = this->end();
}
return i;
}
size_type count(const key_type& k) const
{
std::pair<const_iterator, const_iterator> p = this->equal_range(k);
size_type n = p.second - p.first;
return n;
}
iterator lower_bound(const key_type& k)
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
const_iterator lower_bound(const key_type& k) const
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
iterator upper_bound(const key_type& k)
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
const_iterator upper_bound(const key_type& k) const
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
std::pair<iterator,iterator> equal_range(const key_type& k)
{ return this->priv_equal_range(this->begin(), this->end(), k); }
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
{ return this->priv_equal_range(this->begin(), this->end(), k); }
size_type capacity() const
{ return this->m_data.m_vect.capacity(); }
void reserve(size_type count)
{ this->m_data.m_vect.reserve(count); }
private:
struct insert_commit_data
{
const_iterator position;
};
// insert/erase
void priv_insert_equal_prepare
(const_iterator pos, const value_type& val, insert_commit_data &data)
{
// N1780
// To insert val at pos:
// if pos == end || val <= *pos
// if pos == begin || val >= *(pos-1)
// insert val before pos
// else
// insert val before upper_bound(val)
// else if pos+1 == end || val <= *(pos+1)
// insert val after pos
// else
// insert val before lower_bound(val)
const value_compare &value_comp = this->m_data;
if(pos == this->cend() || !value_comp(*pos, val)){
if (pos == this->cbegin() || !value_comp(val, pos[-1])){
data.position = pos;
}
else{
data.position =
this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
}
}
//Works, but increases code complexity
//else if (++pos == this->end() || !value_comp(*pos, val)){
// return this->m_data.m_vect.insert(pos, val);
//}
else{
data.position =
this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
}
}
std::pair<iterator,bool> priv_insert_unique_prepare
(const_iterator beg, const_iterator end, const value_type& val, insert_commit_data &commit_data)
{
const value_compare &value_comp = this->m_data;
commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val));
return std::pair<iterator,bool>
( *reinterpret_cast<iterator*>(&commit_data.position)
, commit_data.position == end || value_comp(val, *commit_data.position));
}
std::pair<iterator,bool> priv_insert_unique_prepare
(const value_type& val, insert_commit_data &commit_data)
{ return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
std::pair<iterator,bool> priv_insert_unique_prepare
(const_iterator pos, const value_type& val, insert_commit_data &commit_data)
{
//N1780. Props to Howard Hinnant!
//To insert val at pos:
//if pos == end || val <= *pos
// if pos == begin || val >= *(pos-1)
// insert val before pos
// else
// insert val before upper_bound(val)
//else if pos+1 == end || val <= *(pos+1)
// insert val after pos
//else
// insert val before lower_bound(val)
const value_compare &value_comp = this->m_data;
if(pos == this->cend() || value_comp(val, *pos)){
if(pos != this->cbegin() && !value_comp(val, pos[-1])){
if(value_comp(pos[-1], val)){
commit_data.position = pos;
return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), true);
}
else{
return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), false);
}
}
return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);
}
// Works, but increases code complexity
//Next check
//else if (value_comp(*pos, val) && !value_comp(pos[1], val)){
// if(value_comp(val, pos[1])){
// commit_data.position = pos+1;
// return std::pair<iterator,bool>(pos+1, true);
// }
// else{
// return std::pair<iterator,bool>(pos+1, false);
// }
//}
else{
//[... pos ... val ... ]
//The hint is before the insertion position, so insert it
//in the remaining range
return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data);
}
}
template<class Convertible>
iterator priv_insert_commit
(insert_commit_data &commit_data, BOOST_INTERPROCESS_FWD_REF(Convertible) convertible)
{
return this->m_data.m_vect.insert
( commit_data.position
, boost::interprocess::forward<Convertible>(convertible));
}
template <class RanIt>
RanIt priv_lower_bound(RanIt first, RanIt last,
const key_type & key) const
{
const Compare &key_comp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
RanIt middle;
while (len > 0) {
half = len >> 1;
middle = first;
middle += half;
if (key_comp(key_extract(*middle), key)) {
++middle;
first = middle;
len = len - half - 1;
}
else
len = half;
}
return first;
}
template <class RanIt>
RanIt priv_upper_bound(RanIt first, RanIt last,
const key_type & key) const
{
const Compare &key_comp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
RanIt middle;
while (len > 0) {
half = len >> 1;
middle = first;
middle += half;
if (key_comp(key, key_extract(*middle))) {
len = half;
}
else{
first = ++middle;
len = len - half - 1;
}
}
return first;
}
template <class RanIt>
std::pair<RanIt, RanIt>
priv_equal_range(RanIt first, RanIt last, const key_type& key) const
{
const Compare &key_comp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
RanIt middle, left, right;
while (len > 0) {
half = len >> 1;
middle = first;
middle += half;
if (key_comp(key_extract(*middle), key)){
first = middle;
++first;
len = len - half - 1;
}
else if (key_comp(key, key_extract(*middle))){
len = half;
}
else {
left = this->priv_lower_bound(first, middle, key);
first += len;
right = this->priv_upper_bound(++middle, first, key);
return std::pair<RanIt, RanIt>(left, right);
}
}
return std::pair<RanIt, RanIt>(first, first);
}
template <class FwdIt>
void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
{
size_type len = static_cast<size_type>(std::distance(first, last));
this->reserve(this->size()+len);
this->priv_insert_equal(first, last, std::input_iterator_tag());
}
template <class InIt>
void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
{
for ( ; first != last; ++first)
this->insert_equal(*first);
}
/*
template <class FwdIt>
void priv_insert_unique(FwdIt first, FwdIt last, std::forward_iterator_tag)
{
size_type len = static_cast<size_type>(std::distance(first, last));
this->reserve(this->size()+len);
priv_insert_unique(first, last, std::input_iterator_tag());
}
template <class InIt>
void priv_insert_unique(InIt first, InIt last, std::input_iterator_tag)
{
for ( ; first != last; ++first)
this->insert_unique(*first);
}
*/
};
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
inline bool
operator==(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
{
return x.size() == y.size() &&
std::equal(x.begin(), x.end(), y.begin());
}
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
inline bool
operator<(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
{
return std::lexicographical_compare(x.begin(), x.end(),
y.begin(), y.end());
}
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
inline bool
operator!=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
{ return !(x == y); }
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
inline bool
operator>(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
{ return y < x; }
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
inline bool
operator<=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
{ return !(y < x); }
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
inline bool
operator>=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
{ return !(x < y); }
template <class Key, class Value, class KeyOfValue,
class Compare, class Alloc>
inline void
swap(flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
{ x.swap(y); }
} //namespace containers_detail {
} //namespace interprocess_container {
namespace interprocess {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class V, class KOV,
class C, class A>
struct has_trivial_destructor_after_move<boost::interprocess_container::containers_detail::flat_tree<K, V, KOV, C, A> >
{
static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
};
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif // BOOST_CONTAINERS_FLAT_TREE_HPP

View File

@@ -0,0 +1,492 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <boost/interprocess/detail/move.hpp>
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#include <boost/interprocess/containers/container/detail/variadic_templates_tools.hpp>
#else
#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
#endif
#include <iterator>
namespace boost {
namespace interprocess_container {
template <class T, class Difference = std::ptrdiff_t>
class constant_iterator
: public std::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef constant_iterator<T, Difference> this_type;
public:
explicit constant_iterator(const T &ref, Difference range_size)
: m_ptr(&ref), m_num(range_size){}
//Constructors
constant_iterator()
: m_ptr(0), m_num(0){}
constant_iterator& operator++()
{ increment(); return *this; }
constant_iterator operator++(int)
{
constant_iterator result (*this);
increment();
return result;
}
friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
{ return i.equal(i2); }
friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
{ return !(i == i2); }
friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
{ return i.less(i2); }
friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
{ return i2 < i; }
friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
{ return !(i > i2); }
friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
{ return !(i < i2); }
friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
{ return i2.distance_to(i); }
//Arithmetic
constant_iterator& operator+=(Difference off)
{ this->advance(off); return *this; }
constant_iterator operator+(Difference off) const
{
constant_iterator other(*this);
other.advance(off);
return other;
}
friend constant_iterator operator+(Difference off, const constant_iterator& right)
{ return right + off; }
constant_iterator& operator-=(Difference off)
{ this->advance(-off); return *this; }
constant_iterator operator-(Difference off) const
{ return *this + (-off); }
const T& operator*() const
{ return dereference(); }
const T* operator->() const
{ return &(dereference()); }
private:
const T * m_ptr;
Difference m_num;
void increment()
{ --m_num; }
void decrement()
{ ++m_num; }
bool equal(const this_type &other) const
{ return m_num == other.m_num; }
bool less(const this_type &other) const
{ return other.m_num < m_num; }
const T & dereference() const
{ return *m_ptr; }
void advance(Difference n)
{ m_num -= n; }
Difference distance_to(const this_type &other)const
{ return m_num - other.m_num; }
};
template <class T, class Difference = std::ptrdiff_t>
class default_construct_iterator
: public std::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef default_construct_iterator<T, Difference> this_type;
public:
explicit default_construct_iterator(Difference range_size)
: m_num(range_size){}
//Constructors
default_construct_iterator()
: m_num(0){}
default_construct_iterator& operator++()
{ increment(); return *this; }
default_construct_iterator operator++(int)
{
default_construct_iterator result (*this);
increment();
return result;
}
friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
{ return i.equal(i2); }
friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
{ return !(i == i2); }
friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
{ return i.less(i2); }
friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
{ return i2 < i; }
friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
{ return !(i > i2); }
friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
{ return !(i < i2); }
friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
{ return i2.distance_to(i); }
//Arithmetic
default_construct_iterator& operator+=(Difference off)
{ this->advance(off); return *this; }
default_construct_iterator operator+(Difference off) const
{
default_construct_iterator other(*this);
other.advance(off);
return other;
}
friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
{ return right + off; }
default_construct_iterator& operator-=(Difference off)
{ this->advance(-off); return *this; }
default_construct_iterator operator-(Difference off) const
{ return *this + (-off); }
const T& operator*() const
{ return dereference(); }
const T* operator->() const
{ return &(dereference()); }
private:
Difference m_num;
void increment()
{ --m_num; }
void decrement()
{ ++m_num; }
bool equal(const this_type &other) const
{ return m_num == other.m_num; }
bool less(const this_type &other) const
{ return other.m_num < m_num; }
const T & dereference() const
{
static T dummy;
return dummy;
}
void advance(Difference n)
{ m_num -= n; }
Difference distance_to(const this_type &other)const
{ return m_num - other.m_num; }
};
template <class T, class Difference = std::ptrdiff_t>
class repeat_iterator
: public std::iterator
<std::random_access_iterator_tag, T, Difference>
{
typedef repeat_iterator<T, Difference> this_type;
public:
explicit repeat_iterator(T &ref, Difference range_size)
: m_ptr(&ref), m_num(range_size){}
//Constructors
repeat_iterator()
: m_ptr(0), m_num(0){}
this_type& operator++()
{ increment(); return *this; }
this_type operator++(int)
{
this_type result (*this);
increment();
return result;
}
friend bool operator== (const this_type& i, const this_type& i2)
{ return i.equal(i2); }
friend bool operator!= (const this_type& i, const this_type& i2)
{ return !(i == i2); }
friend bool operator< (const this_type& i, const this_type& i2)
{ return i.less(i2); }
friend bool operator> (const this_type& i, const this_type& i2)
{ return i2 < i; }
friend bool operator<= (const this_type& i, const this_type& i2)
{ return !(i > i2); }
friend bool operator>= (const this_type& i, const this_type& i2)
{ return !(i < i2); }
friend Difference operator- (const this_type& i, const this_type& i2)
{ return i2.distance_to(i); }
//Arithmetic
this_type& operator+=(Difference off)
{ this->advance(off); return *this; }
this_type operator+(Difference off) const
{
this_type other(*this);
other.advance(off);
return other;
}
friend this_type operator+(Difference off, const this_type& right)
{ return right + off; }
this_type& operator-=(Difference off)
{ this->advance(-off); return *this; }
this_type operator-(Difference off) const
{ return *this + (-off); }
T& operator*() const
{ return dereference(); }
T *operator->() const
{ return &(dereference()); }
private:
T * m_ptr;
Difference m_num;
void increment()
{ --m_num; }
void decrement()
{ ++m_num; }
bool equal(const this_type &other) const
{ return m_num == other.m_num; }
bool less(const this_type &other) const
{ return other.m_num < m_num; }
T & dereference() const
{ return *m_ptr; }
void advance(Difference n)
{ m_num -= n; }
Difference distance_to(const this_type &other)const
{ return m_num - other.m_num; }
};
template <class T, class E>
class emplace_iterator
: public std::iterator
<std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
{
typedef emplace_iterator this_type;
public:
explicit emplace_iterator(E&e)
: m_num(1), m_pe(&e){}
emplace_iterator()
: m_num(0), m_pe(0){}
this_type& operator++()
{ increment(); return *this; }
this_type operator++(int)
{
this_type result (*this);
increment();
return result;
}
friend bool operator== (const this_type& i, const this_type& i2)
{ return i.equal(i2); }
friend bool operator!= (const this_type& i, const this_type& i2)
{ return !(i == i2); }
friend bool operator< (const this_type& i, const this_type& i2)
{ return i.less(i2); }
friend bool operator> (const this_type& i, const this_type& i2)
{ return i2 < i; }
friend bool operator<= (const this_type& i, const this_type& i2)
{ return !(i > i2); }
friend bool operator>= (const this_type& i, const this_type& i2)
{ return !(i < i2); }
friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2)
{ return i2.distance_to(i); }
//Arithmetic
this_type& operator+=(std::ptrdiff_t off)
{ this->advance(off); return *this; }
this_type operator+(std::ptrdiff_t off) const
{
this_type other(*this);
other.advance(off);
return other;
}
friend this_type operator+(std::ptrdiff_t off, const this_type& right)
{ return right + off; }
this_type& operator-=(std::ptrdiff_t off)
{ this->advance(-off); return *this; }
this_type operator-(std::ptrdiff_t off) const
{ return *this + (-off); }
const T& operator*() const
{ return dereference(); }
const T* operator->() const
{ return &(dereference()); }
void construct_in_place(T* ptr)
{ (*m_pe)(ptr); }
private:
std::ptrdiff_t m_num;
E * m_pe;
void increment()
{ --m_num; }
void decrement()
{ ++m_num; }
bool equal(const this_type &other) const
{ return m_num == other.m_num; }
bool less(const this_type &other) const
{ return other.m_num < m_num; }
const T & dereference() const
{
static T dummy;
return dummy;
}
void advance(std::ptrdiff_t n)
{ m_num -= n; }
std::ptrdiff_t distance_to(const this_type &other)const
{ return m_num - other.m_num; }
};
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
template<class T, class ...Args>
struct emplace_functor
{
typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
emplace_functor(Args&&... args)
: args_(args...)
{}
void operator()(T *ptr)
{ emplace_functor::inplace_impl(ptr, index_tuple_t()); }
template<int ...IdxPack>
void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&)
{ ::new(ptr) T(boost::interprocess::forward<Args>(containers_detail::get<IdxPack>(args_))...); }
containers_detail::tuple<Args&&...> args_;
};
#else
template<class T>
struct emplace_functor
{
emplace_functor()
{}
void operator()(T *ptr)
{ new(ptr) T(); }
};
#define BOOST_PP_LOCAL_MACRO(n) \
template <class T, BOOST_PP_ENUM_PARAMS(n, class P) > \
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
{ \
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
: BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
\
void operator()(T *ptr) \
{ \
new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
} \
BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP

View File

@@ -0,0 +1,152 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008.
//
// 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_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
#define BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <cstddef>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
template <class T, T val>
struct integral_constant
{
static const T value = val;
typedef integral_constant<T,val> type;
};
template< bool C_ >
struct bool_ : integral_constant<bool, C_>
{
static const bool value = C_;
};
typedef bool_<true> true_;
typedef bool_<false> false_;
typedef true_ true_type;
typedef false_ false_type;
typedef char yes_type;
struct no_type
{
char padding[8];
};
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <class Cond, class T = void>
struct disable_if : public enable_if_c<!Cond::value, T> {};
template <class T, class U>
class is_convertible
{
typedef char true_t;
class false_t { char dummy[2]; };
static true_t dispatch(U);
static false_t dispatch(...);
static T trigger();
public:
enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
};
template<
bool C
, typename T1
, typename T2
>
struct if_c
{
typedef T1 type;
};
template<
typename T1
, typename T2
>
struct if_c<false,T1,T2>
{
typedef T2 type;
};
template<
typename T1
, typename T2
, typename T3
>
struct if_
{
typedef typename if_c<0 != T1::value, T2, T3>::type type;
};
template <class Pair>
struct select1st
// : public std::unary_function<Pair, typename Pair::first_type>
{
template<class OtherPair>
const typename Pair::first_type& operator()(const OtherPair& x) const
{ return x.first; }
const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
{ return x; }
};
// identity is an extension: it is not part of the standard.
template <class T>
struct identity
// : public std::unary_function<T,T>
{
typedef T type;
const T& operator()(const T& x) const
{ return x; }
};
template<std::size_t S>
struct ls_zeros
{
static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
};
template<>
struct ls_zeros<0>
{
static const std::size_t value = 0;
};
template<>
struct ls_zeros<1>
{
static const std::size_t value = 0;
};
} //namespace containers_detail {
} //namespace interprocess_container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP

View File

@@ -0,0 +1,554 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. 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_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
#define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/utilities.hpp>
#include <boost/interprocess/containers/container/detail/type_traits.hpp>
#include <boost/interprocess/containers/container/detail/transform_iterator.hpp>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
template<class VoidPointer>
class basic_multiallocation_slist
{
public:
typedef VoidPointer void_pointer;
private:
static VoidPointer &priv_get_ref(const VoidPointer &p)
{ return *static_cast<void_pointer*>(containers_detail::get_pointer(p)); }
basic_multiallocation_slist(basic_multiallocation_slist &);
basic_multiallocation_slist &operator=(basic_multiallocation_slist &);
public:
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_slist)
//!This iterator is returned by "allocate_many" functions so that
//!the user can access the multiple buffers allocated in a single call
class iterator
: public std::iterator<std::input_iterator_tag, char>
{
friend class basic_multiallocation_slist<void_pointer>;
void unspecified_bool_type_func() const {}
typedef void (iterator::*unspecified_bool_type)() const;
iterator(void_pointer node_range)
: next_node_(node_range)
{}
public:
typedef char value_type;
typedef value_type & reference;
typedef value_type * pointer;
iterator()
: next_node_(0)
{}
iterator &operator=(const iterator &other)
{ next_node_ = other.next_node_; return *this; }
public:
iterator& operator++()
{
next_node_ = *static_cast<void_pointer*>(containers_detail::get_pointer(next_node_));
return *this;
}
iterator operator++(int)
{
iterator result(*this);
++*this;
return result;
}
bool operator== (const iterator& other) const
{ return next_node_ == other.next_node_; }
bool operator!= (const iterator& other) const
{ return !operator== (other); }
reference operator*() const
{ return *static_cast<char*>(containers_detail::get_pointer(next_node_)); }
operator unspecified_bool_type() const
{ return next_node_? &iterator::unspecified_bool_type_func : 0; }
pointer operator->() const
{ return &(*(*this)); }
private:
void_pointer next_node_;
};
private:
iterator it_;
public:
basic_multiallocation_slist()
: it_(iterator())
{}
basic_multiallocation_slist(void_pointer p)
: it_(p ? iterator_to(p) : iterator())
{}
basic_multiallocation_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
: it_(iterator())
{ this->swap(other); }
basic_multiallocation_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
{
basic_multiallocation_slist tmp(boost::interprocess::move(other));
this->swap(tmp);
return *this;
}
bool empty() const
{ return !it_; }
iterator before_begin() const
{ return iterator(void_pointer(const_cast<void*>(static_cast<const void*>(&it_.next_node_)))); }
iterator begin() const
{ return it_; }
iterator end() const
{ return iterator(); }
void clear()
{ this->it_.next_node_ = void_pointer(0); }
iterator insert_after(iterator it, void_pointer m)
{
priv_get_ref(m) = priv_get_ref(it.next_node_);
priv_get_ref(it.next_node_) = m;
return iterator(m);
}
void push_front(void_pointer m)
{
priv_get_ref(m) = this->it_.next_node_;
this->it_.next_node_ = m;
}
void pop_front()
{ ++it_; }
void *front() const
{ return containers_detail::get_pointer(it_.next_node_); }
void splice_after(iterator after_this, iterator before_begin, iterator before_end)
{
if (after_this != before_begin && after_this != before_end && before_begin != before_end) {
void_pointer next_b = priv_get_ref(before_begin.next_node_);
void_pointer next_e = priv_get_ref(before_end.next_node_);
void_pointer next_p = priv_get_ref(after_this.next_node_);
priv_get_ref(before_begin.next_node_) = next_e;
priv_get_ref(before_end.next_node_) = next_p;
priv_get_ref(after_this.next_node_) = next_b;
}
}
void swap(basic_multiallocation_slist &other_chain)
{
std::swap(this->it_, other_chain.it_);
}
static iterator iterator_to(void_pointer p)
{ return iterator(p); }
void_pointer extract_data()
{
void_pointer ret = empty() ? void_pointer(0) : void_pointer(&*it_);
it_ = iterator();
return ret;
}
};
template<class VoidPointer>
class basic_multiallocation_cached_slist
{
private:
basic_multiallocation_slist<VoidPointer> slist_;
typename basic_multiallocation_slist<VoidPointer>::iterator last_;
basic_multiallocation_cached_slist(basic_multiallocation_cached_slist &);
basic_multiallocation_cached_slist &operator=(basic_multiallocation_cached_slist &);
public:
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_slist)
typedef typename basic_multiallocation_slist<VoidPointer>::void_pointer void_pointer;
typedef typename basic_multiallocation_slist<VoidPointer>::iterator iterator;
basic_multiallocation_cached_slist()
: slist_(), last_(slist_.before_begin())
{}
/*
basic_multiallocation_cached_slist(iterator first_node)
: slist_(first_node), last_(slist_.before_begin())
{
iterator end;
while(first_node != end){
++last_;
}
}*/
basic_multiallocation_cached_slist(void_pointer p1, void_pointer p2)
: slist_(p1), last_(p2 ? iterator_to(p2) : slist_.before_begin())
{}
basic_multiallocation_cached_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
: slist_(), last_(slist_.before_begin())
{ this->swap(other); }
basic_multiallocation_cached_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
{
basic_multiallocation_cached_slist tmp(boost::interprocess::move(other));
this->swap(tmp);
return *this;
}
bool empty() const
{ return slist_.empty(); }
iterator before_begin() const
{ return slist_.before_begin(); }
iterator begin() const
{ return slist_.begin(); }
iterator end() const
{ return slist_.end(); }
iterator last() const
{ return last_; }
void clear()
{
slist_.clear();
last_ = slist_.before_begin();
}
iterator insert_after(iterator it, void_pointer m)
{
slist_.insert_after(it, m);
if(it == last_){
last_ = slist_.iterator_to(m);
}
return iterator_to(m);
}
void push_front(void_pointer m)
{ this->insert_after(this->before_begin(), m); }
void push_back(void_pointer m)
{ this->insert_after(last_, m); }
void pop_front()
{
if(last_ == slist_.begin()){
last_ = slist_.before_begin();
}
slist_.pop_front();
}
void *front() const
{ return slist_.front(); }
void splice_after(iterator after_this, iterator before_begin, iterator before_end)
{
if(before_begin == before_end)
return;
if(after_this == last_){
last_ = before_end;
}
slist_.splice_after(after_this, before_begin, before_end);
}
void swap(basic_multiallocation_cached_slist &x)
{
slist_.swap(x.slist_);
using std::swap;
swap(last_, x.last_);
if(last_ == x.before_begin()){
last_ = this->before_begin();
}
if(x.last_ == this->before_begin()){
x.last_ = x.before_begin();
}
}
static iterator iterator_to(void_pointer p)
{ return basic_multiallocation_slist<VoidPointer>::iterator_to(p); }
std::pair<void_pointer, void_pointer> extract_data()
{
if(this->empty()){
return std::pair<void_pointer, void_pointer>(void_pointer(0), void_pointer(0));
}
else{
void_pointer p1 = slist_.extract_data();
void_pointer p2 = void_pointer(&*last_);
last_ = iterator();
return std::pair<void_pointer, void_pointer>(p1, p2);
}
}
};
template<class MultiallocatorCachedSlist>
class basic_multiallocation_cached_counted_slist
{
private:
MultiallocatorCachedSlist cached_slist_;
std::size_t size_;
basic_multiallocation_cached_counted_slist(basic_multiallocation_cached_counted_slist &);
basic_multiallocation_cached_counted_slist &operator=(basic_multiallocation_cached_counted_slist &);
public:
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_counted_slist)
typedef typename MultiallocatorCachedSlist::void_pointer void_pointer;
typedef typename MultiallocatorCachedSlist::iterator iterator;
basic_multiallocation_cached_counted_slist()
: cached_slist_(), size_(0)
{}
basic_multiallocation_cached_counted_slist(void_pointer p1, void_pointer p2, std::size_t n)
: cached_slist_(p1, p2), size_(n)
{}
basic_multiallocation_cached_counted_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
: cached_slist_(), size_(0)
{ this->swap(other); }
basic_multiallocation_cached_counted_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
{
basic_multiallocation_cached_counted_slist tmp(boost::interprocess::move(other));
this->swap(tmp);
return *this;
}
basic_multiallocation_cached_counted_slist (MultiallocatorCachedSlist mem, std::size_t n)
: cached_slist_(boost::interprocess::move(mem)), size_(n)
{}
bool empty() const
{ return cached_slist_.empty(); }
std::size_t size() const
{ return size_; }
iterator before_begin() const
{ return cached_slist_.before_begin(); }
iterator begin() const
{ return cached_slist_.begin(); }
iterator end() const
{ return cached_slist_.end(); }
iterator last() const
{ return cached_slist_.last(); }
void clear()
{
cached_slist_.clear();
size_ = 0;
}
iterator insert_after(iterator it, void_pointer m)
{
iterator ret = cached_slist_.insert_after(it, m);
++size_;
return ret;
}
void push_front(void_pointer m)
{ this->insert_after(this->before_begin(), m); }
void push_back(void_pointer m)
{ this->insert_after(this->before_begin(), m); }
void pop_front()
{
cached_slist_.pop_front();
--size_;
}
void *front() const
{ return cached_slist_.front(); }
void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end)
{
std::size_t n = static_cast<std::size_t>(std::distance(before_begin, before_end));
this->splice_after(after_this, x, before_begin, before_end, n);
}
void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end, std::size_t n)
{
cached_slist_.splice_after(after_this, before_begin, before_end);
size_ += n;
x.size_ -= n;
}
void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x)
{
cached_slist_.splice_after(after_this, x.before_begin(), x.last());
size_ += x.size_;
x.size_ = 0;
}
void swap(basic_multiallocation_cached_counted_slist &x)
{
cached_slist_.swap(x.cached_slist_);
using std::swap;
swap(size_, x.size_);
}
static iterator iterator_to(void_pointer p)
{ return MultiallocatorCachedSlist::iterator_to(p); }
std::pair<void_pointer, void_pointer> extract_data()
{
size_ = 0;
return cached_slist_.extract_data();
}
};
template<class T>
struct cast_functor
{
typedef typename containers_detail::add_reference<T>::type result_type;
result_type operator()(char &ptr) const
{ return *static_cast<T*>(static_cast<void*>(&ptr)); }
};
template<class MultiallocationChain, class T>
class transform_multiallocation_chain
{
private:
MultiallocationChain holder_;
typedef typename MultiallocationChain::void_pointer void_pointer;
typedef typename boost::pointer_to_other
<void_pointer, T>::type pointer;
transform_multiallocation_chain(transform_multiallocation_chain &);
transform_multiallocation_chain &operator=(transform_multiallocation_chain &);
static pointer cast(void_pointer p)
{
return pointer(static_cast<T*>(containers_detail::get_pointer(p)));
}
public:
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(transform_multiallocation_chain)
typedef transform_iterator
< typename MultiallocationChain::iterator
, containers_detail::cast_functor <T> > iterator;
transform_multiallocation_chain(void_pointer p1, void_pointer p2, std::size_t n)
: holder_(p1, p2, n)
{}
transform_multiallocation_chain()
: holder_()
{}
transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
: holder_()
{ this->swap(other); }
transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(MultiallocationChain) other)
: holder_(boost::interprocess::move(other))
{}
transform_multiallocation_chain& operator=(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
{
transform_multiallocation_chain tmp(boost::interprocess::move(other));
this->swap(tmp);
return *this;
}
void push_front(pointer mem)
{ holder_.push_front(mem); }
void swap(transform_multiallocation_chain &other_chain)
{ holder_.swap(other_chain.holder_); }
/*
void splice_after(iterator after_this, iterator before_begin, iterator before_end)
{ holder_.splice_after(after_this.base(), before_begin.base(), before_end.base()); }
*/
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
{ holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
void pop_front()
{ holder_.pop_front(); }
pointer front() const
{ return cast(holder_.front()); }
bool empty() const
{ return holder_.empty(); }
iterator before_begin() const
{ return iterator(holder_.before_begin()); }
iterator begin() const
{ return iterator(holder_.begin()); }
iterator end() const
{ return iterator(holder_.end()); }
iterator last() const
{ return iterator(holder_.last()); }
std::size_t size() const
{ return holder_.size(); }
void clear()
{ holder_.clear(); }
iterator insert_after(iterator it, pointer m)
{ return iterator(holder_.insert_after(it.base(), m)); }
static iterator iterator_to(pointer p)
{ return iterator(MultiallocationChain::iterator_to(p)); }
std::pair<void_pointer, void_pointer> extract_data()
{ return holder_.extract_data(); }
MultiallocationChain extract_multiallocation_chain()
{
return MultiallocationChain(boost::interprocess::move(holder_));
}
};
}}}
// namespace containers_detail {
// namespace interprocess_container {
// namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP

View File

@@ -0,0 +1,499 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. 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_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
#define BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <utility>
#include <functional>
#include <boost/interprocess/detail/move.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/interprocess/containers/container/detail/version_type.hpp>
#include <boost/interprocess/containers/container/detail/type_traits.hpp>
#include <boost/interprocess/containers/container/detail/utilities.hpp>
#include <boost/interprocess/containers/container/detail/mpl.hpp>
#include <boost/interprocess/containers/container/detail/destroyers.hpp>
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
#endif
#include <boost/interprocess/containers/container/detail/algorithms.hpp>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
template <class Allocator>
struct scoped_deallocator
{
typedef typename Allocator::pointer pointer;
typedef containers_detail::integral_constant<unsigned,
boost::interprocess_container::containers_detail::
version<Allocator>::value> alloc_version;
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
private:
void priv_deallocate(allocator_v1)
{ m_alloc.deallocate(m_ptr, 1); }
void priv_deallocate(allocator_v2)
{ m_alloc.deallocate_one(m_ptr); }
scoped_deallocator(scoped_deallocator &);
scoped_deallocator& operator=(scoped_deallocator &);
public:
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(scoped_deallocator)
pointer m_ptr;
Allocator& m_alloc;
scoped_deallocator(pointer p, Allocator& a)
: m_ptr(p), m_alloc(a)
{}
~scoped_deallocator()
{ if (m_ptr)priv_deallocate(alloc_version()); }
scoped_deallocator(BOOST_INTERPROCESS_RV_REF(scoped_deallocator) o)
: m_ptr(o.m_ptr), m_alloc(o.m_alloc)
{ o.release(); }
pointer get() const
{ return m_ptr; }
void release()
{ m_ptr = 0; }
};
template <class A>
class allocator_destroyer_and_chain_builder
{
typedef typename A::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
A & a_;
multiallocation_chain &c_;
public:
allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
: a_(a), c_(c)
{}
void operator()(const typename A::pointer &p)
{
value_type *vp = containers_detail::get_pointer(p);
vp->~value_type();
c_.push_front(vp);
}
};
template <class A>
class allocator_multialloc_chain_node_deallocator
{
typedef typename A::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
A & a_;
multiallocation_chain c_;
public:
allocator_multialloc_chain_node_deallocator(A &a)
: a_(a), c_()
{}
chain_builder get_chain_builder()
{ return chain_builder(a_, c_); }
~allocator_multialloc_chain_node_deallocator()
{
if(!c_.empty())
a_.deallocate_individual(boost::interprocess::move(c_));
}
};
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;
node_compare(const ValueCompare &pred)
: ValueCompare(pred)
{}
ValueCompare &value_comp()
{ return static_cast<ValueCompare &>(*this); }
ValueCompare &value_comp() const
{ return static_cast<const ValueCompare &>(*this); }
bool operator()(const Node &a, const Node &b) const
{ return ValueCompare::operator()(a.get_data(), b.get_data()); }
};
template<class A, class ICont>
struct node_alloc_holder
{
typedef node_alloc_holder<A, ICont> self_t;
typedef typename A::value_type value_type;
typedef typename ICont::value_type Node;
typedef typename A::template rebind<Node>::other NodeAlloc;
typedef A ValAlloc;
typedef typename NodeAlloc::pointer NodePtr;
typedef containers_detail::scoped_deallocator<NodeAlloc> Deallocator;
typedef typename NodeAlloc::size_type size_type;
typedef typename NodeAlloc::difference_type difference_type;
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
typedef containers_detail::integral_constant<unsigned,
boost::interprocess_container::containers_detail::
version<NodeAlloc>::value> alloc_version;
typedef typename ICont::iterator icont_iterator;
typedef typename ICont::const_iterator icont_citerator;
typedef allocator_destroyer<NodeAlloc> Destroyer;
private:
node_alloc_holder(node_alloc_holder&);
node_alloc_holder & operator=(node_alloc_holder&);
public:
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(node_alloc_holder)
node_alloc_holder(const ValAlloc &a)
: members_(a)
{}
node_alloc_holder(const node_alloc_holder &other)
: members_(other.node_alloc())
{}
node_alloc_holder(BOOST_INTERPROCESS_RV_REF(node_alloc_holder) other)
: members_(boost::interprocess::move(other.node_alloc()))
{ this->swap(other); }
template<class Pred>
node_alloc_holder(const ValAlloc &a, const Pred &c)
: members_(a, typename ICont::value_compare(c))
{}
template<class Pred>
node_alloc_holder(BOOST_INTERPROCESS_RV_REF(ValAlloc) a, const Pred &c)
: members_(a, typename ICont::value_compare(c))
{}
template<class Pred>
node_alloc_holder(const node_alloc_holder &other, const Pred &c)
: members_(other.node_alloc(), typename ICont::value_compare(c))
{}
~node_alloc_holder()
{ this->clear(alloc_version()); }
size_type max_size() const
{ return this->node_alloc().max_size(); }
NodePtr allocate_one()
{ return this->allocate_one(alloc_version()); }
NodePtr allocate_one(allocator_v1)
{ return this->node_alloc().allocate(1); }
NodePtr allocate_one(allocator_v2)
{ return this->node_alloc().allocate_one(); }
void deallocate_one(NodePtr p)
{ return this->deallocate_one(p, alloc_version()); }
void deallocate_one(NodePtr p, allocator_v1)
{ this->node_alloc().deallocate(p, 1); }
void deallocate_one(NodePtr p, allocator_v2)
{ this->node_alloc().deallocate_one(p); }
template<class Convertible1, class Convertible2>
static void construct(const NodePtr &ptr,
#ifdef BOOST_HAS_RVALUE_REFS
std::pair<Convertible1, Convertible2> &&
#else
boost::interprocess::rv<std::pair<Convertible1, Convertible2> > &
#endif
value)
{
typedef typename Node::hook_type hook_type;
typedef typename Node::value_type::first_type first_type;
typedef typename Node::value_type::second_type second_type;
Node *nodeptr = containers_detail::get_pointer(ptr);
//Hook constructor does not throw
new(static_cast<hook_type*>(nodeptr))hook_type();
//Now construct pair members_holder
value_type *valueptr = &nodeptr->get_data();
new((void*)&valueptr->first) first_type(boost::interprocess::move(value.first));
BOOST_TRY{
new((void*)&valueptr->second) second_type(boost::interprocess::move(value.second));
}
BOOST_CATCH(...){
valueptr->first.~first_type();
static_cast<hook_type*>(nodeptr)->~hook_type();
BOOST_RETHROW
}
BOOST_CATCH_END
}
static void destroy(const NodePtr &ptr)
{ containers_detail::get_pointer(ptr)->~Node(); }
Deallocator create_node_and_deallocator()
{
return Deallocator(this->allocate_one(), this->node_alloc());
}
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
template<class ...Args>
static void construct(const NodePtr &ptr, Args &&...args)
{ new((void*)containers_detail::get_pointer(ptr)) Node(boost::interprocess::forward<Args>(args)...); }
template<class ...Args>
NodePtr create_node(Args &&...args)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
self_t::construct(p, boost::interprocess::forward<Args>(args)...);
node_deallocator.release();
return (p);
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
static void construct(const NodePtr &ptr)
{ new((void*)containers_detail::get_pointer(ptr)) Node(); }
NodePtr create_node()
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
self_t::construct(p);
node_deallocator.release();
return (p);
}
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
void construct(const NodePtr &ptr, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
new((void*)containers_detail::get_pointer(ptr)) \
Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
NodePtr p = this->allocate_one(); \
Deallocator node_deallocator(p, this->node_alloc()); \
self_t::construct(p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
node_deallocator.release(); \
return (p); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
template<class It>
NodePtr create_node_from_it(It it)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
::boost::interprocess_container::construct_in_place(containers_detail::get_pointer(p), it);
node_deallocator.release();
return (p);
}
void destroy_node(NodePtr node)
{
self_t::destroy(node);
this->deallocate_one(node);
}
void swap(node_alloc_holder &x)
{
NodeAlloc& this_alloc = this->node_alloc();
NodeAlloc& other_alloc = x.node_alloc();
if (this_alloc != other_alloc){
containers_detail::do_swap(this_alloc, other_alloc);
}
this->icont().swap(x.icont());
}
template<class FwdIterator, class Inserter>
FwdIterator allocate_many_and_construct
(FwdIterator beg, difference_type n, Inserter inserter)
{
if(n){
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
//Try to allocate memory in a single block
multiallocation_chain mem(this->node_alloc().allocate_individual(n));
int constructed = 0;
Node *p = 0;
BOOST_TRY{
for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
p = containers_detail::get_pointer(mem.front());
mem.pop_front();
//This can throw
constructed = 0;
boost::interprocess_container::construct_in_place(p, beg);
++constructed;
//This can throw in some containers (predicate might throw)
inserter(*p);
}
}
BOOST_CATCH(...){
if(constructed){
this->destroy(p);
}
this->node_alloc().deallocate_individual(boost::interprocess::move(mem));
BOOST_RETHROW
}
BOOST_CATCH_END
}
return beg;
}
void clear(allocator_v1)
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
void clear(allocator_v2)
{
typename NodeAlloc::multiallocation_chain chain;
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
this->icont().clear_and_dispose(builder);
BOOST_STATIC_ASSERT((boost::interprocess::is_movable<typename NodeAlloc::multiallocation_chain>::value == true));
if(!chain.empty())
this->node_alloc().deallocate_individual(boost::interprocess::move(chain));
}
icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1)
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2)
{
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
}
template<class Key, class Comparator>
size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
{ return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
template<class Key, class Comparator>
size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
{
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
}
protected:
struct cloner
{
cloner(node_alloc_holder &holder)
: m_holder(holder)
{}
NodePtr operator()(const Node &other) const
{ return m_holder.create_node(other.get_data()); }
node_alloc_holder &m_holder;
};
struct destroyer
{
destroyer(node_alloc_holder &holder)
: m_holder(holder)
{}
void operator()(NodePtr n) const
{ m_holder.destroy_node(n); }
node_alloc_holder &m_holder;
};
struct members_holder
: public NodeAlloc
{
private:
members_holder(const members_holder&);
public:
template<class ConvertibleToAlloc>
members_holder(const ConvertibleToAlloc &c2alloc)
: NodeAlloc(c2alloc)
{}
template<class ConvertibleToAlloc, class Pred>
members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c)
: NodeAlloc(c2alloc), m_icont(c)
{}
//The intrusive container
ICont m_icont;
} members_;
ICont &non_const_icont() const
{ return const_cast<ICont&>(this->members_.m_icont); }
ICont &icont()
{ return this->members_.m_icont; }
const ICont &icont() const
{ return this->members_.m_icont; }
NodeAlloc &node_alloc()
{ return static_cast<NodeAlloc &>(this->members_); }
const NodeAlloc &node_alloc() const
{ return static_cast<const NodeAlloc &>(this->members_); }
};
} //namespace containers_detail {
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif // BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_

View File

@@ -0,0 +1,189 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
#define BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <boost/interprocess/containers/container/detail/mpl.hpp>
#include <boost/interprocess/containers/container/detail/type_traits.hpp>
#include <utility> //std::pair
#include <boost/interprocess/detail/move.hpp>
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
#endif
namespace boost {
namespace interprocess_container {
namespace containers_detail {
template <class T1, class T2>
struct pair
{
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(pair)
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
//std::pair compatibility
template <class D, class S>
pair(const std::pair<D, S>& p)
: first(p.first), second(p.second)
{}
//To resolve ambiguity with the variadic constructor of 1 argument
//and the previous constructor
pair(std::pair<T1, T2>& x)
: first(x.first), second(x.second)
{}
template <class D, class S>
pair(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
: first(boost::interprocess::move(p.first)), second(boost::interprocess::move(p.second))
{}
pair()
: first(), second()
{}
pair(const pair<T1, T2>& x)
: first(x.first), second(x.second)
{}
//To resolve ambiguity with the variadic constructor of 1 argument
//and the copy constructor
pair(pair<T1, T2>& x)
: first(x.first), second(x.second)
{}
pair(BOOST_INTERPROCESS_RV_REF(pair) p)
: first(boost::interprocess::move(p.first)), second(boost::interprocess::move(p.second))
{}
template <class D, class S>
pair(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
: first(boost::interprocess::move(p.first)), second(boost::interprocess::move(p.second))
{}
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
template<class U, class ...Args>
pair(U &&u, Args &&... args)
: first(boost::interprocess::forward<U>(u))
, second(boost::interprocess::forward<Args>(args)...)
{}
#else
template<class U>
pair( BOOST_CONTAINERS_PARAM(U, u)
#ifndef BOOST_HAS_RVALUE_REFS
, typename containers_detail::disable_if
< containers_detail::is_same<U, boost::interprocess::rv<pair> > >::type* = 0
#endif
)
: first(boost::interprocess::forward<U>(const_cast<U&>(u)))
{}
#define BOOST_PP_LOCAL_MACRO(n) \
template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
pair(BOOST_CONTAINERS_PARAM(U, u) \
,BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
: first(boost::interprocess::forward<U>(const_cast<U&>(u))) \
, second(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif
pair& operator=(BOOST_INTERPROCESS_RV_REF(pair) p)
{
first = boost::interprocess::move(p.first);
second = boost::interprocess::move(p.second);
return *this;
}
pair& operator=(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
{
first = boost::interprocess::move(p.first);
second = boost::interprocess::move(p.second);
return *this;
}
template <class D, class S>
pair& operator=(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
{
first = boost::interprocess::move(p.first);
second = boost::interprocess::move(p.second);
return *this;
}
void swap(pair& p)
{ std::swap(*this, p); }
};
template <class T1, class T2>
inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
{ return static_cast<bool>(x.first == y.first && x.second == y.second); }
template <class T1, class T2>
inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
{ return static_cast<bool>(x.first < y.first ||
(!(y.first < x.first) && x.second < y.second)); }
template <class T1, class T2>
inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
{ return static_cast<bool>(!(x == y)); }
template <class T1, class T2>
inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
{ return y < x; }
template <class T1, class T2>
inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
{ return static_cast<bool>(!(x < y)); }
template <class T1, class T2>
inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
{ return static_cast<bool>(!(y < x)); }
template <class T1, class T2>
inline pair<T1, T2> make_pair(T1 x, T2 y)
{ return pair<T1, T2>(x, y); }
template <class T1, class T2>
inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
{
swap(x.first, y.first);
swap(x.second, y.second);
}
} //namespace containers_detail {
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_PAIR_HPP

View File

@@ -0,0 +1,101 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2008. 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_CONTAINERS_DETAIL_PREPROCESSOR_HPP
#define BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#error "This file is not needed when perfect forwarding is available"
#endif
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#define BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS 10
//Note:
//We define template parameters as const references to
//be able to bind temporaries. After that we will un-const them.
//This cast is ugly but it is necessary until "perfect forwarding"
//is achieved in C++0x. Meanwhile, if we want to be able to
//bind rvalues with non-const references, we have to be ugly
#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
//!
#else
#define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
//!
#endif
#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_CONTAINERS_PARAM(U, u) \
U && u \
//!
#else
#define BOOST_CONTAINERS_PARAM(U, u) \
const U & u \
//!
#endif
#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
//!
#else
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
//!
#endif
#define BOOST_CONTAINERS_AUX_PARAM_INC(z, n, data) \
BOOST_PP_CAT(++m_p, n) \
//!
#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
//!
#else
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
//!
#endif
#define BOOST_CONTAINERS_PP_PARAM_FORWARD(z, n, data) \
boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!
#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
//!
#define BOOST_CONTAINERS_PP_MEMBER_IT_FORWARD(z, n, data) \
BOOST_PP_CAT(*m_p, n) \
//!
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#else
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#error "This file is not needed when perfect forwarding is available"
#endif
#endif //#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP

View File

@@ -0,0 +1,176 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
#define BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <boost/interprocess/containers/container/detail/type_traits.hpp>
#include <iterator>
namespace boost {
namespace interprocess_container {
template <class PseudoReference>
struct operator_arrow_proxy
{
operator_arrow_proxy(const PseudoReference &px)
: m_value(px)
{}
PseudoReference* operator->() const { return &m_value; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
// operator T*() const { return &m_value; }
mutable PseudoReference m_value;
};
template <class T>
struct operator_arrow_proxy<T&>
{
operator_arrow_proxy(T &px)
: m_value(px)
{}
T* operator->() const { return &m_value; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
// operator T*() const { return &m_value; }
mutable T &m_value;
};
template <class Iterator, class UnaryFunction>
class transform_iterator
: public UnaryFunction
, public std::iterator
< typename Iterator::iterator_category
, typename containers_detail::remove_reference<typename UnaryFunction::result_type>::type
, typename Iterator::difference_type
, operator_arrow_proxy<typename UnaryFunction::result_type>
, typename UnaryFunction::result_type>
{
public:
explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
: UnaryFunction(f), m_it(it)
{}
explicit transform_iterator()
: UnaryFunction(), m_it()
{}
//Constructors
transform_iterator& operator++()
{ increment(); return *this; }
transform_iterator operator++(int)
{
transform_iterator result (*this);
increment();
return result;
}
friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
{ return i.equal(i2); }
friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
{ return !(i == i2); }
/*
friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
{ return i2 < i; }
friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
{ return !(i > i2); }
friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
{ return !(i < i2); }
*/
friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
{ return i2.distance_to(i); }
//Arithmetic
transform_iterator& operator+=(typename Iterator::difference_type off)
{ this->advance(off); return *this; }
transform_iterator operator+(typename Iterator::difference_type off) const
{
transform_iterator other(*this);
other.advance(off);
return other;
}
friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
{ return right + off; }
transform_iterator& operator-=(typename Iterator::difference_type off)
{ this->advance(-off); return *this; }
transform_iterator operator-(typename Iterator::difference_type off) const
{ return *this + (-off); }
typename UnaryFunction::result_type operator*() const
{ return dereference(); }
operator_arrow_proxy<typename UnaryFunction::result_type>
operator->() const
{ return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
Iterator & base()
{ return m_it; }
const Iterator & base() const
{ return m_it; }
private:
Iterator m_it;
void increment()
{ ++m_it; }
void decrement()
{ --m_it; }
bool equal(const transform_iterator &other) const
{ return m_it == other.m_it; }
bool less(const transform_iterator &other) const
{ return other.m_it < m_it; }
typename UnaryFunction::result_type dereference() const
{ return UnaryFunction::operator()(*m_it); }
void advance(typename Iterator::difference_type n)
{ std::advance(m_it, n); }
typename Iterator::difference_type distance_to(const transform_iterator &other)const
{ return std::distance(other.m_it, m_it); }
};
template <class Iterator, class UnaryFunc>
transform_iterator<Iterator, UnaryFunc>
make_transform_iterator(Iterator it, UnaryFunc fun)
{
return transform_iterator<Iterator, UnaryFunc>(it, fun);
}
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,166 @@
//////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000.
// (C) Copyright Ion Gaztanaga 2005-2008.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
// The alignment_of implementation comes from John Maddock's boost::alignment_of code
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
struct nat{};
//boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative
template <typename T> struct alignment_of;
template <typename T>
struct alignment_of_hack
{
char c;
T t;
alignment_of_hack();
};
template <unsigned A, unsigned S>
struct alignment_logic
{
enum{ value = A < S ? A : S };
};
template< typename T >
struct alignment_of
{
enum{ value = alignment_logic
< sizeof(alignment_of_hack<T>) - sizeof(T)
, sizeof(T)>::value };
};
//This is not standard, but should work with all compilers
union max_align
{
char char_;
short short_;
int int_;
long long_;
#ifdef BOOST_HAS_LONG_LONG
long long long_long_;
#endif
float float_;
double double_;
long double long_double_;
void * void_ptr_;
};
template<class T>
struct remove_reference
{
typedef T type;
};
template<class T>
struct remove_reference<T&>
{
typedef T type;
};
template<class T>
struct is_reference
{
enum { value = false };
};
template<class T>
struct is_reference<T&>
{
enum { value = true };
};
template<class T>
struct is_pointer
{
enum { value = false };
};
template<class T>
struct is_pointer<T*>
{
enum { value = true };
};
template <typename T>
struct add_reference
{
typedef T& type;
};
template<class T>
struct add_reference<T&>
{
typedef T& type;
};
template<>
struct add_reference<void>
{
typedef nat &type;
};
template<>
struct add_reference<const void>
{
typedef const nat &type;
};
template <class T>
struct add_const_reference
{ typedef const T &type; };
template <class T>
struct add_const_reference<T&>
{ typedef T& type; };
template <typename T, typename U>
struct is_same
{
typedef char yes_type;
struct no_type
{
char padding[8];
};
template <typename V>
static yes_type is_same_tester(V*, V*);
static no_type is_same_tester(...);
static T *t;
static U *u;
static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
};
} // namespace containers_detail
} //namespace interprocess_container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#include <boost/interprocess/containers/container/detail/config_end.hpp>

View File

@@ -0,0 +1,95 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. 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_CONTAINERS_DETAIL_UTILITIES_HPP
#define BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <cstdio>
#include <algorithm>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
template <class SizeType>
SizeType
get_next_capacity(const SizeType max_size
,const SizeType capacity
,const SizeType n)
{
// if (n > max_size - capacity)
// throw std::length_error("get_next_capacity");
const SizeType m3 = max_size/3;
if (capacity < m3)
return capacity + max_value(3*(capacity+1)/5, n);
if (capacity < m3*2)
return capacity + max_value((capacity+1)/2, n);
return max_size;
}
template<class T>
const T &max_value(const T &a, const T &b)
{ return a > b ? a : b; }
template<class T>
const T &min_value(const T &a, const T &b)
{ return a < b ? a : b; }
template<class SmartPtr>
struct smart_ptr_type
{
typedef typename SmartPtr::value_type value_type;
typedef value_type *pointer;
static pointer get (const SmartPtr &smartptr)
{ return smartptr.get();}
};
template<class T>
struct smart_ptr_type<T*>
{
typedef T value_type;
typedef value_type *pointer;
static pointer get (pointer ptr)
{ return ptr;}
};
//!Overload for smart pointers to avoid ADL problems with get_pointer
template<class Ptr>
inline typename smart_ptr_type<Ptr>::pointer
get_pointer(const Ptr &ptr)
{ return smart_ptr_type<Ptr>::get(ptr); }
//!To avoid ADL problems with swap
template <class T>
inline void do_swap(T& x, T& y)
{
using std::swap;
swap(x, y);
}
template <std::size_t OrigSize, std::size_t RoundTo>
struct ct_rounded_size
{
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
};
} //namespace containers_detail {
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP

View File

@@ -0,0 +1,43 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
#define BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
namespace boost {
namespace interprocess_container {
namespace containers_detail {
template<class T>
struct value_init
{
value_init()
: m_t()
{}
T m_t;
};
} //namespace containers_detail {
} //namespace interprocess_container {
} //namespace boost {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP

View File

@@ -0,0 +1,153 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2008. 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_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#define BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#include <boost/interprocess/containers/container/detail/workaround.hpp>
#include <boost/interprocess/containers/container/detail/type_traits.hpp>
#include <cstddef> //std::size_t
namespace boost {
namespace interprocess_container {
namespace containers_detail {
template<typename... Values>
class tuple;
template<> class tuple<>
{};
template<typename Head, typename... Tail>
class tuple<Head, Tail...>
: private tuple<Tail...>
{
typedef tuple<Tail...> inherited;
public:
tuple() { }
// implicit copy-constructor is okay
// Construct tuple from separate arguments.
tuple(typename add_const_reference<Head>::type v,
typename add_const_reference<Tail>::type... vtail)
: inherited(vtail...), m_head(v)
{}
// Construct tuple from another tuple.
template<typename... VValues>
tuple(const tuple<VValues...>& other)
: m_head(other.head()), inherited(other.tail())
{}
template<typename... VValues>
tuple& operator=(const tuple<VValues...>& other)
{
m_head = other.head();
tail() = other.tail();
return this;
}
typename add_reference<Head>::type head() { return m_head; }
typename add_reference<const Head>::type head() const { return m_head; }
inherited& tail() { return *this; }
const inherited& tail() const { return *this; }
protected:
Head m_head;
};
template<typename... Values>
tuple<Values&&...> tie_forward(Values&&... values)
{ return tuple<Values&&...>(values...); }
template<int I, typename Tuple>
struct tuple_element;
template<int I, typename Head, typename... Tail>
struct tuple_element<I, tuple<Head, Tail...> >
{
typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
};
template<typename Head, typename... Tail>
struct tuple_element<0, tuple<Head, Tail...> >
{
typedef Head type;
};
template<int I, typename Tuple>
class get_impl;
template<int I, typename Head, typename... Values>
class get_impl<I, tuple<Head, Values...> >
{
typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
typedef get_impl<I-1, tuple<Values...> > Next;
public:
typedef typename add_reference<Element>::type type;
typedef typename add_const_reference<Element>::type const_type;
static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
};
template<typename Head, typename... Values>
class get_impl<0, tuple<Head, Values...> >
{
public:
typedef typename add_reference<Head>::type type;
typedef typename add_const_reference<Head>::type const_type;
static type get(tuple<Head, Values...>& t) { return t.head(); }
static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
};
template<int I, typename... Values>
typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
{ return get_impl<I, tuple<Values...> >::get(t); }
template<int I, typename... Values>
typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
{ return get_impl<I, tuple<Values...> >::get(t); }
////////////////////////////////////////////////////
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
// be used to "unpack" into comma-separated values
// in a function call.
////////////////////////////////////////////////////
template<int... Indexes>
struct index_tuple{};
template<std::size_t Num, typename Tuple = index_tuple<> >
struct build_number_seq;
template<std::size_t Num, int... Indexes>
struct build_number_seq<Num, index_tuple<Indexes...> >
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
{};
template<int... Indexes>
struct build_number_seq<0, index_tuple<Indexes...> >
{ typedef index_tuple<Indexes...> type; };
}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP

View File

@@ -0,0 +1,89 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//
// This code comes from N1953 document by Howard E. Hinnant
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
#include <boost/interprocess/containers/container/detail/mpl.hpp>
#include <boost/interprocess/containers/container/detail/type_traits.hpp>
namespace boost{
namespace interprocess_container {
namespace containers_detail {
//using namespace boost;
template <class T, unsigned V>
struct version_type
: public containers_detail::integral_constant<unsigned, V>
{
typedef T type;
version_type(const version_type<T, 0>&);
};
namespace impl{
template <class T,
bool = containers_detail::is_convertible<version_type<T, 0>, typename T::version>::value>
struct extract_version
{
static const unsigned value = 1;
};
template <class T>
struct extract_version<T, true>
{
static const unsigned value = T::version::value;
};
template <class T>
struct has_version
{
private:
struct two {char _[2];};
template <class U> static two test(...);
template <class U> static char test(const typename U::version*);
public:
static const bool value = sizeof(test<T>(0)) == 1;
void dummy(){}
};
template <class T, bool = has_version<T>::value>
struct version
{
static const unsigned value = 1;
};
template <class T>
struct version<T, true>
{
static const unsigned value = extract_version<T>::value;
};
} //namespace impl
template <class T>
struct version
: public containers_detail::integral_constant<unsigned, impl::version<T>::value>
{
};
} //namespace containers_detail {
} //namespace interprocess_container {
} //namespace boost{
#endif //#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP

View File

@@ -0,0 +1,24 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. 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_CONTAINERS_DETAIL_WORKAROUND_HPP
#define BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
#include <boost/interprocess/containers/container/detail/config_begin.hpp>
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)\
&& !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
#define BOOST_CONTAINERS_PERFECT_FORWARDING
#endif
#include <boost/interprocess/containers/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff