Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/interprocess for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
|
Chris@16
|
12 #define BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
|
Chris@16
|
13
|
Chris@101
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
15 # include <boost/config.hpp>
|
Chris@101
|
16 #endif
|
Chris@101
|
17 #
|
Chris@101
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@16
|
19 # pragma once
|
Chris@16
|
20 #endif
|
Chris@16
|
21
|
Chris@16
|
22 #include <boost/interprocess/detail/config_begin.hpp>
|
Chris@16
|
23 #include <boost/interprocess/detail/workaround.hpp>
|
Chris@16
|
24
|
Chris@101
|
25 // interprocess
|
Chris@101
|
26 #include <boost/interprocess/exceptions.hpp>
|
Chris@101
|
27 // interprocess/detail
|
Chris@16
|
28 #include <boost/interprocess/detail/type_traits.hpp>
|
Chris@16
|
29 #include <boost/interprocess/detail/utilities.hpp>
|
Chris@16
|
30 #include <boost/interprocess/detail/in_place_interface.hpp>
|
Chris@101
|
31 // container/detail
|
Chris@101
|
32 #include <boost/container/detail/type_traits.hpp> //alignment_of
|
Chris@101
|
33 #include <boost/container/detail/minimal_char_traits_header.hpp>
|
Chris@101
|
34 // intrusive
|
Chris@16
|
35 #include <boost/intrusive/pointer_traits.hpp>
|
Chris@101
|
36 // move/detail
|
Chris@101
|
37 #include <boost/move/detail/type_traits.hpp> //make_unsigned
|
Chris@101
|
38 // other boost
|
Chris@101
|
39 #include <boost/assert.hpp> //BOOST_ASSERT
|
Chris@101
|
40 #include <boost/core/no_exceptions_support.hpp>
|
Chris@101
|
41 // std
|
Chris@16
|
42 #include <cstddef> //std::size_t
|
Chris@16
|
43
|
Chris@16
|
44 //!\file
|
Chris@16
|
45 //!Describes the object placed in a memory segment that provides
|
Chris@16
|
46 //!named object allocation capabilities.
|
Chris@16
|
47
|
Chris@16
|
48 namespace boost{
|
Chris@16
|
49 namespace interprocess{
|
Chris@16
|
50
|
Chris@16
|
51 template<class MemoryManager>
|
Chris@16
|
52 class segment_manager_base;
|
Chris@16
|
53
|
Chris@16
|
54 //!An integer that describes the type of the
|
Chris@16
|
55 //!instance constructed in memory
|
Chris@16
|
56 enum instance_type { anonymous_type, named_type, unique_type, max_allocation_type };
|
Chris@16
|
57
|
Chris@16
|
58 namespace ipcdetail{
|
Chris@16
|
59
|
Chris@16
|
60 template<class MemoryAlgorithm>
|
Chris@16
|
61 class mem_algo_deallocator
|
Chris@16
|
62 {
|
Chris@16
|
63 void * m_ptr;
|
Chris@16
|
64 MemoryAlgorithm & m_algo;
|
Chris@16
|
65
|
Chris@16
|
66 public:
|
Chris@16
|
67 mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo)
|
Chris@16
|
68 : m_ptr(ptr), m_algo(algo)
|
Chris@16
|
69 {}
|
Chris@16
|
70
|
Chris@16
|
71 void release()
|
Chris@16
|
72 { m_ptr = 0; }
|
Chris@16
|
73
|
Chris@16
|
74 ~mem_algo_deallocator()
|
Chris@16
|
75 { if(m_ptr) m_algo.deallocate(m_ptr); }
|
Chris@16
|
76 };
|
Chris@16
|
77
|
Chris@16
|
78 template<class size_type>
|
Chris@16
|
79 struct block_header
|
Chris@16
|
80 {
|
Chris@16
|
81 size_type m_value_bytes;
|
Chris@16
|
82 unsigned short m_num_char;
|
Chris@16
|
83 unsigned char m_value_alignment;
|
Chris@16
|
84 unsigned char m_alloc_type_sizeof_char;
|
Chris@16
|
85
|
Chris@16
|
86 block_header(size_type val_bytes
|
Chris@16
|
87 ,size_type val_alignment
|
Chris@16
|
88 ,unsigned char al_type
|
Chris@16
|
89 ,std::size_t szof_char
|
Chris@16
|
90 ,std::size_t num_char
|
Chris@16
|
91 )
|
Chris@16
|
92 : m_value_bytes(val_bytes)
|
Chris@16
|
93 , m_num_char((unsigned short)num_char)
|
Chris@16
|
94 , m_value_alignment((unsigned char)val_alignment)
|
Chris@16
|
95 , m_alloc_type_sizeof_char( (al_type << 5u) | ((unsigned char)szof_char & 0x1F) )
|
Chris@16
|
96 {};
|
Chris@16
|
97
|
Chris@16
|
98 template<class T>
|
Chris@16
|
99 block_header &operator= (const T& )
|
Chris@16
|
100 { return *this; }
|
Chris@16
|
101
|
Chris@16
|
102 size_type total_size() const
|
Chris@16
|
103 {
|
Chris@16
|
104 if(alloc_type() != anonymous_type){
|
Chris@16
|
105 return name_offset() + (m_num_char+1)*sizeof_char();
|
Chris@16
|
106 }
|
Chris@16
|
107 else{
|
Chris@16
|
108 return this->value_offset() + m_value_bytes;
|
Chris@16
|
109 }
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 size_type value_bytes() const
|
Chris@16
|
113 { return m_value_bytes; }
|
Chris@16
|
114
|
Chris@16
|
115 template<class Header>
|
Chris@16
|
116 size_type total_size_with_header() const
|
Chris@16
|
117 {
|
Chris@16
|
118 return get_rounded_size
|
Chris@16
|
119 ( size_type(sizeof(Header))
|
Chris@101
|
120 , size_type(::boost::container::container_detail::alignment_of<block_header<size_type> >::value))
|
Chris@16
|
121 + total_size();
|
Chris@16
|
122 }
|
Chris@16
|
123
|
Chris@16
|
124 unsigned char alloc_type() const
|
Chris@16
|
125 { return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; }
|
Chris@16
|
126
|
Chris@16
|
127 unsigned char sizeof_char() const
|
Chris@16
|
128 { return m_alloc_type_sizeof_char & (unsigned char)0x1F; }
|
Chris@16
|
129
|
Chris@16
|
130 template<class CharType>
|
Chris@16
|
131 CharType *name() const
|
Chris@16
|
132 {
|
Chris@16
|
133 return const_cast<CharType*>(reinterpret_cast<const CharType*>
|
Chris@16
|
134 (reinterpret_cast<const char*>(this) + name_offset()));
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 unsigned short name_length() const
|
Chris@16
|
138 { return m_num_char; }
|
Chris@16
|
139
|
Chris@16
|
140 size_type name_offset() const
|
Chris@16
|
141 {
|
Chris@16
|
142 return this->value_offset() + get_rounded_size(size_type(m_value_bytes), size_type(sizeof_char()));
|
Chris@16
|
143 }
|
Chris@16
|
144
|
Chris@16
|
145 void *value() const
|
Chris@16
|
146 {
|
Chris@16
|
147 return const_cast<char*>((reinterpret_cast<const char*>(this) + this->value_offset()));
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 size_type value_offset() const
|
Chris@16
|
151 {
|
Chris@16
|
152 return get_rounded_size(size_type(sizeof(block_header<size_type>)), size_type(m_value_alignment));
|
Chris@16
|
153 }
|
Chris@16
|
154
|
Chris@16
|
155 template<class CharType>
|
Chris@16
|
156 bool less_comp(const block_header<size_type> &b) const
|
Chris@16
|
157 {
|
Chris@16
|
158 return m_num_char < b.m_num_char ||
|
Chris@16
|
159 (m_num_char < b.m_num_char &&
|
Chris@101
|
160 std::char_traits<CharType>::compare(name<CharType>(), b.name<CharType>(), m_num_char) < 0);
|
Chris@16
|
161 }
|
Chris@16
|
162
|
Chris@16
|
163 template<class CharType>
|
Chris@16
|
164 bool equal_comp(const block_header<size_type> &b) const
|
Chris@16
|
165 {
|
Chris@16
|
166 return m_num_char == b.m_num_char &&
|
Chris@101
|
167 std::char_traits<CharType>::compare(name<CharType>(), b.name<CharType>(), m_num_char) == 0;
|
Chris@16
|
168 }
|
Chris@16
|
169
|
Chris@16
|
170 template<class T>
|
Chris@16
|
171 static block_header<size_type> *block_header_from_value(T *value)
|
Chris@101
|
172 { return block_header_from_value(value, sizeof(T), ::boost::container::container_detail::alignment_of<T>::value); }
|
Chris@16
|
173
|
Chris@16
|
174 static block_header<size_type> *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
|
Chris@16
|
175 {
|
Chris@16
|
176 block_header * hdr =
|
Chris@16
|
177 const_cast<block_header*>
|
Chris@16
|
178 (reinterpret_cast<const block_header*>(reinterpret_cast<const char*>(value) -
|
Chris@16
|
179 get_rounded_size(sizeof(block_header), algn)));
|
Chris@16
|
180 (void)sz;
|
Chris@16
|
181 //Some sanity checks
|
Chris@16
|
182 BOOST_ASSERT(hdr->m_value_alignment == algn);
|
Chris@16
|
183 BOOST_ASSERT(hdr->m_value_bytes % sz == 0);
|
Chris@16
|
184 return hdr;
|
Chris@16
|
185 }
|
Chris@16
|
186
|
Chris@16
|
187 template<class Header>
|
Chris@16
|
188 static block_header<size_type> *from_first_header(Header *header)
|
Chris@16
|
189 {
|
Chris@16
|
190 block_header<size_type> * hdr =
|
Chris@16
|
191 reinterpret_cast<block_header<size_type>*>(reinterpret_cast<char*>(header) +
|
Chris@101
|
192 get_rounded_size( size_type(sizeof(Header))
|
Chris@101
|
193 , size_type(::boost::container::container_detail::alignment_of<block_header<size_type> >::value)));
|
Chris@16
|
194 //Some sanity checks
|
Chris@16
|
195 return hdr;
|
Chris@16
|
196 }
|
Chris@16
|
197
|
Chris@16
|
198 template<class Header>
|
Chris@16
|
199 static Header *to_first_header(block_header<size_type> *bheader)
|
Chris@16
|
200 {
|
Chris@16
|
201 Header * hdr =
|
Chris@16
|
202 reinterpret_cast<Header*>(reinterpret_cast<char*>(bheader) -
|
Chris@101
|
203 get_rounded_size( size_type(sizeof(Header))
|
Chris@101
|
204 , size_type(::boost::container::container_detail::alignment_of<block_header<size_type> >::value)));
|
Chris@16
|
205 //Some sanity checks
|
Chris@16
|
206 return hdr;
|
Chris@16
|
207 }
|
Chris@16
|
208 };
|
Chris@16
|
209
|
Chris@16
|
210 inline void array_construct(void *mem, std::size_t num, in_place_interface &table)
|
Chris@16
|
211 {
|
Chris@16
|
212 //Try constructors
|
Chris@16
|
213 std::size_t constructed = 0;
|
Chris@16
|
214 BOOST_TRY{
|
Chris@16
|
215 table.construct_n(mem, num, constructed);
|
Chris@16
|
216 }
|
Chris@16
|
217 //If there is an exception call destructors and erase index node
|
Chris@16
|
218 BOOST_CATCH(...){
|
Chris@16
|
219 std::size_t destroyed = 0;
|
Chris@16
|
220 table.destroy_n(mem, constructed, destroyed);
|
Chris@16
|
221 BOOST_RETHROW
|
Chris@16
|
222 }
|
Chris@16
|
223 BOOST_CATCH_END
|
Chris@16
|
224 }
|
Chris@16
|
225
|
Chris@16
|
226 template<class CharT>
|
Chris@16
|
227 struct intrusive_compare_key
|
Chris@16
|
228 {
|
Chris@16
|
229 typedef CharT char_type;
|
Chris@16
|
230
|
Chris@16
|
231 intrusive_compare_key(const CharT *str, std::size_t len)
|
Chris@16
|
232 : mp_str(str), m_len(len)
|
Chris@16
|
233 {}
|
Chris@16
|
234
|
Chris@16
|
235 const CharT * mp_str;
|
Chris@16
|
236 std::size_t m_len;
|
Chris@16
|
237 };
|
Chris@16
|
238
|
Chris@16
|
239 //!This struct indicates an anonymous object creation
|
Chris@16
|
240 //!allocation
|
Chris@16
|
241 template<instance_type type>
|
Chris@16
|
242 class instance_t
|
Chris@16
|
243 {
|
Chris@16
|
244 instance_t(){}
|
Chris@16
|
245 };
|
Chris@16
|
246
|
Chris@16
|
247 template<class T>
|
Chris@16
|
248 struct char_if_void
|
Chris@16
|
249 {
|
Chris@16
|
250 typedef T type;
|
Chris@16
|
251 };
|
Chris@16
|
252
|
Chris@16
|
253 template<>
|
Chris@16
|
254 struct char_if_void<void>
|
Chris@16
|
255 {
|
Chris@16
|
256 typedef char type;
|
Chris@16
|
257 };
|
Chris@16
|
258
|
Chris@16
|
259 typedef instance_t<anonymous_type> anonymous_instance_t;
|
Chris@16
|
260 typedef instance_t<unique_type> unique_instance_t;
|
Chris@16
|
261
|
Chris@16
|
262
|
Chris@16
|
263 template<class Hook, class CharType, class SizeType>
|
Chris@16
|
264 struct intrusive_value_type_impl
|
Chris@16
|
265 : public Hook
|
Chris@16
|
266 {
|
Chris@16
|
267 private:
|
Chris@16
|
268 //Non-copyable
|
Chris@16
|
269 intrusive_value_type_impl(const intrusive_value_type_impl &);
|
Chris@16
|
270 intrusive_value_type_impl& operator=(const intrusive_value_type_impl &);
|
Chris@16
|
271
|
Chris@16
|
272 public:
|
Chris@16
|
273 typedef CharType char_type;
|
Chris@16
|
274 typedef SizeType size_type;
|
Chris@16
|
275
|
Chris@16
|
276 intrusive_value_type_impl(){}
|
Chris@16
|
277
|
Chris@101
|
278 enum { BlockHdrAlignment = ::boost::container::container_detail::alignment_of<block_header<size_type> >::value };
|
Chris@16
|
279
|
Chris@16
|
280 block_header<size_type> *get_block_header() const
|
Chris@16
|
281 {
|
Chris@16
|
282 return const_cast<block_header<size_type>*>
|
Chris@16
|
283 (reinterpret_cast<const block_header<size_type> *>(reinterpret_cast<const char*>(this) +
|
Chris@16
|
284 get_rounded_size(size_type(sizeof(*this)), size_type(BlockHdrAlignment))));
|
Chris@16
|
285 }
|
Chris@16
|
286
|
Chris@16
|
287 bool operator <(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
|
Chris@16
|
288 { return (this->get_block_header())->template less_comp<CharType>(*other.get_block_header()); }
|
Chris@16
|
289
|
Chris@16
|
290 bool operator ==(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
|
Chris@16
|
291 { return (this->get_block_header())->template equal_comp<CharType>(*other.get_block_header()); }
|
Chris@16
|
292
|
Chris@16
|
293 static intrusive_value_type_impl *get_intrusive_value_type(block_header<size_type> *hdr)
|
Chris@16
|
294 {
|
Chris@16
|
295 return reinterpret_cast<intrusive_value_type_impl *>(reinterpret_cast<char*>(hdr) -
|
Chris@16
|
296 get_rounded_size(size_type(sizeof(intrusive_value_type_impl)), size_type(BlockHdrAlignment)));
|
Chris@16
|
297 }
|
Chris@16
|
298
|
Chris@16
|
299 CharType *name() const
|
Chris@16
|
300 { return get_block_header()->template name<CharType>(); }
|
Chris@16
|
301
|
Chris@16
|
302 unsigned short name_length() const
|
Chris@16
|
303 { return get_block_header()->name_length(); }
|
Chris@16
|
304
|
Chris@16
|
305 void *value() const
|
Chris@16
|
306 { return get_block_header()->value(); }
|
Chris@16
|
307 };
|
Chris@16
|
308
|
Chris@16
|
309 template<class CharType>
|
Chris@16
|
310 class char_ptr_holder
|
Chris@16
|
311 {
|
Chris@16
|
312 public:
|
Chris@16
|
313 char_ptr_holder(const CharType *name)
|
Chris@16
|
314 : m_name(name)
|
Chris@16
|
315 {}
|
Chris@16
|
316
|
Chris@16
|
317 char_ptr_holder(const anonymous_instance_t *)
|
Chris@16
|
318 : m_name(static_cast<CharType*>(0))
|
Chris@16
|
319 {}
|
Chris@16
|
320
|
Chris@16
|
321 char_ptr_holder(const unique_instance_t *)
|
Chris@16
|
322 : m_name(reinterpret_cast<CharType*>(-1))
|
Chris@16
|
323 {}
|
Chris@16
|
324
|
Chris@16
|
325 operator const CharType *()
|
Chris@16
|
326 { return m_name; }
|
Chris@16
|
327
|
Chris@101
|
328 const CharType *get() const
|
Chris@101
|
329 { return m_name; }
|
Chris@101
|
330
|
Chris@101
|
331 bool is_unique() const
|
Chris@101
|
332 { return m_name == reinterpret_cast<CharType*>(-1); }
|
Chris@101
|
333
|
Chris@101
|
334 bool is_anonymous() const
|
Chris@101
|
335 { return m_name == static_cast<CharType*>(0); }
|
Chris@101
|
336
|
Chris@16
|
337 private:
|
Chris@16
|
338 const CharType *m_name;
|
Chris@16
|
339 };
|
Chris@16
|
340
|
Chris@16
|
341 //!The key of the the named allocation information index. Stores an offset pointer
|
Chris@16
|
342 //!to a null terminated string and the length of the string to speed up sorting
|
Chris@16
|
343 template<class CharT, class VoidPointer>
|
Chris@16
|
344 struct index_key
|
Chris@16
|
345 {
|
Chris@16
|
346 typedef typename boost::intrusive::
|
Chris@16
|
347 pointer_traits<VoidPointer>::template
|
Chris@16
|
348 rebind_pointer<const CharT>::type const_char_ptr_t;
|
Chris@16
|
349 typedef CharT char_type;
|
Chris@16
|
350 typedef typename boost::intrusive::pointer_traits<const_char_ptr_t>::difference_type difference_type;
|
Chris@101
|
351 typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type;
|
Chris@16
|
352
|
Chris@16
|
353 private:
|
Chris@16
|
354 //Offset pointer to the object's name
|
Chris@16
|
355 const_char_ptr_t mp_str;
|
Chris@16
|
356 //Length of the name buffer (null NOT included)
|
Chris@16
|
357 size_type m_len;
|
Chris@16
|
358 public:
|
Chris@16
|
359
|
Chris@16
|
360 //!Constructor of the key
|
Chris@16
|
361 index_key (const char_type *nm, size_type length)
|
Chris@16
|
362 : mp_str(nm), m_len(length)
|
Chris@16
|
363 {}
|
Chris@16
|
364
|
Chris@16
|
365 //!Less than function for index ordering
|
Chris@16
|
366 bool operator < (const index_key & right) const
|
Chris@16
|
367 {
|
Chris@16
|
368 return (m_len < right.m_len) ||
|
Chris@16
|
369 (m_len == right.m_len &&
|
Chris@101
|
370 std::char_traits<char_type>::compare
|
Chris@101
|
371 (to_raw_pointer(mp_str),to_raw_pointer(right.mp_str), m_len) < 0);
|
Chris@16
|
372 }
|
Chris@16
|
373
|
Chris@16
|
374 //!Equal to function for index ordering
|
Chris@16
|
375 bool operator == (const index_key & right) const
|
Chris@16
|
376 {
|
Chris@16
|
377 return m_len == right.m_len &&
|
Chris@16
|
378 std::char_traits<char_type>::compare
|
Chris@101
|
379 (to_raw_pointer(mp_str), to_raw_pointer(right.mp_str), m_len) == 0;
|
Chris@16
|
380 }
|
Chris@16
|
381
|
Chris@16
|
382 void name(const CharT *nm)
|
Chris@16
|
383 { mp_str = nm; }
|
Chris@16
|
384
|
Chris@16
|
385 void name_length(size_type len)
|
Chris@16
|
386 { m_len = len; }
|
Chris@16
|
387
|
Chris@16
|
388 const CharT *name() const
|
Chris@16
|
389 { return to_raw_pointer(mp_str); }
|
Chris@16
|
390
|
Chris@16
|
391 size_type name_length() const
|
Chris@16
|
392 { return m_len; }
|
Chris@16
|
393 };
|
Chris@16
|
394
|
Chris@16
|
395 //!The index_data stores a pointer to a buffer and the element count needed
|
Chris@16
|
396 //!to know how many destructors must be called when calling destroy
|
Chris@16
|
397 template<class VoidPointer>
|
Chris@16
|
398 struct index_data
|
Chris@16
|
399 {
|
Chris@16
|
400 typedef VoidPointer void_pointer;
|
Chris@16
|
401 void_pointer m_ptr;
|
Chris@101
|
402 explicit index_data(void *ptr) : m_ptr(ptr){}
|
Chris@16
|
403
|
Chris@16
|
404 void *value() const
|
Chris@16
|
405 { return static_cast<void*>(to_raw_pointer(m_ptr)); }
|
Chris@16
|
406 };
|
Chris@16
|
407
|
Chris@16
|
408 template<class MemoryAlgorithm>
|
Chris@16
|
409 struct segment_manager_base_type
|
Chris@16
|
410 { typedef segment_manager_base<MemoryAlgorithm> type; };
|
Chris@16
|
411
|
Chris@16
|
412 template<class CharT, class MemoryAlgorithm>
|
Chris@16
|
413 struct index_config
|
Chris@16
|
414 {
|
Chris@16
|
415 typedef typename MemoryAlgorithm::void_pointer void_pointer;
|
Chris@16
|
416 typedef CharT char_type;
|
Chris@16
|
417 typedef index_key<CharT, void_pointer> key_type;
|
Chris@16
|
418 typedef index_data<void_pointer> mapped_type;
|
Chris@16
|
419 typedef typename segment_manager_base_type
|
Chris@16
|
420 <MemoryAlgorithm>::type segment_manager_base;
|
Chris@16
|
421
|
Chris@16
|
422 template<class HeaderBase>
|
Chris@16
|
423 struct intrusive_value_type
|
Chris@16
|
424 { typedef intrusive_value_type_impl<HeaderBase, CharT, typename segment_manager_base::size_type> type; };
|
Chris@16
|
425
|
Chris@16
|
426 typedef intrusive_compare_key<CharT> intrusive_compare_key_type;
|
Chris@16
|
427 };
|
Chris@16
|
428
|
Chris@16
|
429 template<class Iterator, bool intrusive>
|
Chris@16
|
430 class segment_manager_iterator_value_adaptor
|
Chris@16
|
431 {
|
Chris@16
|
432 typedef typename Iterator::value_type iterator_val_t;
|
Chris@16
|
433 typedef typename iterator_val_t::char_type char_type;
|
Chris@16
|
434
|
Chris@16
|
435 public:
|
Chris@16
|
436 segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
|
Chris@16
|
437 : m_val(&val)
|
Chris@16
|
438 {}
|
Chris@16
|
439
|
Chris@16
|
440 const char_type *name() const
|
Chris@16
|
441 { return m_val->name(); }
|
Chris@16
|
442
|
Chris@16
|
443 unsigned short name_length() const
|
Chris@16
|
444 { return m_val->name_length(); }
|
Chris@16
|
445
|
Chris@16
|
446 const void *value() const
|
Chris@16
|
447 { return m_val->value(); }
|
Chris@16
|
448
|
Chris@16
|
449 const typename Iterator::value_type *m_val;
|
Chris@16
|
450 };
|
Chris@16
|
451
|
Chris@16
|
452
|
Chris@16
|
453 template<class Iterator>
|
Chris@16
|
454 class segment_manager_iterator_value_adaptor<Iterator, false>
|
Chris@16
|
455 {
|
Chris@16
|
456 typedef typename Iterator::value_type iterator_val_t;
|
Chris@16
|
457 typedef typename iterator_val_t::first_type first_type;
|
Chris@16
|
458 typedef typename iterator_val_t::second_type second_type;
|
Chris@16
|
459 typedef typename first_type::char_type char_type;
|
Chris@16
|
460 typedef typename first_type::size_type size_type;
|
Chris@16
|
461
|
Chris@16
|
462 public:
|
Chris@16
|
463 segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
|
Chris@16
|
464 : m_val(&val)
|
Chris@16
|
465 {}
|
Chris@16
|
466
|
Chris@16
|
467 const char_type *name() const
|
Chris@16
|
468 { return m_val->first.name(); }
|
Chris@16
|
469
|
Chris@16
|
470 size_type name_length() const
|
Chris@16
|
471 { return m_val->first.name_length(); }
|
Chris@16
|
472
|
Chris@16
|
473 const void *value() const
|
Chris@16
|
474 {
|
Chris@16
|
475 return reinterpret_cast<block_header<size_type>*>
|
Chris@16
|
476 (to_raw_pointer(m_val->second.m_ptr))->value();
|
Chris@16
|
477 }
|
Chris@16
|
478
|
Chris@16
|
479 const typename Iterator::value_type *m_val;
|
Chris@16
|
480 };
|
Chris@16
|
481
|
Chris@16
|
482 template<class Iterator, bool intrusive>
|
Chris@16
|
483 struct segment_manager_iterator_transform
|
Chris@16
|
484 {
|
Chris@16
|
485 typedef segment_manager_iterator_value_adaptor<Iterator, intrusive> result_type;
|
Chris@16
|
486
|
Chris@101
|
487 template <class T> result_type operator()(const T &arg) const
|
Chris@16
|
488 { return result_type(arg); }
|
Chris@16
|
489 };
|
Chris@16
|
490
|
Chris@16
|
491 } //namespace ipcdetail {
|
Chris@16
|
492
|
Chris@16
|
493 //These pointers are the ones the user will use to
|
Chris@16
|
494 //indicate previous allocation types
|
Chris@16
|
495 static const ipcdetail::anonymous_instance_t * anonymous_instance = 0;
|
Chris@16
|
496 static const ipcdetail::unique_instance_t * unique_instance = 0;
|
Chris@16
|
497
|
Chris@16
|
498 namespace ipcdetail_really_deep_namespace {
|
Chris@16
|
499
|
Chris@16
|
500 //Otherwise, gcc issues a warning of previously defined
|
Chris@16
|
501 //anonymous_instance and unique_instance
|
Chris@16
|
502 struct dummy
|
Chris@16
|
503 {
|
Chris@16
|
504 dummy()
|
Chris@16
|
505 {
|
Chris@16
|
506 (void)anonymous_instance;
|
Chris@16
|
507 (void)unique_instance;
|
Chris@16
|
508 }
|
Chris@16
|
509 };
|
Chris@16
|
510
|
Chris@16
|
511 } //detail_really_deep_namespace
|
Chris@16
|
512
|
Chris@16
|
513 }} //namespace boost { namespace interprocess
|
Chris@16
|
514
|
Chris@16
|
515 #include <boost/interprocess/detail/config_end.hpp>
|
Chris@16
|
516
|
Chris@16
|
517 #endif //#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
|
Chris@16
|
518
|