mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
Make Span's relational operators constexpr since C++20.
_The implementation has not changed, only constexpr markers have been added._ PiperOrigin-RevId: 695435063 Change-Id: I66cd03195e429534c0e58c330f1019c89025abed
This commit is contained in:
committed by
Copybara-Service
parent
feb6aab8db
commit
8d272b2871
@@ -22,6 +22,7 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/algorithm/algorithm.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/throw_delegate.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
|
||||
@@ -86,13 +87,13 @@ using EnableIfMutable =
|
||||
typename std::enable_if<!std::is_const<T>::value, int>::type;
|
||||
|
||||
template <template <typename> class SpanT, typename T>
|
||||
bool EqualImpl(SpanT<T> a, SpanT<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool EqualImpl(SpanT<T> a, SpanT<T> b) {
|
||||
static_assert(std::is_const<T>::value, "");
|
||||
return std::equal(a.begin(), a.end(), b.begin(), b.end());
|
||||
}
|
||||
|
||||
template <template <typename> class SpanT, typename T>
|
||||
bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
|
||||
// We can't use value_type since that is remove_cv_t<T>, so we go the long way
|
||||
// around.
|
||||
static_assert(std::is_const<T>::value, "");
|
||||
|
||||
@@ -522,157 +522,165 @@ const typename Span<T>::size_type Span<T>::npos;
|
||||
|
||||
// operator==
|
||||
template <typename T>
|
||||
bool operator==(Span<T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a, Span<T> b) {
|
||||
return span_internal::EqualImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator==(Span<const T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<const T> a,
|
||||
Span<T> b) {
|
||||
return span_internal::EqualImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator==(Span<T> a, Span<const T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a,
|
||||
Span<const T> b) {
|
||||
return span_internal::EqualImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator==(const U& a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(const U& a, Span<T> b) {
|
||||
return span_internal::EqualImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator==(Span<T> a, const U& b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a, const U& b) {
|
||||
return span_internal::EqualImpl<Span, const T>(a, b);
|
||||
}
|
||||
|
||||
// operator!=
|
||||
template <typename T>
|
||||
bool operator!=(Span<T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a, Span<T> b) {
|
||||
return !(a == b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator!=(Span<const T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<const T> a,
|
||||
Span<T> b) {
|
||||
return !(a == b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator!=(Span<T> a, Span<const T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a,
|
||||
Span<const T> b) {
|
||||
return !(a == b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator!=(const U& a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(const U& a, Span<T> b) {
|
||||
return !(a == b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator!=(Span<T> a, const U& b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a, const U& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
// operator<
|
||||
template <typename T>
|
||||
bool operator<(Span<T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, Span<T> b) {
|
||||
return span_internal::LessThanImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator<(Span<const T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<const T> a, Span<T> b) {
|
||||
return span_internal::LessThanImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator<(Span<T> a, Span<const T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, Span<const T> b) {
|
||||
return span_internal::LessThanImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator<(const U& a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(const U& a, Span<T> b) {
|
||||
return span_internal::LessThanImpl<Span, const T>(a, b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator<(Span<T> a, const U& b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, const U& b) {
|
||||
return span_internal::LessThanImpl<Span, const T>(a, b);
|
||||
}
|
||||
|
||||
// operator>
|
||||
template <typename T>
|
||||
bool operator>(Span<T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, Span<T> b) {
|
||||
return b < a;
|
||||
}
|
||||
template <typename T>
|
||||
bool operator>(Span<const T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<const T> a, Span<T> b) {
|
||||
return b < a;
|
||||
}
|
||||
template <typename T>
|
||||
bool operator>(Span<T> a, Span<const T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, Span<const T> b) {
|
||||
return b < a;
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator>(const U& a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(const U& a, Span<T> b) {
|
||||
return b < a;
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator>(Span<T> a, const U& b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, const U& b) {
|
||||
return b < a;
|
||||
}
|
||||
|
||||
// operator<=
|
||||
template <typename T>
|
||||
bool operator<=(Span<T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a, Span<T> b) {
|
||||
return !(b < a);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator<=(Span<const T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<const T> a,
|
||||
Span<T> b) {
|
||||
return !(b < a);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator<=(Span<T> a, Span<const T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a,
|
||||
Span<const T> b) {
|
||||
return !(b < a);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator<=(const U& a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(const U& a, Span<T> b) {
|
||||
return !(b < a);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator<=(Span<T> a, const U& b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a, const U& b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
// operator>=
|
||||
template <typename T>
|
||||
bool operator>=(Span<T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a, Span<T> b) {
|
||||
return !(a < b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator>=(Span<const T> a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<const T> a,
|
||||
Span<T> b) {
|
||||
return !(a < b);
|
||||
}
|
||||
template <typename T>
|
||||
bool operator>=(Span<T> a, Span<const T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a,
|
||||
Span<const T> b) {
|
||||
return !(a < b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator>=(const U& a, Span<T> b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(const U& a, Span<T> b) {
|
||||
return !(a < b);
|
||||
}
|
||||
template <
|
||||
typename T, typename U,
|
||||
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
|
||||
bool operator>=(Span<T> a, const U& b) {
|
||||
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a, const U& b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
|
||||
@@ -787,9 +787,9 @@ TEST(IntSpan, NoexceptTest) {
|
||||
template <int i>
|
||||
struct ConstexprTester {};
|
||||
|
||||
#define ABSL_TEST_CONSTEXPR(expr) \
|
||||
do { \
|
||||
ABSL_ATTRIBUTE_UNUSED ConstexprTester<(expr, 1)> t; \
|
||||
#define ABSL_TEST_CONSTEXPR(expr) \
|
||||
do { \
|
||||
ABSL_ATTRIBUTE_UNUSED ConstexprTester<(static_cast<void>(expr), 1)> t; \
|
||||
} while (0)
|
||||
|
||||
struct ContainerWithConstexprMethods {
|
||||
@@ -826,6 +826,41 @@ TEST(ConstIntSpan, ConstexprTest) {
|
||||
ABSL_TEST_CONSTEXPR(span[0]);
|
||||
}
|
||||
|
||||
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
|
||||
ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
|
||||
|
||||
TEST(ConstIntSpan, ConstexprRelOpsTest) {
|
||||
static constexpr int lhs_data[] = {1, 2, 3};
|
||||
static constexpr int rhs_data[] = {1, 2, 3};
|
||||
|
||||
constexpr absl::Span<const int> lhs = absl::MakeConstSpan(lhs_data, 3);
|
||||
constexpr absl::Span<const int> rhs = absl::MakeConstSpan(rhs_data, 3);
|
||||
|
||||
ABSL_TEST_CONSTEXPR(lhs_data == rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs_data != rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs_data < rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs_data <= rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs_data > rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs_data >= rhs);
|
||||
|
||||
ABSL_TEST_CONSTEXPR(lhs == rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs != rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs < rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs <= rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs > rhs);
|
||||
ABSL_TEST_CONSTEXPR(lhs >= rhs);
|
||||
|
||||
ABSL_TEST_CONSTEXPR(lhs == rhs_data);
|
||||
ABSL_TEST_CONSTEXPR(lhs != rhs_data);
|
||||
ABSL_TEST_CONSTEXPR(lhs < rhs_data);
|
||||
ABSL_TEST_CONSTEXPR(lhs <= rhs_data);
|
||||
ABSL_TEST_CONSTEXPR(lhs > rhs_data);
|
||||
ABSL_TEST_CONSTEXPR(lhs >= rhs_data);
|
||||
}
|
||||
|
||||
#endif // defined(ABSL_INTERNAL_CPLUSPLUS_LANG) &&
|
||||
// ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
|
||||
|
||||
struct BigStruct {
|
||||
char bytes[10000];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user