construct.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // - construct.hpp -- Lambda Library -------------
  2. //
  3. // Copyright (C) 2000 Gary Powell ([email protected])
  4. // Copyright (C) 1999, 2000 Jaakko Jarvi ([email protected])
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // For more information, see http://www.boost.org
  11. //
  12. // -----------------------------------------------
  13. #if !defined(BOOST_LAMBDA_CONSTRUCT_HPP)
  14. #define BOOST_LAMBDA_CONSTRUCT_HPP
  15. #include "boost/type_traits/remove_cv.hpp"
  16. #include "boost/type_traits/is_pointer.hpp"
  17. #include "boost/config.hpp"
  18. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  19. #include <utility>
  20. #endif
  21. namespace boost {
  22. namespace lambda {
  23. // constructor is used together with bind. constructor<A> creates a bindable
  24. // function object that passes its arguments forward to a constructor call
  25. // of type A
  26. template<class T> struct constructor {
  27. template <class U> struct sig { typedef T type; };
  28. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  29. template <class... Args>
  30. T operator()(Args&&... args) const {
  31. return T(std::forward<Args>(args)...);
  32. }
  33. #else
  34. T operator()() const {
  35. return T();
  36. }
  37. template<class A1>
  38. T operator()(A1& a1) const {
  39. return T(a1);
  40. }
  41. template<class A1, class A2>
  42. T operator()(A1& a1, A2& a2) const {
  43. return T(a1, a2);
  44. }
  45. template<class A1, class A2, class A3>
  46. T operator()(A1& a1, A2& a2, A3& a3) const {
  47. return T(a1, a2, a3);
  48. }
  49. template<class A1, class A2, class A3, class A4>
  50. T operator()(A1& a1, A2& a2, A3& a3, A4& a4) const {
  51. return T(a1, a2, a3, a4);
  52. }
  53. template<class A1, class A2, class A3, class A4, class A5>
  54. T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) const {
  55. return T(a1, a2, a3, a4, a5);
  56. }
  57. template<class A1, class A2, class A3, class A4, class A5, class A6>
  58. T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) const {
  59. return T(a1, a2, a3, a4, a5, a6);
  60. }
  61. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
  62. T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) const {
  63. return T(a1, a2, a3, a4, a5, a6, a7);
  64. }
  65. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
  66. T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) const {
  67. return T(a1, a2, a3, a4, a5, a6, a7, a8);
  68. }
  69. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
  70. T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) const {
  71. return T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
  72. }
  73. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
  74. T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9, A10& a10) const {
  75. return T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
  76. }
  77. #endif
  78. };
  79. namespace detail {
  80. // A standard conforming compiler could disambiguate between
  81. // A1* and A1&, but not all compilers do that, so we need the
  82. // helpers
  83. template <bool IsPointer>
  84. struct destructor_helper {
  85. template<class A1>
  86. static void exec(A1& a1) {
  87. // remove all the qualifiers, not sure whether it is necessary
  88. typedef typename boost::remove_cv<A1>::type plainA1;
  89. a1.~plainA1();
  90. }
  91. };
  92. template <>
  93. struct destructor_helper<true> {
  94. template<class A1>
  95. static void exec(A1* a1) {
  96. typedef typename boost::remove_cv<A1>::type plainA1;
  97. (*a1).~plainA1();
  98. }
  99. };
  100. }
  101. // destructor funtion object
  102. struct destructor {
  103. template <class T> struct sig { typedef void type; };
  104. template<class A1>
  105. void operator()(A1& a1) const {
  106. typedef typename boost::remove_cv<A1>::type plainA1;
  107. detail::destructor_helper<boost::is_pointer<plainA1>::value>::exec(a1);
  108. }
  109. };
  110. // new_ptr is used together with bind.
  111. // note: placement new is not supported
  112. template<class T> struct new_ptr {
  113. template <class U> struct sig { typedef T* type; };
  114. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  115. template <class... Args>
  116. T* operator()(Args&&... args) const {
  117. return new T(std::forward<Args>(args)...);
  118. }
  119. #else
  120. T* operator()() const {
  121. return new T();
  122. }
  123. template<class A1>
  124. T* operator()(A1& a1) const {
  125. return new T(a1);
  126. }
  127. template<class A1, class A2>
  128. T* operator()(A1& a1, A2& a2) const {
  129. return new T(a1, a2);
  130. }
  131. template<class A1, class A2, class A3>
  132. T* operator()(A1& a1, A2& a2, A3& a3) const {
  133. return new T(a1, a2, a3);
  134. }
  135. template<class A1, class A2, class A3, class A4>
  136. T* operator()(A1& a1, A2& a2, A3& a3, A4& a4) const {
  137. return new T(a1, a2, a3, a4);
  138. }
  139. template<class A1, class A2, class A3, class A4, class A5>
  140. T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) const {
  141. return new T(a1, a2, a3, a4, a5);
  142. }
  143. template<class A1, class A2, class A3, class A4, class A5, class A6>
  144. T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) const {
  145. return new T(a1, a2, a3, a4, a5, a6);
  146. }
  147. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
  148. T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) const {
  149. return new T(a1, a2, a3, a4, a5, a6, a7);
  150. }
  151. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
  152. T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) const {
  153. return new T(a1, a2, a3, a4, a5, a6, a7, a8);
  154. }
  155. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
  156. T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) const {
  157. return new T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
  158. }
  159. template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
  160. T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9, A10& a10) const {
  161. return new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
  162. }
  163. #endif
  164. };
  165. // delete_ptr return void
  166. struct delete_ptr {
  167. template <class U> struct sig { typedef void type; };
  168. template <class A1>
  169. void operator()(A1& a1) const {
  170. delete a1;
  171. }
  172. };
  173. // new_array is used together with bind.
  174. template<class T> struct new_array {
  175. template <class U> struct sig { typedef T* type; };
  176. T* operator()(int size) const {
  177. return new T[size];
  178. }
  179. };
  180. // delete_ptr return void
  181. struct delete_array {
  182. template <class U> struct sig { typedef void type; };
  183. template <class A1>
  184. void operator()(A1& a1) const {
  185. delete[] a1;
  186. }
  187. };
  188. } // namespace lambda
  189. } // namespace boost
  190. #endif