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