Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:27:57

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
0012 //
0013 #ifndef RANGES_V3_FUNCTIONAL_OVERLOAD_HPP
0014 #define RANGES_V3_FUNCTIONAL_OVERLOAD_HPP
0015 
0016 #include <meta/meta.hpp>
0017 
0018 #include <concepts/concepts.hpp>
0019 
0020 #include <range/v3/range_fwd.hpp>
0021 
0022 #include <range/v3/functional/concepts.hpp>
0023 #include <range/v3/functional/invoke.hpp>
0024 #include <range/v3/utility/static_const.hpp>
0025 
0026 #include <range/v3/detail/prologue.hpp>
0027 
0028 namespace ranges
0029 {
0030     /// \addtogroup group-functional
0031     /// @{
0032     /// \cond
0033     namespace detail
0034     {
0035         struct _id
0036         {
0037             template<typename T>
0038             using invoke = T;
0039         };
0040         struct _ref
0041         {
0042             template<typename T>
0043             using invoke = T &;
0044         };
0045         struct _cref
0046         {
0047             template<typename T>
0048             using invoke = T const &;
0049         };
0050         template<typename T>
0051         struct _bind_front
0052         {
0053             template<typename... Args>
0054             using invoke = invoke_result_t<T, Args...>;
0055         };
0056     } // namespace detail
0057     /// \endcond
0058 
0059     template<typename... Ts>
0060     struct overloaded;
0061 
0062     template<>
0063     struct overloaded<>
0064     {
0065     private:
0066         template<typename...>
0067         friend struct overloaded;
0068         template<typename, typename...>
0069         using _result_t = void;
0070     };
0071 
0072     template<typename First, typename... Rest>
0073     struct overloaded<First, Rest...>
0074     {
0075     private:
0076         template<typename...>
0077         friend struct overloaded;
0078 
0079         RANGES_NO_UNIQUE_ADDRESS
0080         First first_;
0081         RANGES_NO_UNIQUE_ADDRESS
0082         overloaded<Rest...> second_;
0083 
0084         template<typename Qual>
0085         using _result_first = detail::_bind_front<meta::invoke<Qual, First>>;
0086         template<typename Qual>
0087         struct _result_second
0088         {
0089             template<typename... Args>
0090             using invoke = typename overloaded<Rest...>
0091                 ::template _result_t<Qual, Args...>;
0092         };
0093 
0094         template<typename Qual, typename... Args>
0095         using _result_t =
0096             meta::invoke<
0097                 meta::conditional_t<
0098                     (bool) invocable<meta::invoke<Qual, First>, Args...>,
0099                     _result_first<Qual>,
0100                     _result_second<Qual>>,
0101                 Args...>;
0102 
0103     public:
0104         overloaded() = default;
0105         constexpr overloaded(First first, Rest... rest)
0106           : first_(static_cast<First &&>(first))
0107           , second_{static_cast<Rest &&>(rest)...}
0108         {}
0109 
0110         template(typename... Args)(
0111             requires invocable<First, Args...>)
0112         constexpr _result_t<detail::_id, Args...> operator()(Args &&... args) &&
0113         {
0114             return invoke((First &&) first_, (Args &&) args...);
0115         }
0116         template(typename... Args)(
0117             requires (!invocable<First, Args...>) AND
0118                 invocable<overloaded<Rest...>, Args...>)
0119         constexpr _result_t<detail::_id, Args...> operator()(Args &&... args) &&
0120         {
0121             return invoke((overloaded<Rest...> &&) second_, (Args &&) args...);
0122         }
0123 
0124         template(typename... Args)(
0125             requires invocable<First &, Args...>)
0126         constexpr _result_t<detail::_ref, Args...> operator()(Args &&... args) &
0127         {
0128             return invoke(first_, (Args &&) args...);
0129         }
0130         template(typename... Args)(
0131             requires (!invocable<First &, Args...>) AND
0132                 invocable<overloaded<Rest...> &, Args...>)
0133         constexpr _result_t<detail::_ref, Args...> operator()(Args &&... args) &
0134         {
0135             return invoke(second_, (Args &&) args...);
0136         }
0137 
0138         template(typename... Args)(
0139             requires invocable<First const &, Args...>)
0140         constexpr _result_t<detail::_cref, Args...> operator()(Args &&... args) const &
0141         {
0142             return invoke(first_, (Args &&) args...);
0143         }
0144         template(typename... Args)(
0145             requires (!invocable<First const &, Args...>) AND
0146                 invocable<overloaded<Rest...> const &, Args...>)
0147         constexpr _result_t<detail::_cref, Args...> operator()(Args &&... args) const &
0148         {
0149             return invoke(second_, (Args &&) args...);
0150         }
0151     };
0152 
0153     struct overload_fn
0154     {
0155         template<typename Fn>
0156         constexpr Fn operator()(Fn fn) const
0157         {
0158             return fn;
0159         }
0160         template<typename... Fns>
0161         constexpr overloaded<Fns...> operator()(Fns... fns) const
0162         {
0163             return overloaded<Fns...>{static_cast<Fns &&>(fns)...};
0164         }
0165     };
0166 
0167     /// \ingroup group-functional
0168     /// \sa `overload_fn`
0169     RANGES_INLINE_VARIABLE(overload_fn, overload)
0170     /// @}
0171 } // namespace ranges
0172 
0173 #include <range/v3/detail/epilogue.hpp>
0174 
0175 #endif