Skip to content

Commit 65260d1

Browse files
committed
util: Drop Bind, BindTuple, ComposeFn, GetFn, and ThrowFn helpers
Last remaining uses of these utilities except for ThrowFn were removed in PR "Unify ReadFieldNew / ReadFieldUpdate" #31 Last remaining use of ThrowFn is removed here. After C++14 it is easily replaced with a perfect-forwarding auto&& lambda. Immediate motivation for this change is to fix C++20 compilers complaining about reference to std::result_of in the unused code bitcoin/bitcoin#29248
1 parent 2cbbd09 commit 65260d1

File tree

2 files changed

+3
-155
lines changed

2 files changed

+3
-155
lines changed

include/mp/proxy-types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,8 @@ template <typename LocalType, typename Input>
645645
void ThrowField(TypeList<LocalType>, InvokeContext& invoke_context, Input&& input)
646646
{
647647
ReadField(
648-
TypeList<LocalType>(), invoke_context, input, ReadDestEmplace(TypeList<LocalType>(), ThrowFn<LocalType>()));
648+
TypeList<LocalType>(), invoke_context, input, ReadDestEmplace(TypeList<LocalType>(),
649+
[](auto&& ...args) -> const LocalType& { throw LocalType{std::forward<decltype(args)>(args)...}; }));
649650
}
650651

651652
//! Special case for generic std::exception. It's an abstract type so it can't

include/mp/util.h

Lines changed: 1 addition & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,7 @@
2121

2222
namespace mp {
2323

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.
5725

5826
//! Type holding a list of types.
5927
//!
@@ -79,127 +47,6 @@ Class<Types..., typename std::remove_reference<Args>::type...> Make(Args&&... ar
7947
return Class<Types..., typename std::remove_reference<Args>::type...>{std::forward<Args>(args)...};
8048
}
8149

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-
20350
//! Type helper splitting a TypeList into two halves at position index.
20451
//!
20552
//! Example:

0 commit comments

Comments
 (0)