|
- /// \file
- // Range v3 library
- //
- // Copyright Eric Niebler 2013-present
- //
- // Use, modification and distribution is subject to 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)
- //
- // Project home: https://github.com/ericniebler/range-v3
- //
- #ifndef RANGES_V3_FUNCTIONAL_OVERLOAD_HPP
- #define RANGES_V3_FUNCTIONAL_OVERLOAD_HPP
-
- #include <concepts/concepts.hpp>
-
- #include <range/v3/range_fwd.hpp>
-
- #include <range/v3/functional/invoke.hpp>
- #include <range/v3/utility/static_const.hpp>
-
- namespace ranges
- {
- /// \addtogroup group-functional
- /// @{
- template<typename... Ts>
- struct overloaded;
-
- template<>
- struct overloaded<>
- {};
-
- template<typename First, typename... Rest>
- struct overloaded<First, Rest...>
- {
- private:
- RANGES_NO_UNIQUE_ADDRESS
- First first_;
- RANGES_NO_UNIQUE_ADDRESS
- overloaded<Rest...> second_;
-
- public:
- overloaded() = default;
- constexpr overloaded(First first, Rest... rest)
- : first_(static_cast<First &&>(first))
- , second_{static_cast<Rest &&>(rest)...}
- {}
- // clang-format off
- template<typename... Args>
- auto CPP_auto_fun(operator())(Args &&...args)
- (
- return invoke(first_, static_cast<Args &&>(args)...)
- )
- template<typename... Args>
- auto CPP_auto_fun(operator())(Args &&...args) (const)
- (
- return invoke((First const &) first_, static_cast<Args &&>(args)...)
- )
- template<typename... Args>
- auto CPP_auto_fun(operator())(Args &&...args)
- (
- return second_(static_cast<Args &&>(args)...)
- )
- template<typename... Args>
- auto CPP_auto_fun(operator())(Args &&...args) (const)
- (
- return ((overloaded<Rest...> const &) second_)(static_cast<Args &&>(args)...)
- )
- // clang-format on
- };
-
- struct overload_fn
- {
- template<typename Fn>
- constexpr Fn operator()(Fn fn) const
- {
- return fn;
- }
- template<typename... Fns>
- constexpr overloaded<Fns...> operator()(Fns... fns) const
- {
- return overloaded<Fns...>{static_cast<Fns &&>(fns)...};
- }
- };
-
- /// \ingroup group-functional
- /// \sa `overload_fn`
- RANGES_INLINE_VARIABLE(overload_fn, overload)
- /// @}
- } // namespace ranges
-
- #endif
|