@@ -39,64 +39,59 @@ namespace internal {
3939struct not_an_iterator {};
4040
4141
42- template <typename R, typename C, typename ... Ts>
43- auto member_function_ret_type (R (C::*)(Ts...)) -> R;
44- template <typename R, typename C, typename ... Ts>
45- auto const_member_function_ret_type (R (C::*)(Ts...) const ) -> R;
46-
47- #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230601L))
42+ #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230528L))
4843template <typename T>
4944auto begin_type (T* t) -> decltype(std::ranges::begin(*t));
5045#else
5146template <typename T>
52- auto begin_type (T*) -> decltype(member_function_ret_type(&T:: begin));
47+ auto begin_type (T* t ) -> decltype(t-> begin ( ));
5348#endif
5449
5550auto begin_type (...) -> not_an_iterator;
5651
57- #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230601L ))
52+ #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230528L ))
5853template <typename T>
5954auto const_begin_type (const T* t) -> decltype(std::ranges::begin(*t));
6055#else
6156template <typename T>
62- auto const_begin_type (const T* t) -> decltype(const_member_function_ret_type(&T:: begin));
57+ auto const_begin_type (const T* t) -> decltype(t-> begin ( ));
6358#endif
6459auto const_begin_type (...) -> not_an_iterator;
6560
66- #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230601L ))
61+ #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230528L ))
6762template <typename T>
6863auto end_type (T* t) -> decltype(std::ranges::end(*t));
6964#else
7065template <typename T>
71- auto end_type (T*) -> decltype(member_function_ret_type(&T:: end));
66+ auto end_type (T* t ) -> decltype(t-> end ( ));
7267#endif
7368auto end_type (...) -> not_an_iterator;
7469
75- #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230601L ))
70+ #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230528L ))
7671template <typename T>
7772auto const_end_type (const T* t) -> decltype(std::ranges::end(*t));
7873#else
7974template <typename T>
80- auto const_end_type (T* ) -> decltype(const_member_function_ret_type(&T:: end));
75+ auto const_end_type (const T* t ) -> decltype(t-> end ( ));
8176#endif
8277
8378auto const_end_type (...) -> not_an_iterator;
8479
85- #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230601L ))
80+ #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230528L ))
8681template <typename T>
8782auto cbegin_type (const T* t) -> decltype(std::ranges::cbegin(*t));
8883#else
8984template <typename T>
90- auto cbegin_type (T* ) -> decltype(const_member_function_ret_type(&T:: cbegin));
85+ auto cbegin_type (const T* t ) -> decltype(t-> cbegin ( ));
9186#endif
9287auto cbegin_type (...) -> not_an_iterator;
9388
94- #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230601L ))
89+ #if defined(STRONG_TYPE_HAS_RANGES) && (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20230528L ))
9590template <typename T>
9691auto cend_type (const T* t) -> decltype(std::ranges::cend(*t));
9792#else
9893template <typename T>
99- auto cend_type (T* ) -> decltype(const_member_function_ret_type(&T:: cend));
94+ auto cend_type (const T* t ) -> decltype(t-> cend ( ));
10095#endif
10196auto cend_type (...) -> not_an_iterator;
10297
@@ -155,16 +150,78 @@ class range::modifier<
155150
156151};
157152
158- template <typename T, typename Tag, typename ... M, typename iterator >
153+ template <typename T, typename Tag, typename ... M, typename r_iterator >
159154class range ::modifier<
160155 type<T, Tag, M...>,
161- iterator, iterator ,
162- iterator, iterator ,
163- iterator, iterator >
156+ r_iterator, r_iterator ,
157+ r_iterator, r_iterator ,
158+ r_iterator, r_iterator >
164159{
165- static_assert (impl::always_false<T>, " the underlying type is lying about its iterator type" );
166- };
160+ using type = ::strong::type<T, Tag, M...>;
161+ static constexpr bool random_access = internal::is_random_access(typename internal::iterator_traits<r_iterator>::iterator_category{});
162+ public:
163+ using const_iterator = std::conditional_t <random_access,
164+ ::strong::type<r_iterator, Tag, strong::iterator, strong::default_constructible, strong::equality_with<r_iterator>, strong::ordered_with<r_iterator>>,
165+ ::strong::type<r_iterator, Tag, strong::iterator, strong::default_constructible, strong::equality_with<r_iterator>>
166+ >;
167167
168+ STRONG_NODISCARD
169+ constexpr
170+ const_iterator
171+ begin ()
172+ const
173+ noexcept (noexcept (STRONG_TYPE_BEGIN(std::declval<const T&>())))
174+ {
175+ auto & self = static_cast <const type&>(*this );
176+ return const_iterator{STRONG_TYPE_BEGIN (value_of (self))};
177+ }
178+
179+ STRONG_NODISCARD
180+ constexpr
181+ const_iterator
182+ end ()
183+ const
184+ noexcept (noexcept (STRONG_TYPE_END(std::declval<const T&>())))
185+ {
186+ auto & self = static_cast <const type&>(*this );
187+ return const_iterator{STRONG_TYPE_END (value_of (self))};
188+ }
189+
190+ STRONG_NODISCARD
191+ constexpr
192+ const_iterator
193+ cbegin ()
194+ const
195+ noexcept (noexcept (STRONG_TYPE_CBEGIN(std::declval<const T&>())))
196+ {
197+ auto & self = static_cast <const type&>(*this );
198+ return const_iterator{STRONG_TYPE_CBEGIN (value_of (self))};
199+ }
200+
201+ STRONG_NODISCARD
202+ constexpr
203+ const_iterator
204+ cend ()
205+ const
206+ noexcept (noexcept (STRONG_TYPE_CEND(std::declval<const T&>())))
207+ {
208+ auto & self = static_cast <const type&>(*this );
209+ return const_iterator{STRONG_TYPE_CEND (value_of (self))};
210+ }
211+
212+ template <typename TT = const T&>
213+ STRONG_NODISCARD
214+ constexpr
215+ decltype (std::declval<TT>().size())
216+ size ()
217+ const
218+ noexcept (noexcept (std::declval<TT>().size()))
219+ {
220+ auto & self = static_cast <const type&>(*this );
221+ return value_of (self).size ();
222+ }
223+
224+ };
168225template <typename T, typename Tag, typename ... M, typename r_iterator, typename r_const_iterator>
169226class range ::modifier<
170227 type<T, Tag, M...>,
0 commit comments