21
21
22
22
namespace mp {
23
23
24
- // ! Generic utility functions used by capnp code. This mostly consists of
25
- // ! helpers that work around lack of C++14 functionality in C++11. This file
26
- // ! puts all C++14 workarounds in one place, so if/when bitcoin decides to
27
- // ! decides to upgrade to C++14, code can be accordingly simplified.
28
- // !
29
- // ! C++14 has two features that really simplify generic programming. One is
30
- // ! auto-returning functions
31
- // ! (http://en.cppreference.com/w/cpp/language/template_argument_deduction#auto-returning_functions):
32
- // !
33
- // ! auto DoSomething(Arg arg) {
34
- // ! return expression(arg);
35
- // ! }
36
- // !
37
- // ! which in c++11 has to be written:
38
- // !
39
- // ! auto DoSomething(Arg arg) -> decltype(expression(arg)) {
40
- // ! return expression(arg);
41
- // ! }
42
- // !
43
- // ! Another is generic lambdas (http://en.cppreference.com/w/cpp/language/lambda):
44
- // !
45
- // ! [capture](auto arg) { do_something(arg); }
46
- // !
47
- // ! which in c++11 has to be written like
48
- // !
49
- // ! struct DoSomething {
50
- // ! Capture m_capture;
51
- // !
52
- // ! template<typename Arg>
53
- // ! void operator()(Arg arg) {
54
- // ! return do_something(arg);
55
- // ! }
56
- // ! };
24
+ // ! Generic utility functions used by capnp code.
57
25
58
26
// ! Type holding a list of types.
59
27
// !
@@ -79,127 +47,6 @@ Class<Types..., typename std::remove_reference<Args>::type...> Make(Args&&... ar
79
47
return Class<Types..., typename std::remove_reference<Args>::type...>{std::forward<Args>(args)...};
80
48
}
81
49
82
- // ! Function object composing two other function objects. Can be replaced with
83
- // ! auto lambdas when we update to C++14.
84
- // !
85
- // ! Example:
86
- // ! Make<ComposeFn>(sin, atan2)(3, 4) == sin(atan2(3, 4))
87
- template <typename Fn1, typename Fn2>
88
- struct ComposeFn
89
- {
90
- Fn1&& fn1;
91
- Fn2&& fn2;
92
-
93
- template <typename ... Args>
94
- decltype (auto ) operator ()(Args&&... args) { return this ->fn1 (this ->fn2 (std::forward<Args>(args)...)); }
95
- };
96
-
97
- // ! Bound function. See Bind() below.
98
- template <typename Fn, typename BindArgs, typename BoundArgs = TypeList<>>
99
- struct BoundFn ;
100
-
101
- // ! Specialization of above for base case.
102
- template <typename Fn, typename ... BoundArgs>
103
- struct BoundFn <Fn, TypeList<>, TypeList<BoundArgs...>>
104
- {
105
- Fn&& m_fn;
106
-
107
- template <typename ... FreeArgs>
108
- decltype (auto ) operator ()(BoundArgs&... bound_args, FreeArgs&&... free_args)
109
- {
110
- return this ->m_fn (bound_args..., std::forward<FreeArgs>(free_args)...);
111
- }
112
- };
113
-
114
- // ! Specialization of above for recursive case.
115
- template <typename Fn, typename BindArg, typename ... BindArgs, typename ... BoundArgs>
116
- struct BoundFn <Fn, TypeList<BindArg, BindArgs...>, TypeList<BoundArgs...>>
117
- : BoundFn<Fn, TypeList<BindArgs...>, TypeList<BoundArgs..., BindArg>>
118
- {
119
- using Base = BoundFn<Fn, TypeList<BindArgs...>, TypeList<BoundArgs..., BindArg>>;
120
- BindArg& m_bind_arg;
121
-
122
- BoundFn (Fn& fn, BindArg& bind_arg, BindArgs&... bind_args) : Base{fn, bind_args...}, m_bind_arg(bind_arg) {}
123
-
124
- // Use std::result_of instead of decltype return to work around gcc bug
125
- // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83249
126
- template <typename ... FreeArgs>
127
- auto operator ()(BoundArgs&... bound_args, FreeArgs&&... free_args) ->
128
- typename std::result_of<Base(BoundArgs&..., BindArg&, FreeArgs...)>::type
129
- {
130
- return Base::operator ()(bound_args..., m_bind_arg, std::forward<FreeArgs>(free_args)...);
131
- }
132
- };
133
-
134
- // ! std::bind replacement. Unlike std::bind it doesn't copy the function object
135
- // ! or argument but instead takes rvalue references. This allows it to work with
136
- // ! uncopyable objects, but also limits its use to situations where objects
137
- // ! don't go out of scope. Uses of this can be replaced with auto lambdas when
138
- // ! we update to C++14.
139
- // !
140
- // ! Example:
141
- // ! Bind(atan2, 3)(4) == atan2(3, 4)
142
- // !
143
- // ! Possible TODO: It might be nice to make binding more consistent with composing
144
- // ! and switch to calling syntax Make<Bind>(...) instead of Bind(...).
145
- template <typename Fn, typename ... BindArgs>
146
- BoundFn<Fn, TypeList<BindArgs...>> Bind (Fn&& fn, BindArgs&... bind_args)
147
- {
148
- return {fn, bind_args...};
149
- }
150
-
151
- // ! Bound tuple function. See BindTuple() below.
152
- // !
153
- // ! C++14 equivalent:
154
- // !
155
- // ! BoundTupleFn = [&fn](auto&&... params) { fn(std::forward_as_tuple(params...)); };
156
- template <typename Fn>
157
- struct BoundTupleFn
158
- {
159
- Fn& m_fn;
160
- template <typename ... Params>
161
- decltype (auto ) operator ()(Params&&... params) { return this ->m_fn (std::forward_as_tuple (params...)); }
162
- };
163
-
164
- // ! Bind tuple argument to function. Arguments passed to the returned function
165
- // ! object are grouped together and passed to the wrapped function object as a
166
- // ! single forward_as_tuple argument.
167
- template <typename Fn>
168
- BoundTupleFn<Fn> BindTuple (Fn&& fn)
169
- {
170
- return {fn};
171
- }
172
-
173
- // ! Function object wrapping std::get. Can be replaced with auto lambdas when we
174
- // ! update to C++14.
175
- // !
176
- // ! Example:
177
- // ! GetFn<3>()(a) // Equivalent to std::get<3>(a)
178
- template <std::size_t I>
179
- struct GetFn
180
- {
181
- template <typename Tuple>
182
- auto operator ()(Tuple&& tuple) -> decltype(std::get<I>(tuple))&
183
- {
184
- return std::get<I>(tuple);
185
- }
186
- };
187
-
188
- // ! Function object that throws an exception. Can be replaced with auto lambdas
189
- // ! when we update to C++14.
190
- // !
191
- // ! Example:
192
- // ! ThrowFn<E>()(args) // Equivalent to: throw E(args)
193
- template <typename Exception>
194
- struct ThrowFn
195
- {
196
- template <typename ... Params>
197
- const Exception& operator ()(Params&&... params)
198
- {
199
- throw Exception (std::forward<Params>(params)...);
200
- }
201
- };
202
-
203
50
// ! Type helper splitting a TypeList into two halves at position index.
204
51
// !
205
52
// ! Example:
0 commit comments