summaryrefslogtreecommitdiff
path: root/absl/types/compare.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/types/compare.h')
-rw-r--r--absl/types/compare.h194
1 files changed, 141 insertions, 53 deletions
diff --git a/absl/types/compare.h b/absl/types/compare.h
index 6f371be7..62ca70f9 100644
--- a/absl/types/compare.h
+++ b/absl/types/compare.h
@@ -39,7 +39,7 @@
#include "absl/meta/type_traits.h"
namespace absl {
-inline namespace lts_2019_08_08 {
+ABSL_NAMESPACE_BEGIN
namespace compare_internal {
using value_type = int8_t;
@@ -80,79 +80,72 @@ enum class ord : value_type { less = -1, greater = 1 };
enum class ncmp : value_type { unordered = -127 };
+// Define macros to allow for creation or emulation of C++17 inline variables
+// based on whether the feature is supported. Note: we can't use
+// ABSL_INTERNAL_INLINE_CONSTEXPR here because the variables here are of
+// incomplete types so they need to be defined after the types are complete.
+#ifdef __cpp_inline_variables
+
+#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name)
+
+#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) \
+ static const type name
+
+#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
+ inline constexpr type type::name(init)
+
+#else // __cpp_inline_variables
+
+#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \
+ ABSL_CONST_INIT static const T name
+
+#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name)
+
+#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
+ template <typename T> \
+ const T compare_internal::type##_base<T>::name(init)
+
+#endif // __cpp_inline_variables
+
// These template base classes allow for defining the values of the constants
// in the header file (for performance) without using inline variables (which
// aren't available in C++11).
template <typename T>
struct weak_equality_base {
- ABSL_CONST_INIT static const T equivalent;
- ABSL_CONST_INIT static const T nonequivalent;
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequivalent);
};
-template <typename T>
-const T weak_equality_base<T>::equivalent(eq::equivalent);
-template <typename T>
-const T weak_equality_base<T>::nonequivalent(eq::nonequivalent);
template <typename T>
struct strong_equality_base {
- ABSL_CONST_INIT static const T equal;
- ABSL_CONST_INIT static const T nonequal;
- ABSL_CONST_INIT static const T equivalent;
- ABSL_CONST_INIT static const T nonequivalent;
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(equal);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequal);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequivalent);
};
-template <typename T>
-const T strong_equality_base<T>::equal(eq::equal);
-template <typename T>
-const T strong_equality_base<T>::nonequal(eq::nonequal);
-template <typename T>
-const T strong_equality_base<T>::equivalent(eq::equivalent);
-template <typename T>
-const T strong_equality_base<T>::nonequivalent(eq::nonequivalent);
template <typename T>
struct partial_ordering_base {
- ABSL_CONST_INIT static const T less;
- ABSL_CONST_INIT static const T equivalent;
- ABSL_CONST_INIT static const T greater;
- ABSL_CONST_INIT static const T unordered;
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(unordered);
};
-template <typename T>
-const T partial_ordering_base<T>::less(ord::less);
-template <typename T>
-const T partial_ordering_base<T>::equivalent(eq::equivalent);
-template <typename T>
-const T partial_ordering_base<T>::greater(ord::greater);
-template <typename T>
-const T partial_ordering_base<T>::unordered(ncmp::unordered);
template <typename T>
struct weak_ordering_base {
- ABSL_CONST_INIT static const T less;
- ABSL_CONST_INIT static const T equivalent;
- ABSL_CONST_INIT static const T greater;
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
};
-template <typename T>
-const T weak_ordering_base<T>::less(ord::less);
-template <typename T>
-const T weak_ordering_base<T>::equivalent(eq::equivalent);
-template <typename T>
-const T weak_ordering_base<T>::greater(ord::greater);
template <typename T>
struct strong_ordering_base {
- ABSL_CONST_INIT static const T less;
- ABSL_CONST_INIT static const T equal;
- ABSL_CONST_INIT static const T equivalent;
- ABSL_CONST_INIT static const T greater;
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(equal);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
+ ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
};
-template <typename T>
-const T strong_ordering_base<T>::less(ord::less);
-template <typename T>
-const T strong_ordering_base<T>::equal(eq::equal);
-template <typename T>
-const T strong_ordering_base<T>::equivalent(eq::equivalent);
-template <typename T>
-const T strong_ordering_base<T>::greater(ord::greater);
} // namespace compare_internal
@@ -163,6 +156,9 @@ class weak_equality
friend struct compare_internal::weak_equality_base<weak_equality>;
public:
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_equality, equivalent);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_equality, nonequivalent);
+
// Comparisons
friend constexpr bool operator==(
weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
@@ -180,10 +176,22 @@ class weak_equality
weak_equality v) noexcept {
return 0 != v.value_;
}
+ friend constexpr bool operator==(weak_equality v1,
+ weak_equality v2) noexcept {
+ return v1.value_ == v2.value_;
+ }
+ friend constexpr bool operator!=(weak_equality v1,
+ weak_equality v2) noexcept {
+ return v1.value_ != v2.value_;
+ }
private:
compare_internal::value_type value_;
};
+ABSL_COMPARE_INLINE_INIT(weak_equality, equivalent,
+ compare_internal::eq::equivalent);
+ABSL_COMPARE_INLINE_INIT(weak_equality, nonequivalent,
+ compare_internal::eq::nonequivalent);
class strong_equality
: public compare_internal::strong_equality_base<strong_equality> {
@@ -192,6 +200,11 @@ class strong_equality
friend struct compare_internal::strong_equality_base<strong_equality>;
public:
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, equal);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, nonequal);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, equivalent);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, nonequivalent);
+
// Conversion
constexpr operator weak_equality() const noexcept { // NOLINT
return value_ == 0 ? weak_equality::equivalent
@@ -214,10 +227,25 @@ class strong_equality
strong_equality v) noexcept {
return 0 != v.value_;
}
+ friend constexpr bool operator==(strong_equality v1,
+ strong_equality v2) noexcept {
+ return v1.value_ == v2.value_;
+ }
+ friend constexpr bool operator!=(strong_equality v1,
+ strong_equality v2) noexcept {
+ return v1.value_ != v2.value_;
+ }
private:
compare_internal::value_type value_;
};
+ABSL_COMPARE_INLINE_INIT(strong_equality, equal, compare_internal::eq::equal);
+ABSL_COMPARE_INLINE_INIT(strong_equality, nonequal,
+ compare_internal::eq::nonequal);
+ABSL_COMPARE_INLINE_INIT(strong_equality, equivalent,
+ compare_internal::eq::equivalent);
+ABSL_COMPARE_INLINE_INIT(strong_equality, nonequivalent,
+ compare_internal::eq::nonequivalent);
class partial_ordering
: public compare_internal::partial_ordering_base<partial_ordering> {
@@ -235,6 +263,11 @@ class partial_ordering
}
public:
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, less);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, equivalent);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered);
+
// Conversion
constexpr operator weak_equality() const noexcept { // NOLINT
return value_ == 0 ? weak_equality::equivalent
@@ -289,10 +322,25 @@ class partial_ordering
partial_ordering v) noexcept {
return v.is_ordered() && 0 >= v.value_;
}
+ friend constexpr bool operator==(partial_ordering v1,
+ partial_ordering v2) noexcept {
+ return v1.value_ == v2.value_;
+ }
+ friend constexpr bool operator!=(partial_ordering v1,
+ partial_ordering v2) noexcept {
+ return v1.value_ != v2.value_;
+ }
private:
compare_internal::value_type value_;
};
+ABSL_COMPARE_INLINE_INIT(partial_ordering, less, compare_internal::ord::less);
+ABSL_COMPARE_INLINE_INIT(partial_ordering, equivalent,
+ compare_internal::eq::equivalent);
+ABSL_COMPARE_INLINE_INIT(partial_ordering, greater,
+ compare_internal::ord::greater);
+ABSL_COMPARE_INLINE_INIT(partial_ordering, unordered,
+ compare_internal::ncmp::unordered);
class weak_ordering
: public compare_internal::weak_ordering_base<weak_ordering> {
@@ -303,6 +351,10 @@ class weak_ordering
friend struct compare_internal::weak_ordering_base<weak_ordering>;
public:
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, less);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, equivalent);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater);
+
// Conversions
constexpr operator weak_equality() const noexcept { // NOLINT
return value_ == 0 ? weak_equality::equivalent
@@ -362,10 +414,23 @@ class weak_ordering
weak_ordering v) noexcept {
return 0 >= v.value_;
}
+ friend constexpr bool operator==(weak_ordering v1,
+ weak_ordering v2) noexcept {
+ return v1.value_ == v2.value_;
+ }
+ friend constexpr bool operator!=(weak_ordering v1,
+ weak_ordering v2) noexcept {
+ return v1.value_ != v2.value_;
+ }
private:
compare_internal::value_type value_;
};
+ABSL_COMPARE_INLINE_INIT(weak_ordering, less, compare_internal::ord::less);
+ABSL_COMPARE_INLINE_INIT(weak_ordering, equivalent,
+ compare_internal::eq::equivalent);
+ABSL_COMPARE_INLINE_INIT(weak_ordering, greater,
+ compare_internal::ord::greater);
class strong_ordering
: public compare_internal::strong_ordering_base<strong_ordering> {
@@ -376,6 +441,11 @@ class strong_ordering
friend struct compare_internal::strong_ordering_base<strong_ordering>;
public:
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, less);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equal);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equivalent);
+ ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater);
+
// Conversions
constexpr operator weak_equality() const noexcept { // NOLINT
return value_ == 0 ? weak_equality::equivalent
@@ -443,10 +513,28 @@ class strong_ordering
strong_ordering v) noexcept {
return 0 >= v.value_;
}
+ friend constexpr bool operator==(strong_ordering v1,
+ strong_ordering v2) noexcept {
+ return v1.value_ == v2.value_;
+ }
+ friend constexpr bool operator!=(strong_ordering v1,
+ strong_ordering v2) noexcept {
+ return v1.value_ != v2.value_;
+ }
private:
compare_internal::value_type value_;
};
+ABSL_COMPARE_INLINE_INIT(strong_ordering, less, compare_internal::ord::less);
+ABSL_COMPARE_INLINE_INIT(strong_ordering, equal, compare_internal::eq::equal);
+ABSL_COMPARE_INLINE_INIT(strong_ordering, equivalent,
+ compare_internal::eq::equivalent);
+ABSL_COMPARE_INLINE_INIT(strong_ordering, greater,
+ compare_internal::ord::greater);
+
+#undef ABSL_COMPARE_INLINE_BASECLASS_DECL
+#undef ABSL_COMPARE_INLINE_SUBCLASS_DECL
+#undef ABSL_COMPARE_INLINE_INIT
namespace compare_internal {
// We also provide these comparator adapter functions for internal absl use.
@@ -504,7 +592,7 @@ constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare,
}
} // namespace compare_internal
-} // inline namespace lts_2019_08_08
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_TYPES_COMPARE_H_