tuple.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #ifndef BOOST_COMPUTE_TYPES_TUPLE_HPP
  11. #define BOOST_COMPUTE_TYPES_TUPLE_HPP
  12. #include <string>
  13. #include <utility>
  14. #include <boost/preprocessor/enum.hpp>
  15. #include <boost/preprocessor/expr_if.hpp>
  16. #include <boost/preprocessor/repetition.hpp>
  17. #include <boost/tuple/tuple.hpp>
  18. #include <boost/compute/config.hpp>
  19. #include <boost/compute/functional/get.hpp>
  20. #include <boost/compute/type_traits/type_name.hpp>
  21. #include <boost/compute/detail/meta_kernel.hpp>
  22. #ifndef BOOST_COMPUTE_NO_STD_TUPLE
  23. #include <tuple>
  24. #endif
  25. namespace boost {
  26. namespace compute {
  27. namespace detail {
  28. // meta_kernel operators for boost::tuple literals
  29. #define BOOST_COMPUTE_PRINT_ELEM(z, n, unused) \
  30. BOOST_PP_EXPR_IF(n, << ", ") \
  31. << kernel.make_lit(boost::get<n>(x))
  32. #define BOOST_COMPUTE_PRINT_TUPLE(z, n, unused) \
  33. template<BOOST_PP_ENUM_PARAMS(n, class T)> \
  34. inline meta_kernel& \
  35. operator<<(meta_kernel &kernel, \
  36. const boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> &x) \
  37. { \
  38. return kernel \
  39. << "(" \
  40. << type_name<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> >() \
  41. << ")" \
  42. << "{" \
  43. BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_ELEM, ~) \
  44. << "}"; \
  45. }
  46. BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TUPLE, ~)
  47. #undef BOOST_COMPUTE_PRINT_TUPLE
  48. #undef BOOST_COMPUTE_PRINT_ELEM
  49. // inject_type() specializations for boost::tuple
  50. #define BOOST_COMPUTE_INJECT_TYPE(z, n, unused) \
  51. kernel.inject_type<T ## n>();
  52. #define BOOST_COMPUTE_INJECT_DECL(z, n, unused) \
  53. << " " << type_name<T ## n>() << " v" #n ";\n"
  54. #define BOOST_COMPUTE_INJECT_IMPL(z, n, unused) \
  55. template<BOOST_PP_ENUM_PARAMS(n, class T)> \
  56. struct inject_type_impl<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
  57. { \
  58. void operator()(meta_kernel &kernel) \
  59. { \
  60. typedef boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> tuple_type; \
  61. BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_TYPE, ~) \
  62. std::stringstream declaration; \
  63. declaration << "typedef struct {\n" \
  64. BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_DECL, ~) \
  65. << "} " << type_name<tuple_type>() << ";\n"; \
  66. kernel.add_type_declaration<tuple_type>(declaration.str()); \
  67. } \
  68. };
  69. BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_INJECT_IMPL, ~)
  70. #undef BOOST_COMPUTE_INJECT_IMPL
  71. #undef BOOST_COMPUTE_INJECT_DECL
  72. #undef BOOST_COMPUTE_INJECT_TYPE
  73. #ifdef BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
  74. // type_name() specializations for boost::tuple (without variadic templates)
  75. #define BOOST_COMPUTE_PRINT_TYPE(z, n, unused) \
  76. + type_name<T ## n>() + "_"
  77. #define BOOST_COMPUTE_PRINT_TYPE_NAME(z, n, unused) \
  78. template<BOOST_PP_ENUM_PARAMS(n, class T)> \
  79. struct type_name_trait<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
  80. { \
  81. static const char* value() \
  82. { \
  83. static std::string name = \
  84. std::string("boost_tuple_") \
  85. BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_TYPE, ~) \
  86. "t"; \
  87. return name.c_str(); \
  88. } \
  89. };
  90. BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TYPE_NAME, ~)
  91. #undef BOOST_COMPUTE_PRINT_TYPE_NAME
  92. #undef BOOST_COMPUTE_PRINT_TYPE
  93. #else
  94. template<size_t N, class T, class... Rest>
  95. struct write_tuple_type_names
  96. {
  97. void operator()(std::ostream &os)
  98. {
  99. os << type_name<T>() << "_";
  100. write_tuple_type_names<N-1, Rest...>()(os);
  101. }
  102. };
  103. template<class T, class... Rest>
  104. struct write_tuple_type_names<1, T, Rest...>
  105. {
  106. void operator()(std::ostream &os)
  107. {
  108. os << type_name<T>();
  109. }
  110. };
  111. // type_name<> specialization for boost::tuple<...> (with variadic templates)
  112. template<class... T>
  113. struct type_name_trait<boost::tuple<T...>>
  114. {
  115. static const char* value()
  116. {
  117. static std::string str = make_type_name();
  118. return str.c_str();
  119. }
  120. static std::string make_type_name()
  121. {
  122. typedef typename boost::tuple<T...> tuple_type;
  123. std::stringstream s;
  124. s << "boost_tuple_";
  125. write_tuple_type_names<
  126. boost::tuples::length<tuple_type>::value, T...
  127. >()(s);
  128. s << "_t";
  129. return s.str();
  130. }
  131. };
  132. #endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
  133. #ifndef BOOST_COMPUTE_NO_STD_TUPLE
  134. // type_name<> specialization for std::tuple<T...>
  135. template<class... T>
  136. struct type_name_trait<std::tuple<T...>>
  137. {
  138. static const char* value()
  139. {
  140. static std::string str = make_type_name();
  141. return str.c_str();
  142. }
  143. static std::string make_type_name()
  144. {
  145. typedef typename std::tuple<T...> tuple_type;
  146. std::stringstream s;
  147. s << "std_tuple_";
  148. write_tuple_type_names<
  149. std::tuple_size<tuple_type>::value, T...
  150. >()(s);
  151. s << "_t";
  152. return s.str();
  153. }
  154. };
  155. #endif // BOOST_COMPUTE_NO_STD_TUPLE
  156. // get<N>() result type specialization for boost::tuple<>
  157. #define BOOST_COMPUTE_GET_RESULT_TYPE(z, n, unused) \
  158. template<size_t N, BOOST_PP_ENUM_PARAMS(n, class T)> \
  159. struct get_result_type<N, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
  160. { \
  161. typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \
  162. typedef typename boost::tuples::element<N, T>::type type; \
  163. };
  164. BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_RESULT_TYPE, ~)
  165. #undef BOOST_COMPUTE_GET_RESULT_TYPE
  166. // get<N>() specialization for boost::tuple<>
  167. #define BOOST_COMPUTE_GET_N(z, n, unused) \
  168. template<size_t N, class Arg, BOOST_PP_ENUM_PARAMS(n, class T)> \
  169. inline meta_kernel& operator<<(meta_kernel &kernel, \
  170. const invoked_get<N, Arg, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > &expr) \
  171. { \
  172. typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \
  173. BOOST_STATIC_ASSERT(N < size_t(boost::tuples::length<T>::value)); \
  174. kernel.inject_type<T>(); \
  175. return kernel << expr.m_arg << ".v" << int_(N); \
  176. }
  177. BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_N, ~)
  178. #undef BOOST_COMPUTE_GET_N
  179. } // end detail namespace
  180. } // end compute namespace
  181. } // end boost namespace
  182. #endif // BOOST_COMPUTE_TYPES_TUPLE_HPP