File indexing completed on 2025-01-19 09:47:35
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM)
0007 #define BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/spirit/home/support/unused.hpp>
0014 #include <boost/spirit/home/support/attributes_fwd.hpp>
0015 #include <boost/spirit/home/karma/detail/attributes.hpp>
0016 #include <boost/spirit/home/support/container.hpp>
0017
0018 #include <boost/ref.hpp>
0019 #include <boost/optional.hpp>
0020
0021
0022 namespace boost { namespace spirit { namespace traits
0023 {
0024
0025
0026
0027
0028
0029
0030 namespace detail
0031 {
0032
0033
0034 template <typename T>
0035 struct add_const_ref
0036 : add_reference<typename add_const<T>::type>
0037 {};
0038
0039 template <typename T, int N>
0040 struct value_at_c
0041 : add_const_ref<typename fusion::result_of::value_at_c<T, N>::type>
0042 {};
0043 }
0044
0045
0046 template <typename Attribute, typename Exposed
0047 , bool IsOneElemSeq = traits::one_element_sequence<Attribute>::value>
0048 struct extract_from_attribute_base
0049 {
0050 typedef Attribute const& type;
0051
0052 template <typename Context>
0053 static type call(Attribute const& attr, Context&)
0054 {
0055 return attr;
0056 }
0057 };
0058
0059
0060
0061
0062 template <typename Attribute, typename Exposed>
0063 struct extract_from_attribute_base<Attribute, Exposed, true>
0064 {
0065 typedef typename remove_const<
0066 typename remove_reference<
0067 typename fusion::result_of::at_c<Attribute, 0>::type
0068 >::type
0069 >::type elem_type;
0070
0071 typedef typename result_of::extract_from<Exposed, elem_type>::type type;
0072
0073 template <typename Context>
0074 static type call(Attribute const& attr, Context& ctx)
0075 {
0076 return extract_from<Exposed>(fusion::at_c<0>(attr), ctx);
0077 }
0078 };
0079
0080 template <typename Attribute, typename Exposed, typename Enable>
0081 struct extract_from_attribute
0082 : extract_from_attribute_base<Attribute, Exposed>
0083 {};
0084
0085
0086 template <typename Attribute, typename Exposed>
0087 struct extract_from_attribute<boost::optional<Attribute>, Exposed>
0088 {
0089 typedef Attribute const& type;
0090
0091 template <typename Context>
0092 static type call(boost::optional<Attribute> const& attr, Context& ctx)
0093 {
0094 return extract_from<Exposed>(boost::get<Attribute>(attr), ctx);
0095 }
0096 };
0097
0098 template <typename Attribute, typename Exposed>
0099 struct extract_from_attribute<boost::optional<Attribute const>, Exposed>
0100 {
0101 typedef Attribute const& type;
0102
0103 template <typename Context>
0104 static type call(boost::optional<Attribute const> const& attr, Context& ctx)
0105 {
0106 return extract_from<Exposed>(boost::get<Attribute const>(attr), ctx);
0107 }
0108 };
0109
0110
0111 template <typename Attribute, typename Exposed>
0112 struct extract_from_attribute<reference_wrapper<Attribute>, Exposed>
0113 {
0114 typedef Attribute const& type;
0115
0116 template <typename Context>
0117 static type call(reference_wrapper<Attribute> const& attr, Context& ctx)
0118 {
0119 return extract_from<Exposed>(attr.get(), ctx);
0120 }
0121 };
0122
0123
0124 template <typename Attribute, typename Exposed, typename Enable>
0125 struct extract_from_container
0126 {
0127 typedef typename traits::container_value<Attribute const>::type
0128 value_type;
0129 typedef typename is_convertible<value_type, Exposed>::type
0130 is_convertible_to_value_type;
0131
0132 typedef typename mpl::if_<
0133 mpl::or_<
0134 is_same<value_type, Exposed>, is_same<Attribute, Exposed> >
0135 , Exposed const&, Exposed
0136 >::type type;
0137
0138
0139
0140 template <typename Context, typename Pred>
0141 static type call(Attribute const& attr, Context&, mpl::true_, Pred)
0142 {
0143
0144 typedef typename traits::container_iterator<Attribute const>::type
0145 iterator_type;
0146
0147 iterator_type it = traits::begin(attr);
0148 type result = *it;
0149 ++it;
0150 return result;
0151 }
0152
0153
0154 template <typename Iterator>
0155 static void append_to_string(Exposed& result, Iterator begin, Iterator end)
0156 {
0157 for (Iterator i = begin; i != end; ++i)
0158 push_back(result, *i);
0159 }
0160
0161 template <typename Context>
0162 static type call(Attribute const& attr, Context&, mpl::false_, mpl::true_)
0163 {
0164 typedef typename char_type_of<Attribute>::type char_type;
0165
0166 Exposed result;
0167 append_to_string(result, traits::get_begin<char_type>(attr)
0168 , traits::get_end<char_type>(attr));
0169 return result;
0170 }
0171
0172
0173 template <typename Context>
0174 static type call(Attribute const& attr, Context&, mpl::false_, mpl::false_)
0175 {
0176 return type(attr);
0177 }
0178
0179 template <typename Context>
0180 static type call(Attribute const& attr, Context& ctx)
0181 {
0182 typedef typename mpl::and_<
0183 traits::is_string<Exposed>, traits::is_string<Attribute>
0184 >::type handle_strings;
0185
0186
0187 return call(attr, ctx, is_convertible_to_value_type()
0188 , handle_strings());
0189 }
0190 };
0191
0192 template <typename Attribute>
0193 struct extract_from_container<Attribute, Attribute>
0194 {
0195 typedef Attribute const& type;
0196
0197 template <typename Context>
0198 static type call(Attribute const& attr, Context&)
0199 {
0200 return attr;
0201 }
0202 };
0203
0204
0205 namespace detail
0206 {
0207
0208 template <typename Exposed, typename Attribute, typename Context>
0209 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
0210 extract_from(Attribute const& attr, Context& ctx, mpl::false_)
0211 {
0212 return extract_from_attribute<Attribute, Exposed>::call(attr, ctx);
0213 }
0214
0215
0216
0217 template <typename Exposed, typename Attribute, typename Context>
0218 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
0219 extract_from(Attribute const& attr, Context& ctx, mpl::true_)
0220 {
0221 return extract_from_container<Attribute, Exposed>::call(attr, ctx);
0222 }
0223 }
0224
0225 template <typename Exposed, typename Attribute, typename Context>
0226 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
0227 extract_from(Attribute const& attr, Context& ctx
0228 #if (defined(__GNUC__) && (__GNUC__ < 4)) || \
0229 (defined(__APPLE__) && defined(__INTEL_COMPILER))
0230 , typename enable_if<traits::not_is_unused<Attribute> >::type*
0231 #endif
0232 )
0233 {
0234 typedef typename mpl::and_<
0235 traits::is_container<Attribute>
0236 , traits::not_is_variant<Attribute>
0237 , traits::not_is_optional<Attribute>
0238 >::type is_not_wrapped_container;
0239
0240 return detail::extract_from<Exposed>(attr, ctx
0241 , is_not_wrapped_container());
0242 }
0243
0244 template <typename Exposed, typename Context>
0245 inline unused_type extract_from(unused_type, Context&)
0246 {
0247 return unused;
0248 }
0249 }}}
0250
0251
0252 namespace boost { namespace spirit { namespace result_of
0253 {
0254 template <typename Exposed, typename Attribute>
0255 struct extract_from
0256 : mpl::if_<
0257 mpl::and_<
0258 traits::is_container<Attribute>
0259 , traits::not_is_variant<Attribute>
0260 , traits::not_is_optional<Attribute> >
0261 , traits::extract_from_container<Attribute, Exposed>
0262 , traits::extract_from_attribute<Attribute, Exposed> >::type
0263 {};
0264
0265 template <typename Exposed>
0266 struct extract_from<Exposed, unused_type>
0267 {
0268 typedef unused_type type;
0269 };
0270
0271 template <typename Exposed>
0272 struct extract_from<Exposed, unused_type const>
0273 {
0274 typedef unused_type type;
0275 };
0276 }}}
0277
0278 #endif