summaryrefslogtreecommitdiff
path: root/boost/hof/match.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/hof/match.hpp')
-rw-r--r--boost/hof/match.hpp121
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