comparison DEPENDENCIES/generic/include/boost/interprocess/detail/named_proxy.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11 #ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP
12 #define BOOST_INTERPROCESS_NAMED_PROXY_HPP
13
14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif
17
18 #include <boost/interprocess/detail/config_begin.hpp>
19 #include <boost/interprocess/detail/workaround.hpp>
20
21 #include <new>
22 #include <iterator>
23 #include <boost/interprocess/detail/in_place_interface.hpp>
24 #include <boost/interprocess/detail/mpl.hpp>
25
26 #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
27 #include <boost/interprocess/detail/preprocessor.hpp>
28 #else
29 #include <boost/move/move.hpp>
30 #include <boost/interprocess/detail/variadic_templates_tools.hpp>
31 #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
32
33 //!\file
34 //!Describes a proxy class that implements named allocation syntax.
35
36 namespace boost {
37 namespace interprocess {
38 namespace ipcdetail {
39
40 #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
41
42 template<class T, bool is_iterator, class ...Args>
43 struct CtorNArg : public placement_destroy<T>
44 {
45 typedef bool_<is_iterator> IsIterator;
46 typedef CtorNArg<T, is_iterator, Args...> self_t;
47 typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
48
49 self_t& operator++()
50 {
51 this->do_increment(IsIterator(), index_tuple_t());
52 return *this;
53 }
54
55 self_t operator++(int) { return ++*this; *this; }
56
57 CtorNArg(Args && ...args)
58 : args_(args...)
59 {}
60
61 virtual void construct_n(void *mem
62 , std::size_t num
63 , std::size_t &constructed)
64 {
65 T* memory = static_cast<T*>(mem);
66 for(constructed = 0; constructed < num; ++constructed){
67 this->construct(memory++, IsIterator(), index_tuple_t());
68 this->do_increment(IsIterator(), index_tuple_t());
69 }
70 }
71
72 private:
73 template<int ...IdxPack>
74 void construct(void *mem, true_, const index_tuple<IdxPack...>&)
75 { new((void*)mem)T(*boost::forward<Args>(get<IdxPack>(args_))...); }
76
77 template<int ...IdxPack>
78 void construct(void *mem, false_, const index_tuple<IdxPack...>&)
79 { new((void*)mem)T(boost::forward<Args>(get<IdxPack>(args_))...); }
80
81 template<int ...IdxPack>
82 void do_increment(true_, const index_tuple<IdxPack...>&)
83 {
84 this->expansion_helper(++get<IdxPack>(args_)...);
85 }
86
87 template<class ...ExpansionArgs>
88 void expansion_helper(ExpansionArgs &&...)
89 {}
90
91 template<int ...IdxPack>
92 void do_increment(false_, const index_tuple<IdxPack...>&)
93 {}
94
95 tuple<Args&...> args_;
96 };
97
98 //!Describes a proxy class that implements named
99 //!allocation syntax.
100 template
101 < class SegmentManager //segment manager to construct the object
102 , class T //type of object to build
103 , bool is_iterator //passing parameters are normal object or iterators?
104 >
105 class named_proxy
106 {
107 typedef typename SegmentManager::char_type char_type;
108 const char_type * mp_name;
109 SegmentManager * mp_mngr;
110 mutable std::size_t m_num;
111 const bool m_find;
112 const bool m_dothrow;
113
114 public:
115 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
116 : mp_name(name), mp_mngr(mngr), m_num(1)
117 , m_find(find), m_dothrow(dothrow)
118 {}
119
120 template<class ...Args>
121 T *operator()(Args &&...args) const
122 {
123 CtorNArg<T, is_iterator, Args...> &&ctor_obj = CtorNArg<T, is_iterator, Args...>
124 (boost::forward<Args>(args)...);
125 return mp_mngr->template
126 generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
127 }
128
129 //This operator allows --> named_new("Name")[3]; <-- syntax
130 const named_proxy &operator[](std::size_t num) const
131 { m_num *= num; return *this; }
132 };
133
134 #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
135
136 //!Function object that makes placement new
137 //!without arguments
138 template<class T>
139 struct Ctor0Arg : public placement_destroy<T>
140 {
141 typedef Ctor0Arg self_t;
142
143 Ctor0Arg(){}
144
145 self_t& operator++() { return *this; }
146 self_t operator++(int) { return *this; }
147
148 void construct(void *mem)
149 { new((void*)mem)T; }
150
151 virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)
152 {
153 T* memory = static_cast<T*>(mem);
154 for(constructed = 0; constructed < num; ++constructed)
155 new((void*)memory++)T;
156 }
157 };
158
159 ////////////////////////////////////////////////////////////////
160 // What the macro should generate (n == 2):
161 //
162 // template<class T, bool is_iterator, class P1, class P2>
163 // struct Ctor2Arg
164 // : public placement_destroy<T>
165 // {
166 // typedef bool_<is_iterator> IsIterator;
167 // typedef Ctor2Arg self_t;
168 //
169 // void do_increment(false_)
170 // { ++m_p1; ++m_p2; }
171 //
172 // void do_increment(true_){}
173 //
174 // self_t& operator++()
175 // {
176 // this->do_increment(IsIterator());
177 // return *this;
178 // }
179 //
180 // self_t operator++(int) { return ++*this; *this; }
181 //
182 // Ctor2Arg(const P1 &p1, const P2 &p2)
183 // : p1((P1 &)p_1), p2((P2 &)p_2) {}
184 //
185 // void construct(void *mem)
186 // { new((void*)object)T(m_p1, m_p2); }
187 //
188 // virtual void construct_n(void *mem
189 // , std::size_t num
190 // , std::size_t &constructed)
191 // {
192 // T* memory = static_cast<T*>(mem);
193 // for(constructed = 0; constructed < num; ++constructed){
194 // this->construct(memory++, IsIterator());
195 // this->do_increment(IsIterator());
196 // }
197 // }
198 //
199 // private:
200 // void construct(void *mem, true_)
201 // { new((void*)mem)T(*m_p1, *m_p2); }
202 //
203 // void construct(void *mem, false_)
204 // { new((void*)mem)T(m_p1, m_p2); }
205 //
206 // P1 &m_p1; P2 &m_p2;
207 // };
208 ////////////////////////////////////////////////////////////////
209
210 //Note:
211 //We define template parameters as const references to
212 //be able to bind temporaries. After that we will un-const them.
213 //This cast is ugly but it is necessary until "perfect forwarding"
214 //is achieved in C++0x. Meanwhile, if we want to be able to
215 //bind lvalues with non-const references, we have to be ugly
216 #define BOOST_PP_LOCAL_MACRO(n) \
217 template<class T, bool is_iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
218 struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
219 : public placement_destroy<T> \
220 { \
221 typedef bool_<is_iterator> IsIterator; \
222 typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t; \
223 \
224 void do_increment(true_) \
225 { BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_INC, _); } \
226 \
227 void do_increment(false_){} \
228 \
229 self_t& operator++() \
230 { \
231 this->do_increment(IsIterator()); \
232 return *this; \
233 } \
234 \
235 self_t operator++(int) { return ++*this; *this; } \
236 \
237 BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
238 ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _) ) \
239 : BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_INIT, _) {} \
240 \
241 virtual void construct_n(void *mem \
242 , std::size_t num \
243 , std::size_t &constructed) \
244 { \
245 T* memory = static_cast<T*>(mem); \
246 for(constructed = 0; constructed < num; ++constructed){ \
247 this->construct(memory++, IsIterator()); \
248 this->do_increment(IsIterator()); \
249 } \
250 } \
251 \
252 private: \
253 void construct(void *mem, true_) \
254 { \
255 new((void*)mem) T \
256 (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD, _)); \
257 } \
258 \
259 void construct(void *mem, false_) \
260 { \
261 new((void*)mem) T \
262 (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
263 } \
264 \
265 BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_PP_PARAM_DEFINE, _) \
266 }; \
267 //!
268 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
269 #include BOOST_PP_LOCAL_ITERATE()
270
271 //!Describes a proxy class that implements named
272 //!allocation syntax.
273 template
274 < class SegmentManager //segment manager to construct the object
275 , class T //type of object to build
276 , bool is_iterator //passing parameters are normal object or iterators?
277 >
278 class named_proxy
279 {
280 typedef typename SegmentManager::char_type char_type;
281 const char_type * mp_name;
282 SegmentManager * mp_mngr;
283 mutable std::size_t m_num;
284 const bool m_find;
285 const bool m_dothrow;
286
287 public:
288 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
289 : mp_name(name), mp_mngr(mngr), m_num(1)
290 , m_find(find), m_dothrow(dothrow)
291 {}
292
293 //!makes a named allocation and calls the
294 //!default constructor
295 T *operator()() const
296 {
297 Ctor0Arg<T> ctor_obj;
298 return mp_mngr->template
299 generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
300 }
301 //!
302
303 #define BOOST_PP_LOCAL_MACRO(n) \
304 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
305 T *operator()(BOOST_PP_ENUM (n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) const\
306 { \
307 typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
308 <T, is_iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
309 ctor_obj_t; \
310 ctor_obj_t ctor_obj \
311 (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
312 return mp_mngr->template generic_construct<T> \
313 (mp_name, m_num, m_find, m_dothrow, ctor_obj); \
314 } \
315 //!
316
317 #define BOOST_PP_LOCAL_LIMITS ( 1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS )
318 #include BOOST_PP_LOCAL_ITERATE()
319
320 ////////////////////////////////////////////////////////////////////////
321 // What the macro should generate (n == 2)
322 ////////////////////////////////////////////////////////////////////////
323 //
324 // template <class P1, class P2>
325 // T *operator()(P1 &p1, P2 &p2) const
326 // {
327 // typedef Ctor2Arg
328 // <T, is_iterator, P1, P2>
329 // ctor_obj_t;
330 // ctor_obj_t ctor_obj(p1, p2);
331 //
332 // return mp_mngr->template generic_construct<T>
333 // (mp_name, m_num, m_find, m_dothrow, ctor_obj);
334 // }
335 //
336 //////////////////////////////////////////////////////////////////////////
337
338 //This operator allows --> named_new("Name")[3]; <-- syntax
339 const named_proxy &operator[](std::size_t num) const
340 { m_num *= num; return *this; }
341 };
342
343 #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
344
345 }}} //namespace boost { namespace interprocess { namespace ipcdetail {
346
347 #include <boost/interprocess/detail/config_end.hpp>
348
349 #endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP