Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Compile with: g++ -std=gnu++0x -I. -o terminal_test ./terminal_test.cpp
- #include <string>
- #include <iostream>
- #include <boost/phoenix.hpp>
- #include <boost/function.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/utility/result_of.hpp>
- #include <boost/type_traits/remove_cv.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- using namespace boost;
- namespace boost {
- namespace phoenix {
- namespace result_of {
- template< typename T >
- struct is_nullary< T, typename T::_is_my_terminal > :
- public mpl::false_
- {
- };
- } // namespace result_of
- template< typename T >
- struct is_custom_terminal< T, typename T::_is_my_terminal > :
- public mpl::true_
- {
- };
- template< typename T >
- struct custom_terminal< T, typename T::_is_my_terminal >
- {
- typedef custom_terminal< T, typename T::_is_my_terminal > this_type;
- template< typename >
- struct result;
- template< typename ThisT, typename TermT, typename ContextT >
- struct result< ThisT(TermT, ContextT) >
- {
- typedef typename remove_cv< typename remove_reference< TermT >::type >::type term;
- typedef typename boost::result_of< const term(ContextT) >::type type;
- };
- template< typename ContextT >
- typename result< const this_type(T, ContextT) >::type operator() (T const& term, ContextT& ctx) const
- {
- return term(ctx);
- }
- };
- } // namespace phoenix
- } // namespace boost
- namespace my {
- struct argument
- {
- std::string m_value;
- explicit argument(std::string const& value) : m_value(value)
- {
- }
- };
- template< typename LeftT >
- class output_terminal
- {
- public:
- typedef void _is_my_terminal;
- //! Self type
- typedef output_terminal this_type;
- //! Result type definition
- template< typename >
- struct result;
- template< typename ContextT >
- struct result< this_type(ContextT) >
- {
- typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
- typedef typename phoenix::evaluator::impl<
- typename LeftT::proto_base_expr&,
- context_type,
- phoenix::unused
- >::result_type type;
- };
- template< typename ContextT >
- struct result< const this_type(ContextT) >
- {
- typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
- typedef typename phoenix::evaluator::impl<
- typename LeftT::proto_base_expr const&,
- context_type,
- phoenix::unused
- >::result_type type;
- };
- private:
- //! Left argument actor
- LeftT m_left;
- //! Right argument
- std::string m_right;
- public:
- //! Initializing constructor
- output_terminal(LeftT const& left, std::string const& right) : m_left(left), m_right(right)
- {
- }
- //! Invokation operator
- template< typename ContextT >
- typename result< this_type(ContextT) >::type operator() (ContextT const& ctx)
- {
- typedef typename result< this_type(ContextT) >::type result_type;
- result_type strm = phoenix::eval(m_left, ctx);
- strm << m_right;
- return strm;
- }
- //! Invokation operator
- template< typename ContextT >
- typename result< const this_type(ContextT) >::type operator() (ContextT const& ctx) const
- {
- typedef typename result< const this_type(ContextT) >::type result_type;
- result_type strm = phoenix::eval(m_left, ctx);
- strm << m_right;
- return strm;
- }
- };
- template< typename LeftExprT >
- inline phoenix::actor< output_terminal< phoenix::actor< LeftExprT > > >
- operator<< (phoenix::actor< LeftExprT > const& left, argument const& right)
- {
- phoenix::actor< output_terminal< phoenix::actor< LeftExprT > > > res = { output_terminal< phoenix::actor< LeftExprT > >(left, right.m_value) };
- return res;
- }
- typedef phoenix::expression::argument< 1 >::type stream_type;
- const stream_type stream = {};
- } // namespace my
- int main(int, char*[])
- {
- function< void (std::ostream&) > func;
- func = my::operator<< (my::stream, my::argument("Hello, world!"));
- func(std::cout);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement