Export of internal Abseil changes.
-- 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: I373a7d9bc90befa2a9f06555cb8703610c0313b9
This commit is contained in:
parent
aa468ad755
commit
27c2f6e2f3
18 changed files with 982 additions and 14 deletions
|
@ -213,6 +213,7 @@ cc_library(
|
|||
visibility = [
|
||||
"//absl:__subpackages__",
|
||||
],
|
||||
deps = ["//absl/types:compare"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
|
|
|
@ -204,6 +204,8 @@ absl_cc_library(
|
|||
"internal/test_instance_tracker.cc"
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
DEPS
|
||||
absl::compare
|
||||
TESTONLY
|
||||
)
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class InlinedVector {
|
|||
static_assert(
|
||||
N > 0, "InlinedVector cannot be instantiated with `0` inlined elements.");
|
||||
|
||||
using Storage = inlined_vector_internal::Storage<InlinedVector>;
|
||||
using Storage = inlined_vector_internal::Storage<T, N, A>;
|
||||
using AllocatorTraits = typename Storage::AllocatorTraits;
|
||||
|
||||
template <typename Iterator>
|
||||
|
|
|
@ -31,12 +31,8 @@ using IsAtLeastForwardIterator = std::is_convertible<
|
|||
typename std::iterator_traits<Iterator>::iterator_category,
|
||||
std::forward_iterator_tag>;
|
||||
|
||||
template <typename InlinedVector>
|
||||
class Storage;
|
||||
|
||||
template <template <typename, size_t, typename> class InlinedVector, typename T,
|
||||
size_t N, typename A>
|
||||
class Storage<InlinedVector<T, N, A>> {
|
||||
template <typename T, size_t N, typename A>
|
||||
class Storage {
|
||||
public:
|
||||
using allocator_type = A;
|
||||
using value_type = typename allocator_type::value_type;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
|
||||
#include "absl/types/compare.h"
|
||||
|
||||
namespace absl {
|
||||
namespace test_internal {
|
||||
|
||||
|
@ -96,6 +98,14 @@ class BaseCountedInstance {
|
|||
return value_ >= x.value_;
|
||||
}
|
||||
|
||||
absl::weak_ordering compare(const BaseCountedInstance& x) const {
|
||||
++num_comparisons_;
|
||||
return value_ < x.value_
|
||||
? absl::weak_ordering::less
|
||||
: value_ == x.value_ ? absl::weak_ordering::equivalent
|
||||
: absl::weak_ordering::greater;
|
||||
}
|
||||
|
||||
int value() const {
|
||||
if (!is_live_) std::abort();
|
||||
return value_;
|
||||
|
|
|
@ -174,6 +174,8 @@ TEST(TestInstanceTracker, Comparisons) {
|
|||
EXPECT_EQ(5, tracker.comparisons());
|
||||
EXPECT_FALSE(one >= two);
|
||||
EXPECT_EQ(6, tracker.comparisons());
|
||||
EXPECT_TRUE(one.compare(two) < 0); // NOLINT
|
||||
EXPECT_EQ(7, tracker.comparisons());
|
||||
|
||||
tracker.ResetCopiesMovesSwaps();
|
||||
EXPECT_EQ(0, tracker.comparisons());
|
||||
|
|
|
@ -41,6 +41,7 @@ list(APPEND ABSL_CLANG_CL_FLAGS
|
|||
"-Wno-unreachable-code"
|
||||
"-Wno-unused-macros"
|
||||
"-Wno-weak-vtables"
|
||||
"-Wno-zero-as-null-pointer-constant"
|
||||
"-Wbitfield-enum-conversion"
|
||||
"-Wbool-conversion"
|
||||
"-Wconstant-conversion"
|
||||
|
@ -149,6 +150,7 @@ list(APPEND ABSL_LLVM_FLAGS
|
|||
"-Wno-unreachable-code"
|
||||
"-Wno-unused-macros"
|
||||
"-Wno-weak-vtables"
|
||||
"-Wno-zero-as-null-pointer-constant"
|
||||
"-Wbitfield-enum-conversion"
|
||||
"-Wbool-conversion"
|
||||
"-Wconstant-conversion"
|
||||
|
|
|
@ -42,6 +42,7 @@ ABSL_CLANG_CL_FLAGS = [
|
|||
"-Wno-unreachable-code",
|
||||
"-Wno-unused-macros",
|
||||
"-Wno-weak-vtables",
|
||||
"-Wno-zero-as-null-pointer-constant",
|
||||
"-Wbitfield-enum-conversion",
|
||||
"-Wbool-conversion",
|
||||
"-Wconstant-conversion",
|
||||
|
@ -150,6 +151,7 @@ ABSL_LLVM_FLAGS = [
|
|||
"-Wno-unreachable-code",
|
||||
"-Wno-unused-macros",
|
||||
"-Wno-weak-vtables",
|
||||
"-Wno-zero-as-null-pointer-constant",
|
||||
"-Wbitfield-enum-conversion",
|
||||
"-Wbool-conversion",
|
||||
"-Wconstant-conversion",
|
||||
|
|
|
@ -70,6 +70,8 @@ LLVM_DISABLE_WARNINGS_FLAGS = [
|
|||
# Causes warnings on include guards
|
||||
"-Wno-unused-macros",
|
||||
"-Wno-weak-vtables",
|
||||
# Causes warnings on usage of types/compare.h comparison operators.
|
||||
"-Wno-zero-as-null-pointer-constant",
|
||||
###
|
||||
# Implicit conversion warnings turned off by -Wno-conversion
|
||||
# which are re-enabled below.
|
||||
|
|
|
@ -35,10 +35,10 @@ cc_library(
|
|||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":city",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:endian",
|
||||
"//absl/container:fixed_array",
|
||||
"//absl/hash:city",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/numeric:int128",
|
||||
"//absl/strings",
|
||||
|
|
|
@ -555,13 +555,43 @@ CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept {
|
||||
do { cd += 1; } while (get_weekday(cd) != wd);
|
||||
return cd;
|
||||
CONSTEXPR_D weekday k_weekdays_forw[14] = {
|
||||
weekday::monday, weekday::tuesday, weekday::wednesday,
|
||||
weekday::thursday, weekday::friday, weekday::saturday,
|
||||
weekday::sunday, weekday::monday, weekday::tuesday,
|
||||
weekday::wednesday, weekday::thursday, weekday::friday,
|
||||
weekday::saturday, weekday::sunday,
|
||||
};
|
||||
weekday base = get_weekday(cd);
|
||||
for (int i = 0;; ++i) {
|
||||
if (base == k_weekdays_forw[i]) {
|
||||
for (int j = i + 1;; ++j) {
|
||||
if (wd == k_weekdays_forw[j]) {
|
||||
return cd + (j - i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept {
|
||||
do { cd -= 1; } while (get_weekday(cd) != wd);
|
||||
return cd;
|
||||
CONSTEXPR_D weekday k_weekdays_back[14] = {
|
||||
weekday::sunday, weekday::saturday, weekday::friday,
|
||||
weekday::thursday, weekday::wednesday, weekday::tuesday,
|
||||
weekday::monday, weekday::sunday, weekday::saturday,
|
||||
weekday::friday, weekday::thursday, weekday::wednesday,
|
||||
weekday::tuesday, weekday::monday,
|
||||
};
|
||||
weekday base = get_weekday(cd);
|
||||
for (int i = 0;; ++i) {
|
||||
if (base == k_weekdays_back[i]) {
|
||||
for (int j = i + 1;; ++j) {
|
||||
if (wd == k_weekdays_back[j]) {
|
||||
return cd - (j - i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CONSTEXPR_F int get_yearday(const civil_day& cd) noexcept {
|
||||
|
|
|
@ -47,6 +47,56 @@ void BM_Step_Days(benchmark::State& state) {
|
|||
}
|
||||
BENCHMARK(BM_Step_Days);
|
||||
|
||||
void BM_GetWeekday(benchmark::State& state) {
|
||||
const cctz::civil_day c(2014, 8, 22);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(cctz::get_weekday(c));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_GetWeekday);
|
||||
|
||||
void BM_NextWeekday(benchmark::State& state) {
|
||||
const cctz::civil_day kStart(2014, 8, 22);
|
||||
const cctz::civil_day kDays[7] = {
|
||||
kStart + 0, kStart + 1, kStart + 2, kStart + 3,
|
||||
kStart + 4, kStart + 5, kStart + 6,
|
||||
};
|
||||
const cctz::weekday kWeekdays[7] = {
|
||||
cctz::weekday::monday, cctz::weekday::tuesday, cctz::weekday::wednesday,
|
||||
cctz::weekday::thursday, cctz::weekday::friday, cctz::weekday::saturday,
|
||||
cctz::weekday::sunday,
|
||||
};
|
||||
while (state.KeepRunningBatch(7 * 7)) {
|
||||
for (const auto from : kDays) {
|
||||
for (const auto to : kWeekdays) {
|
||||
benchmark::DoNotOptimize(cctz::next_weekday(from, to));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_NextWeekday);
|
||||
|
||||
void BM_PrevWeekday(benchmark::State& state) {
|
||||
const cctz::civil_day kStart(2014, 8, 22);
|
||||
const cctz::civil_day kDays[7] = {
|
||||
kStart + 0, kStart + 1, kStart + 2, kStart + 3,
|
||||
kStart + 4, kStart + 5, kStart + 6,
|
||||
};
|
||||
const cctz::weekday kWeekdays[7] = {
|
||||
cctz::weekday::monday, cctz::weekday::tuesday, cctz::weekday::wednesday,
|
||||
cctz::weekday::thursday, cctz::weekday::friday, cctz::weekday::saturday,
|
||||
cctz::weekday::sunday,
|
||||
};
|
||||
while (state.KeepRunningBatch(7 * 7)) {
|
||||
for (const auto from : kDays) {
|
||||
for (const auto to : kWeekdays) {
|
||||
benchmark::DoNotOptimize(cctz::prev_weekday(from, to));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_PrevWeekday);
|
||||
|
||||
const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
|
||||
const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
|
||||
|
||||
|
|
|
@ -308,3 +308,27 @@ cc_test(
|
|||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "compare",
|
||||
hdrs = ["compare.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
deps = [
|
||||
"//absl/base:core_headers",
|
||||
"//absl/meta:type_traits",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "compare_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"compare_test.cc",
|
||||
],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
deps = [
|
||||
":compare",
|
||||
"//absl/base",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -299,6 +299,32 @@ absl_cc_test(
|
|||
gmock_main
|
||||
)
|
||||
|
||||
absl_cc_library(
|
||||
NAME
|
||||
compare
|
||||
HDRS
|
||||
"compare.h"
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
DEPS
|
||||
absl::core_headers
|
||||
absl::type_traits
|
||||
PUBLIC
|
||||
)
|
||||
|
||||
absl_cc_test(
|
||||
NAME
|
||||
compare_test
|
||||
SRCS
|
||||
"compare_test.cc"
|
||||
COPTS
|
||||
${ABSL_TEST_COPTS}
|
||||
DEPS
|
||||
absl::base
|
||||
absl::compare
|
||||
gmock_main
|
||||
)
|
||||
|
||||
# TODO(cohenjon,zhangxy) Figure out why this test is failing on gcc 4.8
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
|
||||
else()
|
||||
|
|
506
absl/types/compare.h
Normal file
506
absl/types/compare.h
Normal file
|
@ -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_
|
315
absl/types/compare_test.cc
Normal file
315
absl/types/compare_test.cc
Normal file
|
@ -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
|
|
@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then
|
|||
COMPILATION_MODE="fastbuild opt"
|
||||
fi
|
||||
|
||||
readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190329"
|
||||
readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190508"
|
||||
|
||||
# USE_BAZEL_CACHE=1 only works on Kokoro.
|
||||
# Without access to the credentials this won't work.
|
||||
|
|
|
@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then
|
|||
COMPILATION_MODE="fastbuild opt"
|
||||
fi
|
||||
|
||||
readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190329"
|
||||
readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190508"
|
||||
|
||||
# USE_BAZEL_CACHE=1 only works on Kokoro.
|
||||
# Without access to the credentials this won't work.
|
||||
|
|
Loading…
Reference in a new issue