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