File indexing completed on 2025-01-19 09:47:43
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_SPIRIT_QI_DETAIL_ALTERNATIVE_FUNCTION_HPP
0008 #define BOOST_SPIRIT_QI_DETAIL_ALTERNATIVE_FUNCTION_HPP
0009
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013
0014 #include <boost/spirit/home/qi/domain.hpp>
0015 #include <boost/spirit/home/qi/detail/assign_to.hpp>
0016 #include <boost/spirit/home/support/unused.hpp>
0017 #include <boost/spirit/home/qi/detail/attributes.hpp>
0018 #include <boost/variant.hpp>
0019 #include <boost/mpl/bool.hpp>
0020
0021 namespace boost { namespace spirit { namespace qi { namespace detail
0022 {
0023 template <typename Variant, typename T>
0024 struct find_substitute
0025 {
0026
0027
0028
0029 typedef Variant variant_type;
0030 typedef typename variant_type::types types;
0031 typedef typename mpl::end<types>::type end;
0032
0033 typedef typename mpl::find<types, T>::type iter_1;
0034
0035 typedef typename
0036 mpl::eval_if<
0037 is_same<iter_1, end>,
0038 mpl::find_if<types, traits::is_substitute<T, mpl::_1> >,
0039 mpl::identity<iter_1>
0040 >::type
0041 iter;
0042
0043 typedef typename
0044 mpl::eval_if<
0045 is_same<iter, end>,
0046 mpl::identity<T>,
0047 mpl::deref<iter>
0048 >::type
0049 type;
0050 };
0051
0052 #ifdef _MSC_VER
0053 # pragma warning(push)
0054 # pragma warning(disable: 4512)
0055 #endif
0056 template <typename Iterator, typename Context, typename Skipper,
0057 typename Attribute>
0058 struct alternative_function
0059 {
0060 alternative_function(
0061 Iterator& first_, Iterator const& last_, Context& context_,
0062 Skipper const& skipper_, Attribute& attr_)
0063 : first(first_), last(last_), context(context_), skipper(skipper_),
0064 attr(attr_)
0065 {
0066 }
0067
0068 template <typename Component>
0069 bool call(Component const& component, mpl::true_) const
0070 {
0071
0072 return component.parse(first, last, context, skipper, attr);
0073 }
0074
0075 template <typename Component>
0076 bool call_optional_or_variant(Component const& component, mpl::true_) const
0077 {
0078
0079
0080
0081 typedef typename
0082 traits::attribute_of<Component, Context, Iterator>::type
0083 expected_type;
0084
0085 typename mpl::if_<
0086 is_same<expected_type, unused_type>,
0087 unused_type,
0088 typename Attribute::value_type>::type
0089 val;
0090
0091 if (component.parse(first, last, context, skipper, val))
0092 {
0093 traits::assign_to(val, attr);
0094 return true;
0095 }
0096 return false;
0097 }
0098
0099 template <typename Component>
0100 bool call_variant(Component const& component, mpl::false_) const
0101 {
0102
0103
0104
0105 typename
0106 find_substitute<Attribute,
0107 typename traits::attribute_of<Component, Context, Iterator>::type
0108 >::type
0109 val;
0110
0111 if (component.parse(first, last, context, skipper, val))
0112 {
0113 traits::assign_to(val, attr);
0114 return true;
0115 }
0116 return false;
0117 }
0118
0119 template <typename Component>
0120 bool call_variant(Component const& component, mpl::true_) const
0121 {
0122
0123
0124
0125 return component.parse(first, last, context, skipper, attr);
0126 }
0127
0128 template <typename Component>
0129 bool call_optional_or_variant(Component const& component, mpl::false_) const
0130 {
0131
0132
0133 typedef typename
0134 traits::attribute_of<Component, Context, Iterator>::type
0135 expected;
0136 return call_variant(component,
0137 is_same<Attribute, expected>());
0138 }
0139
0140 template <typename Component>
0141 bool call(Component const& component, mpl::false_) const
0142 {
0143 return call_optional_or_variant(
0144 component, spirit::traits::not_is_variant<Attribute, qi::domain>());
0145 }
0146
0147 template <typename Component>
0148 bool call_unused(Component const& component, mpl::true_) const
0149 {
0150
0151 return call(component,
0152 mpl::and_<
0153 spirit::traits::not_is_variant<Attribute, qi::domain>,
0154 spirit::traits::not_is_optional<Attribute, qi::domain>
0155 >());
0156 }
0157
0158 template <typename Component>
0159 bool call_unused(Component const& component, mpl::false_) const
0160 {
0161 return component.parse(first, last, context, skipper, unused);
0162 }
0163
0164 template <typename Component>
0165 bool operator()(Component const& component) const
0166 {
0167
0168 typedef typename traits::not_is_unused<
0169 typename traits::attribute_of<Component, Context, Iterator>::type
0170 >::type predicate;
0171
0172 return call_unused(component, predicate());
0173 }
0174
0175 Iterator& first;
0176 Iterator const& last;
0177 Context& context;
0178 Skipper const& skipper;
0179 Attribute& attr;
0180 };
0181
0182 template <typename Iterator, typename Context, typename Skipper>
0183 struct alternative_function<Iterator, Context, Skipper, unused_type const>
0184 {
0185 alternative_function(
0186 Iterator& first_, Iterator const& last_, Context& context_,
0187 Skipper const& skipper_, unused_type)
0188 : first(first_), last(last_), context(context_), skipper(skipper_)
0189 {
0190 }
0191
0192 template <typename Component>
0193 bool operator()(Component const& component) const
0194 {
0195
0196 return component.parse(first, last, context, skipper,
0197 unused);
0198 }
0199
0200 Iterator& first;
0201 Iterator const& last;
0202 Context& context;
0203 Skipper const& skipper;
0204 };
0205 #ifdef _MSC_VER
0206 # pragma warning(pop)
0207 #endif
0208
0209 }}}}
0210
0211 #endif