PageRenderTime 36ms CodeModel.GetById 18ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/interprocess/detail/named_proxy.hpp

http://hadesmem.googlecode.com/
C++ Header | 349 lines | 210 code | 42 blank | 97 comment | 5 complexity | ad231dcc082bd9b1a3140f4a12d8ddbc MD5 | raw file
  1//////////////////////////////////////////////////////////////////////////////
  2//
  3// (C) Copyright Ion Gaztanaga 2005-2009. 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/interprocess/detail/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
 36namespace boost {
 37namespace interprocess { 
 38namespace detail {
 39
 40#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
 41
 42template<class T, bool is_iterator, class ...Args>
 43struct CtorNArg : public placement_destroy<T>
 44{
 45   typedef detail::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, detail::true_, const index_tuple<IdxPack...>&)
 75   {  new((void*)mem)T(*boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
 76
 77   template<int ...IdxPack>
 78   void construct(void *mem, detail::false_, const index_tuple<IdxPack...>&)
 79   {  new((void*)mem)T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
 80
 81   template<int ...IdxPack>
 82   void do_increment(detail::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(detail::false_, const index_tuple<IdxPack...>&)
 93   {}
 94
 95   tuple<Args&...> args_;
 96};                                                                      
 97
 98//!Describes a proxy class that implements named
 99//!allocation syntax.
100template 
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   >
105class 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::interprocess::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
138template<class T>
139struct 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 detail::bool_<is_iterator> IsIterator;
167//       typedef Ctor2Arg self_t;
168//
169//       void do_increment(detail::false_)
170//       { ++m_p1; ++m_p2;  }
171//
172//       void do_increment(detail::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, detail::true_)
201//       {  new((void*)mem)T(*m_p1, *m_p2); }
202//                                                                           
203//       void construct(void *mem, detail::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 detail::bool_<is_iterator> IsIterator;                       \
222      typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t;             \
223                                                                           \
224      void do_increment(detail::true_)                                     \
225         { BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); }        \
226                                                                           \
227      void do_increment(detail::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_AUX_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, detail::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, detail::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_AUX_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.
273template 
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   >
278class 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 detail {
346
347#include <boost/interprocess/detail/config_end.hpp>
348
349#endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP