File indexing completed on 2025-01-19 09:47:34
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_META_CREATE_NOV_21_2009_0425PM)
0007 #define BOOST_SPIRIT_KARMA_META_CREATE_NOV_21_2009_0425PM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/spirit/home/karma/domain.hpp>
0014 #include <boost/spirit/home/support/common_terminals.hpp>
0015 #include <boost/spirit/home/support/auto/meta_create.hpp>
0016
0017 #include <boost/utility/enable_if.hpp>
0018 #include <boost/variant.hpp>
0019 #include <boost/optional.hpp>
0020 #include <boost/config.hpp>
0021 #include <boost/mpl/not.hpp>
0022 #include <boost/mpl/fold.hpp>
0023 #include <boost/mpl/vector.hpp>
0024 #include <boost/mpl/push_back.hpp>
0025 #include <boost/fusion/include/as_vector.hpp>
0026 #include <boost/proto/tags.hpp>
0027 #include <boost/type_traits/is_same.hpp>
0028
0029
0030 namespace boost { namespace spirit { namespace karma
0031 {
0032
0033
0034 template <typename Container>
0035 struct meta_create_container
0036 {
0037 typedef make_unary_proto_expr<
0038 typename Container::value_type
0039 , proto::tag::dereference, karma::domain
0040 > make_proto_expr;
0041
0042 typedef typename make_proto_expr::type type;
0043
0044 static type call()
0045 {
0046 return make_proto_expr::call();
0047 }
0048 };
0049
0050
0051
0052 template <typename String>
0053 struct meta_create_string
0054 {
0055 typedef spirit::standard::string_type type;
0056 static type const call() { return type(); }
0057 };
0058
0059 template <>
0060 struct meta_create_string<wchar_t*>
0061 {
0062 typedef spirit::standard_wide::string_type type;
0063 static type const call() { return type(); }
0064 };
0065
0066 template <>
0067 struct meta_create_string<wchar_t const*>
0068 {
0069 typedef spirit::standard_wide::string_type type;
0070 static type const call() { return type(); }
0071 };
0072
0073 template <int N>
0074 struct meta_create_string<wchar_t[N]>
0075 {
0076 typedef spirit::standard_wide::string_type type;
0077 static type const call() { return type(); }
0078 };
0079
0080 template <int N>
0081 struct meta_create_string<wchar_t const[N]>
0082 {
0083 typedef spirit::standard_wide::string_type type;
0084 static type const call() { return type(); }
0085 };
0086
0087 template <int N>
0088 struct meta_create_string<wchar_t(&)[N]>
0089 {
0090 typedef spirit::standard_wide::string_type type;
0091 static type const call() { return type(); }
0092 };
0093
0094 template <int N>
0095 struct meta_create_string<wchar_t const(&)[N]>
0096 {
0097 typedef spirit::standard_wide::string_type type;
0098 static type const call() { return type(); }
0099 };
0100
0101 template <typename Traits, typename Allocator>
0102 struct meta_create_string<std::basic_string<wchar_t, Traits, Allocator> >
0103 {
0104 typedef spirit::standard_wide::string_type type;
0105 static type const call() { return type(); }
0106 };
0107
0108
0109
0110 template <typename Sequence>
0111 struct meta_create_sequence
0112 {
0113
0114 typedef typename mpl::fold<
0115 typename fusion::result_of::as_vector<Sequence>::type
0116 , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
0117 >::type sequence_type;
0118
0119 typedef make_nary_proto_expr<
0120 sequence_type, proto::tag::shift_left, karma::domain
0121 > make_proto_expr;
0122
0123 typedef typename make_proto_expr::type type;
0124
0125 static type call()
0126 {
0127 return make_proto_expr::call();
0128 }
0129 };
0130
0131
0132
0133
0134
0135
0136
0137 struct no_auto_mapping_exists {};
0138
0139 template <typename T, typename Enable = void>
0140 struct meta_create_impl : mpl::identity<no_auto_mapping_exists> {};
0141
0142 template <typename T>
0143 struct meta_create_impl<T
0144 , typename enable_if<
0145 mpl::and_<
0146 traits::is_container<T>
0147 , mpl::not_<traits::is_string<T> >
0148 , mpl::not_<fusion::traits::is_sequence<T> >
0149 > >::type>
0150 : meta_create_container<T> {};
0151
0152 template <typename T>
0153 struct meta_create_impl<T
0154 , typename enable_if<traits::is_string<T> >::type>
0155 : meta_create_string<T> {};
0156
0157 template <typename T>
0158 struct meta_create_impl<T, typename enable_if<
0159 spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
0160 >::type>
0161 : meta_create_sequence<T> {};
0162
0163 template <typename T, typename Enable = void>
0164 struct meta_create : meta_create_impl<T> {};
0165
0166
0167
0168 template <typename T>
0169 struct meta_create<boost::optional<T> >
0170 {
0171 typedef make_unary_proto_expr<
0172 T, proto::tag::negate, karma::domain
0173 > make_proto_expr;
0174
0175 typedef typename make_proto_expr::type type;
0176
0177 static type call()
0178 {
0179 return make_proto_expr::call();
0180 }
0181 };
0182
0183
0184
0185 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
0186 struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
0187 {
0188 typedef make_nary_proto_expr<
0189 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
0190 , proto::tag::bitwise_or, karma::domain
0191 > make_proto_expr;
0192
0193 typedef typename make_proto_expr::type type;
0194
0195 static type call()
0196 {
0197 return make_proto_expr::call();
0198 }
0199 };
0200
0201
0202
0203
0204
0205 template <>
0206 struct meta_create<char>
0207 {
0208 typedef spirit::standard::char_type type;
0209 static type const call() { return type(); }
0210 };
0211 template <>
0212 struct meta_create<signed char>
0213 {
0214 typedef spirit::standard::char_type type;
0215 static type const call() { return type(); }
0216 };
0217 template <>
0218 struct meta_create<wchar_t>
0219 {
0220 typedef spirit::standard_wide::char_type type;
0221 static type const call() { return type(); }
0222 };
0223
0224 template <>
0225 struct meta_create<unsigned char>
0226 {
0227 typedef spirit::standard::char_type type;
0228 static type const call() { return type(); }
0229 };
0230
0231
0232 template <>
0233 struct meta_create<bool>
0234 {
0235 typedef spirit::bool_type type;
0236 static type call() { return type(); }
0237 };
0238
0239
0240 template <>
0241 struct meta_create<int>
0242 {
0243 typedef spirit::int_type type;
0244 static type call() { return type(); }
0245 };
0246 template <>
0247 struct meta_create<short>
0248 {
0249 typedef spirit::short_type type;
0250 static type call() { return type(); }
0251 };
0252 template <>
0253 struct meta_create<long>
0254 {
0255 typedef spirit::long_type type;
0256 static type call() { return type(); }
0257 };
0258 template <>
0259 struct meta_create<unsigned int>
0260 {
0261 typedef spirit::uint_type type;
0262 static type call() { return type(); }
0263 };
0264 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
0265 template <>
0266 struct meta_create<unsigned short>
0267 {
0268 typedef spirit::ushort_type type;
0269 static type call() { return type(); }
0270 };
0271 #endif
0272 template <>
0273 struct meta_create<unsigned long>
0274 {
0275 typedef spirit::ulong_type type;
0276 static type call() { return type(); }
0277 };
0278
0279 #ifdef BOOST_HAS_LONG_LONG
0280 template <>
0281 struct meta_create<boost::long_long_type>
0282 {
0283 typedef spirit::long_long_type type;
0284 static type call() { return type(); }
0285 };
0286 template <>
0287 struct meta_create<boost::ulong_long_type>
0288 {
0289 typedef spirit::ulong_long_type type;
0290 static type call() { return type(); }
0291 };
0292 #endif
0293
0294
0295 template <>
0296 struct meta_create<float>
0297 {
0298 typedef spirit::float_type type;
0299 static type call() { return type(); }
0300 };
0301 template <>
0302 struct meta_create<double>
0303 {
0304 typedef spirit::double_type type;
0305 static type call() { return type(); }
0306 };
0307 template <>
0308 struct meta_create<long double>
0309 {
0310 typedef spirit::long_double_type type;
0311 static type call() { return type(); }
0312 };
0313 }}}
0314
0315
0316 namespace boost { namespace spirit { namespace traits
0317 {
0318
0319
0320 template <typename T, typename Enable = void>
0321 struct create_generator : karma::meta_create<T> {};
0322
0323
0324
0325 template <typename T>
0326 struct meta_create<karma::domain, T>
0327 : create_generator<typename spirit::detail::remove_const_ref<T>::type> {};
0328
0329
0330
0331
0332 template <typename T>
0333 struct meta_create_exists<karma::domain, T>
0334 : mpl::not_<is_same<
0335 karma::no_auto_mapping_exists
0336 , typename meta_create<karma::domain, T>::type
0337 > > {};
0338 }}}
0339
0340 #endif