/*============================================================================= Copyright (c) 2001-2014 Joel de Guzman Copyright (c) 2013-2014 Agustin Berge Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #if !defined(BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM) #define BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM #include #include #include #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace x3 { template < typename Iterator , typename Attribute = unused_type , typename Context = subcontext<>> struct any_parser : parser> { typedef Attribute attribute_type; static bool const has_attribute = !is_same::value; static bool const handles_container = traits::is_container::value; public: any_parser() : _content(nullptr) {} template >::type> any_parser(Expr const& expr) : _content(new holder(expr)) {} any_parser(any_parser const& other) : _content(other._content ? other._content->clone() : nullptr) {} any_parser(any_parser&& other) = default; any_parser& operator=(any_parser const& other) { _content.reset(other._content ? other._content->clone() : nullptr); return *this; } any_parser& operator=(any_parser&& other) = default; template bool parse(Iterator_& first, Iterator_ const& last , Context_ const& context, unused_type, Attribute& attr) const { BOOST_STATIC_ASSERT_MSG( (is_same::value) , "Incompatible iterator used" ); BOOST_ASSERT_MSG( (_content != nullptr) , "Invalid use of uninitialized any_parser" ); return _content->parse(first, last, context, attr); } template bool parse(Iterator_& first, Iterator_ const& last , Context_ const& context, unused_type, Attribute_& attr_) const { Attribute attr; if (parse(first, last, context, unused, attr)) { traits::move_to(attr, attr_); return true; } return false; } std::string get_info() const { return _content ? _content->get_info() : ""; } private: struct placeholder { virtual placeholder* clone() const = 0; virtual bool parse(Iterator& first, Iterator const& last , Context const& context, Attribute& attr) const = 0; virtual std::string get_info() const = 0; virtual ~placeholder() {} }; template struct holder : placeholder { typedef typename extension::as_parser::value_type parser_type; explicit holder(Expr const& p) : _parser(as_parser(p)) {} holder* clone() const override { return new holder(*this); } bool parse(Iterator& first, Iterator const& last , Context const& context, Attribute& attr) const override { return _parser.parse(first, last, context, unused, attr); } std::string get_info() const override { return x3::what(_parser); } parser_type _parser; }; private: std::unique_ptr _content; }; template struct get_info> { typedef std::string result_type; std::string operator()( any_parser const& p) const { return p.get_info(); } }; }}} #endif