diff --git a/include/mp/proxy-types.h b/include/mp/proxy-types.h index 38170d8c..f11fb359 100644 --- a/include/mp/proxy-types.h +++ b/include/mp/proxy-types.h @@ -645,7 +645,8 @@ template void ThrowField(TypeList, InvokeContext& invoke_context, Input&& input) { ReadField( - TypeList(), invoke_context, input, ReadDestEmplace(TypeList(), ThrowFn())); + TypeList(), invoke_context, input, ReadDestEmplace(TypeList(), + [](auto&& ...args) -> const LocalType& { throw LocalType{std::forward(args)...}; })); } //! Special case for generic std::exception. It's an abstract type so it can't diff --git a/include/mp/util.h b/include/mp/util.h index 9ccd3fac..6fc92778 100644 --- a/include/mp/util.h +++ b/include/mp/util.h @@ -21,39 +21,7 @@ namespace mp { -//! Generic utility functions used by capnp code. This mostly consists of -//! helpers that work around lack of C++14 functionality in C++11. This file -//! puts all C++14 workarounds in one place, so if/when bitcoin decides to -//! decides to upgrade to C++14, code can be accordingly simplified. -//! -//! C++14 has two features that really simplify generic programming. One is -//! auto-returning functions -//! (http://en.cppreference.com/w/cpp/language/template_argument_deduction#auto-returning_functions): -//! -//! auto DoSomething(Arg arg) { -//! return expression(arg); -//! } -//! -//! which in c++11 has to be written: -//! -//! auto DoSomething(Arg arg) -> decltype(expression(arg)) { -//! return expression(arg); -//! } -//! -//! Another is generic lambdas (http://en.cppreference.com/w/cpp/language/lambda): -//! -//! [capture](auto arg) { do_something(arg); } -//! -//! which in c++11 has to be written like -//! -//! struct DoSomething { -//! Capture m_capture; -//! -//! template -//! void operator()(Arg arg) { -//! return do_something(arg); -//! } -//! }; +//! Generic utility functions used by capnp code. //! Type holding a list of types. //! @@ -79,127 +47,6 @@ Class::type...> Make(Args&&... ar return Class::type...>{std::forward(args)...}; } -//! Function object composing two other function objects. Can be replaced with -//! auto lambdas when we update to C++14. -//! -//! Example: -//! Make(sin, atan2)(3, 4) == sin(atan2(3, 4)) -template -struct ComposeFn -{ - Fn1&& fn1; - Fn2&& fn2; - - template - decltype(auto) operator()(Args&&... args) { return this->fn1(this->fn2(std::forward(args)...)); } -}; - -//! Bound function. See Bind() below. -template > -struct BoundFn; - -//! Specialization of above for base case. -template -struct BoundFn, TypeList> -{ - Fn&& m_fn; - - template - decltype(auto) operator()(BoundArgs&... bound_args, FreeArgs&&... free_args) - { - return this->m_fn(bound_args..., std::forward(free_args)...); - } -}; - -//! Specialization of above for recursive case. -template -struct BoundFn, TypeList> - : BoundFn, TypeList> -{ - using Base = BoundFn, TypeList>; - BindArg& m_bind_arg; - - BoundFn(Fn& fn, BindArg& bind_arg, BindArgs&... bind_args) : Base{fn, bind_args...}, m_bind_arg(bind_arg) {} - - // Use std::result_of instead of decltype return to work around gcc bug - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83249 - template - auto operator()(BoundArgs&... bound_args, FreeArgs&&... free_args) -> - typename std::result_of::type - { - return Base::operator()(bound_args..., m_bind_arg, std::forward(free_args)...); - } -}; - -//! std::bind replacement. Unlike std::bind it doesn't copy the function object -//! or argument but instead takes rvalue references. This allows it to work with -//! uncopyable objects, but also limits its use to situations where objects -//! don't go out of scope. Uses of this can be replaced with auto lambdas when -//! we update to C++14. -//! -//! Example: -//! Bind(atan2, 3)(4) == atan2(3, 4) -//! -//! Possible TODO: It might be nice to make binding more consistent with composing -//! and switch to calling syntax Make(...) instead of Bind(...). -template -BoundFn> Bind(Fn&& fn, BindArgs&... bind_args) -{ - return {fn, bind_args...}; -} - -//! Bound tuple function. See BindTuple() below. -//! -//! C++14 equivalent: -//! -//! BoundTupleFn = [&fn](auto&&... params) { fn(std::forward_as_tuple(params...)); }; -template -struct BoundTupleFn -{ - Fn& m_fn; - template - decltype(auto) operator()(Params&&... params) { return this->m_fn(std::forward_as_tuple(params...)); } -}; - -//! Bind tuple argument to function. Arguments passed to the returned function -//! object are grouped together and passed to the wrapped function object as a -//! single forward_as_tuple argument. -template -BoundTupleFn BindTuple(Fn&& fn) -{ - return {fn}; -} - -//! Function object wrapping std::get. Can be replaced with auto lambdas when we -//! update to C++14. -//! -//! Example: -//! GetFn<3>()(a) // Equivalent to std::get<3>(a) -template -struct GetFn -{ - template - auto operator()(Tuple&& tuple) -> decltype(std::get(tuple))& - { - return std::get(tuple); - } -}; - -//! Function object that throws an exception. Can be replaced with auto lambdas -//! when we update to C++14. -//! -//! Example: -//! ThrowFn()(args) // Equivalent to: throw E(args) -template -struct ThrowFn -{ - template - const Exception& operator()(Params&&... params) - { - throw Exception(std::forward(params)...); - } -}; - //! Type helper splitting a TypeList into two halves at position index. //! //! Example: