|
|
@@ -108,7 +108,11 @@ public:
|
|
|
}
|
|
|
|
|
|
friend bool operator==(self_type const & left, self_type const & right) {
|
|
|
- return left.equal_to(right);
|
|
|
+ if constexpr (has_sentinel<self_type>) {
|
|
|
+ return (left.at_end() && right.at_end()) || left.equal_to(right);
|
|
|
+ } else {
|
|
|
+ return left.equal_to(right);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
friend auto operator<=>(self_type const & left, self_type const & right)
|
|
|
@@ -125,10 +129,6 @@ protected:
|
|
|
};
|
|
|
}
|
|
|
|
|
|
-// In C++20, a concept/requires could be used to eschew the need for the below
|
|
|
-// macros.
|
|
|
-#define MAKE_ITERATOR_FACADE_TYPEDEFS_T(Iter)
|
|
|
-
|
|
|
template <typename It>
|
|
|
requires std::is_base_of_v<iterator::facade<It>, It>
|
|
|
struct std::iterator_traits<It> {
|
|
|
@@ -145,40 +145,4 @@ struct std::iterator_traits<It> {
|
|
|
forward_iterator_tag>>>;
|
|
|
};
|
|
|
|
|
|
-// template <typename It> requires(std::derived_from<It, iterator::facade<It,
|
|
|
-// iterator::category::single_pass>>) struct std::iterator_traits<It> {
|
|
|
-// using reference = decltype(std::declval<It>().operator*());
|
|
|
-// using value_type = std::decay_t<reference>;
|
|
|
-// using pointer = decltype(std::declval<It>().operator->());
|
|
|
-// using difference_type = ::iterator::infer_difference_type_t<It>;
|
|
|
-// using iterator_category = std::input_iterator_tag;
|
|
|
-// };
|
|
|
-//
|
|
|
-// template <typename It> requires(std::derived_from<It, iterator::facade<It,
|
|
|
-// iterator::category::forward>>) struct std::iterator_traits<It> {
|
|
|
-// using reference = decltype(std::declval<It>().operator*());
|
|
|
-// using value_type = std::decay_t<reference>;
|
|
|
-// using pointer = decltype(std::declval<It>().operator->());
|
|
|
-// using difference_type = ::iterator::infer_difference_type_t<It>;
|
|
|
-// using iterator_category = std::forward_iterator_tag;
|
|
|
-// };
|
|
|
-//
|
|
|
-// template <typename It> requires(std::derived_from<It, iterator::facade<It,
|
|
|
-// iterator::category::bidirectional>>) struct std::iterator_traits<It> {
|
|
|
-// using reference = decltype(std::declval<It>().operator*());
|
|
|
-// using value_type = std::decay_t<reference>;
|
|
|
-// using pointer = decltype(std::declval<It>().operator->());
|
|
|
-// using difference_type = ::iterator::infer_difference_type_t<It>;
|
|
|
-// using iterator_category = std::bidirectional_iterator_tag;
|
|
|
-// };
|
|
|
-//
|
|
|
-// template <typename It> requires(std::derived_from<It, iterator::facade<It,
|
|
|
-// iterator::category::random_access>>) struct std::iterator_traits<It> {
|
|
|
-// using reference = decltype(std::declval<It>().operator*());
|
|
|
-// using value_type = std::decay_t<reference>;
|
|
|
-// using pointer = decltype(std::declval<It>().operator->());
|
|
|
-// using difference_type = ::iterator::infer_difference_type_t<It>;
|
|
|
-// using iterator_category = std::random_access_iterator_tag;
|
|
|
-// };
|
|
|
-
|
|
|
#include <iterator/detail/undef.h>
|