/Src/Dependencies/Boost/boost/spirit/home/qi/operator/permutation.hpp

http://hadesmem.googlecode.com/ · C++ Header · 146 lines · 98 code · 19 blank · 29 comment · 1 complexity · c5b125cf6c2da4114748816af164b2b9 MD5 · raw file

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