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_STRUCT_HPP
0012 #define BOOST_COMPUTE_TYPES_STRUCT_HPP
0013
0014 #include <sstream>
0015
0016 #include <boost/static_assert.hpp>
0017
0018 #include <boost/preprocessor/expr_if.hpp>
0019 #include <boost/preprocessor/stringize.hpp>
0020 #include <boost/preprocessor/seq/fold_left.hpp>
0021 #include <boost/preprocessor/seq/for_each.hpp>
0022 #include <boost/preprocessor/seq/transform.hpp>
0023
0024 #include <boost/compute/type_traits/type_definition.hpp>
0025 #include <boost/compute/type_traits/type_name.hpp>
0026 #include <boost/compute/detail/meta_kernel.hpp>
0027 #include <boost/compute/detail/variadic_macros.hpp>
0028
0029 namespace boost {
0030 namespace compute {
0031 namespace detail {
0032
0033 template<class Struct, class T>
0034 inline std::string adapt_struct_insert_member(T Struct::*, const char *name)
0035 {
0036 std::stringstream s;
0037 s << " " << type_name<T>() << " " << name << ";\n";
0038 return s.str();
0039 }
0040
0041
0042 template<class Struct, class T, int N>
0043 inline std::string adapt_struct_insert_member(T (Struct::*)[N], const char *name)
0044 {
0045 std::stringstream s;
0046 s << " " << type_name<T>() << " " << name << "[" << N << "]" << ";\n";
0047 return s.str();
0048 }
0049
0050 }
0051 }
0052 }
0053
0054
0055 #define BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_INSERT_MEMBER(r, type, member) \
0056 << ::boost::compute::detail::adapt_struct_insert_member( \
0057 &type::member, BOOST_PP_STRINGIZE(member) \
0058 )
0059
0060
0061 #define BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_STREAM_MEMBER(r, data, i, elem) \
0062 BOOST_PP_EXPR_IF(i, << ", ") << data.elem
0063
0064
0065 #define BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE(s, struct_, member_) \
0066 sizeof(((struct_ *)0)->member_)
0067
0068
0069 #define BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_ADD(s, x, y) (x+y)
0070
0071
0072 #define BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_SUM(struct_, members_) \
0073 BOOST_PP_SEQ_FOLD_LEFT( \
0074 BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_ADD, \
0075 0, \
0076 BOOST_PP_SEQ_TRANSFORM( \
0077 BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE, struct_, members_ \
0078 ) \
0079 )
0080
0081
0082
0083
0084
0085 #define BOOST_COMPUTE_DETAIL_STRUCT_IS_PACKED(struct_, members_) \
0086 (sizeof(struct_) == BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_SUM(struct_, members_))
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 #define BOOST_COMPUTE_ADAPT_STRUCT(type, name, members) \
0133 BOOST_STATIC_ASSERT_MSG( \
0134 BOOST_COMPUTE_DETAIL_STRUCT_IS_PACKED(type, BOOST_COMPUTE_PP_TUPLE_TO_SEQ(members)), \
0135 "BOOST_COMPUTE_ADAPT_STRUCT() does not support structs with internal padding." \
0136 ); \
0137 BOOST_COMPUTE_TYPE_NAME(type, name) \
0138 namespace boost { namespace compute { \
0139 template<> \
0140 inline std::string type_definition<type>() \
0141 { \
0142 std::stringstream declaration; \
0143 declaration << "typedef struct __attribute__((packed)) {\n" \
0144 BOOST_PP_SEQ_FOR_EACH( \
0145 BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_INSERT_MEMBER, \
0146 type, \
0147 BOOST_COMPUTE_PP_TUPLE_TO_SEQ(members) \
0148 ) \
0149 << "} " << type_name<type>() << ";\n"; \
0150 return declaration.str(); \
0151 } \
0152 namespace detail { \
0153 template<> \
0154 struct inject_type_impl<type> \
0155 { \
0156 void operator()(meta_kernel &kernel) \
0157 { \
0158 kernel.add_type_declaration<type>(type_definition<type>()); \
0159 } \
0160 }; \
0161 inline meta_kernel& operator<<(meta_kernel &k, type s) \
0162 { \
0163 return k << "(" << #name << "){" \
0164 BOOST_PP_SEQ_FOR_EACH_I( \
0165 BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_STREAM_MEMBER, \
0166 s, \
0167 BOOST_COMPUTE_PP_TUPLE_TO_SEQ(members) \
0168 ) \
0169 << "}"; \
0170 } \
0171 }}}
0172
0173 #endif