Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove absl::result_of_t in C++20 #705

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions absl/container/btree_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
#include <type_traits>
#include <utility>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/container/btree_map.h"
Expand All @@ -38,6 +36,8 @@
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/compare.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

ABSL_FLAG(int, test_values, 10000, "The number of values to use for tests");

Expand Down Expand Up @@ -1249,21 +1249,35 @@ void AssertKeyCompareToAdapted() {
using Adapted = typename key_compare_to_adapter<Compare>::type;
static_assert(!std::is_same<Adapted, Compare>::value,
"key_compare_to_adapter should have adapted this comparator.");
#if !defined(__cpp_lib_is_invocable)
static_assert(
std::is_same<absl::weak_ordering,
absl::result_of_t<Adapted(const K &, const K &)>>::value,
"Adapted comparator should be a key-compare-to comparator.");
#else
static_assert(
std::is_same<absl::weak_ordering,
absl::invoke_result_t<Adapted, const K &, const K &>>::value,
"Adapted comparator should be a key-compare-to comparator.");
#endif
}
template <typename Compare, typename K>
void AssertKeyCompareToNotAdapted() {
using Unadapted = typename key_compare_to_adapter<Compare>::type;
static_assert(
std::is_same<Unadapted, Compare>::value,
"key_compare_to_adapter shouldn't have adapted this comparator.");
#if !defined(__cpp_lib_is_invocable)
static_assert(
std::is_same<bool,
absl::result_of_t<Unadapted(const K &, const K &)>>::value,
"Un-adapted comparator should return bool.");
#else
static_assert(
std::is_same<
bool, absl::invoke_result_t<Unadapted, const K &, const K &>>::value,
"Un-adapted comparator should return bool.");
#endif
}

