Update of /cvsroot/boost/boost/boost/interprocess/detail
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv22035/detail
Modified Files:
move.hpp named_proxy.hpp type_traits.hpp utilities.hpp
Added Files:
segment_manager_helper.hpp
Log Message:
New Interprocess version
--- NEW FILE: segment_manager_helper.hpp ---
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
#define BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/in_place_interface.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <cstddef> //std::size_t
#include <string> //char_traits
#include <new> //std::nothrow
#include <utility> //std::pair
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
#endif
/*!\file
Describes the object placed in a memory segment that provides
named object allocation capabilities for single-segment and
multi-segment allocations.
*/
namespace boost{
namespace interprocess{
template<class MemoryManager>
class segment_manager_base;
//!An integer that describes the type of the
//!instance constructed in memory
enum instance_type { anonymous_type, named_type, unique_type,
max_allocation_type };
namespace detail{
template<class MemoryAlgorithm>
class mem_algo_deallocator
{
void * m_ptr;
MemoryAlgorithm & m_algo;
public:
mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo)
: m_ptr(ptr), m_algo(algo)
{}
void release()
{ m_ptr = 0; }
~mem_algo_deallocator()
{ if(m_ptr) m_algo.deallocate(m_ptr); }
};
/// @cond
struct block_header
{
std::size_t m_value_bytes;
unsigned short m_num_char;
unsigned char m_value_alignment;
unsigned char m_alloc_type_sizeof_char;
block_header(std::size_t value_bytes
,std::size_t value_alignment
,std::size_t allocation_type
,std::size_t sizeof_char
,std::size_t num_char
)
: m_value_bytes(value_bytes)
, m_num_char(num_char)
, m_value_alignment(value_alignment)
, m_alloc_type_sizeof_char
( ((unsigned char)allocation_type << 5u) |
((unsigned char)sizeof_char & 0x1F) )
{};
template<class T>
block_header &operator= (const T& )
{ return *this; }
std::size_t total_size() const
{
if(allocation_type() != anonymous_type){
return name_offset() + (m_num_char+1)*sizeof_char();
}
else{
return value_offset() + m_value_bytes;
}
}
std::size_t value_bytes() const
{ return m_value_bytes; }
template<class Header>
std::size_t total_size_with_header() const
{
return get_rounded_size
( sizeof(Header)
, detail::alignment_of<block_header>::value)
+ total_size();
}
std::size_t allocation_type() const
{ return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; }
std::size_t sizeof_char() const
{ return m_alloc_type_sizeof_char & (unsigned char)0x1F; }
template<class CharType>
CharType *name() const
{
return reinterpret_cast<CharType*>
(detail::char_ptr_cast(this) + name_offset());
}
std::size_t name_length() const
{ return m_num_char; }
std::size_t name_offset() const
{
return value_offset() + get_rounded_size(m_value_bytes, sizeof_char());
}
void *value() const
{
return detail::char_ptr_cast(this) + value_offset();
}
std::size_t value_offset() const
{
return get_rounded_size(sizeof(block_header), m_value_alignment);
}
template<class CharType>
bool less(const block_header &b) const
{
return m_num_char < b.m_num_char ||
(m_num_char < b.m_num_char &&
std::char_traits<CharType>::compare
(name<CharType>(), b.name<CharType>(), m_num_char) < 0);
}
template<class CharType>
bool equal(const block_header &b) const
{
return m_num_char == b.m_num_char &&
std::char_traits<CharType>::compare
(name<CharType>(), b.name<CharType>(), m_num_char) == 0;
}
template<class T>
static block_header *block_header_from_value(T *value)
{ return block_header_from_value(value, sizeof(T),
detail::alignment_of<T>::value); }
static block_header *block_header_from_value(const void *value, std::size_t
sz, std::size_t algn)
{
block_header * hdr =
reinterpret_cast<block_header*>(detail::char_ptr_cast(value) -
get_rounded_size(sizeof(block_header), algn));
(void)sz;
//Some sanity checks
assert(hdr->m_value_alignment == algn);
assert(hdr->m_value_bytes % sz == 0);
return hdr;
}
template<class Header>
static block_header *from_first_header(Header *header)
{
block_header * hdr =
reinterpret_cast<block_header*>(detail::char_ptr_cast(header) +
get_rounded_size(sizeof(Header),
detail::alignment_of<block_header>::value));
//Some sanity checks
return hdr;
}
template<class Header>
static Header *to_first_header(block_header *bheader)
{
Header * hdr =
reinterpret_cast<Header*>(detail::char_ptr_cast(bheader) -
get_rounded_size(sizeof(Header),
detail::alignment_of<block_header>::value));
//Some sanity checks
return hdr;
}
};
inline void array_construct(void *mem, std::size_t num,
detail::in_place_interface &table)
{
//Try constructors
std::size_t constructed = 0;
BOOST_TRY{
table.construct_n(mem, num, constructed);
}
//If there is an exception call destructors and erase index node
BOOST_CATCH(...){
std::size_t destroyed = 0;
table.destroy_n(mem, constructed, destroyed);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
//Anti-exception node eraser
template<class Cont>
class value_eraser
{
public:
value_eraser(Cont & cont, typename Cont::iterator it)
: m_cont(cont), m_index_it(it), m_erase(true){}
~value_eraser()
{ if(m_erase) m_cont.erase(m_index_it); }
void release() { m_erase = false; }
private:
Cont &m_cont;
typename Cont::iterator m_index_it;
bool m_erase;
};
template<class CharT>
struct intrusive_compare_key
{
typedef CharT char_type;
intrusive_compare_key(const CharT *str, std::size_t len)
: mp_str(str), m_len(len)
{}
const CharT * mp_str;
std::size_t m_len;
};
//!This struct indicates an anonymous object creation
//!allocation
template<instance_type type>
class instance_t
{
instance_t(){}
};
template<class T>
struct char_if_void
{
typedef T type;
};
template<>
struct char_if_void<void>
{
typedef char type;
};
typedef instance_t<anonymous_type> anonymous_instance_t;
typedef instance_t<unique_type> unique_instance_t;
template<class Hook, class CharType>
struct intrusive_value_type_impl
: public Hook
{
private:
//Non-copyable
intrusive_value_type_impl(const intrusive_value_type_impl &);
intrusive_value_type_impl& operator=(const intrusive_value_type_impl &);
public:
typedef CharType char_type;
intrusive_value_type_impl(){}
enum { BlockHdrAlignment = detail::alignment_of<block_header>::value };
block_header *get_block_header() const
{
return (block_header *)(detail::char_ptr_cast(this) +
get_rounded_size(sizeof(*this), BlockHdrAlignment));
}
bool operator <(const intrusive_value_type_impl<Hook, CharType> & other)
const
{ return this->get_block_header()->template
less<CharType>(*other.get_block_header()); }
bool operator ==(const intrusive_value_type_impl<Hook, CharType> & other)
const
{ return this->get_block_header()->template
equal<CharType>(*other.get_block_header()); }
static intrusive_value_type_impl *get_intrusive_value_type(block_header *hdr)
{
return (intrusive_value_type_impl *)(detail::char_ptr_cast(hdr) -
get_rounded_size(sizeof(intrusive_value_type_impl),
BlockHdrAlignment));
}
CharType *name() const
{ return get_block_header()->template name<CharType>(); }
std::size_t name_length() const
{ return get_block_header()->name_length(); }
void *value() const
{ return get_block_header()->value(); }
};
template<class CharType>
class char_ptr_holder
{
public:
char_ptr_holder(const CharType *name)
: m_name(name)
{}
char_ptr_holder(const detail::anonymous_instance_t *)
: m_name((CharType*)0)
{}
char_ptr_holder(const detail::unique_instance_t *)
: m_name((CharType*)-1)
{}
operator const CharType *()
{ return m_name; }
private:
const CharType *m_name;
};
//!The key of the the named allocation information index. Stores an offset
pointer
//!to a null terminated string and the length of the string to speed up sorting
template<class CharT, class VoidPointer>
struct index_key
{
typedef typename detail::
pointer_to_other<VoidPointer, const CharT>::type const_char_ptr_t;
typedef CharT char_type;
private:
//Offset pointer to the object's name
const_char_ptr_t mp_str;
//Length of the name buffer (null NOT included)
std::size_t m_len;
public:
//!Constructor of the key
index_key (const char_type *name, std::size_t length)
: mp_str(name), m_len(length) {}
//!Less than function for index ordering
bool operator < (const index_key & right) const
{
return (m_len < right.m_len) ||
(m_len == right.m_len &&
std::char_traits<char_type>::compare
(detail::get_pointer(mp_str)
,detail::get_pointer(right.mp_str), m_len) < 0);
}
//!Equal to function for index ordering
bool operator == (const index_key & right) const
{
return m_len == right.m_len &&
std::char_traits<char_type>::compare
(detail::get_pointer(mp_str),
detail::get_pointer(right.mp_str), m_len) == 0;
}
void name(const CharT *name)
{ mp_str = name; }
void name_length(std::size_t len)
{ m_len = len; }
const CharT *name() const
{ return detail::get_pointer(mp_str); }
std::size_t name_length() const
{ return m_len; }
};
//!The index_data stores a pointer to a buffer and the element count needed
//!to know how many destructors must be called when calling destroy
template<class VoidPointer>
struct index_data
{
typedef VoidPointer void_ptr;
void_ptr m_ptr;
index_data(void *ptr) : m_ptr(ptr){}
void *value() const
{ return (void*)detail::get_pointer(m_ptr); }
};
template<class MemoryAlgorithm>
struct segment_manager_base_type
{ typedef segment_manager_base<MemoryAlgorithm> type; };
template<class CharT, class MemoryAlgorithm>
struct index_config
{
typedef typename MemoryAlgorithm::void_pointer void_pointer;
typedef CharT char_type;
typedef detail::index_key<CharT, void_pointer> key_type;
typedef detail::index_data<void_pointer> mapped_type;
typedef typename segment_manager_base_type
<MemoryAlgorithm>::type segment_manager_base;
template<class HeaderBase>
struct intrusive_value_type
{ typedef detail::intrusive_value_type_impl<HeaderBase, CharT> type; };
typedef intrusive_compare_key<CharT> intrusive_compare_key_type;
};
template<class Iterator, bool intrusive>
class segment_manager_iterator_value_adaptor
{
typedef typename Iterator::value_type iterator_val_t;
typedef typename iterator_val_t::char_type char_type;
public:
segment_manager_iterator_value_adaptor(const typename Iterator::value_type
&val)
: m_val(&val)
{}
const char_type *name() const
{ return m_val->name(); }
std::size_t name_length() const
{ return m_val->name_length(); }
const void *value() const
{ return m_val->value(); }
const typename Iterator::value_type *m_val;
};
template<class Iterator>
class segment_manager_iterator_value_adaptor<Iterator, false>
{
typedef typename Iterator::value_type iterator_val_t;
typedef typename iterator_val_t::first_type first_type;
typedef typename iterator_val_t::second_type second_type;
typedef typename first_type::char_type char_type;
public:
segment_manager_iterator_value_adaptor(const typename Iterator::value_type
&val)
: m_val(&val)
{}
const char_type *name() const
{ return m_val->first.name(); }
std::size_t name_length() const
{ return m_val->first.name_length(); }
const void *value() const
{
return reinterpret_cast<block_header*>
(detail::get_pointer(m_val->second.m_ptr))->value();
}
const typename Iterator::value_type *m_val;
};
template<class Iterator, bool intrusive>
struct segment_manager_iterator_transform
: std::unary_function< typename Iterator::value_type
, segment_manager_iterator_value_adaptor<Iterator,
intrusive> >
{
typedef segment_manager_iterator_value_adaptor<Iterator, intrusive>
result_type;
result_type operator()(const typename Iterator::value_type &arg) const
{ return result_type(arg); }
};
} //namespace detail {
}} //namespace boost { namespace interprocess
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
Index: move.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/detail/move.hpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- move.hpp 23 Jun 2007 12:53:00 -0000 1.6
+++ move.hpp 22 Jul 2007 14:05:53 -0000 1.7
@@ -117,6 +117,8 @@
#else //#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#include <boost/interprocess/detail/type_traits.hpp>
+
namespace boost {
namespace interprocess {
Index: named_proxy.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/detail/named_proxy.hpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- named_proxy.hpp 23 Jun 2007 12:53:00 -0000 1.5
+++ named_proxy.hpp 22 Jul 2007 14:05:53 -0000 1.6
@@ -26,6 +26,7 @@
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/interprocess/detail/mpl.hpp>
+#include <iterator>
/*!\file
Describes a proxy class that implements named allocation syntax.
@@ -40,14 +41,13 @@
struct Ctor0Arg : public placement_destroy<T>
{
typedef Ctor0Arg self_t;
- typedef T target_t;
Ctor0Arg(){}
self_t& operator++() { return *this; }
self_t operator++(int) { return *this; }
- virtual void construct(void *mem)
+ void construct(void *mem)
{ new(mem)T; }
virtual void construct_n(void *mem, std::size_t num, std::size_t
&constructed)
@@ -65,9 +65,10 @@
////////////////////////////////////////////////////////////////
// What the macro should generate (n == 2):
//
-// template<class T, bool param_or_it, class P1, class P2>
+// template<class T, bool is_iterator, class P1, class P2>
// struct Ctor2Arg
// {
+// typedef detail::bool_<is_iterator> IsIterator;
// typedef Ctor2Arg self_t;
//
// void do_increment(detail::false_)
@@ -77,8 +78,7 @@
//
// self_t& operator++()
// {
-// typedef detail::bool_<param_or_it> Result;
-// this->do_increment(Result());
+// this->do_increment(IsIterator());
// return *this;
// }
//
@@ -87,7 +87,7 @@
// Ctor2Arg(const P1 &p1, const P2 &p2)
// : p1((P1 &)p_1), p2((P2 &)p_2) {}
//
-// virtual void construct(void *mem)
+// void construct(void *mem)
// { new(object)T(m_p1, m_p2); }
//
// virtual void construct_n(void *mem
@@ -96,13 +96,18 @@
// {
// T* memory = static_cast<T*>(mem);
// for(constructed = 0; constructed < num; ++constructed){
-// new(memory++)T(m_p1, m_p2);
-// typedef detail::bool_<param_or_it> Result;
-// this->do_increment(Result());
+// this->construct(memory++, IsIterator());
+// this->do_increment(IsIterator());
// }
// }
//
-// private:
+// private:
+// void construct(void *mem, detail::true_)
+// { new(mem)T(*m_p1, *m_p2); }
+//
+// void construct(void *mem, detail::false_)
+// { new(mem)T(m_p1, m_p2); }
+//
// P1 &m_p1; P2 &m_p2;
// };
////////////////////////////////////////////////////////////////
@@ -128,54 +133,53 @@
#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
-#define BOOST_INTERPROCESS_AUX_PARAM_DEREFERENCE(z, n, data) \
- BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
/**/
-#define BOOST_PP_LOCAL_MACRO(n) \
- template<class T, bool param_or_it, BOOST_PP_ENUM_PARAMS(n, class P) >\
- struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
- : public placement_destroy<T>
\
- { \
- typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t; \
- typedef T target_t; \
- \
- void do_increment(detail::false_) \
- { BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); } \
- \
- void do_increment(detail::true_){} \
- \
- self_t& operator++() \
- { \
- typedef detail::bool_<param_or_it> Result; \
- this->do_increment(Result()); \
- return *this; \
- } \
- \
- self_t operator++(int) { return ++*this; *this; } \
- \
- BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
- ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _) ) \
- : BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {} \
- \
- virtual void construct(void *mem) \
- { new(mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
- \
- virtual void construct_n(void *mem \
- , std::size_t num \
- , std::size_t &constructed) \
- { \
- T* memory = static_cast<T*>(mem); \
- for(constructed = 0; constructed < num; ++constructed){ \
- new(memory++)T(BOOST_PP_ENUM_PARAMS(n, m_p)); \
- typedef detail::bool_<param_or_it> Result; \
- this->do_increment(Result()); \
- } \
- } \
- \
- private: \
- BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
- }; \
+#define BOOST_PP_LOCAL_MACRO(n) \
+ template<class T, bool is_iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
+ struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
+ : public placement_destroy<T> \
+ { \
+ typedef detail::bool_<is_iterator> IsIterator; \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t; \
+ \
+ void do_increment(detail::true_) \
+ { BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); } \
+ \
+ void do_increment(detail::false_){} \
+ \
+ self_t& operator++() \
+ { \
+ this->do_increment(IsIterator()); \
+ return *this; \
+ } \
+ \
+ self_t operator++(int) { return ++*this; *this; } \
+ \
+ BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
+ ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _) ) \
+ : BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {} \
+ \
+ virtual void construct_n(void *mem \
+ , std::size_t num \
+ , std::size_t &constructed) \
+ { \
+ T* memory = static_cast<T*>(mem); \
+ for(constructed = 0; constructed < num; ++constructed){ \
+ this->construct(memory++, IsIterator()); \
+ this->do_increment(IsIterator()); \
+ } \
+ } \
+ \
+ private: \
+ void construct(void *mem, detail::true_) \
+ { new(mem)T(BOOST_PP_ENUM_PARAMS(n, *m_p)); } \
+ \
+ void construct(void *mem, detail::false_) \
+ { new(mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
+ \
+ BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
+ }; \
/**/
@@ -192,12 +196,12 @@
template
< class SegmentManager //segment manager to construct the object
, class T //type of object to build
- , bool param_or_it //passing parameters are normal object or iterators?
+ , bool is_iterator //passing parameters are normal object or iterators?
>
class named_proxy
{
typedef typename SegmentManager::char_type char_type;
- const char_type * mp_name;
+ const char_type * mp_name;
SegmentManager * mp_mngr;
mutable std::size_t m_num;
const bool m_find;
@@ -232,7 +236,7 @@
T *operator()(BOOST_PP_ENUM (n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _))
const \
{ \
typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
- <T, param_or_it, BOOST_PP_ENUM (n,
BOOST_INTERPROCESS_AUX_TYPE_LIST, _)> \
+ <T, is_iterator, BOOST_PP_ENUM (n,
BOOST_INTERPROCESS_AUX_TYPE_LIST, _)> \
ctor_obj_t; \
ctor_obj_t ctor_obj (BOOST_PP_ENUM_PARAMS(n, p)); \
return mp_mngr->template generic_construct<T> \
@@ -253,7 +257,7 @@
// T *operator()(P1 &p1, P2 &p2) const
// {
// typedef Ctor2Arg
- // <T, param_or_it, P1, P2>
+ // <T, is_iterator, P1, P2>
// ctor_obj_t;
// ctor_obj_t ctor_obj(p1, p2);
//
Index: type_traits.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/detail/type_traits.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- type_traits.hpp 23 Jun 2007 12:53:54 -0000 1.1
+++ type_traits.hpp 22 Jul 2007 14:05:55 -0000 1.2
@@ -25,6 +25,8 @@
namespace interprocess {
namespace detail {
+struct nat{};
+
//boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative
template <typename T> struct alignment_of;
@@ -118,13 +120,13 @@
template<>
struct add_reference<void>
{
- typedef int& type;
+ typedef nat& type;
};
template<>
struct add_reference<const void>
{
- typedef int& type;
+ typedef const nat& type;
};
template <typename T, typename U>
struct is_same
Index: utilities.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/detail/utilities.hpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- utilities.hpp 23 Jun 2007 12:53:54 -0000 1.8
+++ utilities.hpp 22 Jul 2007 14:05:55 -0000 1.9
@@ -67,13 +67,13 @@
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
template <class Allocator>
-struct scoped_ptr_deallocator
+struct scoped_ptr_dealloc_functor
{
typedef typename Allocator::pointer pointer;
Allocator& m_alloc;
- scoped_ptr_deallocator(Allocator& a)
+ scoped_ptr_dealloc_functor(Allocator& a)
: m_alloc(a) {}
void operator()(pointer ptr)
@@ -81,24 +81,6 @@
};
//!A deleter for scoped_ptr that deallocates the memory
-//!allocated for an array of objects using a STL allocator.
-template <class Allocator>
-struct scoped_ptr_array_deallocator
-{
- typedef typename Allocator::pointer pointer;
-
- scoped_ptr_array_deallocator(Allocator& a, std::size_t length)
- : m_alloc(a), m_length(length) {}
-
- void operator()(pointer &ptr)
- { m_alloc.deallocate(ptr, m_length); }
-
- private:
- Allocator& m_alloc;
- std::size_t m_length;
-};
-
-//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
template <class Allocator>
struct scoped_deallocator
@@ -185,6 +167,62 @@
}
};
+//!A class used for exception-safe multi-allocation + construction.
+template <class Allocator>
+struct multiallocation_deallocator
+{
+ typedef typename Allocator::multiallocation_iterator
multiallocation_iterator;
+
+ multiallocation_iterator m_itbeg;
+ Allocator& m_alloc;
+
+ multiallocation_deallocator(multiallocation_iterator itbeg, Allocator& a)
+ : m_itbeg(itbeg), m_alloc(a) {}
+
+ ~multiallocation_deallocator()
+ {
+ multiallocation_iterator endit;
+ while(m_itbeg != endit){
+ m_alloc.deallocate(&*m_itbeg, 1);
+ ++m_itbeg;
+ }
+ }
+
+ void release()
+ { m_itbeg = multiallocation_iterator(); }
+};
+
+
+//!A class used for exception-safe multi-allocation + construction.
+template <class Allocator>
+struct multiallocation_destroy_dealloc
+{
+ typedef typename Allocator::multiallocation_iterator
multiallocation_iterator;
+ typedef typename Allocator::value_type value_type;
+
+ multiallocation_iterator m_itbeg;
+ Allocator& m_alloc;
+
+ multiallocation_destroy_dealloc(multiallocation_iterator itbeg, Allocator&
a)
+ : m_itbeg(itbeg), m_alloc(a) {}
+
+ ~multiallocation_destroy_dealloc()
+ {
+ multiallocation_iterator endit;
+ while(m_itbeg != endit){
+ detail::get_pointer(&*m_itbeg)->~value_type();
+ m_alloc.deallocate(&*m_itbeg, 1);
+ ++m_itbeg;
+ }
+ }
+
+ void next()
+ { ++m_itbeg; }
+
+ void release()
+ { m_itbeg = multiallocation_iterator(); }
+};
+
/*!Forces a cast from any pointer to char * pointer*/
template<class T>
inline char* char_ptr_cast(T *ptr)
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs