[dawn/common] Use C++20 concepts
Also removed the useless declaration of <type_traits> in many files.
Bug: 343500108
Change-Id: I0da8f77721b2d822a3722c02ab399aae94a7a71c
Skip-Clang-Tidy-Checks: google-explicit-constructor
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/246594
Reviewed-by: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn/common/Math.h b/src/dawn/common/Math.h
index 1673703..fbb2d7a 100644
--- a/src/dawn/common/Math.h
+++ b/src/dawn/common/Math.h
@@ -35,7 +35,6 @@
#include <limits>
#include <optional>
-#include <type_traits>
#include "dawn/common/Assert.h"
#include "dawn/common/Platform.h"
@@ -142,9 +141,8 @@
float SRGBToLinear(float srgb);
-template <typename T1,
- typename T2,
- typename Enable = typename std::enable_if<sizeof(T1) == sizeof(T2)>::type>
+template <typename T1, typename T2>
+ requires(sizeof(T1) == sizeof(T2))
constexpr bool IsSubset(T1 subset, T2 set) {
T2 bitsAlsoInSet = subset & set;
return bitsAlsoInSet == subset;
diff --git a/src/dawn/common/Numeric.h b/src/dawn/common/Numeric.h
index 4488136..c90014c 100644
--- a/src/dawn/common/Numeric.h
+++ b/src/dawn/common/Numeric.h
@@ -28,9 +28,9 @@
#ifndef SRC_DAWN_COMMON_NUMERIC_H_
#define SRC_DAWN_COMMON_NUMERIC_H_
+#include <concepts>
#include <cstdint>
#include <limits>
-#include <type_traits>
#include "dawn/common/Assert.h"
@@ -59,7 +59,8 @@
// Only defined for unsigned integers because that is all that is
// needed at the time of writing.
-template <typename Dst, typename Src, typename = std::enable_if_t<std::is_unsigned_v<Src>>>
+template <typename Dst, typename Src>
+ requires std::unsigned_integral<Src>
inline Dst checked_cast(const Src& value) {
DAWN_ASSERT(value <= std::numeric_limits<Dst>::max());
return static_cast<Dst>(value);
@@ -67,18 +68,15 @@
// Returns if two inclusive integral ranges [x0, x1] and [y0, y1] have overlap.
template <typename T>
+ requires std::integral<T>
bool RangesOverlap(T x0, T x1, T y0, T y1) {
DAWN_ASSERT(x0 <= x1 && y0 <= y1);
- if constexpr (std::is_integral_v<T>) {
// Two ranges DON'T have overlap if and only if:
// 1. [x0, x1] [y0, y1], or
// 2. [y0, y1] [x0, x1]
// which is (x1 < y0 || y1 < x0)
// The inverse of which ends in the following statement.
return x0 <= y1 && y0 <= x1;
- } else {
- static_assert(std::is_integral_v<T>, "Unsupported type");
- }
}
} // namespace dawn
diff --git a/src/dawn/common/Range.h b/src/dawn/common/Range.h
index f4fd777..7326602 100644
--- a/src/dawn/common/Range.h
+++ b/src/dawn/common/Range.h
@@ -28,9 +28,6 @@
#ifndef SRC_DAWN_COMMON_RANGE_H_
#define SRC_DAWN_COMMON_RANGE_H_
-#include <type_traits>
-#include <utility>
-
namespace dawn {
// An iterator over a range of numbers. Simplified version of Python's range() iterator that works
diff --git a/src/dawn/common/RefBase.h b/src/dawn/common/RefBase.h
index e341006..74ff361 100644
--- a/src/dawn/common/RefBase.h
+++ b/src/dawn/common/RefBase.h
@@ -28,8 +28,8 @@
#ifndef SRC_DAWN_COMMON_REFBASE_H_
#define SRC_DAWN_COMMON_REFBASE_H_
+#include <concepts>
#include <cstddef>
-#include <type_traits>
#include <utility>
#include "dawn/common/Assert.h"
@@ -95,23 +95,27 @@
// Constructors from a RefBase<U>. Note that in the *-assignment operators this cannot be the
// same as `other` because overload resolution rules would have chosen the *-assignement
// operators defined with `other` == RefBase<T, Traits>.
- template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
+ template <typename U, typename UTraits>
+ requires std::convertible_to<U, T>
RefBase(const RefBase<U, UTraits>& other) : mValue(other.mValue) {
AddRef(other.mValue);
}
- template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
+ template <typename U, typename UTraits>
+ requires std::convertible_to<U, T>
RefBase<T, Traits>& operator=(const RefBase<U, UTraits>& other) {
Set(other.mValue);
return *this;
}
- template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
+ template <typename U, typename UTraits>
+ requires std::convertible_to<U, T>
RefBase(RefBase<U, UTraits>&& other) {
mValue = other.Detach();
}
- template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
+ template <typename U, typename UTraits>
+ requires std::convertible_to<U, T>
RefBase<T, Traits>& operator=(RefBase<U, UTraits>&& other) {
Release(mValue);
mValue = other.Detach();
@@ -165,7 +169,8 @@
template <typename U, typename UTraits>
friend class RefBase;
- template <typename U, typename UTraits, typename = typename std::is_convertible<U, T>::type>
+ template <typename U, typename UTraits>
+ requires std::convertible_to<U, T>
static void CastImpl(RefBase<T, Traits>* ref, RefBase<U, UTraits>* other) {
other->Acquire(static_cast<U>(ref->Detach()));
}
diff --git a/src/dawn/common/RefCounted.h b/src/dawn/common/RefCounted.h
index cf062d2..419a592 100644
--- a/src/dawn/common/RefCounted.h
+++ b/src/dawn/common/RefCounted.h
@@ -30,7 +30,6 @@
#include <atomic>
#include <cstdint>
-#include <type_traits>
namespace dawn {
diff --git a/src/dawn/common/Result.h b/src/dawn/common/Result.h
index 8000a0f..b2e6359 100644
--- a/src/dawn/common/Result.h
+++ b/src/dawn/common/Result.h
@@ -28,10 +28,10 @@
#ifndef SRC_DAWN_COMMON_RESULT_H_
#define SRC_DAWN_COMMON_RESULT_H_
+#include <concepts>
#include <cstddef>
#include <cstdint>
#include <memory>
-#include <type_traits>
#include <utility>
#include <variant>
@@ -137,8 +137,10 @@
// Support returning a Result<T*, E*> from a Result<TChild*, E*>
template <typename TChild>
+ requires std::same_as<TChild, T> || std::derived_from<TChild, T>
Result(Result<TChild*, E>&& other);
template <typename TChild>
+ requires std::same_as<TChild, T> || std::derived_from<TChild, T>
Result<T*, E>& operator=(Result<TChild*, E>&& other);
~Result();
@@ -194,14 +196,18 @@
"Result<Ref<T>, E> reserves two bits for tagging pointers");
template <typename U>
+ requires std::convertible_to<U*, T*>
Result(Ref<U>&& success);
template <typename U>
+ requires std::convertible_to<U*, T*>
Result(const Ref<U>& success);
Result(std::unique_ptr<E> error);
template <typename U>
+ requires std::convertible_to<U*, T*>
Result(Result<Ref<U>, E>&& other);
template <typename U>
+ requires std::convertible_to<U*, T*>
Result<Ref<U>, E>& operator=(Result<Ref<U>, E>&& other);
~Result();
@@ -310,16 +316,16 @@
template <typename T, typename E>
template <typename TChild>
+ requires std::same_as<TChild, T> || std::derived_from<TChild, T>
Result<T*, E>::Result(Result<TChild*, E>&& other) : mPayload(other.mPayload) {
other.mPayload = detail::kEmptyPayload;
- static_assert(std::is_same<T, TChild>::value || std::is_base_of<T, TChild>::value);
}
template <typename T, typename E>
template <typename TChild>
+ requires std::same_as<TChild, T> || std::derived_from<TChild, T>
Result<T*, E>& Result<T*, E>::operator=(Result<TChild*, E>&& other) {
DAWN_ASSERT(mPayload == detail::kEmptyPayload);
- static_assert(std::is_same<T, TChild>::value || std::is_base_of<T, TChild>::value);
mPayload = other.mPayload;
other.mPayload = detail::kEmptyPayload;
return *this;
@@ -408,13 +414,13 @@
// Implementation of Result<Ref<T>, E>
template <typename T, typename E>
template <typename U>
+ requires std::convertible_to<U*, T*>
Result<Ref<T>, E>::Result(Ref<U>&& success)
- : mPayload(detail::MakePayload(success.Detach(), detail::Success)) {
- static_assert(std::is_convertible<U*, T*>::value);
-}
+ : mPayload(detail::MakePayload(success.Detach(), detail::Success)) {}
template <typename T, typename E>
template <typename U>
+ requires std::convertible_to<U*, T*>
Result<Ref<T>, E>::Result(const Ref<U>& success) : Result(Ref<U>(success)) {}
template <typename T, typename E>
@@ -423,15 +429,15 @@
template <typename T, typename E>
template <typename U>
+ requires std::convertible_to<U*, T*>
Result<Ref<T>, E>::Result(Result<Ref<U>, E>&& other) : mPayload(other.mPayload) {
- static_assert(std::is_convertible<U*, T*>::value);
other.mPayload = detail::kEmptyPayload;
}
template <typename T, typename E>
template <typename U>
+ requires std::convertible_to<U*, T*>
Result<Ref<U>, E>& Result<Ref<T>, E>::operator=(Result<Ref<U>, E>&& other) {
- static_assert(std::is_convertible<U*, T*>::value);
DAWN_ASSERT(mPayload == detail::kEmptyPayload);
mPayload = other.mPayload;
other.mPayload = detail::kEmptyPayload;
diff --git a/src/dawn/common/ityp_array.h b/src/dawn/common/ityp_array.h
index 546050b..54a569c 100644
--- a/src/dawn/common/ityp_array.h
+++ b/src/dawn/common/ityp_array.h
@@ -31,7 +31,6 @@
#include <array>
#include <cstddef>
#include <limits>
-#include <type_traits>
#include <utility>
#include "dawn/common/TypedInteger.h"
diff --git a/src/dawn/common/ityp_span.h b/src/dawn/common/ityp_span.h
index e6b364f..fe345f3 100644
--- a/src/dawn/common/ityp_span.h
+++ b/src/dawn/common/ityp_span.h
@@ -28,8 +28,6 @@
#ifndef SRC_DAWN_COMMON_ITYP_SPAN_H_
#define SRC_DAWN_COMMON_ITYP_SPAN_H_
-#include <type_traits>
-
#include "dawn/common/TypedInteger.h"
#include "dawn/common/UnderlyingType.h"
diff --git a/src/dawn/common/ityp_vector.h b/src/dawn/common/ityp_vector.h
index e7aee9b..83c21ac 100644
--- a/src/dawn/common/ityp_vector.h
+++ b/src/dawn/common/ityp_vector.h
@@ -29,7 +29,6 @@
#define SRC_DAWN_COMMON_ITYP_VECTOR_H_
#include <limits>
-#include <type_traits>
#include <vector>
#include "dawn/common/TypedInteger.h"