1 //[ RGB
2 ///////////////////////////////////////////////////////////////////////////////
3 //  Copyright 2008 Eric Niebler. Distributed under the Boost
4 //  Software License, Version 1.0. (See accompanying file
5 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // This is a simple example of doing arbitrary type manipulations with proto
8 // transforms. It takes some expression involving primary colors and combines
9 // the colors according to arbitrary rules. It is a port of the RGB example
10 // from PETE (http://www.codesourcery.com/pooma/download.html).
11 
12 #include <iostream>
13 #include <boost/proto/core.hpp>
14 #include <boost/proto/transform.hpp>
15 namespace proto = boost::proto;
16 
17 struct RedTag
18 {
operator <<(std::ostream & sout,RedTag)19     friend std::ostream &operator <<(std::ostream &sout, RedTag)
20     {
21         return sout << "This expression is red.";
22     }
23 };
24 
25 struct BlueTag
26 {
operator <<(std::ostream & sout,BlueTag)27     friend std::ostream &operator <<(std::ostream &sout, BlueTag)
28     {
29         return sout << "This expression is blue.";
30     }
31 };
32 
33 struct GreenTag
34 {
operator <<(std::ostream & sout,GreenTag)35     friend std::ostream &operator <<(std::ostream &sout, GreenTag)
36     {
37         return sout << "This expression is green.";
38     }
39 };
40 
41 typedef proto::terminal<RedTag>::type RedT;
42 typedef proto::terminal<BlueTag>::type BlueT;
43 typedef proto::terminal<GreenTag>::type GreenT;
44 
45 struct Red;
46 struct Blue;
47 struct Green;
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 // A transform that produces new colors according to some arbitrary rules:
51 // red & green give blue, red & blue give green, blue and green give red.
52 struct Red
53   : proto::or_<
54         proto::plus<Green, Blue>
55       , proto::plus<Blue, Green>
56       , proto::plus<Red, Red>
57       , proto::terminal<RedTag>
58     >
59 {};
60 
61 struct Green
62   : proto::or_<
63         proto::plus<Red, Blue>
64       , proto::plus<Blue, Red>
65       , proto::plus<Green, Green>
66       , proto::terminal<GreenTag>
67     >
68 {};
69 
70 struct Blue
71   : proto::or_<
72         proto::plus<Red, Green>
73       , proto::plus<Green, Red>
74       , proto::plus<Blue, Blue>
75       , proto::terminal<BlueTag>
76     >
77 {};
78 
79 struct RGB
80   : proto::or_<
81         proto::when< Red, RedTag() >
82       , proto::when< Blue, BlueTag() >
83       , proto::when< Green, GreenTag() >
84     >
85 {};
86 
87 template<typename Expr>
printColor(Expr const & expr)88 void printColor(Expr const & expr)
89 {
90     int i = 0; // dummy state and data parameter, not used
91     std::cout << RGB()(expr, i, i) << std::endl;
92 }
93 
main()94 int main()
95 {
96     printColor(RedT() + GreenT());
97     printColor(RedT() + GreenT() + BlueT());
98     printColor(RedT() + (GreenT() + BlueT()));
99 
100     return 0;
101 }
102 //]
103