1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP
12 #define BOOST_INTERPROCESS_NAMED_PROXY_HPP
14 #ifndef BOOST_CONFIG_HPP
15 # include <boost/config.hpp>
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
22 #include <boost/interprocess/detail/config_begin.hpp>
23 #include <boost/interprocess/detail/workaround.hpp>
25 // interprocess/detail
26 #include <boost/interprocess/detail/in_place_interface.hpp>
27 #include <boost/interprocess/detail/mpl.hpp>
28 #include <boost/move/utility_core.hpp>
29 #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
30 #include <boost/move/detail/fwd_macros.hpp>
32 #include <boost/move/utility_core.hpp>
33 #include <boost/interprocess/detail/variadic_templates_tools.hpp>
34 #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
35 #include <boost/container/detail/placement_new.hpp>
40 //!Describes a proxy class that implements named allocation syntax.
43 namespace interprocess {
46 #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
48 template<class T, bool is_iterator, class ...Args>
49 struct CtorArgN : public placement_destroy<T>
51 typedef bool_<is_iterator> IsIterator;
52 typedef CtorArgN<T, is_iterator, Args...> self_t;
53 typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
57 this->do_increment(IsIterator(), index_tuple_t());
61 self_t operator++(int) { return ++*this; *this; }
63 CtorArgN(Args && ...args)
67 virtual void construct_n(void *mem
69 , std::size_t &constructed)
71 T* memory = static_cast<T*>(mem);
72 for(constructed = 0; constructed < num; ++constructed){
73 this->construct(memory++, IsIterator(), index_tuple_t());
74 this->do_increment(IsIterator(), index_tuple_t());
79 template<std::size_t ...IdxPack>
80 void construct(void *mem, true_, const index_tuple<IdxPack...>&)
81 { ::new((void*)mem, boost_container_new_t())T(*boost::forward<Args>(get<IdxPack>(args_))...); }
83 template<std::size_t ...IdxPack>
84 void construct(void *mem, false_, const index_tuple<IdxPack...>&)
85 { ::new((void*)mem, boost_container_new_t())T(boost::forward<Args>(get<IdxPack>(args_))...); }
87 template<std::size_t ...IdxPack>
88 void do_increment(true_, const index_tuple<IdxPack...>&)
90 this->expansion_helper(++get<IdxPack>(args_)...);
93 template<class ...ExpansionArgs>
94 void expansion_helper(ExpansionArgs &&...)
97 template<std::size_t ...IdxPack>
98 void do_increment(false_, const index_tuple<IdxPack...>&)
101 tuple<Args&...> args_;
104 //!Describes a proxy class that implements named
105 //!allocation syntax.
107 < class SegmentManager //segment manager to construct the object
108 , class T //type of object to build
109 , bool is_iterator //passing parameters are normal object or iterators?
113 typedef typename SegmentManager::char_type char_type;
114 const char_type * mp_name;
115 SegmentManager * mp_mngr;
116 mutable std::size_t m_num;
118 const bool m_dothrow;
121 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
122 : mp_name(name), mp_mngr(mngr), m_num(1)
123 , m_find(find), m_dothrow(dothrow)
126 template<class ...Args>
127 T *operator()(Args &&...args) const
129 CtorArgN<T, is_iterator, Args...> &&ctor_obj = CtorArgN<T, is_iterator, Args...>
130 (boost::forward<Args>(args)...);
131 return mp_mngr->template
132 generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
135 //This operator allows --> named_new("Name")[3]; <-- syntax
136 const named_proxy &operator[](std::size_t num) const
137 { m_num *= num; return *this; }
140 #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
142 ////////////////////////////////////////////////////////////////
143 // What the macro should generate (n == 2):
145 // template<class T, bool is_iterator, class P1, class P2>
147 // : public placement_destroy<T>
149 // typedef bool_<is_iterator> IsIterator;
150 // typedef Ctor2Arg self_t;
152 // void do_increment(false_)
153 // { ++m_p1; ++m_p2; }
155 // void do_increment(true_){}
157 // self_t& operator++()
159 // this->do_increment(IsIterator());
163 // self_t operator++(int) { return ++*this; *this; }
165 // Ctor2Arg(const P1 &p1, const P2 &p2)
166 // : p1((P1 &)p_1), p2((P2 &)p_2) {}
168 // void construct(void *mem)
169 // { new((void*)object)T(m_p1, m_p2); }
171 // virtual void construct_n(void *mem
173 // , std::size_t &constructed)
175 // T* memory = static_cast<T*>(mem);
176 // for(constructed = 0; constructed < num; ++constructed){
177 // this->construct(memory++, IsIterator());
178 // this->do_increment(IsIterator());
183 // void construct(void *mem, true_)
184 // { new((void*)mem)T(*m_p1, *m_p2); }
186 // void construct(void *mem, false_)
187 // { new((void*)mem)T(m_p1, m_p2); }
189 // P1 &m_p1; P2 &m_p2;
191 ////////////////////////////////////////////////////////////////
193 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN(N)\
195 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
196 struct CtorArg##N : placement_destroy<T>\
198 typedef CtorArg##N self_t;\
200 CtorArg##N ( BOOST_MOVE_UREF##N )\
201 BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
203 virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\
205 T* memory = static_cast<T*>(mem);\
206 for(constructed = 0; constructed < num; ++constructed){\
207 ::new((void*)memory++) T ( BOOST_MOVE_MFWD##N );\
215 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN)
216 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN
218 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORITN(N)\
220 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
221 struct CtorIt##N : public placement_destroy<T>\
223 typedef CtorIt##N self_t;\
225 self_t& operator++()\
226 { BOOST_MOVE_MINC##N; return *this; }\
228 self_t operator++(int) { return ++*this; *this; }\
230 CtorIt##N ( BOOST_MOVE_VAL##N )\
231 BOOST_MOVE_COLON##N BOOST_MOVE_VAL_INIT##N{}\
233 virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\
235 T* memory = static_cast<T*>(mem);\
236 for(constructed = 0; constructed < num; ++constructed){\
237 ::new((void*)memory++) T( BOOST_MOVE_MITFWD##N );\
246 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORITN)
247 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORITN
249 //!Describes a proxy class that implements named
250 //!allocation syntax.
252 < class SegmentManager //segment manager to construct the object
253 , class T //type of object to build
254 , bool is_iterator //passing parameters are normal object or iterators?
258 typedef typename SegmentManager::char_type char_type;
259 const char_type * mp_name;
260 SegmentManager * mp_mngr;
261 mutable std::size_t m_num;
263 const bool m_dothrow;
266 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
267 : mp_name(name), mp_mngr(mngr), m_num(1)
268 , m_find(find), m_dothrow(dothrow)
271 #define BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR(N)\
273 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
274 T *operator()( BOOST_MOVE_UREF##N ) const\
276 typedef typename if_c<is_iterator \
277 , CtorIt##N<T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
278 , CtorArg##N<T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
280 ctor_obj_t ctor_obj = ctor_obj_t( BOOST_MOVE_FWD##N );\
281 return mp_mngr->template generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);\
284 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR)
285 #undef BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR
287 ////////////////////////////////////////////////////////////////////////
288 // What the macro should generate (n == 2)
289 ////////////////////////////////////////////////////////////////////////
291 // template <class P1, class P2>
292 // T *operator()(P1 &p1, P2 &p2) const
295 // <T, is_iterator, P1, P2>
297 // ctor_obj_t ctor_obj(p1, p2);
299 // return mp_mngr->template generic_construct<T>
300 // (mp_name, m_num, m_find, m_dothrow, ctor_obj);
303 //////////////////////////////////////////////////////////////////////////
305 //This operator allows --> named_new("Name")[3]; <-- syntax
306 const named_proxy &operator[](std::size_t num) const
307 { m_num *= num; return *this; }
310 #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
312 }}} //namespace boost { namespace interprocess { namespace ipcdetail {
314 #include <boost/interprocess/detail/config_end.hpp>
316 #endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP