annotate DEPENDENCIES/generic/include/boost/spirit/home/qi/operator/permutation.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 2665513ce2d3
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2001-2011 Joel de Guzman
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_PERMUTATION_OR_MARCH_13_2007_1145PM)
Chris@16 8 #define SPIRIT_PERMUTATION_OR_MARCH_13_2007_1145PM
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/meta_compiler.hpp>
Chris@16 15 #include <boost/spirit/home/qi/detail/permute_function.hpp>
Chris@16 16 #include <boost/spirit/home/qi/detail/attributes.hpp>
Chris@16 17 #include <boost/spirit/home/support/algorithm/any_if_ns.hpp>
Chris@16 18 #include <boost/spirit/home/support/detail/what_function.hpp>
Chris@16 19 #include <boost/spirit/home/support/has_semantic_action.hpp>
Chris@16 20 #include <boost/spirit/home/support/handles_container.hpp>
Chris@16 21 #include <boost/spirit/home/support/info.hpp>
Chris@16 22 #include <boost/fusion/include/size.hpp>
Chris@16 23 #include <boost/optional.hpp>
Chris@16 24 #include <boost/foreach.hpp>
Chris@16 25 #include <boost/array.hpp>
Chris@16 26
Chris@16 27 namespace boost { namespace spirit
Chris@16 28 {
Chris@16 29 ///////////////////////////////////////////////////////////////////////////
Chris@16 30 // Enablers
Chris@16 31 ///////////////////////////////////////////////////////////////////////////
Chris@16 32 template <>
Chris@16 33 struct use_operator<qi::domain, proto::tag::bitwise_xor> // enables ^
Chris@16 34 : mpl::true_ {};
Chris@16 35
Chris@16 36 template <>
Chris@16 37 struct flatten_tree<qi::domain, proto::tag::bitwise_xor> // flattens ^
Chris@16 38 : mpl::true_ {};
Chris@16 39 }}
Chris@16 40
Chris@16 41 namespace boost { namespace spirit { namespace qi
Chris@16 42 {
Chris@16 43 template <typename Elements>
Chris@16 44 struct permutation : nary_parser<permutation<Elements> >
Chris@16 45 {
Chris@16 46 template <typename Context, typename Iterator>
Chris@16 47 struct attribute
Chris@16 48 {
Chris@16 49 // Put all the element attributes in a tuple,
Chris@16 50 // wrapping each element in a boost::optional
Chris@16 51 typedef typename traits::build_attribute_sequence<
Chris@16 52 Elements, Context, traits::permutation_attribute_transform
Chris@16 53 , Iterator, qi::domain
Chris@16 54 >::type all_attributes;
Chris@16 55
Chris@16 56 // Now, build a fusion vector over the attributes. Note
Chris@16 57 // that build_fusion_vector 1) removes all unused attributes
Chris@16 58 // and 2) may return unused_type if all elements have
Chris@16 59 // unused_type(s).
Chris@16 60 typedef typename
Chris@16 61 traits::build_fusion_vector<all_attributes>::type
Chris@16 62 type;
Chris@16 63 };
Chris@16 64
Chris@16 65 permutation(Elements const& elements_)
Chris@16 66 : elements(elements_) {}
Chris@16 67
Chris@16 68 template <typename Iterator, typename Context
Chris@16 69 , typename Skipper, typename Attribute>
Chris@16 70 bool parse(Iterator& first, Iterator const& last
Chris@16 71 , Context& context, Skipper const& skipper
Chris@16 72 , Attribute& attr_) const
Chris@16 73 {
Chris@16 74 typedef traits::attribute_not_unused<Context, Iterator> predicate;
Chris@16 75 detail::permute_function<Iterator, Context, Skipper>
Chris@16 76 f(first, last, context, skipper);
Chris@16 77
Chris@16 78 boost::array<bool, fusion::result_of::size<Elements>::value> flags;
Chris@16 79 BOOST_FOREACH(bool& taken, flags)
Chris@16 80 {
Chris@16 81 taken = false;
Chris@16 82 }
Chris@16 83
Chris@16 84 // wrap the attribute in a tuple if it is not a tuple
Chris@16 85 typename traits::wrap_if_not_tuple<Attribute>::type attr_local(attr_);
Chris@16 86
Chris@16 87 // We have a bool array 'flags' with one flag for each parser.
Chris@16 88 // permute_function sets the slot to true when the corresponding
Chris@16 89 // parser successful matches. We loop until there are no more
Chris@16 90 // successful parsers.
Chris@16 91
Chris@16 92 bool result = false;
Chris@16 93 f.taken = flags.begin();
Chris@16 94 while (spirit::any_if_ns(elements, attr_local, f, predicate()))
Chris@16 95 {
Chris@16 96 f.taken = flags.begin();
Chris@16 97 result = true;
Chris@16 98 }
Chris@16 99 return result;
Chris@16 100 }
Chris@16 101
Chris@16 102 template <typename Context>
Chris@16 103 info what(Context& context) const
Chris@16 104 {
Chris@16 105 info result("permutation");
Chris@16 106 fusion::for_each(elements,
Chris@16 107 spirit::detail::what_function<Context>(result, context));
Chris@16 108 return result;
Chris@16 109 }
Chris@16 110
Chris@16 111 Elements elements;
Chris@16 112 };
Chris@16 113
Chris@16 114 ///////////////////////////////////////////////////////////////////////////
Chris@16 115 // Parser generators: make_xxx function (objects)
Chris@16 116 ///////////////////////////////////////////////////////////////////////////
Chris@16 117 template <typename Elements, typename Modifiers>
Chris@16 118 struct make_composite<proto::tag::bitwise_xor, Elements, Modifiers>
Chris@16 119 : make_nary_composite<Elements, permutation>
Chris@16 120 {};
Chris@16 121 }}}
Chris@16 122
Chris@16 123 namespace boost { namespace spirit { namespace traits
Chris@16 124 {
Chris@16 125 ///////////////////////////////////////////////////////////////////////////
Chris@16 126 // We specialize this for permutation (see support/attributes.hpp).
Chris@16 127 // For permutation, we only wrap the attribute in a tuple IFF
Chris@16 128 // it is not already a fusion tuple.
Chris@16 129 template <typename Elements, typename Attribute>
Chris@16 130 struct pass_attribute<qi::permutation<Elements>, Attribute>
Chris@16 131 : wrap_if_not_tuple<Attribute> {};
Chris@16 132
Chris@16 133 ///////////////////////////////////////////////////////////////////////////
Chris@16 134 template <typename Elements>
Chris@16 135 struct has_semantic_action<qi::permutation<Elements> >
Chris@16 136 : nary_has_semantic_action<Elements> {};
Chris@16 137
Chris@16 138 ///////////////////////////////////////////////////////////////////////////
Chris@16 139 template <typename Elements, typename Attribute, typename Context
Chris@16 140 , typename Iterator>
Chris@16 141 struct handles_container<qi::permutation<Elements>, Attribute, Context
Chris@16 142 , Iterator>
Chris@16 143 : nary_handles_container<Elements, Attribute, Context, Iterator> {};
Chris@16 144 }}}
Chris@16 145
Chris@16 146 #endif