File indexing completed on 2025-12-16 10:27:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
0031
0032
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 }
0057
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
0168
0169 RANGES_INLINE_VARIABLE(overload_fn, overload)
0170
0171 }
0172
0173 #include <range/v3/detail/epilogue.hpp>
0174
0175 #endif