preprocessor.hpp 5.9 KB
Newer Older
xuebingbing's avatar
xuebingbing committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_INTERPROCESS_DETAIL_PREPROCESSOR_HPP
#define BOOST_INTERPROCESS_DETAIL_PREPROCESSOR_HPP

#if defined(_MSC_VER)
#  pragma once
#endif

#include <boost/interprocess/detail/config_begin.hpp>

#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
#error "This file is not needed when perfect forwarding is available"
#endif

#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#define BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS 10

//Note:
//We define template parameters as const references to
//be able to bind temporaries. After that we will un-const them.
//This cast is ugly but it is necessary until "perfect forwarding"
//is achieved in C++0x. Meanwhile, if we want to be able to
//bind rvalues with non-const references, we have to be ugly
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
   #define BOOST_INTERPROCESS_PP_PARAM_LIST(z, n, data) \
   BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
   //!
#else
   #define BOOST_INTERPROCESS_PP_PARAM_LIST(z, n, data) \
   const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
   //!
#endif

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
   #define BOOST_INTERPROCESS_PP_PARAM(U, u) \
   U && u \
   //!
#else
   #define BOOST_INTERPROCESS_PP_PARAM(U, u) \
   const U & u \
   //!
#endif

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES

   #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
     BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ))  \
   //!

#else //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES

   #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
     BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
   //!
#endif

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES

   #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)

      namespace boost {
      namespace interprocess {
      namespace ipcdetail {
         template<class T>
         struct ref_holder;

         template<class T>
         struct ref_holder<T &>
         {
            ref_holder(T &t)
               : t_(t)
            {}
            T &t_;
            T & get() {  return t_;   }
            T & get_lvalue() {  return t_;   }
         };

         template<class T>
         struct ref_holder<const T>
         {
            ref_holder(const T &t)
               : t_(t)
            {}
            const T &t_;
            const T & get() {  return t_;   }
            const T & get_lvalue() {  return t_;   }
         };

         template<class T>
         struct ref_holder<const T &&>
         {
            ref_holder(const T &t)
               : t_(t)
            {}
            const T &t_;
            const T & get() {  return t_;   }
            const T & get_lvalue() {  return t_;   }
         };

         template<class T>
         struct ref_holder
         {
            ref_holder(T &&t)
               : t_(t)
            {}
            T &t_;
            T && get() {  return ::boost::move(t_);   }
            T & get_lvalue() {  return t_;   }
         };

         template<class T>
         struct ref_holder<T &&>
         {
            ref_holder(T &&t)
               : t(t)
            {}
            T &t;
            T && get()  { return ::boost::move(t_); }
            T & get_lvalue() {  return t_;   }
         };

      }  //namespace ipcdetail {
      }  //namespace interprocess {
      }  //namespace boost {

      #define BOOST_INTERPROCESS_PP_PARAM_DEFINE(z, n, data)  \
         ::boost::interprocess::ipcdetail::ref_holder<BOOST_PP_CAT(P, n)> BOOST_PP_CAT(m_p, n);  \
      //!

      #define BOOST_INTERPROCESS_PP_PARAM_INC(z, n, data)   \
         BOOST_PP_CAT(++m_p, n).get_lvalue()                \
      //!

   #else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG

      #define BOOST_INTERPROCESS_PP_PARAM_DEFINE(z, n, data)\
      BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n);           \
      //!

      #define BOOST_INTERPROCESS_PP_PARAM_INC(z, n, data)   \
         BOOST_PP_CAT(++m_p, n)                             \
      //!

   #endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)

#else
   #define BOOST_INTERPROCESS_PP_PARAM_DEFINE(z, n, data)   \
   BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n);               \
   //!

   #define BOOST_INTERPROCESS_PP_PARAM_INC(z, n, data)      \
      BOOST_PP_CAT(++m_p, n)                                \
   //!

#endif

#define BOOST_INTERPROCESS_PP_PARAM_FORWARD(z, n, data) \
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)

   #define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) BOOST_PP_CAT(this->m_p, n).get() \
   //!

   #define BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD(z, n, data) \
   BOOST_PP_CAT(*m_p, n).get_lvalue()                          \
   //!

#else

   #define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data)       \
   ::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
   //!

   #define BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD(z, n, data)    \
   BOOST_PP_CAT(*m_p, n)                                          \
   //!


#endif   //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)

#include <boost/interprocess/detail/config_end.hpp>

#else
#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
#error "This file is not needed when perfect forwarding is available"
#endif
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_PREPROCESSOR_HPP