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