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