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 11 #ifndef BOOST_COMPUTE_TYPES_TUPLE_HPP 12 #define BOOST_COMPUTE_TYPES_TUPLE_HPP 13 14 #include <string> 15 #include <utility> 16 17 #include <boost/preprocessor/enum.hpp> 18 #include <boost/preprocessor/expr_if.hpp> 19 #include <boost/preprocessor/repetition.hpp> 20 #include <boost/tuple/tuple.hpp> 21 22 #include <boost/compute/config.hpp> 23 #include <boost/compute/functional/get.hpp> 24 #include <boost/compute/type_traits/type_name.hpp> 25 #include <boost/compute/detail/meta_kernel.hpp> 26 27 #ifndef BOOST_COMPUTE_NO_STD_TUPLE 28 #include <tuple> 29 #endif 30 31 namespace boost { 32 namespace compute { 33 namespace detail { 34 35 // meta_kernel operators for boost::tuple literals 36 #define BOOST_COMPUTE_PRINT_ELEM(z, n, unused) \ 37 BOOST_PP_EXPR_IF(n, << ", ") \ 38 << kernel.make_lit(boost::get<n>(x)) 39 40 #define BOOST_COMPUTE_PRINT_TUPLE(z, n, unused) \ 41 template<BOOST_PP_ENUM_PARAMS(n, class T)> \ 42 inline meta_kernel& \ 43 operator<<(meta_kernel &kernel, \ 44 const boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> &x) \ 45 { \ 46 return kernel \ 47 << "(" \ 48 << type_name<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> >() \ 49 << ")" \ 50 << "{" \ 51 BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_ELEM, ~) \ 52 << "}"; \ 53 } 54 55 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TUPLE, ~) 56 57 #undef BOOST_COMPUTE_PRINT_TUPLE 58 #undef BOOST_COMPUTE_PRINT_ELEM 59 60 // inject_type() specializations for boost::tuple 61 #define BOOST_COMPUTE_INJECT_TYPE(z, n, unused) \ 62 kernel.inject_type<T ## n>(); 63 64 #define BOOST_COMPUTE_INJECT_DECL(z, n, unused) \ 65 << " " << type_name<T ## n>() << " v" #n ";\n" 66 67 #define BOOST_COMPUTE_INJECT_IMPL(z, n, unused) \ 68 template<BOOST_PP_ENUM_PARAMS(n, class T)> \ 69 struct inject_type_impl<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \ 70 { \ 71 void operator()(meta_kernel &kernel) \ 72 { \ 73 typedef boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> tuple_type; \ 74 BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_TYPE, ~) \ 75 std::stringstream declaration; \ 76 declaration << "typedef struct {\n" \ 77 BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_DECL, ~) \ 78 << "} " << type_name<tuple_type>() << ";\n"; \ 79 kernel.add_type_declaration<tuple_type>(declaration.str()); \ 80 } \ 81 }; 82 83 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_INJECT_IMPL, ~) 84 85 #undef BOOST_COMPUTE_INJECT_IMPL 86 #undef BOOST_COMPUTE_INJECT_DECL 87 #undef BOOST_COMPUTE_INJECT_TYPE 88 89 #ifdef BOOST_COMPUTE_NO_VARIADIC_TEMPLATES 90 // type_name() specializations for boost::tuple (without variadic templates) 91 #define BOOST_COMPUTE_PRINT_TYPE(z, n, unused) \ 92 + type_name<T ## n>() + "_" 93 94 #define BOOST_COMPUTE_PRINT_TYPE_NAME(z, n, unused) \ 95 template<BOOST_PP_ENUM_PARAMS(n, class T)> \ 96 struct type_name_trait<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \ 97 { \ 98 static const char* value() \ 99 { \ 100 static std::string name = \ 101 std::string("boost_tuple_") \ 102 BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_TYPE, ~) \ 103 "t"; \ 104 return name.c_str(); \ 105 } \ 106 }; 107 108 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TYPE_NAME, ~) 109 110 #undef BOOST_COMPUTE_PRINT_TYPE_NAME 111 #undef BOOST_COMPUTE_PRINT_TYPE 112 113 #else 114 template<size_t N, class T, class... Rest> 115 struct write_tuple_type_names 116 { 117 void operator()(std::ostream &os) 118 { 119 os << type_name<T>() << "_"; 120 write_tuple_type_names<N-1, Rest...>()(os); 121 } 122 }; 123 124 template<class T, class... Rest> 125 struct write_tuple_type_names<1, T, Rest...> 126 { 127 void operator()(std::ostream &os) 128 { 129 os << type_name<T>(); 130 } 131 }; 132 133 // type_name<> specialization for boost::tuple<...> (with variadic templates) 134 template<class... T> 135 struct type_name_trait<boost::tuple<T...>> 136 { 137 static const char* value() 138 { 139 static std::string str = make_type_name(); 140 141 return str.c_str(); 142 } 143 144 static std::string make_type_name() 145 { 146 typedef typename boost::tuple<T...> tuple_type; 147 148 std::stringstream s; 149 s << "boost_tuple_"; 150 write_tuple_type_names< 151 boost::tuples::length<tuple_type>::value, T... 152 >()(s); 153 s << "_t"; 154 return s.str(); 155 } 156 }; 157 #endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES 158 159 #ifndef BOOST_COMPUTE_NO_STD_TUPLE 160 // type_name<> specialization for std::tuple<T...> 161 template<class... T> 162 struct type_name_trait<std::tuple<T...>> 163 { valueboost::compute::detail::type_name_trait164 static const char* value() 165 { 166 static std::string str = make_type_name(); 167 168 return str.c_str(); 169 } 170 make_type_nameboost::compute::detail::type_name_trait171 static std::string make_type_name() 172 { 173 typedef typename std::tuple<T...> tuple_type; 174 175 std::stringstream s; 176 s << "std_tuple_"; 177 write_tuple_type_names< 178 std::tuple_size<tuple_type>::value, T... 179 >()(s); 180 s << "_t"; 181 return s.str(); 182 } 183 }; 184 #endif // BOOST_COMPUTE_NO_STD_TUPLE 185 186 // get<N>() result type specialization for boost::tuple<> 187 #define BOOST_COMPUTE_GET_RESULT_TYPE(z, n, unused) \ 188 template<size_t N, BOOST_PP_ENUM_PARAMS(n, class T)> \ 189 struct get_result_type<N, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \ 190 { \ 191 typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \ 192 typedef typename boost::tuples::element<N, T>::type type; \ 193 }; 194 195 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_RESULT_TYPE, ~) 196 197 #undef BOOST_COMPUTE_GET_RESULT_TYPE 198 199 200 // get<N>() specialization for boost::tuple<> 201 #define BOOST_COMPUTE_GET_N(z, n, unused) \ 202 template<size_t N, class Arg, BOOST_PP_ENUM_PARAMS(n, class T)> \ 203 inline meta_kernel& operator<<(meta_kernel &kernel, \ 204 const invoked_get<N, Arg, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > &expr) \ 205 { \ 206 typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \ 207 BOOST_STATIC_ASSERT(N < size_t(boost::tuples::length<T>::value)); \ 208 kernel.inject_type<T>(); \ 209 return kernel << expr.m_arg << ".v" << int_(N); \ 210 } 211 212 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_N, ~) 213 214 #undef BOOST_COMPUTE_GET_N 215 216 } // end detail namespace 217 } // end compute namespace 218 } // end boost namespace 219 220 #endif // BOOST_COMPUTE_TYPES_TUPLE_HPP 221