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_NAMED_PROXY_HPP
|
Chris@16
|
12 #define BOOST_INTERPROCESS_NAMED_PROXY_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/detail
|
Chris@16
|
26 #include <boost/interprocess/detail/in_place_interface.hpp>
|
Chris@16
|
27 #include <boost/interprocess/detail/mpl.hpp>
|
Chris@101
|
28 #include <boost/move/utility_core.hpp>
|
Chris@16
|
29 #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
Chris@101
|
30 #include <boost/move/detail/fwd_macros.hpp>
|
Chris@16
|
31 #else
|
Chris@101
|
32 #include <boost/move/utility_core.hpp>
|
Chris@16
|
33 #include <boost/interprocess/detail/variadic_templates_tools.hpp>
|
Chris@16
|
34 #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
Chris@101
|
35 #include <boost/container/detail/placement_new.hpp>
|
Chris@16
|
36
|
Chris@16
|
37 //!\file
|
Chris@16
|
38 //!Describes a proxy class that implements named allocation syntax.
|
Chris@16
|
39
|
Chris@16
|
40 namespace boost {
|
Chris@16
|
41 namespace interprocess {
|
Chris@16
|
42 namespace ipcdetail {
|
Chris@16
|
43
|
Chris@16
|
44 #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
Chris@16
|
45
|
Chris@16
|
46 template<class T, bool is_iterator, class ...Args>
|
Chris@101
|
47 struct CtorArgN : public placement_destroy<T>
|
Chris@16
|
48 {
|
Chris@16
|
49 typedef bool_<is_iterator> IsIterator;
|
Chris@101
|
50 typedef CtorArgN<T, is_iterator, Args...> self_t;
|
Chris@16
|
51 typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
Chris@16
|
52
|
Chris@16
|
53 self_t& operator++()
|
Chris@16
|
54 {
|
Chris@16
|
55 this->do_increment(IsIterator(), index_tuple_t());
|
Chris@16
|
56 return *this;
|
Chris@16
|
57 }
|
Chris@16
|
58
|
Chris@16
|
59 self_t operator++(int) { return ++*this; *this; }
|
Chris@16
|
60
|
Chris@101
|
61 CtorArgN(Args && ...args)
|
Chris@16
|
62 : args_(args...)
|
Chris@16
|
63 {}
|
Chris@16
|
64
|
Chris@16
|
65 virtual void construct_n(void *mem
|
Chris@16
|
66 , std::size_t num
|
Chris@16
|
67 , std::size_t &constructed)
|
Chris@16
|
68 {
|
Chris@16
|
69 T* memory = static_cast<T*>(mem);
|
Chris@16
|
70 for(constructed = 0; constructed < num; ++constructed){
|
Chris@16
|
71 this->construct(memory++, IsIterator(), index_tuple_t());
|
Chris@16
|
72 this->do_increment(IsIterator(), index_tuple_t());
|
Chris@16
|
73 }
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 private:
|
Chris@16
|
77 template<int ...IdxPack>
|
Chris@16
|
78 void construct(void *mem, true_, const index_tuple<IdxPack...>&)
|
Chris@101
|
79 { ::new((void*)mem, boost_container_new_t())T(*boost::forward<Args>(get<IdxPack>(args_))...); }
|
Chris@16
|
80
|
Chris@16
|
81 template<int ...IdxPack>
|
Chris@16
|
82 void construct(void *mem, false_, const index_tuple<IdxPack...>&)
|
Chris@101
|
83 { ::new((void*)mem, boost_container_new_t())T(boost::forward<Args>(get<IdxPack>(args_))...); }
|
Chris@16
|
84
|
Chris@16
|
85 template<int ...IdxPack>
|
Chris@16
|
86 void do_increment(true_, const index_tuple<IdxPack...>&)
|
Chris@16
|
87 {
|
Chris@16
|
88 this->expansion_helper(++get<IdxPack>(args_)...);
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 template<class ...ExpansionArgs>
|
Chris@16
|
92 void expansion_helper(ExpansionArgs &&...)
|
Chris@16
|
93 {}
|
Chris@16
|
94
|
Chris@16
|
95 template<int ...IdxPack>
|
Chris@16
|
96 void do_increment(false_, const index_tuple<IdxPack...>&)
|
Chris@16
|
97 {}
|
Chris@16
|
98
|
Chris@16
|
99 tuple<Args&...> args_;
|
Chris@16
|
100 };
|
Chris@16
|
101
|
Chris@16
|
102 //!Describes a proxy class that implements named
|
Chris@16
|
103 //!allocation syntax.
|
Chris@16
|
104 template
|
Chris@16
|
105 < class SegmentManager //segment manager to construct the object
|
Chris@16
|
106 , class T //type of object to build
|
Chris@16
|
107 , bool is_iterator //passing parameters are normal object or iterators?
|
Chris@16
|
108 >
|
Chris@16
|
109 class named_proxy
|
Chris@16
|
110 {
|
Chris@16
|
111 typedef typename SegmentManager::char_type char_type;
|
Chris@16
|
112 const char_type * mp_name;
|
Chris@16
|
113 SegmentManager * mp_mngr;
|
Chris@16
|
114 mutable std::size_t m_num;
|
Chris@16
|
115 const bool m_find;
|
Chris@16
|
116 const bool m_dothrow;
|
Chris@16
|
117
|
Chris@16
|
118 public:
|
Chris@16
|
119 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
|
Chris@16
|
120 : mp_name(name), mp_mngr(mngr), m_num(1)
|
Chris@16
|
121 , m_find(find), m_dothrow(dothrow)
|
Chris@16
|
122 {}
|
Chris@16
|
123
|
Chris@16
|
124 template<class ...Args>
|
Chris@16
|
125 T *operator()(Args &&...args) const
|
Chris@16
|
126 {
|
Chris@101
|
127 CtorArgN<T, is_iterator, Args...> &&ctor_obj = CtorArgN<T, is_iterator, Args...>
|
Chris@16
|
128 (boost::forward<Args>(args)...);
|
Chris@16
|
129 return mp_mngr->template
|
Chris@16
|
130 generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 //This operator allows --> named_new("Name")[3]; <-- syntax
|
Chris@16
|
134 const named_proxy &operator[](std::size_t num) const
|
Chris@16
|
135 { m_num *= num; return *this; }
|
Chris@16
|
136 };
|
Chris@16
|
137
|
Chris@16
|
138 #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
Chris@16
|
139
|
Chris@16
|
140 ////////////////////////////////////////////////////////////////
|
Chris@16
|
141 // What the macro should generate (n == 2):
|
Chris@16
|
142 //
|
Chris@16
|
143 // template<class T, bool is_iterator, class P1, class P2>
|
Chris@16
|
144 // struct Ctor2Arg
|
Chris@16
|
145 // : public placement_destroy<T>
|
Chris@16
|
146 // {
|
Chris@16
|
147 // typedef bool_<is_iterator> IsIterator;
|
Chris@16
|
148 // typedef Ctor2Arg self_t;
|
Chris@16
|
149 //
|
Chris@16
|
150 // void do_increment(false_)
|
Chris@16
|
151 // { ++m_p1; ++m_p2; }
|
Chris@16
|
152 //
|
Chris@16
|
153 // void do_increment(true_){}
|
Chris@16
|
154 //
|
Chris@16
|
155 // self_t& operator++()
|
Chris@16
|
156 // {
|
Chris@16
|
157 // this->do_increment(IsIterator());
|
Chris@16
|
158 // return *this;
|
Chris@16
|
159 // }
|
Chris@16
|
160 //
|
Chris@16
|
161 // self_t operator++(int) { return ++*this; *this; }
|
Chris@16
|
162 //
|
Chris@16
|
163 // Ctor2Arg(const P1 &p1, const P2 &p2)
|
Chris@16
|
164 // : p1((P1 &)p_1), p2((P2 &)p_2) {}
|
Chris@16
|
165 //
|
Chris@16
|
166 // void construct(void *mem)
|
Chris@16
|
167 // { new((void*)object)T(m_p1, m_p2); }
|
Chris@16
|
168 //
|
Chris@16
|
169 // virtual void construct_n(void *mem
|
Chris@16
|
170 // , std::size_t num
|
Chris@16
|
171 // , std::size_t &constructed)
|
Chris@16
|
172 // {
|
Chris@16
|
173 // T* memory = static_cast<T*>(mem);
|
Chris@16
|
174 // for(constructed = 0; constructed < num; ++constructed){
|
Chris@16
|
175 // this->construct(memory++, IsIterator());
|
Chris@16
|
176 // this->do_increment(IsIterator());
|
Chris@16
|
177 // }
|
Chris@16
|
178 // }
|
Chris@16
|
179 //
|
Chris@16
|
180 // private:
|
Chris@16
|
181 // void construct(void *mem, true_)
|
Chris@16
|
182 // { new((void*)mem)T(*m_p1, *m_p2); }
|
Chris@16
|
183 //
|
Chris@16
|
184 // void construct(void *mem, false_)
|
Chris@16
|
185 // { new((void*)mem)T(m_p1, m_p2); }
|
Chris@16
|
186 //
|
Chris@16
|
187 // P1 &m_p1; P2 &m_p2;
|
Chris@16
|
188 // };
|
Chris@16
|
189 ////////////////////////////////////////////////////////////////
|
Chris@16
|
190
|
Chris@101
|
191 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN(N)\
|
Chris@101
|
192 \
|
Chris@101
|
193 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
|
Chris@101
|
194 struct CtorArg##N : placement_destroy<T>\
|
Chris@101
|
195 {\
|
Chris@101
|
196 typedef CtorArg##N self_t;\
|
Chris@101
|
197 \
|
Chris@101
|
198 CtorArg##N ( BOOST_MOVE_UREF##N )\
|
Chris@101
|
199 BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
|
Chris@101
|
200 \
|
Chris@101
|
201 virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\
|
Chris@101
|
202 {\
|
Chris@101
|
203 T* memory = static_cast<T*>(mem);\
|
Chris@101
|
204 for(constructed = 0; constructed < num; ++constructed){\
|
Chris@101
|
205 ::new((void*)memory++) T ( BOOST_MOVE_MFWD##N );\
|
Chris@101
|
206 }\
|
Chris@101
|
207 }\
|
Chris@101
|
208 \
|
Chris@101
|
209 private:\
|
Chris@101
|
210 BOOST_MOVE_MREF##N\
|
Chris@101
|
211 };\
|
Chris@16
|
212 //!
|
Chris@101
|
213 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN)
|
Chris@101
|
214 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN
|
Chris@101
|
215
|
Chris@101
|
216 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORITN(N)\
|
Chris@101
|
217 \
|
Chris@101
|
218 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
|
Chris@101
|
219 struct CtorIt##N : public placement_destroy<T>\
|
Chris@101
|
220 {\
|
Chris@101
|
221 typedef CtorIt##N self_t;\
|
Chris@101
|
222 \
|
Chris@101
|
223 self_t& operator++()\
|
Chris@101
|
224 { BOOST_MOVE_MINC##N; return *this; }\
|
Chris@101
|
225 \
|
Chris@101
|
226 self_t operator++(int) { return ++*this; *this; }\
|
Chris@101
|
227 \
|
Chris@101
|
228 CtorIt##N ( BOOST_MOVE_VAL##N )\
|
Chris@101
|
229 BOOST_MOVE_COLON##N BOOST_MOVE_VAL_INIT##N{}\
|
Chris@101
|
230 \
|
Chris@101
|
231 virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\
|
Chris@101
|
232 {\
|
Chris@101
|
233 T* memory = static_cast<T*>(mem);\
|
Chris@101
|
234 for(constructed = 0; constructed < num; ++constructed){\
|
Chris@101
|
235 ::new((void*)memory++) T( BOOST_MOVE_MITFWD##N );\
|
Chris@101
|
236 ++(*this);\
|
Chris@101
|
237 }\
|
Chris@101
|
238 }\
|
Chris@101
|
239 \
|
Chris@101
|
240 private:\
|
Chris@101
|
241 BOOST_MOVE_MEMB##N\
|
Chris@101
|
242 };\
|
Chris@101
|
243 //!
|
Chris@101
|
244 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORITN)
|
Chris@101
|
245 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORITN
|
Chris@16
|
246
|
Chris@16
|
247 //!Describes a proxy class that implements named
|
Chris@16
|
248 //!allocation syntax.
|
Chris@16
|
249 template
|
Chris@16
|
250 < class SegmentManager //segment manager to construct the object
|
Chris@16
|
251 , class T //type of object to build
|
Chris@16
|
252 , bool is_iterator //passing parameters are normal object or iterators?
|
Chris@16
|
253 >
|
Chris@16
|
254 class named_proxy
|
Chris@16
|
255 {
|
Chris@16
|
256 typedef typename SegmentManager::char_type char_type;
|
Chris@16
|
257 const char_type * mp_name;
|
Chris@16
|
258 SegmentManager * mp_mngr;
|
Chris@16
|
259 mutable std::size_t m_num;
|
Chris@16
|
260 const bool m_find;
|
Chris@16
|
261 const bool m_dothrow;
|
Chris@16
|
262
|
Chris@16
|
263 public:
|
Chris@16
|
264 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
|
Chris@16
|
265 : mp_name(name), mp_mngr(mngr), m_num(1)
|
Chris@16
|
266 , m_find(find), m_dothrow(dothrow)
|
Chris@16
|
267 {}
|
Chris@16
|
268
|
Chris@101
|
269 #define BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR(N)\
|
Chris@101
|
270 \
|
Chris@101
|
271 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
Chris@101
|
272 T *operator()( BOOST_MOVE_UREF##N ) const\
|
Chris@101
|
273 {\
|
Chris@101
|
274 typedef typename if_c<is_iterator \
|
Chris@101
|
275 , CtorIt##N<T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
|
Chris@101
|
276 , CtorArg##N<T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
|
Chris@101
|
277 >::type ctor_obj_t;\
|
Chris@101
|
278 ctor_obj_t ctor_obj = ctor_obj_t( BOOST_MOVE_FWD##N );\
|
Chris@101
|
279 return mp_mngr->template generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);\
|
Chris@101
|
280 }\
|
Chris@101
|
281 //
|
Chris@101
|
282 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR)
|
Chris@101
|
283 #undef BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR
|
Chris@16
|
284
|
Chris@16
|
285 ////////////////////////////////////////////////////////////////////////
|
Chris@16
|
286 // What the macro should generate (n == 2)
|
Chris@16
|
287 ////////////////////////////////////////////////////////////////////////
|
Chris@16
|
288 //
|
Chris@16
|
289 // template <class P1, class P2>
|
Chris@16
|
290 // T *operator()(P1 &p1, P2 &p2) const
|
Chris@16
|
291 // {
|
Chris@101
|
292 // typedef CtorArg2
|
Chris@16
|
293 // <T, is_iterator, P1, P2>
|
Chris@16
|
294 // ctor_obj_t;
|
Chris@16
|
295 // ctor_obj_t ctor_obj(p1, p2);
|
Chris@16
|
296 //
|
Chris@16
|
297 // return mp_mngr->template generic_construct<T>
|
Chris@16
|
298 // (mp_name, m_num, m_find, m_dothrow, ctor_obj);
|
Chris@16
|
299 // }
|
Chris@16
|
300 //
|
Chris@16
|
301 //////////////////////////////////////////////////////////////////////////
|
Chris@16
|
302
|
Chris@16
|
303 //This operator allows --> named_new("Name")[3]; <-- syntax
|
Chris@16
|
304 const named_proxy &operator[](std::size_t num) const
|
Chris@16
|
305 { m_num *= num; return *this; }
|
Chris@16
|
306 };
|
Chris@16
|
307
|
Chris@16
|
308 #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
Chris@16
|
309
|
Chris@16
|
310 }}} //namespace boost { namespace interprocess { namespace ipcdetail {
|
Chris@16
|
311
|
Chris@16
|
312 #include <boost/interprocess/detail/config_end.hpp>
|
Chris@16
|
313
|
Chris@16
|
314 #endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP
|