![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /usr/include/boost/spirit/home/x3/support/ast/ |
Upload File : |
/*============================================================================= Copyright (c) 2014 Joel de Guzman 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_POSITION_TAGGED_MAY_01_2014_0321PM) #define BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM #include <boost/range.hpp> #include <boost/type_traits/is_base_of.hpp> #include <boost/core/enable_if.hpp> namespace boost { namespace spirit { namespace x3 { struct position_tagged { // Use this to annotate an AST with the iterator position. // These ids are used as a key to the position_cache (below) // and marks the start and end of an AST node. int id_first = -1; int id_last = -1; }; template <typename Container> class position_cache { public: typedef typename Container::value_type iterator_type; position_cache( iterator_type first , iterator_type last) : first_(first), last_(last) {} // This will catch all nodes inheriting from position_tagged boost::iterator_range<iterator_type> position_of(position_tagged const& ast) const { return boost::iterator_range<iterator_type>( positions.at(ast.id_first) // throws if out of range , positions.at(ast.id_last) // throws if out of range ); } // This will catch all nodes except those inheriting from position_tagged template <typename AST> typename boost::enable_if_c< (!is_base_of<position_tagged, AST>::value) , boost::iterator_range<iterator_type> >::type position_of(AST const& /* ast */) const { // returns an empty position return boost::iterator_range<iterator_type>(); } // This will catch all nodes except those inheriting from position_tagged template <typename AST> void annotate(AST& /* ast */, iterator_type /* first */, iterator_type /* last */, mpl::false_) { // (no-op) no need for tags } // This will catch all nodes inheriting from position_tagged void annotate(position_tagged& ast, iterator_type first, iterator_type last, mpl::true_) { ast.id_first = int(positions.size()); positions.push_back(first); ast.id_last = int(positions.size()); positions.push_back(last); } template <typename AST> void annotate(AST& ast, iterator_type first, iterator_type last) { annotate(ast, first, last, is_base_of<position_tagged, AST>()); } Container const& get_positions() const { return positions; } iterator_type first() const { return first_; } iterator_type last() const { return last_; } private: Container positions; iterator_type first_; iterator_type last_; }; }}} #endif