1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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_HEAP_ALLOCATOR_V1_HPP
#define BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/move/adl_move_swap.hpp>
//!\file
//!Describes an heap_allocator_v1 that allocates portions of fixed size
//!memory buffer (shared memory, mapped file...)
namespace boost {
namespace interprocess {
namespace test {
//!An STL compatible heap_allocator_v1 that uses a segment manager as
//!memory source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the heap_allocator_v1 in shared memory, memory mapped-files, etc...*/
template<class T, class SegmentManager>
class heap_allocator_v1
{
private:
typedef heap_allocator_v1<T, SegmentManager> self_t;
typedef SegmentManager segment_manager;
typedef typename segment_manager::void_pointer aux_pointer_t;
typedef typename boost::intrusive::
pointer_traits<aux_pointer_t>::template
rebind_pointer<const void>::type cvoid_ptr;
typedef typename boost::intrusive::
pointer_traits<cvoid_ptr>::template
rebind_pointer<segment_manager>::type alloc_ptr_t;
template<class T2, class SegmentManager2>
heap_allocator_v1& operator=(const heap_allocator_v1<T2, SegmentManager2>&);
heap_allocator_v1& operator=(const heap_allocator_v1&);
alloc_ptr_t mp_mngr;
public:
typedef T value_type;
typedef typename boost::intrusive::
pointer_traits<cvoid_ptr>::template
rebind_pointer<T>::type pointer;
typedef typename boost::intrusive::
pointer_traits<cvoid_ptr>::template
rebind_pointer<const T>::type const_pointer;
typedef typename ipcdetail::add_reference
<value_type>::type reference;
typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename SegmentManager::size_type size_type;
typedef typename SegmentManager::difference_type difference_type;
//!Obtains an heap_allocator_v1 of other type
template<class T2>
struct rebind
{
typedef heap_allocator_v1<T2, SegmentManager> other;
};
//!Returns the segment manager. Never throws
segment_manager* get_segment_manager()const
{ return ipcdetail::to_raw_pointer(mp_mngr); }
//!Returns address of mutable object. Never throws
pointer address(reference value) const
{ return pointer(addressof(value)); }
//!Returns address of non mutable object. Never throws
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
//!Constructor from the segment manager. Never throws
heap_allocator_v1(segment_manager *segment_mngr)
: mp_mngr(segment_mngr) { }
//!Constructor from other heap_allocator_v1. Never throws
heap_allocator_v1(const heap_allocator_v1 &other)
: mp_mngr(other.get_segment_manager()){ }
//!Constructor from related heap_allocator_v1. Never throws
template<class T2>
heap_allocator_v1(const heap_allocator_v1<T2, SegmentManager> &other)
: mp_mngr(other.get_segment_manager()){}
//!Allocates memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_ptr hint = 0)
{
(void)hint;
char *raw_mem = ::new char[sizeof(value_type)*count];
return boost::intrusive::pointer_traits<pointer>::pointer_to(reinterpret_cast<value_type &>(*raw_mem));
}
//!Deallocates memory previously allocated. Never throws
void deallocate(const pointer &ptr, size_type)
{ return ::delete[] ipcdetail::to_raw_pointer(ptr) ; }
//!Construct object, calling constructor.
//!Throws if T(const T&) throws
void construct(const pointer &ptr, const_reference value)
{ new((void*)ipcdetail::to_raw_pointer(ptr)) value_type(value); }
//!Destroys object. Throws if object's destructor throws
void destroy(const pointer &ptr)
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
//!Returns the number of elements that could be allocated. Never throws
size_type max_size() const
{ return mp_mngr->get_size(); }
//!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in
//!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ ::boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
};
//!Equality test for same type of heap_allocator_v1
template<class T, class SegmentManager> inline
bool operator==(const heap_allocator_v1<T , SegmentManager> &alloc1,
const heap_allocator_v1<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
//!Inequality test for same type of heap_allocator_v1
template<class T, class SegmentManager> inline
bool operator!=(const heap_allocator_v1<T, SegmentManager> &alloc1,
const heap_allocator_v1<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
} //namespace test {
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP
|