//---------------------------------------------------------------------------// // Copyright (c) 2013 Kyle Lutz // // 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 #include #include #include #include #include #include #include #include #include #ifndef BOOST_COMPUTE_NO_STD_TUPLE #include #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(x)) #define BOOST_COMPUTE_PRINT_TUPLE(z, n, unused) \ template \ inline meta_kernel& \ operator<<(meta_kernel &kernel, \ const boost::tuple &x) \ { \ return kernel \ << "(" \ << type_name >() \ << ")" \ << "{" \ 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(); #define BOOST_COMPUTE_INJECT_DECL(z, n, unused) \ << " " << type_name() << " v" #n ";\n" #define BOOST_COMPUTE_INJECT_IMPL(z, n, unused) \ template \ struct inject_type_impl > \ { \ void operator()(meta_kernel &kernel) \ { \ typedef boost::tuple 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() << ";\n"; \ kernel.add_type_declaration(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() + "_" #define BOOST_COMPUTE_PRINT_TYPE_NAME(z, n, unused) \ template \ struct type_name_trait > \ { \ 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 struct write_tuple_type_names { void operator()(std::ostream &os) { os << type_name() << "_"; write_tuple_type_names()(os); } }; template struct write_tuple_type_names<1, T, Rest...> { void operator()(std::ostream &os) { os << type_name(); } }; // type_name<> specialization for boost::tuple<...> (with variadic templates) template struct type_name_trait> { 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 tuple_type; std::stringstream s; s << "boost_tuple_"; write_tuple_type_names< boost::tuples::length::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 template struct type_name_trait> { 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 tuple_type; std::stringstream s; s << "std_tuple_"; write_tuple_type_names< std::tuple_size::value, T... >()(s); s << "_t"; return s.str(); } }; #endif // BOOST_COMPUTE_NO_STD_TUPLE // get() result type specialization for boost::tuple<> #define BOOST_COMPUTE_GET_RESULT_TYPE(z, n, unused) \ template \ struct get_result_type > \ { \ typedef typename boost::tuple T; \ typedef typename boost::tuples::element::type type; \ }; BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_RESULT_TYPE, ~) #undef BOOST_COMPUTE_GET_RESULT_TYPE // get() specialization for boost::tuple<> #define BOOST_COMPUTE_GET_N(z, n, unused) \ template \ inline meta_kernel& operator<<(meta_kernel &kernel, \ const invoked_get > &expr) \ { \ typedef typename boost::tuple T; \ BOOST_STATIC_ASSERT(N < size_t(boost::tuples::length::value)); \ kernel.inject_type(); \ return kernel << expr.m_arg << ".v" << int_(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