15#ifndef RANGES_V3_ITERATOR_ACCESS_HPP
16#define RANGES_V3_ITERATOR_ACCESS_HPP
22#include <std/detail/associated_types.hpp>
31#include <range/v3/utility/static_const.hpp>
34#include <range/v3/detail/prologue.hpp>
45#ifdef RANGES_WORKAROUND_MSVC_683388
47 std::is_pointer<uncvref_t<I>>::value &&
48 std::is_array<std::remove_pointer_t<uncvref_t<I>>>::value,
49 std::add_lvalue_reference_t<std::remove_pointer_t<uncvref_t<I>>>,
50 decltype(*std::declval<I &>())>,
52 typename R =
decltype(*std::declval<I &>()),
55 using iter_reference_t_ = R;
57#if defined(RANGES_DEEP_STL_INTEGRATION) && RANGES_DEEP_STL_INTEGRATION && \
58 !defined(RANGES_DOXYGEN_INVOKED)
62 is_std_iterator_traits_specialized_v<T>,
63 std::iterator_traits<T>,
64 indirectly_readable_traits<T>>::value_type;
67 using iter_value_t_ =
typename indirectly_readable_traits<T>::value_type;
73 using iter_reference_t = detail::iter_reference_t_<R>;
76 using iter_value_t = detail::iter_value_t_<uncvref_t<R>>;
81#if RANGES_BROKEN_CPO_LOOKUP
86 decltype(iter_move(std::declval<T>())) try_adl_iter_move_(
int);
89 void try_adl_iter_move_(
long);
92 RANGES_INLINE_VAR
constexpr bool is_adl_indirectly_movable_v =
93 !RANGES_IS_SAME(
void,
decltype(_iter_move_::try_adl_iter_move_<T>(42)));
99 typename = detail::enable_if_t<is_adl_indirectly_movable_v<I &>>>
100#ifndef RANGES_WORKAROUND_CLANG_23135
103 auto CPP_auto_fun(
operator())(I &&i)(
const)
110 typename = detail::enable_if_t<!is_adl_indirectly_movable_v<I &>>,
111 typename R = iter_reference_t<I>>
112#ifndef RANGES_WORKAROUND_CLANG_23135
115 auto CPP_auto_fun(
operator())(I &&i)(
const)
117 return static_cast<aux::move_t<R>
>(aux::move(*i))
124 RANGES_DEFINE_CPO(_iter_move_::fn, iter_move)
129 template<
typename I,
typename O>
130 auto is_indirectly_movable_(I & (*i)(), O & (*o)(), iter_value_t<I> * v =
nullptr)
131 -> always_<std::true_type,
132 decltype(iter_value_t<I>(iter_move(i()))),
133 decltype(*v = iter_move(i())),
134 decltype(*o() = (iter_value_t<I> &&) * v),
135 decltype(*o() = iter_move(i()))>;
136 template<
typename I,
typename O>
137 auto is_indirectly_movable_(...) -> std::false_type;
139 template<
typename I,
typename O>
140 auto is_nothrow_indirectly_movable_(iter_value_t<I> * v) ->
meta::bool_<
141 noexcept(iter_value_t<I>(iter_move(std::declval<I &>()))) &&
142 noexcept(*v = iter_move(std::declval<I &>())) &&
143 noexcept(*std::declval<O &>() = (iter_value_t<I> &&) * v) &&
144 noexcept(*std::declval<O &>() = iter_move(std::declval<I &>()))>;
145 template<
typename I,
typename O>
146 auto is_nothrow_indirectly_movable_(...) -> std::false_type;
150 template<
typename I,
typename O>
151 RANGES_INLINE_VAR
constexpr bool is_indirectly_movable_v =
152 decltype(detail::is_indirectly_movable_<I, O>(
nullptr,
nullptr))::value;
154 template<
typename I,
typename O>
155 RANGES_INLINE_VAR
constexpr bool is_nothrow_indirectly_movable_v =
156 decltype(detail::is_nothrow_indirectly_movable_<I, O>(
nullptr))::value;
158 template<
typename I,
typename O>
162 template<
typename I,
typename O>
164 :
meta::bool_<is_nothrow_indirectly_movable_v<I, O>>
168 namespace _iter_swap_
191 template<
typename T,
typename U>
192 nope iter_swap(T, U) =
delete;
194#ifdef RANGES_WORKAROUND_MSVC_895622
198 template<
typename T,
typename U>
199 decltype(iter_swap(std::declval<T>(), std::declval<U>())) try_adl_iter_swap_(
int);
201 template<
typename T,
typename U>
202 nope try_adl_iter_swap_(
long);
208 template<
typename T,
typename U>
209 RANGES_INLINE_VAR
constexpr bool is_adl_indirectly_swappable_v =
210 !RANGES_IS_SAME(nope,
decltype(_iter_swap_::try_adl_iter_swap_<T, U>(42)));
215 template<
typename T,
typename U>
216 constexpr detail::enable_if_t<is_adl_indirectly_swappable_v<T, U>> operator()(
217 T && t, U && u)
const noexcept(
noexcept(iter_swap((T &&) t, (U &&) u)))
219 (void)iter_swap((T &&) t, (U &&) u);
224 template<
typename I0,
typename I1>
225 constexpr detail::enable_if_t<
226 !is_adl_indirectly_swappable_v<I0, I1> &&
227 is_swappable_with<iter_reference_t<I0>, iter_reference_t<I1>>::value>
228 operator()(I0 && a, I1 && b)
const noexcept(
noexcept(ranges::swap(*a, *b)))
230 ranges::swap(*a, *b);
238 template<
typename I0,
typename I1>
239 constexpr detail::enable_if_t<
240 !is_adl_indirectly_swappable_v<I0, I1> &&
241 !is_swappable_with<iter_reference_t<I0>, iter_reference_t<I1>>::value &&
242 is_indirectly_movable_v<I0, I1> && is_indirectly_movable_v<I1, I0>>
243 operator()(I0 && a, I1 && b)
const
244 noexcept(is_nothrow_indirectly_movable_v<I0, I1> &&
245 is_nothrow_indirectly_movable_v<I1, I0>)
247 iter_value_t<I0> v0 = iter_move(a);
249 *b = detail::move(v0);
256 RANGES_DEFINE_CPO(_iter_swap_::fn, iter_swap)
261 template<
typename T,
typename U>
262 auto is_indirectly_swappable_(T & (*t)(), U & (*u)())
263 -> detail::always_<std::true_type,
decltype(iter_swap(t(), u()))>;
264 template<
typename T,
typename U>
265 auto is_indirectly_swappable_(...) -> std::false_type;
267 template<
typename T,
typename U>
268 auto is_nothrow_indirectly_swappable_(
int)
270 template<
typename T,
typename U>
271 auto is_nothrow_indirectly_swappable_(
long) -> std::false_type;
275 template<
typename T,
typename U>
276 RANGES_INLINE_VAR
constexpr bool is_indirectly_swappable_v =
277 decltype(detail::is_indirectly_swappable_<T, U>(
nullptr,
nullptr))::value;
279 template<
typename T,
typename U>
280 RANGES_INLINE_VAR
constexpr bool is_nothrow_indirectly_swappable_v =
281 decltype(detail::is_nothrow_indirectly_swappable_<T, U>(0))::value;
283 template<
typename T,
typename U>
287 template<
typename T,
typename U>
289 :
meta::bool_<is_nothrow_indirectly_swappable_v<T, U>>
294 using ranges::iter_move;
295 using ranges::iter_reference_t;
296 using ranges::iter_swap;
297 using ranges::iter_value_t;
302#include <range/v3/detail/epilogue.hpp>
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1148
Definition access.hpp:160
Definition access.hpp:285
Definition access.hpp:165
Definition access.hpp:290