diff options
Diffstat (limited to 'boost/compute/types/tuple.hpp')
-rw-r--r-- | boost/compute/types/tuple.hpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/boost/compute/types/tuple.hpp b/boost/compute/types/tuple.hpp new file mode 100644 index 0000000000..095bd95448 --- /dev/null +++ b/boost/compute/types/tuple.hpp @@ -0,0 +1,220 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com> +// +// Distributed under the Boost Software License, Version 1.0 +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://boostorg.github.com/compute for more information. +//---------------------------------------------------------------------------// + +#ifndef BOOST_COMPUTE_TYPES_TUPLE_HPP +#define BOOST_COMPUTE_TYPES_TUPLE_HPP + +#include <string> +#include <utility> + +#include <boost/preprocessor/enum.hpp> +#include <boost/preprocessor/expr_if.hpp> +#include <boost/preprocessor/repetition.hpp> +#include <boost/tuple/tuple.hpp> + +#include <boost/compute/config.hpp> +#include <boost/compute/functional/get.hpp> +#include <boost/compute/type_traits/type_name.hpp> +#include <boost/compute/detail/meta_kernel.hpp> + +#ifndef BOOST_COMPUTE_NO_STD_TUPLE +#include <tuple> +#endif + +namespace boost { +namespace compute { +namespace detail { + +// meta_kernel operators for boost::tuple literals +#define BOOST_COMPUTE_PRINT_ELEM(z, n, unused) \ + BOOST_PP_EXPR_IF(n, << ", ") \ + << kernel.make_lit(boost::get<n>(x)) + +#define BOOST_COMPUTE_PRINT_TUPLE(z, n, unused) \ +template<BOOST_PP_ENUM_PARAMS(n, class T)> \ +inline meta_kernel& \ +operator<<(meta_kernel &kernel, \ + const boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> &x) \ +{ \ + return kernel \ + << "(" \ + << type_name<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> >() \ + << ")" \ + << "{" \ + BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_ELEM, ~) \ + << "}"; \ +} + +BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TUPLE, ~) + +#undef BOOST_COMPUTE_PRINT_TUPLE +#undef BOOST_COMPUTE_PRINT_ELEM + +// inject_type() specializations for boost::tuple +#define BOOST_COMPUTE_INJECT_TYPE(z, n, unused) \ + kernel.inject_type<T ## n>(); + +#define BOOST_COMPUTE_INJECT_DECL(z, n, unused) \ + << " " << type_name<T ## n>() << " v" #n ";\n" + +#define BOOST_COMPUTE_INJECT_IMPL(z, n, unused) \ +template<BOOST_PP_ENUM_PARAMS(n, class T)> \ +struct inject_type_impl<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \ +{ \ + void operator()(meta_kernel &kernel) \ + { \ + typedef boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> tuple_type; \ + BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_TYPE, ~) \ + std::stringstream declaration; \ + declaration << "typedef struct {\n" \ + BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_DECL, ~) \ + << "} " << type_name<tuple_type>() << ";\n"; \ + kernel.add_type_declaration<tuple_type>(declaration.str()); \ + } \ +}; + +BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_INJECT_IMPL, ~) + +#undef BOOST_COMPUTE_INJECT_IMPL +#undef BOOST_COMPUTE_INJECT_DECL +#undef BOOST_COMPUTE_INJECT_TYPE + +#ifdef BOOST_COMPUTE_NO_VARIADIC_TEMPLATES +// type_name() specializations for boost::tuple (without variadic templates) +#define BOOST_COMPUTE_PRINT_TYPE(z, n, unused) \ + + type_name<T ## n>() + "_" + +#define BOOST_COMPUTE_PRINT_TYPE_NAME(z, n, unused) \ +template<BOOST_PP_ENUM_PARAMS(n, class T)> \ +struct type_name_trait<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \ +{ \ + static const char* value() \ + { \ + static std::string name = \ + std::string("boost_tuple_") \ + BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_TYPE, ~) \ + "t"; \ + return name.c_str(); \ + } \ +}; + +BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TYPE_NAME, ~) + +#undef BOOST_COMPUTE_PRINT_TYPE_NAME +#undef BOOST_COMPUTE_PRINT_TYPE + +#else +template<size_t N, class T, class... Rest> +struct write_tuple_type_names +{ + void operator()(std::ostream &os) + { + os << type_name<T>() << "_"; + write_tuple_type_names<N-1, Rest...>()(os); + } +}; + +template<class T, class... Rest> +struct write_tuple_type_names<1, T, Rest...> +{ + void operator()(std::ostream &os) + { + os << type_name<T>(); + } +}; + +// type_name<> specialization for boost::tuple<...> (with variadic templates) +template<class... T> +struct type_name_trait<boost::tuple<T...>> +{ + static const char* value() + { + static std::string str = make_type_name(); + + return str.c_str(); + } + + static std::string make_type_name() + { + typedef typename boost::tuple<T...> tuple_type; + + std::stringstream s; + s << "boost_tuple_"; + write_tuple_type_names< + boost::tuples::length<tuple_type>::value, T... + >()(s); + s << "_t"; + return s.str(); + } +}; +#endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES + +#ifndef BOOST_COMPUTE_NO_STD_TUPLE +// type_name<> specialization for std::tuple<T...> +template<class... T> +struct type_name_trait<std::tuple<T...>> +{ + static const char* value() + { + static std::string str = make_type_name(); + + return str.c_str(); + } + + static std::string make_type_name() + { + typedef typename std::tuple<T...> tuple_type; + + std::stringstream s; + s << "std_tuple_"; + write_tuple_type_names< + std::tuple_size<tuple_type>::value, T... + >()(s); + s << "_t"; + return s.str(); + } +}; +#endif // BOOST_COMPUTE_NO_STD_TUPLE + +// get<N>() result type specialization for boost::tuple<> +#define BOOST_COMPUTE_GET_RESULT_TYPE(z, n, unused) \ +template<size_t N, BOOST_PP_ENUM_PARAMS(n, class T)> \ +struct get_result_type<N, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \ +{ \ + typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \ + typedef typename boost::tuples::element<N, T>::type type; \ +}; + +BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_RESULT_TYPE, ~) + +#undef BOOST_COMPUTE_GET_RESULT_TYPE + + +// get<N>() specialization for boost::tuple<> +#define BOOST_COMPUTE_GET_N(z, n, unused) \ +template<size_t N, class Arg, BOOST_PP_ENUM_PARAMS(n, class T)> \ +inline meta_kernel& operator<<(meta_kernel &kernel, \ + const invoked_get<N, Arg, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > &expr) \ +{ \ + typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \ + BOOST_STATIC_ASSERT(N < size_t(boost::tuples::length<T>::value)); \ + kernel.inject_type<T>(); \ + return kernel << expr.m_arg << ".v" << uint_(N); \ +} + +BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_N, ~) + +#undef BOOST_COMPUTE_GET_N + +} // end detail namespace +} // end compute namespace +} // end boost namespace + +#endif // BOOST_COMPUTE_TYPES_TUPLE_HPP |