functor_facilities.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 204 行
CPP
204 行
// Copyright (c) 2001-2008 Hartmut Kaiser// // 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)// This examples demonstrate how to write functor based generators for special// purposes. #include <boost/config/warning_disable.hpp>#include <boost/spirit/include/karma.hpp>#include <boost/spirit/include/karma_stream.hpp>#include <boost/spirit/include/phoenix_core.hpp>#include <boost/spirit/include/phoenix_bind.hpp>#include <iostream>#include <string>#include <vector>#include <list>#include <algorithm>#include <cstdlib> using namespace boost::spirit;///////////////////////////////////////////////////////////////////////////////// The functor generator 'counter' can be used for output annotation with some// item counting information.///////////////////////////////////////////////////////////////////////////////struct counter_impl : boost::spirit::karma::functor_base{ template <typename OutputIterator, typename Context, typename Parameter> bool operator()(Parameter const&, Context& ctx, OutputIterator& sink) const { namespace karma = boost::spirit::karma; return karma::generate(sink, int_ << ": ", counter++); } counter_impl(int& counter_) : counter(counter_) {} int& counter;};inline boost::spirit::result_of::as_generator<counter_impl>::typecounter(int& counter_){ using namespace boost::spirit::karma; return as_generator(counter_impl(counter_));}///////////////////////////////////////////////////////////////////////////////// The functor generator 'confix' allows a simple syntax for generating // output wrapped inside a pair of a prefix and a suffix.///////////////////////////////////////////////////////////////////////////////template <typename Expr>struct confix_impl : public boost::spirit::karma::functor_base{ template <typename Context> struct apply { typedef boost::spirit::hold_any type; }; template <typename OutputIterator, typename Context, typename Parameter> bool operator()(Parameter const& v, Context& ctx, OutputIterator& sink) const { namespace karma = boost::spirit::karma; return karma::generate(sink, open << xpr << close, v); } confix_impl(char const* open_, char const* close_, Expr const& xpr_) : open(open_), close(close_), xpr(xpr_) {} std::string open; std::string close; Expr xpr;};template <typename Expr>inline typename boost::spirit::result_of::as_generator<confix_impl<Expr> >::typeconfix(Expr const& xpr_, char const* open_ = "", char const* close_ = ""){ using namespace boost::spirit::karma; return as_generator(confix_impl<Expr>(open_, close_, xpr_));}///////////////////////////////////////////////////////////////////////////////// The functor generator 'list' allows a simple syntax for generating // list formatted output.//// This example uses phoenix::bind to allow to omit the second argument from // the operator() and to allow to switch the remaining two arguments.///////////////////////////////////////////////////////////////////////////////template <typename Expr>struct list_impl : boost::spirit::karma::functor_base{ // this function will be called to generate the output template <typename OutputIterator, typename Parameter> bool operator()(OutputIterator& sink, Parameter const& v) const { namespace karma = boost::spirit::karma; return karma::generate(sink, xpr % delim, v); } list_impl(Expr const& xpr_, char const* delim_) : xpr(xpr_), delim(delim_) {} Expr xpr; std::string delim;};// Supply the expected parameter type explicitlystruct list_impl_mf{ // the expected parameter type of a functor has to be defined using a // embedded apply metafunction template <typename Context> struct apply { typedef boost::spirit::hold_any type; };};template <typename Expr>inline list_impl<Expr>list(Expr const& xpr, char const* delim){ return list_impl<Expr>(xpr, delim);}///////////////////////////////////////////////////////////////////////////////int main(){ namespace karma = boost::spirit::karma; using namespace boost::phoenix; using namespace boost::phoenix::arg_names; /////////////////////////////////////////////////////////////////////////// // Output the given containers in list format // We use a special functor generator here to annotate the output with // a integer counting the entries. /////////////////////////////////////////////////////////////////////////// std::vector<int> v (8); std::generate(v.begin(), v.end(), std::rand); // randomly fill the vector int counter1 = 1; std::cout << karma::format( (counter(counter1) << int_) % ", ", // format description v // data ) << std::endl; // Here we initialize the counter to 100 int counter2 = 100; std::cout << karma::format( '[' << ( (counter(counter2) << int_) % ", " ) << ']', // format description v // data ) << std::endl; /////////////////////////////////////////////////////////////////////////// // list // The output format description used below adds special item formatting /////////////////////////////////////////////////////////////////////////// std::list<std::string> names; names.push_back("Spirit"); names.push_back("Qi"); names.push_back("Karma"); // specifying a prefix item suffix scheme directly std::cout << karma::format( ('{' << stream << '}') % ", ", // format description names // data ) << std::endl; // The confix generator nicely wraps the given expression with prefix and // suffix strings std::cout << karma::format( confix(stream % ", ", "[", "]"), // format description names // data ) << std::endl; /////////////////////////////////////////////////////////////////////////// // Output the given container as a list // We use a separate metafunction list_impl_mf to specify the expected // parameter type of this functor generator. // We use phoenix::bind to allow to omit the 2nd argument from the functor // function operator and to change the sequence of the remaining two // arguments. /////////////////////////////////////////////////////////////////////////// std::string str("Hello world!"); std::cout << karma::format( karma::as_generator_mf<list_impl_mf>(bind(list(stream, ", "), _3, _1)), str ) << std::endl; return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?