TEST(Btree, KeyCompareToAdapter) {
Expand Down
19 changes: 15 additions & 4 deletions absl/container/internal/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,17 @@ namespace container_internal {

// A helper class that indicates if the Compare parameter is a key-compare-to
// comparator.
#if !defined(__cpp_lib_is_invocable)
template <typename Compare, typename T>
using btree_is_key_compare_to =
std::is_convertible<absl::result_of_t<Compare(const T &, const T &)>,
absl::weak_ordering>;
#else
template <typename Compare, typename T>
using btree_is_key_compare_to =
std::is_convertible<absl::invoke_result_t<Compare, const T &, const T &>,
absl::weak_ordering>;
#endif

struct StringBtreeDefaultLess {
using is_transparent = void;
Expand Down Expand Up @@ -425,10 +432,9 @@ class btree_node {
// - Otherwise, choose binary.
// TODO(ezb): Might make sense to add condition(s) based on node-size.
using use_linear_search = std::integral_constant<
bool,
std::is_arithmetic<key_type>::value &&
(std::is_same<std::less<key_type>, key_compare>::value ||
std::is_same<std::greater<key_type>, key_compare>::value)>;
bool, std::is_arithmetic<key_type>::value &&
(std::is_same<std::less<key_type>, key_compare>::value ||
std::is_same<std::greater<key_type>, key_compare>::value)>;

// This class is organized by gtl::Layout as if it had the following
// structure:
Expand Down Expand Up @@ -1829,8 +1835,13 @@ constexpr bool btree<P>::static_assert_validation() {
"target node size too large");

// Verify that key_compare returns an absl::{weak,strong}_ordering or bool.
#if !defined(__cpp_lib_is_invocable)
using compare_result_type =
absl::result_of_t<key_compare(key_type, key_type)>;
#else
using compare_result_type =
absl::invoke_result_t<key_compare, key_type, key_type>;
#endif
static_assert(
std::is_same<compare_result_type, bool>::value ||
std::is_convertible<compare_result_type, absl::weak_ordering>::value,
Expand Down
21 changes: 14 additions & 7 deletions absl/meta/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#define ABSL_META_TYPE_TRAITS_H_

#include <stddef.h>

#include <functional>
#include <type_traits>

Expand Down Expand Up @@ -244,8 +245,8 @@ template <typename... Ts>
struct disjunction;

template <typename T, typename... Ts>
struct disjunction<T, Ts...> :
std::conditional<T::value, T, disjunction<Ts...>>::type {};
struct disjunction<T, Ts...>
: std::conditional<T::value, T, disjunction<Ts...>>::type {};

template <typename T>
struct disjunction<T> : T {};
Expand Down Expand Up @@ -297,7 +298,7 @@ struct is_function
template <typename T>
struct is_trivially_destructible
: std::integral_constant<bool, __has_trivial_destructor(T) &&
std::is_destructible<T>::value> {
std::is_destructible<T>::value> {
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
private:
static constexpr bool compliant = std::is_trivially_destructible<T>::value ==
Expand Down Expand Up @@ -345,9 +346,10 @@ struct is_trivially_destructible
// Nontrivially destructible types will cause the expression to be nontrivial.
template <typename T>
struct is_trivially_default_constructible
: std::integral_constant<bool, __has_trivial_constructor(T) &&
std::is_default_constructible<T>::value &&
is_trivially_destructible<T>::value> {
: std::integral_constant<bool,
__has_trivial_constructor(T) &&
std::is_default_constructible<T>::value &&
is_trivially_destructible<T>::value> {
#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
!defined( \
ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
Expand Down Expand Up @@ -616,8 +618,13 @@ using common_type_t = typename std::common_type<T...>::type;
template <typename T>
using underlying_type_t = typename std::underlying_type<T>::type;

#if !defined(__cpp_lib_is_invocable)
template <typename T>
using result_of_t = typename std::result_of<T>::type;
#else
template <typename T, typename... Ts>
using invoke_result_t = typename std::invoke_result<T, Ts...>::type;
#endif

namespace type_traits_internal {
// In MSVC we can't probe std::hash or stdext::hash because it triggers a
Expand Down Expand Up @@ -749,8 +756,8 @@ namespace type_traits_internal {
// Make the swap-related traits/function accessible from this namespace.
using swap_internal::IsNothrowSwappable;
using swap_internal::IsSwappable;
using swap_internal::Swap;
using swap_internal::StdSwapIsUnconstrained;
using swap_internal::Swap;

} // namespace type_traits_internal
ABSL_NAMESPACE_END
Expand Down
39 changes: 30 additions & 9 deletions absl/meta/type_traits_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ TEST(TypeTraitsTest, TestIsFunction) {
EXPECT_TRUE(absl::is_function<void() noexcept>::value);
EXPECT_TRUE(absl::is_function<void(...) noexcept>::value);

EXPECT_FALSE(absl::is_function<void(*)()>::value);
EXPECT_FALSE(absl::is_function<void(&)()>::value);
EXPECT_FALSE(absl::is_function<void (*)()>::value);
EXPECT_FALSE(absl::is_function<void (&)()>::value);
EXPECT_FALSE(absl::is_function<int>::value);
EXPECT_FALSE(absl::is_function<Callable>::value);
}
Expand Down Expand Up @@ -431,10 +431,10 @@ TEST(TypeTraitsTest, TestTrivialDestructor) {

// Verify that simple_pairs of types without trivial destructors
// are not marked as trivial.
EXPECT_FALSE((absl::is_trivially_destructible<
simple_pair<int, std::string>>::value));
EXPECT_FALSE((absl::is_trivially_destructible<
simple_pair<std::string, int>>::value));
EXPECT_FALSE(
(absl::is_trivially_destructible<simple_pair<int, std::string>>::value));
EXPECT_FALSE(
(absl::is_trivially_destructible<simple_pair<std::string, int>>::value));

// array of such types is trivial
using int10 = int[10];
Expand Down Expand Up @@ -1126,7 +1126,7 @@ TEST(TypeTraitsTest, TestDecay) {
ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[][1]);

ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int());
ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float)); // NOLINT
ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float)); // NOLINT
ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...)); // NOLINT
}

Expand Down Expand Up @@ -1192,6 +1192,8 @@ TEST(TypeTraitsTest, TestUnderlyingType) {
ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_long_long);
}

#if !defined(__cpp_lib_is_invocable)

struct GetTypeExtT {
template <typename T>
absl::result_of_t<const GetTypeT&(T)> operator()(T&& arg) const {
Expand All @@ -1208,6 +1210,26 @@ TEST(TypeTraitsTest, TestResultOf) {
EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap<TypeD>()));
}

#else

struct GetTypeExtT {
template <typename T>
absl::invoke_result_t<const GetTypeT&, T> operator()(T&& arg) const {
return GetType(std::forward<T>(arg));
}

TypeEnum operator()(Wrap<TypeD>) const { return TypeEnum::D; }
} constexpr GetTypeExt = {};

TEST(TypeTraitsTest, TestInvokeResult) {
EXPECT_EQ(TypeEnum::A, GetTypeExt(Wrap<TypeA>()));
EXPECT_EQ(TypeEnum::B, GetTypeExt(Wrap<TypeB>()));
EXPECT_EQ(TypeEnum::C, GetTypeExt(Wrap<TypeC>()));
EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap<TypeD>()));
}

#endif

template <typename T>
bool TestCopyAssign() {
return absl::is_copy_assignable<T>::value ==
Expand Down Expand Up @@ -1286,8 +1308,7 @@ TEST(TypeTraitsTest, IsMoveAssignable) {

namespace adl_namespace {

struct DeletedSwap {
};
struct DeletedSwap {};

void swap(DeletedSwap&, DeletedSwap&) = delete;

Expand Down
17 changes: 16 additions & 1 deletion absl/types/compare.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,21 +569,36 @@ constexpr absl::weak_ordering compare_result_as_ordering(
const absl::weak_ordering c) {
return c;
}

#if !defined(__cpp_lib_is_invocable)
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>
#else
template <
typename Compare, typename K, typename LK,
absl::enable_if_t<!std::is_same<bool, absl::invoke_result_t<Compare,
const K &, const LK &>>::value,
int> = 0>
#endif
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));
}
#if !defined(__cpp_lib_is_invocable)
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>
#else
template <
typename Compare, typename K, typename LK,
absl::enable_if_t<std::is_same<bool, absl::invoke_result_t<Compare,
const K &, const LK &>>::value,
int> = 0>
#endif
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
Expand Down
Loading