boost/xpressive/proto/compiler/fold.hpp
/////////////////////////////////////////////////////////////////////////////// /// \file fold.hpp /// A special-purpose proto compiler for merging sequences of binary operations. /// It compiles the right operand and passes the result as state while compiling /// the left. Or, it might do the left first, if you choose. // // Copyright 2004 Eric Niebler. 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) #ifndef BOOST_PROTO_COMPILER_FOLD_HPP_EAN_04_01_2005 #define BOOST_PROTO_COMPILER_FOLD_HPP_EAN_04_01_2005 #include <boost/xpressive/proto/proto_fwd.hpp> namespace boost { namespace proto { /////////////////////////////////////////////////////////////////////////////// // fold_compiler // Compiles the right side and passes the result as state while compiling the left. // This is useful for serializing a tree. template<typename OpTag, typename DomainTag, bool RightFirst> struct fold_compiler { // sample compiler implementation for sequencing template<typename Op, typename State, typename Visitor> struct apply { typedef typename right_type<Op>::type right_type; typedef typename left_type<Op>::type left_type; // compile the right branch typedef typename compiler<typename tag_type<right_type>::type, DomainTag>:: BOOST_NESTED_TEMPLATE apply < right_type , State , Visitor >::type right_compiled_type; // forward the result of the right branch to the left typedef typename compiler<typename tag_type<left_type>::type, DomainTag>:: BOOST_NESTED_TEMPLATE apply < left_type , right_compiled_type , Visitor >::type type; }; template<typename Op, typename State, typename Visitor> static typename apply<Op, State, Visitor>::type call(Op const &op, State const &state, Visitor &visitor) { return proto::compile( proto::left(op) , proto::compile(proto::right(op), state, visitor, DomainTag()) , visitor , DomainTag() ); } }; /////////////////////////////////////////////////////////////////////////////// // fold_compiler // Compiles the left side and passes the result as state while compiling the right. // This is useful for serializing a tree. template<typename OpTag, typename DomainTag> struct fold_compiler<OpTag, DomainTag, false> { // sample compiler implementation for sequencing template<typename Op, typename State, typename Visitor> struct apply { typedef typename right_type<Op>::type right_type; typedef typename left_type<Op>::type left_type; // compile the right branch typedef typename compiler<typename tag_type<left_type>::type, DomainTag>:: BOOST_NESTED_TEMPLATE apply < left_type , State , Visitor >::type left_compiled_type; // forward the result of the right branch to the left typedef typename compiler<typename tag_type<right_type>::type, DomainTag>:: BOOST_NESTED_TEMPLATE apply < right_type , left_compiled_type , Visitor >::type type; }; template<typename Op, typename State, typename Visitor> static typename apply<Op, State, Visitor>::type call(Op const &op, State const &state, Visitor &visitor) { return proto::compile( proto::right(op) , proto::compile(proto::left(op), state, visitor, DomainTag()) , visitor , DomainTag() ); } }; }} #endif