language: C++ 4.7.2 (gcc-4.7.2)
date: 648 days 14 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
class IPrinter
{
public:
   virtual ~IPrinter() {}
   virtual std::ostream& print(std::ostream&) const = 0;
};
 
class StupidHelper
{
    std::vector<boost::shared_ptr<IPrinter> > printables;
public:
    template <class T, class U>
    StupidHelper(const T& a, const U& b);
 
    std::ostream& operator>> (std::ostream& os);
 
    template <class T>
    StupidHelper& operator>> (const T& a);
};
 
class Weirdo
{
    int n;
public:
    Weirdo(int n):n(n) {}
    std::ostream& operator >>(std::ostream& os) const
    {
        return os << n;
    }
    template <class T>
    StupidHelper operator >> (const T& rhv) const
    {
        return StupidHelper(*this, rhv);
    }
};
 
 
template <class T>
class Printer: public IPrinter
{
    const T* value;
public:
    Printer(const T& t): value(&t) {}
    std::ostream& print(std::ostream& os) const { return os << *value; }
};
 
template <>
class Printer<Weirdo>: public IPrinter
{
    const Weirdo* value;
public:
    Printer(const Weirdo& w): value(&w) {}
    std::ostream& print(std::ostream& os) const
    {
        return *value >> os;
    }
};
 
template <class T>
typename boost::disable_if<boost::is_same<T, StupidHelper>, StupidHelper>::type operator>>(const T& a, Weirdo& b)
{
    return StupidHelper(a, b);
}
 
template <class T, class U>
StupidHelper::StupidHelper(const T& a, const U& b)
{
    printables.push_back(boost::shared_ptr<IPrinter>(new Printer<T>(a)));
    printables.push_back(boost::shared_ptr<IPrinter>(new Printer<U>(b)));
}
 
 
template <class T>
StupidHelper& StupidHelper::operator>> (const T& a)
{
    printables.push_back(boost::shared_ptr<IPrinter>(new Printer<T>(a)));
    return *this;
}
 
std::ostream& StupidHelper::operator>> (std::ostream& os)
{
    for (unsigned i = 0; i < printables.size(); ++i) {
        printables[i]->print(os);
    }
    return os;
}
 
int main()
{
    Weirdo a(1), b(2), c(3);
    "These are printed left to right: a = " >> a >> ", b = " >> b >> " and c = " >> c >> '\n' >> std::cout;
}