File indexing completed on 2025-01-18 09:30:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_TYPES_TUPLE_HPP
0012 #define BOOST_COMPUTE_TYPES_TUPLE_HPP
0013
0014 #include <string>
0015 #include <utility>
0016
0017 #include <boost/preprocessor/enum.hpp>
0018 #include <boost/preprocessor/expr_if.hpp>
0019 #include <boost/preprocessor/repetition.hpp>
0020 #include <boost/tuple/tuple.hpp>
0021
0022 #include <boost/compute/config.hpp>
0023 #include <boost/compute/functional/get.hpp>
0024 #include <boost/compute/type_traits/type_name.hpp>
0025 #include <boost/compute/detail/meta_kernel.hpp>
0026
0027 #ifndef BOOST_COMPUTE_NO_STD_TUPLE
0028 #include <tuple>
0029 #endif
0030
0031 namespace boost {
0032 namespace compute {
0033 namespace detail {
0034
0035
0036 #define BOOST_COMPUTE_PRINT_ELEM(z, n, unused) \
0037 BOOST_PP_EXPR_IF(n, << ", ") \
0038 << kernel.make_lit(boost::get<n>(x))
0039
0040 #define BOOST_COMPUTE_PRINT_TUPLE(z, n, unused) \
0041 template<BOOST_PP_ENUM_PARAMS(n, class T)> \
0042 inline meta_kernel& \
0043 operator<<(meta_kernel &kernel, \
0044 const boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> &x) \
0045 { \
0046 return kernel \
0047 << "(" \
0048 << type_name<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> >() \
0049 << ")" \
0050 << "{" \
0051 BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_ELEM, ~) \
0052 << "}"; \
0053 }
0054
0055 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TUPLE, ~)
0056
0057 #undef BOOST_COMPUTE_PRINT_TUPLE
0058 #undef BOOST_COMPUTE_PRINT_ELEM
0059
0060
0061 #define BOOST_COMPUTE_INJECT_TYPE(z, n, unused) \
0062 kernel.inject_type<T ## n>();
0063
0064 #define BOOST_COMPUTE_INJECT_DECL(z, n, unused) \
0065 << " " << type_name<T ## n>() << " v" #n ";\n"
0066
0067 #define BOOST_COMPUTE_INJECT_IMPL(z, n, unused) \
0068 template<BOOST_PP_ENUM_PARAMS(n, class T)> \
0069 struct inject_type_impl<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
0070 { \
0071 void operator()(meta_kernel &kernel) \
0072 { \
0073 typedef boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> tuple_type; \
0074 BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_TYPE, ~) \
0075 std::stringstream declaration; \
0076 declaration << "typedef struct {\n" \
0077 BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_DECL, ~) \
0078 << "} " << type_name<tuple_type>() << ";\n"; \
0079 kernel.add_type_declaration<tuple_type>(declaration.str()); \
0080 } \
0081 };
0082
0083 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_INJECT_IMPL, ~)
0084
0085 #undef BOOST_COMPUTE_INJECT_IMPL
0086 #undef BOOST_COMPUTE_INJECT_DECL
0087 #undef BOOST_COMPUTE_INJECT_TYPE
0088
0089 #ifdef BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
0090
0091 #define BOOST_COMPUTE_PRINT_TYPE(z, n, unused) \
0092 + type_name<T ## n>() + "_"
0093
0094 #define BOOST_COMPUTE_PRINT_TYPE_NAME(z, n, unused) \
0095 template<BOOST_PP_ENUM_PARAMS(n, class T)> \
0096 struct type_name_trait<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
0097 { \
0098 static const char* value() \
0099 { \
0100 static std::string name = \
0101 std::string("boost_tuple_") \
0102 BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_TYPE, ~) \
0103 "t"; \
0104 return name.c_str(); \
0105 } \
0106 };
0107
0108 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TYPE_NAME, ~)
0109
0110 #undef BOOST_COMPUTE_PRINT_TYPE_NAME
0111 #undef BOOST_COMPUTE_PRINT_TYPE
0112
0113 #else
0114 template<size_t N, class T, class... Rest>
0115 struct write_tuple_type_names
0116 {
0117 void operator()(std::ostream &os)
0118 {
0119 os << type_name<T>() << "_";
0120 write_tuple_type_names<N-1, Rest...>()(os);
0121 }
0122 };
0123
0124 template<class T, class... Rest>
0125 struct write_tuple_type_names<1, T, Rest...>
0126 {
0127 void operator()(std::ostream &os)
0128 {
0129 os << type_name<T>();
0130 }
0131 };
0132
0133
0134 template<class... T>
0135 struct type_name_trait<boost::tuple<T...>>
0136 {
0137 static const char* value()
0138 {
0139 static std::string str = make_type_name();
0140
0141 return str.c_str();
0142 }
0143
0144 static std::string make_type_name()
0145 {
0146 typedef typename boost::tuple<T...> tuple_type;
0147
0148 std::stringstream s;
0149 s << "boost_tuple_";
0150 write_tuple_type_names<
0151 boost::tuples::length<tuple_type>::value, T...
0152 >()(s);
0153 s << "_t";
0154 return s.str();
0155 }
0156 };
0157 #endif
0158
0159 #ifndef BOOST_COMPUTE_NO_STD_TUPLE
0160
0161 template<class... T>
0162 struct type_name_trait<std::tuple<T...>>
0163 {
0164 static const char* value()
0165 {
0166 static std::string str = make_type_name();
0167
0168 return str.c_str();
0169 }
0170
0171 static std::string make_type_name()
0172 {
0173 typedef typename std::tuple<T...> tuple_type;
0174
0175 std::stringstream s;
0176 s << "std_tuple_";
0177 write_tuple_type_names<
0178 std::tuple_size<tuple_type>::value, T...
0179 >()(s);
0180 s << "_t";
0181 return s.str();
0182 }
0183 };
0184 #endif
0185
0186
0187 #define BOOST_COMPUTE_GET_RESULT_TYPE(z, n, unused) \
0188 template<size_t N, BOOST_PP_ENUM_PARAMS(n, class T)> \
0189 struct get_result_type<N, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
0190 { \
0191 typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \
0192 typedef typename boost::tuples::element<N, T>::type type; \
0193 };
0194
0195 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_RESULT_TYPE, ~)
0196
0197 #undef BOOST_COMPUTE_GET_RESULT_TYPE
0198
0199
0200
0201 #define BOOST_COMPUTE_GET_N(z, n, unused) \
0202 template<size_t N, class Arg, BOOST_PP_ENUM_PARAMS(n, class T)> \
0203 inline meta_kernel& operator<<(meta_kernel &kernel, \
0204 const invoked_get<N, Arg, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > &expr) \
0205 { \
0206 typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \
0207 BOOST_STATIC_ASSERT(N < size_t(boost::tuples::length<T>::value)); \
0208 kernel.inject_type<T>(); \
0209 return kernel << expr.m_arg << ".v" << int_(N); \
0210 }
0211
0212 BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_N, ~)
0213
0214 #undef BOOST_COMPUTE_GET_N
0215
0216 }
0217 }
0218 }
0219
0220 #endif