File indexing completed on 2025-01-18 10:12:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_STD_DETAIL_ASSOCIATED_TYPES_HPP
0015 #define RANGES_V3_STD_DETAIL_ASSOCIATED_TYPES_HPP
0016
0017 #include <climits>
0018 #include <cstdint>
0019
0020 #include <range/v3/detail/config.hpp>
0021
0022 #include <range/v3/detail/prologue.hpp>
0023
0024 namespace ranges
0025 {
0026
0027
0028
0029
0030
0031 namespace detail
0032 {
0033 struct nil_
0034 {};
0035
0036 template<typename T, typename...>
0037 using always_ = T;
0038
0039 #if defined(_MSC_VER) && !defined(__clang__) && !defined(__EDG__)
0040
0041
0042
0043 using std::conditional_t;
0044 using std::enable_if;
0045 using std::enable_if_t;
0046 #else
0047 template<bool>
0048 struct _cond
0049 {
0050 template<typename, typename U>
0051 using invoke = U;
0052 };
0053 template<>
0054 struct _cond<true>
0055 {
0056 template<typename T, typename>
0057 using invoke = T;
0058 };
0059 template<bool B, typename T, typename U>
0060 using conditional_t = typename _cond<B>::template invoke<T, U>;
0061
0062 template<bool>
0063 struct enable_if
0064 {};
0065 template<>
0066 struct enable_if<true>
0067 {
0068 template<typename T>
0069 using invoke = T;
0070 };
0071 template<bool B, typename T = void>
0072 using enable_if_t = typename enable_if<B>::template invoke<T>;
0073
0074 #ifndef __clang__
0075
0076
0077 void is_objptr_(void const volatile *);
0078
0079
0080 template<typename T>
0081 constexpr bool is_object_(long)
0082 {
0083 return false;
0084 }
0085 template<typename T>
0086 constexpr bool is_object_(int, T * (*q)(T &) = nullptr, T * p = nullptr,
0087 decltype(detail::is_objptr_(q(*p))) * = nullptr)
0088 {
0089 return (void)p, (void)q, true;
0090 }
0091 #endif
0092
0093 template<typename T>
0094 constexpr bool is_integral_(...)
0095 {
0096 return false;
0097 }
0098 template<typename T, T = 1>
0099 constexpr bool is_integral_(long)
0100 {
0101 return true;
0102 }
0103 #if defined(__cpp_nontype_template_parameter_class) && \
0104 __cpp_nontype_template_parameter_class > 0
0105 template<typename T>
0106 constexpr bool is_integral_(int, int T::* = nullptr)
0107 {
0108 return false;
0109 }
0110 #endif
0111 #endif
0112
0113 template<typename T>
0114 struct with_difference_type_
0115 {
0116 using difference_type = T;
0117 };
0118
0119 template<typename T>
0120 using difference_result_t =
0121 decltype(std::declval<T const &>() - std::declval<T const &>());
0122
0123 template<typename, typename = void>
0124 struct incrementable_traits_2_
0125 {};
0126
0127 template<typename T>
0128 struct incrementable_traits_2_<
0129 T,
0130 #if defined(_MSC_VER) && !defined(__clang__) && !defined(__EDG__)
0131 std::enable_if_t<std::is_integral_v<difference_result_t<T>>>>
0132 #elif defined(RANGES_WORKAROUND_GCC_91923)
0133 std::enable_if_t<std::is_integral<difference_result_t<T>>::value>>
0134 #else
0135 always_<void, int[is_integral_<difference_result_t<T>>(0)]>>
0136 #endif
0137 {
0138 using difference_type = std::make_signed_t<difference_result_t<T>>;
0139 };
0140
0141 template<typename T, typename = void>
0142 struct incrementable_traits_1_ : incrementable_traits_2_<T>
0143 {};
0144
0145 template<typename T>
0146 struct incrementable_traits_1_<T *>
0147 #ifdef __clang__
0148 : conditional_t<__is_object(T), with_difference_type_<std::ptrdiff_t>, nil_>
0149 #elif defined(_MSC_VER) && !defined(__EDG__)
0150 : conditional_t<std::is_object_v<T>, with_difference_type_<std::ptrdiff_t>, nil_>
0151 #else
0152 : conditional_t<is_object_<T>(0), with_difference_type_<std::ptrdiff_t>, nil_>
0153 #endif
0154 {};
0155
0156 template<typename T>
0157 struct incrementable_traits_1_<T, always_<void, typename T::difference_type>>
0158 {
0159 using difference_type = typename T::difference_type;
0160 };
0161 }
0162
0163
0164 template<typename T>
0165 struct incrementable_traits : detail::incrementable_traits_1_<T>
0166 {};
0167
0168 template<typename T>
0169 struct incrementable_traits<T const> : incrementable_traits<T>
0170 {};
0171
0172
0173 namespace detail
0174 {
0175 #ifdef __clang__
0176 template<typename T, bool = __is_object(T)>
0177 #elif defined(_MSC_VER) && !defined(__EDG__)
0178 template<typename T, bool = std::is_object_v<T>>
0179 #else
0180 template<typename T, bool = is_object_<T>(0)>
0181 #endif
0182 struct with_value_type_
0183 {};
0184 template<typename T>
0185 struct with_value_type_<T, true>
0186 {
0187 using value_type = T;
0188 };
0189 template<typename T>
0190 struct with_value_type_<T const, true>
0191 {
0192 using value_type = T;
0193 };
0194 template<typename T>
0195 struct with_value_type_<T volatile, true>
0196 {
0197 using value_type = T;
0198 };
0199 template<typename T>
0200 struct with_value_type_<T const volatile, true>
0201 {
0202 using value_type = T;
0203 };
0204 template<typename, typename = void>
0205 struct readable_traits_2_
0206 {};
0207 template<typename T>
0208 struct readable_traits_2_<T, always_<void, typename T::element_type>>
0209 : with_value_type_<typename T::element_type>
0210 {};
0211 template<typename T, typename = void>
0212 struct readable_traits_1_ : readable_traits_2_<T>
0213 {};
0214 template<typename T>
0215 struct readable_traits_1_<T[]> : with_value_type_<T>
0216 {};
0217 template<typename T, std::size_t N>
0218 struct readable_traits_1_<T[N]> : with_value_type_<T>
0219 {};
0220 template<typename T>
0221 struct readable_traits_1_<T *> : detail::with_value_type_<T>
0222 {};
0223 template<typename T>
0224 struct readable_traits_1_<T, always_<void, typename T::value_type>>
0225 : with_value_type_<typename T::value_type>
0226 {};
0227 }
0228
0229
0230
0231
0232
0233
0234 template<typename T>
0235 struct indirectly_readable_traits : detail::readable_traits_1_<T>
0236 {};
0237
0238 template<typename T>
0239 struct indirectly_readable_traits<T const> : indirectly_readable_traits<T>
0240 {};
0241
0242
0243 namespace detail
0244 {
0245 template<typename D = std::ptrdiff_t>
0246 struct std_output_iterator_traits
0247 {
0248 using iterator_category = std::output_iterator_tag;
0249 using difference_type = D;
0250 using value_type = void;
0251 using reference = void;
0252 using pointer = void;
0253 };
0254
0255
0256
0257 #if defined(_MSVC_STL_UPDATE) && defined(__cpp_lib_concepts) && _MSVC_STL_UPDATE >= 201908L
0258 template<typename I>
0259 inline constexpr bool is_std_iterator_traits_specialized_v =
0260 !std::_Is_from_primary<std::iterator_traits<I>>;
0261 #else
0262 #if defined(__GLIBCXX__)
0263 template<typename I>
0264 char (&is_std_iterator_traits_specialized_impl_(std::__iterator_traits<I> *))[2];
0265 template<typename I>
0266 char is_std_iterator_traits_specialized_impl_(void *);
0267 #elif defined(_LIBCPP_VERSION)
0268
0269 template<template<typename, bool> class IteratorTraitsBase, typename I, bool B>
0270 char (&libcpp_iterator_traits_base_impl(IteratorTraitsBase<I, B> *))[2];
0271 template<template<typename, bool> class IteratorTraitsBase, typename I>
0272 char libcpp_iterator_traits_base_impl(void *);
0273
0274
0275
0276 template<template<typename> class, typename I>
0277 char (&libcpp_iterator_traits_base_impl(typename std::iterator_traits<I>::__primary_template *))[2];
0278 template<template<typename> class, typename I>
0279 char libcpp_iterator_traits_base_impl(void *);
0280
0281 template<typename I>
0282 auto is_std_iterator_traits_specialized_impl_(std::iterator_traits<I>* traits)
0283 -> decltype(libcpp_iterator_traits_base_impl<std::__iterator_traits, I>(traits));
0284 #elif defined(_MSVC_STL_VERSION)
0285 template<typename I>
0286 char (&is_std_iterator_traits_specialized_impl_(
0287 std::_Iterator_traits_base<I> *))[2];
0288 template<typename I>
0289 char is_std_iterator_traits_specialized_impl_(void *);
0290 #else
0291 template<typename I>
0292 char (&is_std_iterator_traits_specialized_impl_(void *))[2];
0293 #endif
0294 template<typename, typename T>
0295 char (&is_std_iterator_traits_specialized_impl_(std::iterator_traits<T *> *))[2];
0296
0297 template<typename I>
0298 RANGES_INLINE_VAR constexpr bool is_std_iterator_traits_specialized_v =
0299 1 == sizeof(is_std_iterator_traits_specialized_impl_<I>(
0300 static_cast<std::iterator_traits<I> *>(nullptr)));
0301 #endif
0302
0303
0304
0305 template<typename T>
0306 RANGES_INLINE_VAR constexpr bool is_std_iterator_traits_specialized_v<T *> =
0307 false;
0308 }
0309
0310 }
0311
0312 #include <range/v3/detail/epilogue.hpp>
0313
0314 #endif