//[ RGB /////////////////////////////////////////////////////////////////////////////// // Copyright 2008 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) // // This is a simple example of doing arbitrary type manipulations with proto // transforms. It takes some expression involving primary colors and combines // the colors according to arbitrary rules. It is a port of the RGB example // from PETE (http://www.codesourcery.com/pooma/download.html). #include #include #include namespace proto = boost::proto; struct RedTag { friend std::ostream &operator <<(std::ostream &sout, RedTag) { return sout << "This expression is red."; } }; struct BlueTag { friend std::ostream &operator <<(std::ostream &sout, BlueTag) { return sout << "This expression is blue."; } }; struct GreenTag { friend std::ostream &operator <<(std::ostream &sout, GreenTag) { return sout << "This expression is green."; } }; typedef proto::terminal::type RedT; typedef proto::terminal::type BlueT; typedef proto::terminal::type GreenT; struct Red; struct Blue; struct Green; /////////////////////////////////////////////////////////////////////////////// // A transform that produces new colors according to some arbitrary rules: // red & green give blue, red & blue give green, blue and green give red. struct Red : proto::or_< proto::plus , proto::plus , proto::plus , proto::terminal > {}; struct Green : proto::or_< proto::plus , proto::plus , proto::plus , proto::terminal > {}; struct Blue : proto::or_< proto::plus , proto::plus , proto::plus , proto::terminal > {}; struct RGB : proto::or_< proto::when< Red, RedTag() > , proto::when< Blue, BlueTag() > , proto::when< Green, GreenTag() > > {}; template void printColor(Expr const & expr) { int i = 0; // dummy state and data parameter, not used std::cout << RGB()(expr, i, i) << std::endl; } int main() { printColor(RedT() + GreenT()); printColor(RedT() + GreenT() + BlueT()); printColor(RedT() + (GreenT() + BlueT())); return 0; } //]