-
Notifications
You must be signed in to change notification settings - Fork 2
/
composable.h
61 lines (48 loc) · 1.99 KB
/
composable.h
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
#ifndef LZY_COMPOSABLE_H
#define LZY_COMPOSABLE_H
namespace lzy {
template<typename Derived>
class composable;
template<typename FirstComposable, typename SecondComposable>
class composition : public composable<composition<FirstComposable, SecondComposable>> {
public:
composition (FirstComposable& first, SecondComposable& second) : first(first), second(second) {};
template<typename Input>
using FirstResult = typename std::result_of<FirstComposable(Input)>::type;
template<typename Input>
using EndResult = typename std::result_of<SecondComposable(FirstResult<Input>)>::type;
template<typename Input>
EndResult<Input> operator() (Input&& input) {
return second(first(std::move(input)));
}
private:
FirstComposable& first;
SecondComposable& second;
};
template<typename Derived>
class composable {
public:
template<typename OtherComposable>
composition<Derived, OtherComposable> operator | (OtherComposable&& other) {
return composition<Derived, OtherComposable>(static_cast<Derived&>(*this), other);
}
};
template<typename FirstComposable, typename SecondComposable>
class owning_composition : public composable<owning_composition<FirstComposable, SecondComposable>> {
public:
owning_composition (FirstComposable&& first, SecondComposable&& second)
: first(std::move(first)), second(std::move(second)) {};
template<typename Input>
using FirstResult = typename std::result_of<FirstComposable(Input)>::type;
template<typename Input>
using EndResult = typename std::result_of<SecondComposable(FirstResult<Input>)>::type;
template<typename Input>
EndResult<Input> operator() (Input&& input) {
return second(first(std::move(input)));
}
private:
FirstComposable first;
SecondComposable second;
};
}
#endif //LZY_COMPOSABLE_H