14#ifndef RANGES_V3_STD_DETAIL_ASSOCIATED_TYPES_HPP
15#define RANGES_V3_STD_DETAIL_ASSOCIATED_TYPES_HPP
20#include <range/v3/detail/config.hpp>
22#include <range/v3/detail/prologue.hpp>
36 template<
typename T,
typename...>
39#if defined(_MSC_VER) && !defined(__clang__) && !defined(__EDG__)
43 using std::conditional_t;
45 using std::enable_if_t;
50 template<
typename,
typename U>
56 template<
typename T,
typename>
59 template<
bool B,
typename T,
typename U>
60 using conditional_t =
typename _cond<B>::template invoke<T, U>;
66 struct enable_if<true>
71 template<
bool B,
typename T =
void>
72 using enable_if_t =
typename enable_if<B>::template invoke<T>;
77 void is_objptr_(
void const volatile *);
81 constexpr bool is_object_(
long)
86 constexpr bool is_object_(
int, T * (*q)(T &) =
nullptr, T * p =
nullptr,
87 decltype(detail::is_objptr_(q(*p))) * =
nullptr)
89 return (
void)p, (void)q,
true;
94 constexpr bool is_integral_(...)
98 template<
typename T, T = 1>
99 constexpr bool is_integral_(
long)
103#if defined(__cpp_nontype_template_parameter_class) && \
104 __cpp_nontype_template_parameter_class > 0
106 constexpr bool is_integral_(
int,
int T::* = nullptr)
114 struct with_difference_type_
116 using difference_type = T;
120 using difference_result_t =
121 decltype(std::declval<T const &>() - std::declval<T const &>());
123 template<
typename,
typename =
void>
124 struct incrementable_traits_2_
128 struct incrementable_traits_2_<
130#if defined(_MSC_VER) && !defined(__clang__) && !defined(__EDG__)
131 std::enable_if_t<std::is_integral_v<difference_result_t<T>>>>
132#elif defined(RANGES_WORKAROUND_GCC_91923)
133 std::enable_if_t<std::is_integral<difference_result_t<T>>::value>>
135 always_<void, int[is_integral_<difference_result_t<T>>(0)]>>
138 using difference_type = std::make_signed_t<difference_result_t<T>>;
141 template<
typename T,
typename =
void>
142 struct incrementable_traits_1_ : incrementable_traits_2_<T>
146 struct incrementable_traits_1_<T *>
148 :
conditional_t<__is_object(T), with_difference_type_<std::ptrdiff_t>, nil_>
149#elif defined(_MSC_VER) && !defined(__EDG__)
150 : conditional_t<std::is_object_v<T>, with_difference_type_<std::ptrdiff_t>, nil_>
152 : conditional_t<is_object_<T>(0), with_difference_type_<std::ptrdiff_t>, nil_>
157 struct incrementable_traits_1_<T, always_<void, typename T::difference_type>>
159 using difference_type =
typename T::difference_type;
176 template<
typename T,
bool = __is_
object(T)>
177#elif defined(_MSC_VER) && !defined(__EDG__)
178 template<
typename T,
bool = std::is_
object_v<T>>
180 template<typename T, bool = is_object_<T>(0)>
182 struct with_value_type_
185 struct with_value_type_<T, true>
187 using value_type = T;
190 struct with_value_type_<T const, true>
192 using value_type = T;
195 struct with_value_type_<T volatile, true>
197 using value_type = T;
200 struct with_value_type_<T const volatile, true>
202 using value_type = T;
204 template<
typename,
typename =
void>
205 struct readable_traits_2_
208 struct readable_traits_2_<T, always_<void, typename T::element_type>>
209 : with_value_type_<typename T::element_type>
211 template<
typename T,
typename =
void>
212 struct readable_traits_1_ : readable_traits_2_<T>
215 struct readable_traits_1_<T[]> : with_value_type_<T>
217 template<
typename T, std::
size_t N>
218 struct readable_traits_1_<T[N]> : with_value_type_<T>
221 struct readable_traits_1_<T *> : detail::with_value_type_<T>
224 struct readable_traits_1_<T, always_<void, typename T::value_type>>
225 : with_value_type_<typename T::value_type>
245 template<
typename D = std::ptrdiff_t>
246 struct std_output_iterator_traits
248 using iterator_category = std::output_iterator_tag;
249 using difference_type = D;
250 using value_type = void;
251 using reference = void;
252 using pointer = void;
257#if defined(_MSVC_STL_UPDATE) && defined(__cpp_lib_concepts) && _MSVC_STL_UPDATE >= 201908L
259 inline constexpr bool is_std_iterator_traits_specialized_v =
260 !std::_Is_from_primary<std::iterator_traits<I>>;
262#if defined(__GLIBCXX__)
264 char (&is_std_iterator_traits_specialized_impl_(std::__iterator_traits<I> *))[2];
266 char is_std_iterator_traits_specialized_impl_(
void *);
267#elif defined(_LIBCPP_VERSION)
269 template<
template<
typename,
bool>
class IteratorTraitsBase,
typename I,
bool B>
270 char (&libcpp_iterator_traits_base_impl(IteratorTraitsBase<I, B> *))[2];
271 template<
template<
typename,
bool>
class IteratorTraitsBase,
typename I>
272 char libcpp_iterator_traits_base_impl(
void *);
276 template<
template<
typename>
class,
typename I>
277 char (&libcpp_iterator_traits_base_impl(
typename std::iterator_traits<I>::__primary_template *))[2];
278 template<
template<
typename>
class,
typename I>
279 char libcpp_iterator_traits_base_impl(
void *);
282 auto is_std_iterator_traits_specialized_impl_(std::iterator_traits<I>* traits)
283 ->
decltype(libcpp_iterator_traits_base_impl<std::__iterator_traits, I>(traits));
284#elif defined(_MSVC_STL_VERSION)
286 char (&is_std_iterator_traits_specialized_impl_(
287 std::_Iterator_traits_base<I> *))[2];
289 char is_std_iterator_traits_specialized_impl_(
void *);
292 char (&is_std_iterator_traits_specialized_impl_(
void *))[2];
294 template<
typename,
typename T>
295 char (&is_std_iterator_traits_specialized_impl_(std::iterator_traits<T *> *))[2];
298 RANGES_INLINE_VAR
constexpr bool is_std_iterator_traits_specialized_v =
299 1 ==
sizeof(is_std_iterator_traits_specialized_impl_<I>(
300 static_cast<std::iterator_traits<I> *
>(
nullptr)));
306 RANGES_INLINE_VAR
constexpr bool is_std_iterator_traits_specialized_v<T *> =
312#include <range/v3/detail/epilogue.hpp>
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition meta.hpp:541
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 associated_types.hpp:166
Definition associated_types.hpp:236