-- 9fa04b5fb4b6aeb47226b9095b3bc36a53669c39 by Abseil Team <absl-team@google.com>: Release types/compare.h, which contains stand ins for three-way comparison result types from C++20. Use absl::weak_ordering for a three-way comparator in test-instance-tracker.h. PiperOrigin-RevId: 247290078 -- 70a762f4eb35ea1d5a5fcb3274a8086824a0b82c by Derek Mauro <dmauro@google.com>: Upgrade linux_clang-latest builds to LLVM r356814 and Bazel 0.25.0 PiperOrigin-RevId: 247250176 -- f305cd5c36561e4dbb69eb87568553ae5badcb15 by CJ Johnson <johnsoncj@google.com>: Remove argument deduction based on template template argument in InlinedVector/Storage PiperOrigin-RevId: 247232334 -- 2cab8e426838baceb7d08edb313416480d26aa5b by Eric Fiselier <ericwf@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 247140132 GitOrigin-RevId: 9fa04b5fb4b6aeb47226b9095b3bc36a53669c39 Change-Id: I373a7d9bc90befa2a9f06555cb8703610c0313b9pull/302/head
parent
aa468ad755
commit
27c2f6e2f3
18 changed files with 982 additions and 14 deletions
@ -0,0 +1,506 @@ |
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// compare.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header file defines the `absl::weak_equality`, `absl::strong_equality`,
|
||||
// `absl::partial_ordering`, `absl::weak_ordering`, and `absl::strong_ordering`
|
||||
// types for storing the results of three way comparisons.
|
||||
//
|
||||
// Example:
|
||||
// absl::weak_ordering compare(const std::string& a, const std::string& b);
|
||||
//
|
||||
// These are C++11 compatible versions of the C++20 corresponding types
|
||||
// (`std::weak_equality`, etc.) and are designed to be drop-in replacements
|
||||
// for code compliant with C++20.
|
||||
|
||||
#ifndef ABSL_TYPES_COMPARE_H_ |
||||
#define ABSL_TYPES_COMPARE_H_ |
||||
|
||||
#include <cstddef> |
||||
#include <cstdint> |
||||
#include <cstdlib> |
||||
#include <type_traits> |
||||
|
||||
#include "absl/base/attributes.h" |
||||
#include "absl/meta/type_traits.h" |
||||
|
||||
namespace absl { |
||||
namespace compare_internal { |
||||
|
||||
using value_type = int8_t; |
||||
|
||||
template <typename T> |
||||
struct Fail { |
||||
static_assert(sizeof(T) < 0, "Only literal `0` is allowed."); |
||||
}; |
||||
|
||||
// We need the NullPtrT template to avoid triggering the modernize-use-nullptr
|
||||
// ClangTidy warning in user code.
|
||||
template <typename NullPtrT = std::nullptr_t> |
||||
struct OnlyLiteralZero { |
||||
constexpr OnlyLiteralZero(NullPtrT) noexcept {} // NOLINT
|
||||
|
||||
// Fails compilation when `nullptr` or integral type arguments other than
|
||||
// `int` are passed. This constructor doesn't accept `int` because literal `0`
|
||||
// has type `int`. Literal `0` arguments will be implicitly converted to
|
||||
// `std::nullptr_t` and accepted by the above constructor, while other `int`
|
||||
// arguments will fail to be converted and cause compilation failure.
|
||||
template < |
||||
typename T, |
||||
typename = typename std::enable_if< |
||||
std::is_same<T, std::nullptr_t>::value || |
||||
(std::is_integral<T>::value && !std::is_same<T, int>::value)>::type, |
||||
typename = typename Fail<T>::type> |
||||
OnlyLiteralZero(T); // NOLINT
|
||||
}; |
||||
|
||||
enum class eq : value_type { |
||||
equal = 0, |
||||
equivalent = equal, |
||||
nonequal = 1, |
||||
nonequivalent = nonequal, |
||||
}; |
||||
|
||||
enum class ord : value_type { less = -1, greater = 1 }; |
||||
|
||||
enum class ncmp : value_type { unordered = -127 }; |
||||
|
||||
// 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; |
||||
}; |
||||
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; |
||||
}; |
||||
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; |
||||
}; |
||||
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; |
||||
}; |
||||
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; |
||||
}; |
||||
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
|
||||
|
||||
class weak_equality |
||||
: public compare_internal::weak_equality_base<weak_equality> { |
||||
explicit constexpr weak_equality(compare_internal::eq v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
friend struct compare_internal::weak_equality_base<weak_equality>; |
||||
|
||||
public: |
||||
// Comparisons
|
||||
friend constexpr bool operator==( |
||||
weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ == 0; |
||||
} |
||||
friend constexpr bool operator!=( |
||||
weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ != 0; |
||||
} |
||||
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, |
||||
weak_equality v) noexcept { |
||||
return 0 == v.value_; |
||||
} |
||||
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, |
||||
weak_equality v) noexcept { |
||||
return 0 != v.value_; |
||||
} |
||||
|
||||
private: |
||||
compare_internal::value_type value_; |
||||
}; |
||||
|
||||
class strong_equality |
||||
: public compare_internal::strong_equality_base<strong_equality> { |
||||
explicit constexpr strong_equality(compare_internal::eq v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
friend struct compare_internal::strong_equality_base<strong_equality>; |
||||
|
||||
public: |
||||
// Conversion
|
||||
constexpr operator weak_equality() const noexcept { // NOLINT
|
||||
return value_ == 0 ? weak_equality::equivalent |
||||
: weak_equality::nonequivalent; |
||||
} |
||||
// Comparisons
|
||||
friend constexpr bool operator==( |
||||
strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ == 0; |
||||
} |
||||
friend constexpr bool operator!=( |
||||
strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ != 0; |
||||
} |
||||
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, |
||||
strong_equality v) noexcept { |
||||
return 0 == v.value_; |
||||
} |
||||
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, |
||||
strong_equality v) noexcept { |
||||
return 0 != v.value_; |
||||
} |
||||
|
||||
private: |
||||
compare_internal::value_type value_; |
||||
}; |
||||
|
||||
class partial_ordering |
||||
: public compare_internal::partial_ordering_base<partial_ordering> { |
||||
explicit constexpr partial_ordering(compare_internal::eq v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
explicit constexpr partial_ordering(compare_internal::ord v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
explicit constexpr partial_ordering(compare_internal::ncmp v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
friend struct compare_internal::partial_ordering_base<partial_ordering>; |
||||
|
||||
constexpr bool is_ordered() const noexcept { |
||||
return value_ != |
||||
compare_internal::value_type(compare_internal::ncmp::unordered); |
||||
} |
||||
|
||||
public: |
||||
// Conversion
|
||||
constexpr operator weak_equality() const noexcept { // NOLINT
|
||||
return value_ == 0 ? weak_equality::equivalent |
||||
: weak_equality::nonequivalent; |
||||
} |
||||
// Comparisons
|
||||
friend constexpr bool operator==( |
||||
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.is_ordered() && v.value_ == 0; |
||||
} |
||||
friend constexpr bool operator!=( |
||||
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return !v.is_ordered() || v.value_ != 0; |
||||
} |
||||
friend constexpr bool operator<( |
||||
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.is_ordered() && v.value_ < 0; |
||||
} |
||||
friend constexpr bool operator<=( |
||||
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.is_ordered() && v.value_ <= 0; |
||||
} |
||||
friend constexpr bool operator>( |
||||
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.is_ordered() && v.value_ > 0; |
||||
} |
||||
friend constexpr bool operator>=( |
||||
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.is_ordered() && v.value_ >= 0; |
||||
} |
||||
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, |
||||
partial_ordering v) noexcept { |
||||
return v.is_ordered() && 0 == v.value_; |
||||
} |
||||
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, |
||||
partial_ordering v) noexcept { |
||||
return !v.is_ordered() || 0 != v.value_; |
||||
} |
||||
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, |
||||
partial_ordering v) noexcept { |
||||
return v.is_ordered() && 0 < v.value_; |
||||
} |
||||
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, |
||||
partial_ordering v) noexcept { |
||||
return v.is_ordered() && 0 <= v.value_; |
||||
} |
||||
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, |
||||
partial_ordering v) noexcept { |
||||
return v.is_ordered() && 0 > v.value_; |
||||
} |
||||
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, |
||||
partial_ordering v) noexcept { |
||||
return v.is_ordered() && 0 >= v.value_; |
||||
} |
||||
|
||||
private: |
||||
compare_internal::value_type value_; |
||||
}; |
||||
|
||||
class weak_ordering |
||||
: public compare_internal::weak_ordering_base<weak_ordering> { |
||||
explicit constexpr weak_ordering(compare_internal::eq v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
explicit constexpr weak_ordering(compare_internal::ord v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
friend struct compare_internal::weak_ordering_base<weak_ordering>; |
||||
|
||||
public: |
||||
// Conversions
|
||||
constexpr operator weak_equality() const noexcept { // NOLINT
|
||||
return value_ == 0 ? weak_equality::equivalent |
||||
: weak_equality::nonequivalent; |
||||
} |
||||
constexpr operator partial_ordering() const noexcept { // NOLINT
|
||||
return value_ == 0 ? partial_ordering::equivalent |
||||
: (value_ < 0 ? partial_ordering::less |
||||
: partial_ordering::greater); |
||||
} |
||||
// Comparisons
|
||||
friend constexpr bool operator==( |
||||
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ == 0; |
||||
} |
||||
friend constexpr bool operator!=( |
||||
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ != 0; |
||||
} |
||||
friend constexpr bool operator<( |
||||
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ < 0; |
||||
} |
||||
friend constexpr bool operator<=( |
||||
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ <= 0; |
||||
} |
||||
friend constexpr bool operator>( |
||||
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ > 0; |
||||
} |
||||
friend constexpr bool operator>=( |
||||
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ >= 0; |
||||
} |
||||
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, |
||||
weak_ordering v) noexcept { |
||||
return 0 == v.value_; |
||||
} |
||||
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, |
||||
weak_ordering v) noexcept { |
||||
return 0 != v.value_; |
||||
} |
||||
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, |
||||
weak_ordering v) noexcept { |
||||
return 0 < v.value_; |
||||
} |
||||
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, |
||||
weak_ordering v) noexcept { |
||||
return 0 <= v.value_; |
||||
} |
||||
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, |
||||
weak_ordering v) noexcept { |
||||
return 0 > v.value_; |
||||
} |
||||
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, |
||||
weak_ordering v) noexcept { |
||||
return 0 >= v.value_; |
||||
} |
||||
|
||||
private: |
||||
compare_internal::value_type value_; |
||||
}; |
||||
|
||||
class strong_ordering |
||||
: public compare_internal::strong_ordering_base<strong_ordering> { |
||||
explicit constexpr strong_ordering(compare_internal::eq v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
explicit constexpr strong_ordering(compare_internal::ord v) noexcept |
||||
: value_(static_cast<compare_internal::value_type>(v)) {} |
||||
friend struct compare_internal::strong_ordering_base<strong_ordering>; |
||||
|
||||
public: |
||||
// Conversions
|
||||
constexpr operator weak_equality() const noexcept { // NOLINT
|
||||
return value_ == 0 ? weak_equality::equivalent |
||||
: weak_equality::nonequivalent; |
||||
} |
||||
constexpr operator strong_equality() const noexcept { // NOLINT
|
||||
return value_ == 0 ? strong_equality::equal : strong_equality::nonequal; |
||||
} |
||||
constexpr operator partial_ordering() const noexcept { // NOLINT
|
||||
return value_ == 0 ? partial_ordering::equivalent |
||||
: (value_ < 0 ? partial_ordering::less |
||||
: partial_ordering::greater); |
||||
} |
||||
constexpr operator weak_ordering() const noexcept { // NOLINT
|
||||
return value_ == 0 |
||||
? weak_ordering::equivalent |
||||
: (value_ < 0 ? weak_ordering::less : weak_ordering::greater); |
||||
} |
||||
// Comparisons
|
||||
friend constexpr bool operator==( |
||||
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ == 0; |
||||
} |
||||
friend constexpr bool operator!=( |
||||
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ != 0; |
||||
} |
||||
friend constexpr bool operator<( |
||||
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ < 0; |
||||
} |
||||
friend constexpr bool operator<=( |
||||
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ <= 0; |
||||
} |
||||
friend constexpr bool operator>( |
||||
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ > 0; |
||||
} |
||||
friend constexpr bool operator>=( |
||||
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { |
||||
return v.value_ >= 0; |
||||
} |
||||
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, |
||||
strong_ordering v) noexcept { |
||||
return 0 == v.value_; |
||||
} |
||||
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, |
||||
strong_ordering v) noexcept { |
||||
return 0 != v.value_; |
||||
} |
||||
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, |
||||
strong_ordering v) noexcept { |
||||
return 0 < v.value_; |
||||
} |
||||
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, |
||||
strong_ordering v) noexcept { |
||||
return 0 <= v.value_; |
||||
} |
||||
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, |
||||
strong_ordering v) noexcept { |
||||
return 0 > v.value_; |
||||
} |
||||
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, |
||||
strong_ordering v) noexcept { |
||||
return 0 >= v.value_; |
||||
} |
||||
|
||||
private: |
||||
compare_internal::value_type value_; |
||||
}; |
||||
|
||||
namespace compare_internal { |
||||
// We also provide these comparator adapter functions for internal absl use.
|
||||
|
||||
// Helper functions to do a boolean comparison of two keys given a boolean
|
||||
// or three-way comparator.
|
||||
constexpr bool compare_result_as_less_than(const bool r) { return r; } |
||||
constexpr bool compare_result_as_less_than(const int r) { return r < 0; } |
||||
constexpr bool compare_result_as_less_than(const absl::weak_ordering r) { |
||||
return r < 0; |
||||
} |
||||
|
||||
template <typename Compare, typename K, typename LK> |
||||
constexpr bool do_less_than_comparison(const Compare &compare, const K &x, |
||||
const LK &y) { |
||||
return compare_result_as_less_than(compare(x, y)); |
||||
} |
||||
|
||||
// Helper functions to do a three-way comparison of two keys given a boolean or
|
||||
// three-way comparator.
|
||||
// SFINAE prevents implicit conversions to int (such as from bool).
|
||||
template <typename Int, |
||||
absl::enable_if_t<std::is_same<int, Int>::value, int> = 0> |
||||
constexpr absl::weak_ordering compare_result_as_ordering(const Int c) { |
||||
return c < 0 ? absl::weak_ordering::less |
||||
: c == 0 ? absl::weak_ordering::equivalent |
||||
: absl::weak_ordering::greater; |
||||
} |
||||
constexpr absl::weak_ordering compare_result_as_ordering( |
||||
const absl::weak_ordering c) { |
||||
return c; |
||||
} |
||||
|
||||
template < |
||||
typename Compare, typename K, typename LK, |
||||
absl::enable_if_t<!std::is_same<bool, absl::result_of_t<Compare( |
||||
const K &, const LK &)>>::value, |
||||
int> = 0> |
||||
constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, |
||||
const K &x, const LK &y) { |
||||
return compare_result_as_ordering(compare(x, y)); |
||||
} |
||||
template < |
||||
typename Compare, typename K, typename LK, |
||||
absl::enable_if_t<std::is_same<bool, absl::result_of_t<Compare( |
||||
const K &, const LK &)>>::value, |
||||
int> = 0> |
||||
constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, |
||||
const K &x, const LK &y) { |
||||
return compare(x, y) ? absl::weak_ordering::less |
||||
: compare(y, x) ? absl::weak_ordering::greater |
||||
: absl::weak_ordering::equivalent; |
||||
} |
||||
|
||||
} // namespace compare_internal
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_TYPES_COMPARE_H_
|
@ -0,0 +1,315 @@ |
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/types/compare.h" |
||||
|
||||
#include "gtest/gtest.h" |
||||
#include "absl/base/casts.h" |
||||
|
||||
namespace absl { |
||||
namespace { |
||||
|
||||
// This is necessary to avoid a bunch of lint warnings suggesting that we use
|
||||
// EXPECT_EQ/etc., which doesn't work in this case because they convert the `0`
|
||||
// to an int, which can't be converted to the unspecified zero type.
|
||||
bool Identity(bool b) { return b; } |
||||
|
||||
TEST(Compare, WeakEquality) { |
||||
EXPECT_TRUE(Identity(weak_equality::equivalent == 0)); |
||||
EXPECT_TRUE(Identity(0 == weak_equality::equivalent)); |
||||
EXPECT_TRUE(Identity(weak_equality::nonequivalent != 0)); |
||||
EXPECT_TRUE(Identity(0 != weak_equality::nonequivalent)); |
||||
} |
||||
|
||||
TEST(Compare, StrongEquality) { |
||||
EXPECT_TRUE(Identity(strong_equality::equal == 0)); |
||||
EXPECT_TRUE(Identity(0 == strong_equality::equal)); |
||||
EXPECT_TRUE(Identity(strong_equality::nonequal != 0)); |
||||
EXPECT_TRUE(Identity(0 != strong_equality::nonequal)); |
||||
EXPECT_TRUE(Identity(strong_equality::equivalent == 0)); |
||||
EXPECT_TRUE(Identity(0 == strong_equality::equivalent)); |
||||
EXPECT_TRUE(Identity(strong_equality::nonequivalent != 0)); |
||||
EXPECT_TRUE(Identity(0 != strong_equality::nonequivalent)); |
||||
} |
||||
|
||||
TEST(Compare, PartialOrdering) { |
||||
EXPECT_TRUE(Identity(partial_ordering::less < 0)); |
||||
EXPECT_TRUE(Identity(0 > partial_ordering::less)); |
||||
EXPECT_TRUE(Identity(partial_ordering::less <= 0)); |
||||
EXPECT_TRUE(Identity(0 >= partial_ordering::less)); |
||||
EXPECT_TRUE(Identity(partial_ordering::equivalent == 0)); |
||||
EXPECT_TRUE(Identity(0 == partial_ordering::equivalent)); |
||||
EXPECT_TRUE(Identity(partial_ordering::greater > 0)); |
||||
EXPECT_TRUE(Identity(0 < partial_ordering::greater)); |
||||
EXPECT_TRUE(Identity(partial_ordering::greater >= 0)); |
||||
EXPECT_TRUE(Identity(0 <= partial_ordering::greater)); |
||||
EXPECT_TRUE(Identity(partial_ordering::unordered != 0)); |
||||
EXPECT_TRUE(Identity(0 != partial_ordering::unordered)); |
||||
EXPECT_FALSE(Identity(partial_ordering::unordered < 0)); |
||||
EXPECT_FALSE(Identity(0 < partial_ordering::unordered)); |
||||
EXPECT_FALSE(Identity(partial_ordering::unordered <= 0)); |
||||
EXPECT_FALSE(Identity(0 <= partial_ordering::unordered)); |
||||
EXPECT_FALSE(Identity(partial_ordering::unordered > 0)); |
||||
EXPECT_FALSE(Identity(0 > partial_ordering::unordered)); |
||||
EXPECT_FALSE(Identity(partial_ordering::unordered >= 0)); |
||||
EXPECT_FALSE(Identity(0 >= partial_ordering::unordered)); |
||||
} |
||||
|
||||
TEST(Compare, WeakOrdering) { |
||||
EXPECT_TRUE(Identity(weak_ordering::less < 0)); |
||||
EXPECT_TRUE(Identity(0 > weak_ordering::less)); |
||||
EXPECT_TRUE(Identity(weak_ordering::less <= 0)); |
||||
EXPECT_TRUE(Identity(0 >= weak_ordering::less)); |
||||
EXPECT_TRUE(Identity(weak_ordering::equivalent == 0)); |
||||
EXPECT_TRUE(Identity(0 == weak_ordering::equivalent)); |
||||
EXPECT_TRUE(Identity(weak_ordering::greater > 0)); |
||||
EXPECT_TRUE(Identity(0 < weak_ordering::greater)); |
||||
EXPECT_TRUE(Identity(weak_ordering::greater >= 0)); |
||||
EXPECT_TRUE(Identity(0 <= weak_ordering::greater)); |
||||
} |
||||
|
||||
TEST(Compare, StrongOrdering) { |
||||
EXPECT_TRUE(Identity(strong_ordering::less < 0)); |
||||
EXPECT_TRUE(Identity(0 > strong_ordering::less)); |
||||
EXPECT_TRUE(Identity(strong_ordering::less <= 0)); |
||||
EXPECT_TRUE(Identity(0 >= strong_ordering::less)); |
||||
EXPECT_TRUE(Identity(strong_ordering::equal == 0)); |
||||
EXPECT_TRUE(Identity(0 == strong_ordering::equal)); |
||||
EXPECT_TRUE(Identity(strong_ordering::equivalent == 0)); |
||||
EXPECT_TRUE(Identity(0 == strong_ordering::equivalent)); |
||||
EXPECT_TRUE(Identity(strong_ordering::greater > 0)); |
||||
EXPECT_TRUE(Identity(0 < strong_ordering::greater)); |
||||
EXPECT_TRUE(Identity(strong_ordering::greater >= 0)); |
||||
EXPECT_TRUE(Identity(0 <= strong_ordering::greater)); |
||||
} |
||||
|
||||
TEST(Compare, Conversions) { |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(strong_equality::equal) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(strong_equality::nonequal) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(strong_equality::equivalent) == 0)); |
||||
EXPECT_TRUE(Identity( |
||||
implicit_cast<weak_equality>(strong_equality::nonequivalent) != 0)); |
||||
|
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(partial_ordering::less) != 0)); |
||||
EXPECT_TRUE(Identity( |
||||
implicit_cast<weak_equality>(partial_ordering::equivalent) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(partial_ordering::greater) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(partial_ordering::unordered) != 0)); |
||||
|
||||
EXPECT_TRUE(implicit_cast<weak_equality>(weak_ordering::less) != 0); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(weak_ordering::equivalent) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(weak_ordering::greater) != 0)); |
||||
|
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(weak_ordering::less) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(weak_ordering::less) < 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(weak_ordering::less) <= 0)); |
||||
EXPECT_TRUE(Identity( |
||||
implicit_cast<partial_ordering>(weak_ordering::equivalent) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(weak_ordering::greater) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(weak_ordering::greater) > 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(weak_ordering::greater) >= 0)); |
||||
|
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(strong_ordering::less) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(strong_ordering::equal) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(strong_ordering::equivalent) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_equality>(strong_ordering::greater) != 0)); |
||||
|
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<strong_equality>(strong_ordering::less) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<strong_equality>(strong_ordering::equal) == 0)); |
||||
EXPECT_TRUE(Identity( |
||||
implicit_cast<strong_equality>(strong_ordering::equivalent) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<strong_equality>(strong_ordering::greater) != 0)); |
||||
|
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(strong_ordering::less) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(strong_ordering::less) < 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(strong_ordering::less) <= 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(strong_ordering::equal) == 0)); |
||||
EXPECT_TRUE(Identity( |
||||
implicit_cast<partial_ordering>(strong_ordering::equivalent) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(strong_ordering::greater) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(strong_ordering::greater) > 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<partial_ordering>(strong_ordering::greater) >= 0)); |
||||
|
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::less) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::less) < 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::less) <= 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::equal) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::equivalent) == 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::greater) != 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::greater) > 0)); |
||||
EXPECT_TRUE( |
||||
Identity(implicit_cast<weak_ordering>(strong_ordering::greater) >= 0)); |
||||
} |
||||
|
||||
struct WeakOrderingLess { |
||||
template <typename T> |
||||
absl::weak_ordering operator()(const T &a, const T &b) const { |
||||
return a < b ? absl::weak_ordering::less |
||||
: a == b ? absl::weak_ordering::equivalent |
||||
: absl::weak_ordering::greater; |
||||
} |
||||
}; |
||||
|
||||
TEST(CompareResultAsLessThan, SanityTest) { |
||||
EXPECT_FALSE(absl::compare_internal::compare_result_as_less_than(false)); |
||||
EXPECT_TRUE(absl::compare_internal::compare_result_as_less_than(true)); |
||||
|
||||
EXPECT_TRUE(absl::compare_internal::compare_result_as_less_than(-1)); |
||||
EXPECT_FALSE(absl::compare_internal::compare_result_as_less_than(0)); |
||||
EXPECT_FALSE(absl::compare_internal::compare_result_as_less_than(1)); |
||||
|
||||
EXPECT_TRUE( |
||||
absl::compare_internal::compare_result_as_less_than(weak_ordering::less)); |
||||
EXPECT_FALSE(absl::compare_internal::compare_result_as_less_than( |
||||
weak_ordering::equivalent)); |
||||
EXPECT_FALSE(absl::compare_internal::compare_result_as_less_than( |
||||
weak_ordering::greater)); |
||||
} |
||||
|
||||
TEST(DoLessThanComparison, SanityTest) { |
||||
std::less<int> less; |
||||
WeakOrderingLess weak; |
||||
|
||||
EXPECT_TRUE(absl::compare_internal::do_less_than_comparison(less, -1, 0)); |
||||
EXPECT_TRUE(absl::compare_internal::do_less_than_comparison(weak, -1, 0)); |
||||
|
||||
EXPECT_FALSE(absl::compare_internal::do_less_than_comparison(less, 10, 10)); |
||||
EXPECT_FALSE(absl::compare_internal::do_less_than_comparison(weak, 10, 10)); |
||||
|
||||
EXPECT_FALSE(absl::compare_internal::do_less_than_comparison(less, 10, 5)); |
||||
EXPECT_FALSE(absl::compare_internal::do_less_than_comparison(weak, 10, 5)); |
||||
} |
||||
|
||||
TEST(CompareResultAsOrdering, SanityTest) { |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(-1) < 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(-1) == 0)); |
||||
EXPECT_FALSE( |
||||
Identity(absl::compare_internal::compare_result_as_ordering(-1) > 0)); |
||||
EXPECT_TRUE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::less) < 0)); |
||||
EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::less) == 0)); |
||||
EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::less) > 0)); |
||||
|
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(0) < 0)); |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(0) == 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(0) > 0)); |
||||
EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::equivalent) < 0)); |
||||
EXPECT_TRUE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::equivalent) == 0)); |
||||
EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::equivalent) > 0)); |
||||
|
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(1) < 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(1) == 0)); |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::compare_result_as_ordering(1) > 0)); |
||||
EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::greater) < 0)); |
||||
EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::greater) == 0)); |
||||
EXPECT_TRUE(Identity(absl::compare_internal::compare_result_as_ordering( |
||||
weak_ordering::greater) > 0)); |
||||
} |
||||
|
||||
TEST(DoThreeWayComparison, SanityTest) { |
||||
std::less<int> less; |
||||
WeakOrderingLess weak; |
||||
|
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, -1, 0) < 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, -1, 0) == 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, -1, 0) > 0)); |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, -1, 0) < 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, -1, 0) == 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, -1, 0) > 0)); |
||||
|
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, 10, 10) < 0)); |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, 10, 10) == 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, 10, 10) > 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, 10, 10) < 0)); |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, 10, 10) == 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, 10, 10) > 0)); |
||||
|
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, 10, 5) < 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, 10, 5) == 0)); |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(less, 10, 5) > 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, 10, 5) < 0)); |
||||
EXPECT_FALSE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, 10, 5) == 0)); |
||||
EXPECT_TRUE(Identity( |
||||
absl::compare_internal::do_three_way_comparison(weak, 10, 5) > 0)); |
||||
} |
||||
|
||||
} // namespace
|
||||
} // namespace absl
|
Loading…
Reference in new issue