Mercurial > hg > vamp-build-and-test
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 |