diff --git a/samples/cpp_tokens/slex/cpp_slex_lexer.hpp b/samples/cpp_tokens/slex/cpp_slex_lexer.hpp index 2c6b31c..556123d 100644 --- a/samples/cpp_tokens/slex/cpp_slex_lexer.hpp +++ b/samples/cpp_tokens/slex/cpp_slex_lexer.hpp @@ -670,7 +670,7 @@ public: } break; } - + result = token_type(id, token_val, pos); #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 return guards.detect_guard(result); @@ -678,13 +678,13 @@ public: return result; #endif } - + // skip the T_CONTLINE token } while (true); } return result = token_type(); // return T_EOI } - + void set_position(PositionT const &pos) { // set position has to change the file name and line number only diff --git a/samples/cpp_tokens/slex_iterator.hpp b/samples/cpp_tokens/slex_iterator.hpp index 43962a7..65a45de 100644 --- a/samples/cpp_tokens/slex_iterator.hpp +++ b/samples/cpp_tokens/slex_iterator.hpp @@ -64,7 +64,7 @@ public: typedef lex_input_interface* shared; BOOST_WAVE_EOF_PREFIX result_type const eof; - + template static result_type& get_next(MultiPass& mp, result_type& result) { @@ -84,14 +84,14 @@ public: { mp.shared->ftor->set_position(pos); } - + #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 template static bool has_include_guards(MultiPass& mp, std::string& guard_name) { return mp.shared->ftor->has_include_guards(guard_name); } -#endif +#endif private: boost::shared_ptr > functor_ptr; @@ -149,7 +149,7 @@ struct make_multi_pass typedef boost::spirit::multi_pass_policies::no_check check_policy; #endif typedef boost::spirit::multi_pass_policies::split_std_deque storage_policy; - + typedef boost::spirit::multi_pass_policies::default_policy< ownership_policy, check_policy, input_policy, storage_policy> policy_type; @@ -169,13 +169,13 @@ class slex_iterator typedef typename input_policy_type::unique unique_functor_type; typedef typename input_policy_type::shared shared_functor_type; - + public: typedef TokenT token_type; - + slex_iterator() {} - + template slex_iterator(IteratorT const &first, IteratorT const &last, typename TokenT::position_type const &pos, @@ -192,22 +192,22 @@ public: void set_position(typename TokenT::position_type const &pos) { typedef typename token_type::position_type position_type; - + // set the new position in the current token - token_type const& currtoken = base_type::get_input(); + token_type& currtoken = this->base_type::dereference(*this); position_type currpos = currtoken.get_position(); - + currpos.set_file(pos.get_file()); currpos.set_line(pos.get_line()); - base_type::get_input().set_position(currpos); - + currtoken.set_position(currpos); + // set the new position for future tokens as well if (token_type::string_type::npos != currtoken.get_value().find_first_of('\n')) { currpos.set_line(pos.get_line() + 1); } - unique_functor_type::get_functor().set_position(currpos); + unique_functor_type::set_position(*this, currpos); } #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 @@ -216,9 +216,9 @@ public: // completely bool has_include_guards(std::string& guard_name) const { - return unique_functor_type::has_include_guards(guard_name); + return unique_functor_type::has_include_guards(*this, guard_name); } -#endif +#endif }; /////////////////////////////////////////////////////////////////////////////// diff --git a/samples/list_includes/lexertl/lexertl_lexer.hpp b/samples/list_includes/lexertl/lexertl_lexer.hpp index 0685124..c00e47c 100644 --- a/samples/list_includes/lexertl/lexertl_lexer.hpp +++ b/samples/list_includes/lexertl/lexertl_lexer.hpp @@ -602,9 +602,8 @@ public: ~lexertl_functor() {} // get the next token from the input stream - token_type get() + token_type& get(token_type& result) { - token_type token; if (lexer_.is_initialized() && !at_eof) { do { // generate and return the next token @@ -710,18 +709,19 @@ public: } break; } - + + result = token_type(id, token_val, pos); #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 - return guards.detect_guard(token_type(id, token_val, pos)); + return guards.detect_guard(result); #else - return token_type(id, token_val, pos); + return result; #endif } } while (true); // skip the T_CONTLINE token } - return token; // return T_EOI + return result = token_type(); // return T_EOI } - + void set_position(Position const &pos) { // set position has to change the file name and line number only diff --git a/samples/list_includes/lexertl_iterator.hpp b/samples/list_includes/lexertl_iterator.hpp index 0ae07cf..ba9c8c2 100644 --- a/samples/list_includes/lexertl_iterator.hpp +++ b/samples/list_includes/lexertl_iterator.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -47,14 +47,11 @@ namespace impl { template class iterator_functor_shim { + typedef typename TokenT::position_type position_type; + public: - template - iterator_functor_shim(IteratorT const &first, IteratorT const &last, - typename TokenT::position_type const &pos, - wave::language_support language) - : functor_ptr(lexertl_input_interface - ::new_lexer(first, last, pos, language)) -#if 0 != __DECCXX_VER || defined(__PGI) + iterator_functor_shim() +#if /*0 != __DECCXX_VER || */defined(__PGI) , eof() #endif // 0 != __DECCXX_VER {} @@ -62,27 +59,38 @@ public: // interface to the boost::spirit::classic::multi_pass_policies::functor_input // policy typedef TokenT result_type; + typedef iterator_functor_shim unique; + typedef lex_input_interface* shared; BOOST_WAVE_EOF_PREFIX result_type const eof; - - result_type operator()() + + template + static result_type& get_next(MultiPass& mp, result_type& result) { - BOOST_ASSERT(0 != functor_ptr.get()); - return functor_ptr->get(); + return mp.shared->ftor->get(result); } - void set_position(typename TokenT::position_type const &pos) + + // this will be called whenever the last reference to a multi_pass will + // be released + template + static void destroy(MultiPass& mp) + { + delete mp.shared->ftor; + } + + template + static void set_position(MultiPass& mp, position_type const &pos) { - BOOST_ASSERT(0 != functor_ptr.get()); - functor_ptr->set_position(pos); + mp.shared->ftor->set_position(pos); } - + #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 - bool has_include_guards(std::string& guard_name) const + template + static bool has_include_guards(MultiPass& mp, std::string& guard_name) { - BOOST_ASSERT(0 != functor_ptr.get()); - return functor_ptr->has_include_guards(guard_name); + return mp.shared->ftor->has_include_guards(guard_name); } -#endif +#endif private: boost::shared_ptr > functor_ptr; @@ -121,31 +129,62 @@ typename iterator_functor_shim::result_type const // /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Divide the given functor type into its components (unique and shared) +// and build a std::pair from these parts +template +struct make_multi_pass +{ + typedef + std::pair + functor_data_type; + typedef typename FunctorData::result_type result_type; + + typedef boost::spirit::multi_pass_policies::split_functor_input input_policy; + typedef boost::spirit::multi_pass_policies::ref_counted ownership_policy; +#if defined(BOOST_WAVE_DEBUG) + typedef boost::spirit::multi_pass_policies::buf_id_check check_policy; +#else + typedef boost::spirit::multi_pass_policies::no_check check_policy; +#endif + typedef boost::spirit::multi_pass_policies::split_std_deque storage_policy; + + typedef boost::spirit::multi_pass_policies::default_policy< + ownership_policy, check_policy, input_policy, storage_policy> + policy_type; + typedef boost::spirit::multi_pass type; +}; + template class lex_iterator -: public boost::spirit::classic::multi_pass< - impl::iterator_functor_shim, - boost::wave::util::functor_input - > +: public make_multi_pass >::type { typedef impl::iterator_functor_shim input_policy_type; - typedef - boost::spirit::classic::multi_pass - base_type; - typedef lex_iterator self_type; - + + typedef typename make_multi_pass::type base_type; + typedef typename make_multi_pass::functor_data_type + functor_data_type; + + typedef typename input_policy_type::unique unique_functor_type; + typedef typename input_policy_type::shared shared_functor_type; + public: typedef TokenT token_type; - + lex_iterator() {} - + template lex_iterator(IteratorT const &first, IteratorT const &last, typename TokenT::position_type const &pos, boost::wave::language_support language) - : base_type(input_policy_type(first, last, pos, language)) + : base_type( + functor_data_type( + unique_functor_type(), + lexertl_input_interface + ::new_lexer(first, last, pos, language) + ) + ) {} void set_position(typename TokenT::position_type const &pos) @@ -153,7 +192,7 @@ public: typedef typename TokenT::position_type position_type; // set the new position in the current token - token_type& currtoken = base_type::get_input(); + token_type& currtoken = this->base_type::dereference(*this); position_type currpos = currtoken.get_position(); currpos.set_file(pos.get_file()); @@ -166,18 +205,18 @@ public: { currpos.set_line(pos.get_line() + 1); } - base_type::get_functor().set_position(currpos); + unique_functor_type::set_position(*this, currpos); } - + #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 // Return, whether the current file has include guards. This function // returns meaningful results only if the file was scanned completely. // For now we always return false, but this can be fixed easily later on. bool has_include_guards(std::string& guard_name) const { - return base_type::get_functor().has_include_guards(guard_name); + return base_type::get_functor().has_include_guards(*this, guard_name); } -#endif +#endif }; /////////////////////////////////////////////////////////////////////////////// diff --git a/samples/preprocess_pragma_output/example.cpp b/samples/preprocess_pragma_output/example.cpp index a646c8e..fdd5f49 100644 --- a/samples/preprocess_pragma_output/example.cpp +++ b/samples/preprocess_pragma_output/example.cpp @@ -15,7 +15,7 @@ // provided in the preprocess_pragma_output_hooks policy class. This // #pragma preprocesses the provided arguments in the current context. #pragma wave pp ( \ - "#define A() \"some text\" and more\n" \ + "#define A() \"some text\" and more\n" \ "#define B() 1.0\n" \ ) \ /**/ diff --git a/samples/quick_start/quick_start.cpp b/samples/quick_start/quick_start.cpp index f2dbea6..f8d2d5e 100644 --- a/samples/quick_start/quick_start.cpp +++ b/samples/quick_start/quick_start.cpp @@ -65,13 +65,13 @@ boost::wave::util::file_position_type current_position; typedef boost::wave::context context_type; - // The preprocessor iterator shouldn't be constructed directly. It is - // to be generated through a wave::context<> object. This wave:context<> - // object is to be used additionally to initialize and define different - // parameters of the actual preprocessing (not done here). + // The preprocessor iterator shouldn't be constructed directly. It is + // to be generated through a wave::context<> object. This wave:context<> + // object is to be used additionally to initialize and define different + // parameters of the actual preprocessing (not done here). // - // The preprocessing of the input stream is done on the fly behind the - // scenes during iteration over the context_type::iterator_type stream. + // The preprocessing of the input stream is done on the fly behind the + // scenes during iteration over the context_type::iterator_type stream. context_type ctx (instring.begin(), instring.end(), argv[1]); // Get the preprocessor iterators and use them to generate