File indexing completed on 2025-12-15 10:26:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef RANGES_V3_FUNCTIONAL_REFERENCE_WRAPPER_HPP
0014 #define RANGES_V3_FUNCTIONAL_REFERENCE_WRAPPER_HPP
0015
0016 #include <type_traits>
0017 #include <utility>
0018
0019 #include <meta/meta.hpp>
0020
0021 #include <concepts/concepts.hpp>
0022
0023 #include <range/v3/functional/invoke.hpp>
0024 #include <range/v3/utility/addressof.hpp>
0025 #include <range/v3/utility/static_const.hpp>
0026
0027 #include <range/v3/detail/prologue.hpp>
0028
0029 namespace ranges
0030 {
0031
0032
0033
0034
0035 namespace detail
0036 {
0037 template<typename T>
0038 struct reference_wrapper_
0039 {
0040 T * t_ = nullptr;
0041 constexpr reference_wrapper_() = default;
0042 constexpr reference_wrapper_(T & t) noexcept
0043 : t_(detail::addressof(t))
0044 {}
0045 constexpr reference_wrapper_(T &&) = delete;
0046 constexpr T & get() const noexcept
0047 {
0048 return *t_;
0049 }
0050 };
0051 template<typename T>
0052 struct reference_wrapper_<T &> : reference_wrapper_<T>
0053 {
0054 using reference_wrapper_<T>::reference_wrapper_;
0055 };
0056 template<typename T>
0057 struct reference_wrapper_<T &&>
0058 {
0059 T * t_ = nullptr;
0060 constexpr reference_wrapper_() = default;
0061 constexpr reference_wrapper_(T && t) noexcept
0062 : t_(detail::addressof(t))
0063 {}
0064 constexpr T && get() const noexcept
0065 {
0066 return static_cast<T &&>(*t_);
0067 }
0068 };
0069 }
0070
0071
0072
0073
0074 template<typename T>
0075 struct reference_wrapper : private detail::reference_wrapper_<T>
0076 {
0077 private:
0078 using base_ = detail::reference_wrapper_<T>;
0079 using base_::t_;
0080
0081 public:
0082 using type = meta::_t<std::remove_reference<T>>;
0083 using reference = meta::if_<std::is_reference<T>, T, T &>;
0084
0085 constexpr reference_wrapper() = default;
0086 template(typename U)(
0087 requires (!same_as<uncvref_t<U>, reference_wrapper>) AND
0088 constructible_from<base_, U>)
0089 constexpr reference_wrapper(U && u) noexcept(
0090 std::is_nothrow_constructible<base_, U>::value)
0091 : detail::reference_wrapper_<T>{static_cast<U &&>(u)}
0092 {}
0093 constexpr reference get() const noexcept
0094 {
0095 return this->base_::get();
0096 }
0097 constexpr operator reference() const noexcept
0098 {
0099 return get();
0100 }
0101 template(typename...)(
0102 requires (!std::is_rvalue_reference<T>::value))
0103 constexpr operator std::reference_wrapper<type>() const noexcept
0104 {
0105 return {get()};
0106 }
0107
0108 template<typename ...Args>
0109 constexpr auto CPP_auto_fun(operator())(Args &&...args) (const)
0110 (
0111 return invoke(static_cast<reference>(*t_), static_cast<Args &&>(args)...)
0112 )
0113
0114 };
0115
0116 struct ref_fn
0117 {
0118 template(typename T)(
0119 requires (!is_reference_wrapper_v<T>))
0120 constexpr reference_wrapper<T> operator()(T & t) const
0121 {
0122 return {t};
0123 }
0124
0125 template<typename T>
0126 constexpr reference_wrapper<T> operator()(reference_wrapper<T> t) const
0127 {
0128 return t;
0129 }
0130
0131 template<typename T>
0132 constexpr reference_wrapper<T> operator()(std::reference_wrapper<T> t) const
0133 {
0134 return {t.get()};
0135 }
0136 };
0137
0138
0139
0140 RANGES_INLINE_VARIABLE(ref_fn, ref)
0141
0142 template<typename T>
0143 using ref_t = decltype(ref(std::declval<T>()));
0144
0145 struct unwrap_reference_fn
0146 {
0147 template<typename T>
0148 constexpr T && operator()(T && t) const noexcept
0149 {
0150 return static_cast<T &&>(t);
0151 }
0152
0153 template<typename T>
0154 constexpr typename reference_wrapper<T>::reference operator()(reference_wrapper<T> t) const
0155 noexcept
0156 {
0157 return t.get();
0158 }
0159
0160 template<typename T>
0161 constexpr T & operator()(std::reference_wrapper<T> t) const noexcept
0162 {
0163 return t.get();
0164 }
0165
0166 template<typename T>
0167 constexpr T & operator()(ref_view<T> t) const noexcept
0168 {
0169 return t.base();
0170 }
0171 };
0172
0173
0174
0175 RANGES_INLINE_VARIABLE(unwrap_reference_fn, unwrap_reference)
0176
0177 template<typename T>
0178 using unwrap_reference_t = decltype(unwrap_reference(std::declval<T>()));
0179
0180 }
0181
0182 #include <range/v3/detail/epilogue.hpp>
0183
0184 #endif