103 lines
2.5 KiB
C++
103 lines
2.5 KiB
C++
//[ 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 <iostream>
|
|
#include <boost/proto/core.hpp>
|
|
#include <boost/proto/transform.hpp>
|
|
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<RedTag>::type RedT;
|
|
typedef proto::terminal<BlueTag>::type BlueT;
|
|
typedef proto::terminal<GreenTag>::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<Green, Blue>
|
|
, proto::plus<Blue, Green>
|
|
, proto::plus<Red, Red>
|
|
, proto::terminal<RedTag>
|
|
>
|
|
{};
|
|
|
|
struct Green
|
|
: proto::or_<
|
|
proto::plus<Red, Blue>
|
|
, proto::plus<Blue, Red>
|
|
, proto::plus<Green, Green>
|
|
, proto::terminal<GreenTag>
|
|
>
|
|
{};
|
|
|
|
struct Blue
|
|
: proto::or_<
|
|
proto::plus<Red, Green>
|
|
, proto::plus<Green, Red>
|
|
, proto::plus<Blue, Blue>
|
|
, proto::terminal<BlueTag>
|
|
>
|
|
{};
|
|
|
|
struct RGB
|
|
: proto::or_<
|
|
proto::when< Red, RedTag() >
|
|
, proto::when< Blue, BlueTag() >
|
|
, proto::when< Green, GreenTag() >
|
|
>
|
|
{};
|
|
|
|
template<typename Expr>
|
|
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;
|
|
}
|
|
//]
|