1 /*=============================================================================
2     Copyright (c) 2001-2014 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 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM)
8 #define BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM
9 
10 #include <boost/spirit/home/x3/support/unused.hpp>
11 #include <boost/spirit/home/x3/support/context.hpp>
12 #include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
13 #include <boost/mpl/bool.hpp>
14 #include <boost/mpl/not.hpp>
15 #include <boost/type_traits/remove_cv.hpp>
16 #include <boost/type_traits/remove_reference.hpp>
17 #include <boost/utility/declval.hpp>
18 
19 namespace boost { namespace spirit { namespace x3
20 {
21     ///////////////////////////////////////////////////////////////////////////
22     // Move the /first/ iterator to the first non-matching position
23     // given a skip-parser. The function is a no-op if unused_type or
24     // unused_skipper is passed as the skip-parser.
25     ///////////////////////////////////////////////////////////////////////////
26     template <typename Skipper>
27     struct unused_skipper : unused_type
28     {
unused_skipperboost::spirit::x3::unused_skipper29         unused_skipper(Skipper const& skipper)
30           : skipper(skipper) {}
31         Skipper const& skipper;
32     };
33 
34     namespace detail
35     {
36         template <typename Skipper>
37         struct is_unused_skipper
38           : mpl::false_ {};
39 
40         template <typename Skipper>
41         struct is_unused_skipper<unused_skipper<Skipper>>
42           : mpl::true_ {};
43 
44         template <>
45         struct is_unused_skipper<unused_type>
46           : mpl::true_ {};
47 
48         template <typename Skipper>
49         inline Skipper const&
get_unused_skipper(Skipper const & skipper)50         get_unused_skipper(Skipper const& skipper)
51         {
52             return skipper;
53         }
54         template <typename Skipper>
55         inline Skipper const&
get_unused_skipper(unused_skipper<Skipper> const & unused_skipper)56         get_unused_skipper(unused_skipper<Skipper> const& unused_skipper)
57         {
58             return unused_skipper.skipper;
59         }
60 
61         template <typename Iterator, typename Skipper>
skip_over(Iterator & first,Iterator const & last,Skipper const & skipper)62         inline void skip_over(
63             Iterator& first, Iterator const& last, Skipper const& skipper)
64         {
65             while (first != last && skipper.parse(first, last, unused, unused, unused))
66                 /***/;
67         }
68 
69         template <typename Iterator>
skip_over(Iterator &,Iterator const &,unused_type)70         inline void skip_over(Iterator&, Iterator const&, unused_type)
71         {
72         }
73 
74         template <typename Iterator, typename Skipper>
skip_over(Iterator &,Iterator const &,unused_skipper<Skipper> const &)75         inline void skip_over(
76             Iterator&, Iterator const&, unused_skipper<Skipper> const&)
77         {
78         }
79     }
80 
81     // this tag is used to find the skipper from the context
82     struct skipper_tag;
83 
84     template <typename Context>
85     struct has_skipper
86       : mpl::not_<detail::is_unused_skipper<
87             typename remove_cv<typename remove_reference<
88                 decltype(x3::get<skipper_tag>(boost::declval<Context>()))
89             >::type>::type
90         >> {};
91 
92     template <typename Iterator, typename Context>
skip_over(Iterator & first,Iterator const & last,Context const & context)93     inline void skip_over(
94         Iterator& first, Iterator const& last, Context const& context)
95     {
96         detail::skip_over(first, last, x3::get<skipper_tag>(context));
97     }
98 }}}
99 
100 #endif
101