diff options
Diffstat (limited to 'boost/hof/match.hpp')
-rw-r--r-- | boost/hof/match.hpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/boost/hof/match.hpp b/boost/hof/match.hpp new file mode 100644 index 0000000000..abf60194f5 --- /dev/null +++ b/boost/hof/match.hpp @@ -0,0 +1,121 @@ +/*============================================================================= + Copyright (c) 2012 Paul Fultz II + match.h + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_HOF_GUARD_FUNCTION_OVERLOAD_H +#define BOOST_HOF_GUARD_FUNCTION_OVERLOAD_H + +/// match +/// ===== +/// +/// Description +/// ----------- +/// +/// The `match` function adaptor combines several functions together and +/// resolves which one should be called by using C++ overload resolution. This +/// is different than the [`first_of`](/include/boost/hof/conditional) adaptor which resolves +/// them based on order. +/// +/// Synopsis +/// -------- +/// +/// template<class... Fs> +/// constexpr match_adaptor<Fs...> match(Fs...fs); +/// +/// Requirements +/// ------------ +/// +/// Fs must be: +/// +/// * [ConstInvocable](ConstInvocable) +/// * MoveConstructible +/// +/// Example +/// ------- +/// +/// #include <boost/hof.hpp> +/// using namespace boost::hof; +/// +/// struct int_class +/// { +/// int operator()(int) const +/// { +/// return 1; +/// } +/// }; +/// +/// struct foo +/// {}; +/// +/// struct foo_class +/// { +/// foo operator()(foo) const +/// { +/// return foo(); +/// } +/// }; +/// +/// typedef match_adaptor<int_class, foo_class> fun; +/// +/// static_assert(std::is_same<int, decltype(fun()(1))>::value, "Failed match"); +/// static_assert(std::is_same<foo, decltype(fun()(foo()))>::value, "Failed match"); +/// +/// int main() {} +/// +/// References +/// ---------- +/// +/// * [POO51](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0051r2.pdf) - Proposal for C++ +/// Proposal for C++ generic overload function +/// + +#include <boost/hof/reveal.hpp> +#include <boost/hof/detail/callable_base.hpp> +#include <boost/hof/detail/delegate.hpp> +#include <boost/hof/detail/move.hpp> +#include <boost/hof/detail/make.hpp> +#include <boost/hof/detail/static_const_var.hpp> + +namespace boost { namespace hof { + +template<class...Fs> struct match_adaptor; + +template<class F, class...Fs> +struct match_adaptor<F, Fs...> : detail::callable_base<F>, match_adaptor<Fs...> +{ + typedef match_adaptor<Fs...> base; + typedef match_adaptor fit_rewritable_tag; + + struct failure + : failure_for<detail::callable_base<F>, Fs...> + {}; + + BOOST_HOF_INHERIT_DEFAULT(match_adaptor, detail::callable_base<F>, base); + + template<class X, class... Xs, BOOST_HOF_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>), BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(base, Xs...)> + constexpr match_adaptor(X&& f1, Xs&& ... fs) + : detail::callable_base<F>(BOOST_HOF_FORWARD(X)(f1)), base(BOOST_HOF_FORWARD(Xs)(fs)...) + {} + + using F::operator(); + using base::operator(); +}; + +template<class F> +struct match_adaptor<F> : detail::callable_base<F> +{ + typedef detail::callable_base<F> base; + typedef match_adaptor fit_rewritable_tag; + using F::operator(); + + BOOST_HOF_INHERIT_CONSTRUCTOR(match_adaptor, detail::callable_base<F>); +}; + +BOOST_HOF_DECLARE_STATIC_VAR(match, detail::make<match_adaptor>); + +}} // namespace boost::hof + +#endif |