annotate DEPENDENCIES/generic/include/boost/spirit/home/qi/detail/alternative_function.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 3
Chris@16 4 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 =============================================================================*/
Chris@16 7 #if !defined(SPIRIT_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM)
Chris@16 8 #define SPIRIT_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM
Chris@16 9
Chris@16 10 #if defined(_MSC_VER)
Chris@16 11 #pragma once
Chris@16 12 #endif
Chris@16 13
Chris@16 14 #include <boost/spirit/home/qi/domain.hpp>
Chris@16 15 #include <boost/spirit/home/qi/detail/assign_to.hpp>
Chris@16 16 #include <boost/spirit/home/support/unused.hpp>
Chris@16 17 #include <boost/spirit/home/qi/detail/attributes.hpp>
Chris@16 18 #include <boost/variant.hpp>
Chris@16 19 #include <boost/mpl/bool.hpp>
Chris@16 20
Chris@16 21 namespace boost { namespace spirit { namespace qi { namespace detail
Chris@16 22 {
Chris@16 23 template <typename Variant, typename Expected>
Chris@16 24 struct find_substitute
Chris@16 25 {
Chris@16 26 // Get the typr from the variant that can be a substitute for Expected.
Chris@16 27 // If none is found, just return Expected
Chris@16 28
Chris@16 29 typedef Variant variant_type;
Chris@16 30 typedef typename variant_type::types types;
Chris@16 31 typedef typename mpl::end<types>::type end;
Chris@16 32
Chris@16 33 typedef typename
Chris@16 34 mpl::find_if<types, is_same<mpl::_1, Expected> >::type
Chris@16 35 iter_1;
Chris@16 36
Chris@16 37 typedef typename
Chris@16 38 mpl::eval_if<
Chris@16 39 is_same<iter_1, end>,
Chris@16 40 mpl::find_if<types, traits::is_substitute<mpl::_1, Expected> >,
Chris@16 41 mpl::identity<iter_1>
Chris@16 42 >::type
Chris@16 43 iter;
Chris@16 44
Chris@16 45 typedef typename
Chris@16 46 mpl::eval_if<
Chris@16 47 is_same<iter, end>,
Chris@16 48 mpl::identity<Expected>,
Chris@16 49 mpl::deref<iter>
Chris@16 50 >::type
Chris@16 51 type;
Chris@16 52 };
Chris@16 53
Chris@16 54 template <typename Iterator, typename Context, typename Skipper,
Chris@16 55 typename Attribute>
Chris@16 56 struct alternative_function
Chris@16 57 {
Chris@16 58 alternative_function(
Chris@16 59 Iterator& first_, Iterator const& last_, Context& context_,
Chris@16 60 Skipper const& skipper_, Attribute& attr_)
Chris@16 61 : first(first_), last(last_), context(context_), skipper(skipper_),
Chris@16 62 attr(attr_)
Chris@16 63 {
Chris@16 64 }
Chris@16 65
Chris@16 66 template <typename Component>
Chris@16 67 bool call(Component const& component, mpl::true_) const
Chris@16 68 {
Chris@16 69 // if Attribute is not a variant, then pass it as-is
Chris@16 70 return component.parse(first, last, context, skipper, attr);
Chris@16 71 }
Chris@16 72
Chris@16 73 template <typename Component>
Chris@16 74 bool call_optional_or_variant(Component const& component, mpl::true_) const
Chris@16 75 {
Chris@16 76 // If Attribute is an optional, then create an attribute for the Component
Chris@16 77 // with the type optional::value_type. If the expected attribute is unused type,
Chris@16 78 // use it instead.
Chris@16 79 typedef typename
Chris@16 80 traits::attribute_of<Component, Context, Iterator>::type
Chris@16 81 expected_type;
Chris@16 82
Chris@16 83 typename mpl::if_<
Chris@16 84 is_same<expected_type, unused_type>,
Chris@16 85 unused_type,
Chris@16 86 typename Attribute::value_type>::type
Chris@16 87 val;
Chris@16 88
Chris@16 89 if (component.parse(first, last, context, skipper, val))
Chris@16 90 {
Chris@16 91 traits::assign_to(val, attr);
Chris@16 92 return true;
Chris@16 93 }
Chris@16 94 return false;
Chris@16 95 }
Chris@16 96
Chris@16 97 template <typename Component>
Chris@16 98 bool call_variant(Component const& component, mpl::false_) const
Chris@16 99 {
Chris@16 100 // If Attribute is a variant, then search the variant types for a
Chris@16 101 // suitable substitute type.
Chris@16 102
Chris@16 103 typename
Chris@16 104 find_substitute<Attribute,
Chris@16 105 typename traits::attribute_of<Component, Context, Iterator>::type
Chris@16 106 >::type
Chris@16 107 val;
Chris@16 108
Chris@16 109 if (component.parse(first, last, context, skipper, val))
Chris@16 110 {
Chris@16 111 traits::assign_to(val, attr);
Chris@16 112 return true;
Chris@16 113 }
Chris@16 114 return false;
Chris@16 115 }
Chris@16 116
Chris@16 117 template <typename Component>
Chris@16 118 bool call_variant(Component const& component, mpl::true_) const
Chris@16 119 {
Chris@16 120 // If Attribute is a variant and the expected attribute is
Chris@16 121 // the same type (pass the variant as-is).
Chris@16 122
Chris@16 123 return component.parse(first, last, context, skipper, attr);
Chris@16 124 }
Chris@16 125
Chris@16 126 template <typename Component>
Chris@16 127 bool call_optional_or_variant(Component const& component, mpl::false_) const
Chris@16 128 {
Chris@16 129 // Attribute is a variant...
Chris@16 130
Chris@16 131 typedef typename
Chris@16 132 traits::attribute_of<Component, Context, Iterator>::type
Chris@16 133 expected;
Chris@16 134 return call_variant(component,
Chris@16 135 is_same<Attribute, expected>());
Chris@16 136 }
Chris@16 137
Chris@16 138 template <typename Component>
Chris@16 139 bool call(Component const& component, mpl::false_) const
Chris@16 140 {
Chris@16 141 return call_optional_or_variant(
Chris@16 142 component, spirit::traits::not_is_variant<Attribute, qi::domain>());
Chris@16 143 }
Chris@16 144
Chris@16 145 template <typename Component>
Chris@16 146 bool call_unused(Component const& component, mpl::true_) const
Chris@16 147 {
Chris@16 148 // return true if the parser succeeds
Chris@16 149 return call(component,
Chris@16 150 mpl::and_<
Chris@16 151 spirit::traits::not_is_variant<Attribute, qi::domain>,
Chris@16 152 spirit::traits::not_is_optional<Attribute, qi::domain>
Chris@16 153 >());
Chris@16 154 }
Chris@16 155
Chris@16 156 template <typename Component>
Chris@16 157 bool call_unused(Component const& component, mpl::false_) const
Chris@16 158 {
Chris@16 159 return component.parse(first, last, context, skipper, unused);
Chris@16 160 }
Chris@16 161
Chris@16 162 template <typename Component>
Chris@16 163 bool operator()(Component const& component) const
Chris@16 164 {
Chris@16 165 // return true if the parser succeeds
Chris@16 166 typedef typename traits::not_is_unused<
Chris@16 167 typename traits::attribute_of<Component, Context, Iterator>::type
Chris@16 168 >::type predicate;
Chris@16 169
Chris@16 170 return call_unused(component, predicate());
Chris@16 171 }
Chris@16 172
Chris@16 173 Iterator& first;
Chris@16 174 Iterator const& last;
Chris@16 175 Context& context;
Chris@16 176 Skipper const& skipper;
Chris@16 177 Attribute& attr;
Chris@16 178
Chris@16 179 private:
Chris@16 180 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 181 alternative_function& operator= (alternative_function const&);
Chris@16 182 };
Chris@16 183
Chris@16 184 template <typename Iterator, typename Context, typename Skipper>
Chris@16 185 struct alternative_function<Iterator, Context, Skipper, unused_type const>
Chris@16 186 {
Chris@16 187 alternative_function(
Chris@16 188 Iterator& first_, Iterator const& last_, Context& context_,
Chris@16 189 Skipper const& skipper_, unused_type)
Chris@16 190 : first(first_), last(last_), context(context_), skipper(skipper_)
Chris@16 191 {
Chris@16 192 }
Chris@16 193
Chris@16 194 template <typename Component>
Chris@101 195 bool operator()(Component const& component) const
Chris@16 196 {
Chris@16 197 // return true if the parser succeeds
Chris@16 198 return component.parse(first, last, context, skipper,
Chris@16 199 unused);
Chris@16 200 }
Chris@16 201
Chris@16 202 Iterator& first;
Chris@16 203 Iterator const& last;
Chris@16 204 Context& context;
Chris@16 205 Skipper const& skipper;
Chris@16 206
Chris@16 207 private:
Chris@16 208 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 209 alternative_function& operator= (alternative_function const&);
Chris@16 210 };
Chris@16 211
Chris@16 212 }}}}
Chris@16 213
Chris@16 214 #endif