preprocessor.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2008-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/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
  11. #define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
  12. #if defined(_MSC_VER)
  13. # pragma once
  14. #endif
  15. #include <boost/container/detail/config_begin.hpp>
  16. #include <boost/container/detail/workaround.hpp>
  17. #include <boost/move/utility.hpp>
  18. #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  19. //#error "This file is not needed when perfect forwarding is available"
  20. #endif //BOOST_CONTAINER_PERFECT_FORWARDING
  21. #include <boost/preprocessor/iteration/local.hpp>
  22. #include <boost/preprocessor/punctuation/paren_if.hpp>
  23. #include <boost/preprocessor/punctuation/comma_if.hpp>
  24. #include <boost/preprocessor/control/expr_if.hpp>
  25. #include <boost/preprocessor/cat.hpp>
  26. #include <boost/preprocessor/repetition/enum.hpp>
  27. #include <boost/preprocessor/repetition/enum_params.hpp>
  28. #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  29. #include <boost/preprocessor/repetition/enum_trailing.hpp>
  30. #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
  31. #include <boost/preprocessor/repetition/enum_shifted.hpp>
  32. #include <boost/preprocessor/repetition/repeat.hpp>
  33. #include <boost/preprocessor/logical/not.hpp>
  34. #include <boost/preprocessor/arithmetic/sub.hpp>
  35. #include <boost/preprocessor/arithmetic/add.hpp>
  36. #include <boost/preprocessor/iteration/iterate.hpp>
  37. #include <boost/move/utility.hpp>
  38. #define BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS 10
  39. //Note:
  40. //We define template parameters as const references to
  41. //be able to bind temporaries. After that we will un-const them.
  42. //This cast is ugly but it is necessary until "perfect forwarding"
  43. //is achieved in C++0x. Meanwhile, if we want to be able to
  44. //bind rvalues with non-const references, we have to be ugly
  45. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  46. #define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
  47. BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
  48. //!
  49. #else
  50. #define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
  51. const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
  52. //!
  53. #endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  54. #define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
  55. const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
  56. //!
  57. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  58. #define BOOST_CONTAINER_PP_PARAM(U, u) \
  59. U && u \
  60. //!
  61. #else
  62. #define BOOST_CONTAINER_PP_PARAM(U, u) \
  63. const U & u \
  64. //!
  65. #endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  66. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  67. #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
  68. BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
  69. //!
  70. #else //BOOST_NO_CXX11_RVALUE_REFERENCES
  71. #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
  72. BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
  73. //!
  74. #endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  75. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  76. #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
  77. namespace boost {
  78. namespace container {
  79. namespace container_detail {
  80. template<class T>
  81. struct ref_holder;
  82. template<class T>
  83. struct ref_holder<T &>
  84. {
  85. explicit ref_holder(T &t)
  86. : t_(t)
  87. {}
  88. T &t_;
  89. T & get() { return t_; }
  90. };
  91. template<class T>
  92. struct ref_holder<const T>
  93. {
  94. explicit ref_holder(const T &t)
  95. : t_(t)
  96. {}
  97. const T &t_;
  98. const T & get() { return t_; }
  99. };
  100. template<class T>
  101. struct ref_holder<const T &&>
  102. {
  103. explicit ref_holder(const T &t)
  104. : t_(t)
  105. {}
  106. const T &t_;
  107. const T & get() { return t_; }
  108. };
  109. template<class T>
  110. struct ref_holder
  111. {
  112. explicit ref_holder(T &&t)
  113. : t_(t)
  114. {}
  115. T &t_;
  116. T && get() { return ::boost::move(t_); }
  117. };
  118. template<class T>
  119. struct ref_holder<T &&>
  120. {
  121. explicit ref_holder(T &&t)
  122. : t_(t)
  123. {}
  124. T &t_;
  125. T && get() { return ::boost::move(t_); }
  126. };
  127. } //namespace container_detail {
  128. } //namespace container {
  129. } //namespace boost {
  130. #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
  131. ::boost::container::container_detail::ref_holder<BOOST_PP_CAT(P, n)> BOOST_PP_CAT(m_p, n); \
  132. //!
  133. #else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
  134. #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
  135. BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
  136. //!
  137. #endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
  138. #else //BOOST_NO_CXX11_RVALUE_REFERENCES
  139. #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
  140. BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
  141. //!
  142. #endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  143. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
  144. #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) BOOST_PP_CAT(this->m_p, n).get() \
  145. //!
  146. #else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
  147. #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
  148. ::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
  149. //!
  150. #endif //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
  151. #define BOOST_CONTAINER_PP_PARAM_INC(z, n, data) \
  152. BOOST_PP_CAT(++this->m_p, n) \
  153. //!
  154. #define BOOST_CONTAINER_PP_IDENTITY(z, n, data) data
  155. #define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
  156. ::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
  157. //!
  158. #define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
  159. ::boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
  160. //!
  161. #define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
  162. BOOST_PP_CAT(*this->m_p, n) \
  163. //!
  164. #define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
  165. BOOST_PP_CAT(class P, n) = void \
  166. //!
  167. #define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
  168. BOOST_PP_CAT(class P, n) = default_type \
  169. //!
  170. #define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
  171. static BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n); \
  172. //!
  173. #define BOOST_CONTAINER_PP_PARAM_PASS(z, n, data) \
  174. BOOST_PP_CAT(p, n) \
  175. //!
  176. #define BOOST_CONTAINER_PP_FWD_TYPE(z, n, data) \
  177. typename ::boost::move_detail::forward_type< BOOST_PP_CAT(P, n) >::type \
  178. //!
  179. #include <boost/container/detail/config_end.hpp>
  180. //#else
  181. //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  182. //#error "This file is not needed when perfect forwarding is available"
  183. //#endif //BOOST_CONTAINER_PERFECT_FORWARDING
  184. #endif //#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP