• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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