@@ -52,7 +52,10 @@ namespace ztd {
5252 using __is_unwrappable_value_test = decltype (unwrap(::std::declval<_Type>()));
5353
5454 template <typename _Type>
55- using __is_unwrappable_iter_value_test = decltype (unwrap_iterator(::std::declval<_Type>()));
55+ using __is_unwrappable_iter_value_test = decltype (unwrap_iterator_value(::std::declval<_Type>()));
56+
57+ template <typename _Type>
58+ using __is_unwrappable_iter_test = decltype (unwrap_iterator(::std::declval<_Type>()));
5659 } // namespace __idk_detail
5760
5861 // ////
@@ -62,11 +65,17 @@ namespace ztd {
6265 = ztd::is_detected_v<__idk_detail::__is_unwrappable_value_test, _Type>;
6366
6467 // ////
65- // / @brief Test whether a type can have `unwrap_iterator (...)` called on it.
68+ // / @brief Test whether a type can have `unwrap_iterator_value (...)` called on it.
6669 template <typename _Type>
6770 inline constexpr bool is_unwrappable_iterator_value_v
6871 = ztd::is_detected_v<__idk_detail::__is_unwrappable_iter_value_test, _Type>;
6972
73+ // ////
74+ // / @brief Test whether a type can have `unwrap_iterator(...)` called on it.
75+ template <typename _Type>
76+ inline constexpr bool is_unwrappable_iterator_v
77+ = ztd::is_detected_v<__idk_detail::__is_unwrappable_iter_test, _Type>;
78+
7079 namespace __idk_detail {
7180 class __unwrap_fn : public ::ztd::hijack::token<__unwrap_fn>, public ::ztd_hijack_global_token<__unwrap_fn> {
7281 public:
@@ -99,13 +108,13 @@ namespace ztd {
99108
100109
101110 namespace __idk_detail {
102- class __unwrap_iterator_fn : public ::ztd::hijack::token<__unwrap_iterator_fn >,
103- public ::ztd_hijack_global_token<__unwrap_iterator_fn > {
111+ class __unwrap_iterator_value_fn : public ::ztd::hijack::token<__unwrap_iterator_value_fn >,
112+ public ::ztd_hijack_global_token<__unwrap_iterator_value_fn > {
104113 public:
105114 template <typename _Type>
106115 constexpr decltype (auto ) operator()(_Type&& __value) const noexcept {
107116 if constexpr (is_unwrappable_iterator_value_v<_Type>) {
108- return unwrap_iterator (::std::forward<_Type>(__value));
117+ return unwrap_iterator_value (::std::forward<_Type>(__value));
109118 }
110119 else {
111120 return ::ztd::unwrap (*::std::forward<_Type>(__value));
@@ -120,6 +129,37 @@ namespace ztd {
120129 // / value through.
121130 // /
122131 // / @returns The iterator's unwrapped value.
132+ inline constexpr __idk_detail::__unwrap_iterator_value_fn unwrap_iterator_value = {};
133+ } // namespace __fn
134+
135+
136+ namespace __idk_detail {
137+ class __unwrap_iterator_fn : public ::ztd::hijack::token<__unwrap_iterator_fn>,
138+ public ::ztd_hijack_global_token<__unwrap_iterator_fn> {
139+ public:
140+ template <typename _Type>
141+ constexpr decltype (auto ) operator()(_Type&& __value) const noexcept {
142+ #if ZTD_IS_ON(ZTD_STD_LIBRARY_RANGES_BASIC_CONST_ITERATOR)
143+ if constexpr (::ztd::is_specialization_of_v<::ztd::remove_cvref_t <_Type>,
144+ ::std::basic_const_iterator>) {
145+ // peel off the const iterator where possible
146+ return ::std::forward<_Type>(__value).base ();
147+ }
148+ else
149+ #endif
150+ {
151+ return ::std::forward<_Type>(__value);
152+ }
153+ }
154+ };
155+ } // namespace __idk_detail
156+
157+ inline namespace __fn {
158+ // ////
159+ // / @brief Peels layers off of an iterator that may be wrapped in implementation-defined and standards-defined
160+ // / abstraction layers.
161+ // /
162+ // / @returns The iterator's unwrapped value.
123163 inline constexpr __idk_detail::__unwrap_iterator_fn unwrap_iterator = {};
124164 } // namespace __fn
125165
@@ -131,9 +171,18 @@ namespace ztd {
131171 using unwrap_t = decltype (::ztd::unwrap(::std::declval<_Type>()));
132172
133173 // ////
134- // / @brief Retrives the unwrapped type if the object were put through a call to ztd::unwrap .
174+ // / @brief Retrives the unwrapped type if the object were put through a call to ztd::unwrap_iterator_value .
135175 // /
136- // / @remarks Typically used to get the type underlying a `std::reference_wrapper` or similar.
176+ // / @remarks Typically used to get the type underlying an iterator whose value may be wrapped up in certain
177+ // / abstractions.
178+ template <typename _Type>
179+ using unwrap_iterator_value_t = decltype (::ztd::unwrap_iterator_value(::std::declval<_Type>()));
180+
181+ // ////
182+ // / @brief Retrives the unwrapped type if the object were put through a call to ztd::unwrap_iterator.
183+ // /
184+ // / @remarks Typically used to peel off various layers of implementation-defiend and other boilerplate around
185+ // / iterator types.
137186 template <typename _Type>
138187 using unwrap_iterator_t = decltype (::ztd::unwrap_iterator(::std::declval<_Type>()));
139188
0 commit comments