Move traits into utils.
This CL moves the tint/traits file into tint/utils/traits. Traits is one of the few items not in utils which is referred to by utils. Change-Id: Ie955398f24e949b7618fdc868dbcb903fe20b3f1 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/127400 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
b7285f3c9e
commit
0559005494
|
@ -218,7 +218,6 @@ libtint_source_set("libtint_base_src") {
|
||||||
"symbol.h",
|
"symbol.h",
|
||||||
"symbol_table.cc",
|
"symbol_table.cc",
|
||||||
"symbol_table.h",
|
"symbol_table.h",
|
||||||
"traits.h",
|
|
||||||
"utils/bitcast.h",
|
"utils/bitcast.h",
|
||||||
"utils/bitset.h",
|
"utils/bitset.h",
|
||||||
"utils/block_allocator.h",
|
"utils/block_allocator.h",
|
||||||
|
@ -243,6 +242,7 @@ libtint_source_set("libtint_base_src") {
|
||||||
"utils/string.h",
|
"utils/string.h",
|
||||||
"utils/string_stream.cc",
|
"utils/string_stream.cc",
|
||||||
"utils/string_stream.h",
|
"utils/string_stream.h",
|
||||||
|
"utils/traits.h",
|
||||||
"utils/unique_allocator.h",
|
"utils/unique_allocator.h",
|
||||||
"utils/unique_vector.h",
|
"utils/unique_vector.h",
|
||||||
"utils/vector.h",
|
"utils/vector.h",
|
||||||
|
@ -1606,6 +1606,7 @@ if (tint_build_unittests) {
|
||||||
"utils/slice_test.cc",
|
"utils/slice_test.cc",
|
||||||
"utils/string_stream_test.cc",
|
"utils/string_stream_test.cc",
|
||||||
"utils/string_test.cc",
|
"utils/string_test.cc",
|
||||||
|
"utils/traits_test.cc",
|
||||||
"utils/transform_test.cc",
|
"utils/transform_test.cc",
|
||||||
"utils/unique_allocator_test.cc",
|
"utils/unique_allocator_test.cc",
|
||||||
"utils/unique_vector_test.cc",
|
"utils/unique_vector_test.cc",
|
||||||
|
@ -1990,7 +1991,6 @@ if (tint_build_unittests) {
|
||||||
"switch_test.cc",
|
"switch_test.cc",
|
||||||
"symbol_table_test.cc",
|
"symbol_table_test.cc",
|
||||||
"symbol_test.cc",
|
"symbol_test.cc",
|
||||||
"traits_test.cc",
|
|
||||||
]
|
]
|
||||||
deps = [ ":libtint_base_src" ]
|
deps = [ ":libtint_base_src" ]
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,6 @@ list(APPEND TINT_LIB_SRCS
|
||||||
symbol.cc
|
symbol.cc
|
||||||
symbol.h
|
symbol.h
|
||||||
tint.cc
|
tint.cc
|
||||||
traits.h
|
|
||||||
transform/add_empty_entry_point.cc
|
transform/add_empty_entry_point.cc
|
||||||
transform/add_empty_entry_point.h
|
transform/add_empty_entry_point.h
|
||||||
transform/add_block_attribute.cc
|
transform/add_block_attribute.cc
|
||||||
|
@ -535,6 +534,7 @@ list(APPEND TINT_LIB_SRCS
|
||||||
utils/string.h
|
utils/string.h
|
||||||
utils/string_stream.cc
|
utils/string_stream.cc
|
||||||
utils/string_stream.h
|
utils/string_stream.h
|
||||||
|
utils/traits.h
|
||||||
utils/unique_allocator.h
|
utils/unique_allocator.h
|
||||||
utils/unique_vector.h
|
utils/unique_vector.h
|
||||||
utils/vector.h
|
utils/vector.h
|
||||||
|
@ -969,7 +969,6 @@ if(TINT_BUILD_TESTS)
|
||||||
symbol_test.cc
|
symbol_test.cc
|
||||||
test_main.cc
|
test_main.cc
|
||||||
text/unicode_test.cc
|
text/unicode_test.cc
|
||||||
traits_test.cc
|
|
||||||
transform/transform_test.cc
|
transform/transform_test.cc
|
||||||
type/array_test.cc
|
type/array_test.cc
|
||||||
type/atomic_test.cc
|
type/atomic_test.cc
|
||||||
|
@ -1013,6 +1012,7 @@ if(TINT_BUILD_TESTS)
|
||||||
utils/slice_test.cc
|
utils/slice_test.cc
|
||||||
utils/string_stream_test.cc
|
utils/string_stream_test.cc
|
||||||
utils/string_test.cc
|
utils/string_test.cc
|
||||||
|
utils/traits_test.cc
|
||||||
utils/transform_test.cc
|
utils/transform_test.cc
|
||||||
utils/unique_allocator_test.cc
|
utils/unique_allocator_test.cc
|
||||||
utils/unique_vector_test.cc
|
utils/unique_vector_test.cc
|
||||||
|
|
|
@ -80,7 +80,7 @@ class Module final : public Castable<Module, Node> {
|
||||||
auto& GlobalVariables() { return global_variables_; }
|
auto& GlobalVariables() { return global_variables_; }
|
||||||
|
|
||||||
/// @returns the global variable declarations of kind 'T' for the module
|
/// @returns the global variable declarations of kind 'T' for the module
|
||||||
template <typename T, typename = traits::EnableIfIsType<T, Variable>>
|
template <typename T, typename = utils::traits::EnableIfIsType<T, Variable>>
|
||||||
auto Globals() const {
|
auto Globals() const {
|
||||||
utils::Vector<const T*, 32> out;
|
utils::Vector<const T*, 32> out;
|
||||||
out.Reserve(global_variables_.Length());
|
out.Reserve(global_variables_.Length());
|
||||||
|
|
|
@ -96,7 +96,7 @@ void CheckIdentifier(const Identifier* ident, const TemplatedIdentifierMatcher<A
|
||||||
const auto* got_arg = got->arguments[arg_idx++];
|
const auto* got_arg = got->arguments[arg_idx++];
|
||||||
|
|
||||||
using T = std::decay_t<decltype(expected_arg)>;
|
using T = std::decay_t<decltype(expected_arg)>;
|
||||||
if constexpr (traits::IsStringLike<T>) {
|
if constexpr (utils::traits::IsStringLike<T>) {
|
||||||
ASSERT_TRUE(got_arg->Is<IdentifierExpression>());
|
ASSERT_TRUE(got_arg->Is<IdentifierExpression>());
|
||||||
CheckIdentifier(got_arg->As<IdentifierExpression>()->identifier, expected_arg);
|
CheckIdentifier(got_arg->As<IdentifierExpression>()->identifier, expected_arg);
|
||||||
} else if constexpr (IsTemplatedIdentifierMatcher<T>::value) {
|
} else if constexpr (IsTemplatedIdentifierMatcher<T>::value) {
|
||||||
|
|
|
@ -62,8 +62,9 @@ enum class TraverseOrder {
|
||||||
/// @return true on success, false on error
|
/// @return true on success, false on error
|
||||||
template <TraverseOrder ORDER = TraverseOrder::LeftToRight, typename CALLBACK>
|
template <TraverseOrder ORDER = TraverseOrder::LeftToRight, typename CALLBACK>
|
||||||
bool TraverseExpressions(const Expression* root, diag::List& diags, CALLBACK&& callback) {
|
bool TraverseExpressions(const Expression* root, diag::List& diags, CALLBACK&& callback) {
|
||||||
using EXPR_TYPE = std::remove_pointer_t<traits::ParameterType<CALLBACK, 0>>;
|
using EXPR_TYPE = std::remove_pointer_t<utils::traits::ParameterType<CALLBACK, 0>>;
|
||||||
constexpr static bool kHasDepthArg = traits::SignatureOfT<CALLBACK>::parameter_count == 2;
|
constexpr static bool kHasDepthArg =
|
||||||
|
utils::traits::SignatureOfT<CALLBACK>::parameter_count == 2;
|
||||||
|
|
||||||
struct Pending {
|
struct Pending {
|
||||||
const Expression* expr;
|
const Expression* expr;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/tint/traits.h"
|
|
||||||
#include "src/tint/utils/crc32.h"
|
#include "src/tint/utils/crc32.h"
|
||||||
|
#include "src/tint/utils/traits.h"
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
/// Temporarily disable certain warnings when using Castable API
|
/// Temporarily disable certain warnings when using Castable API
|
||||||
|
@ -60,7 +60,7 @@ namespace tint {
|
||||||
/// True if all template types that are not Ignore derive from CastableBase
|
/// True if all template types that are not Ignore derive from CastableBase
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
static constexpr bool IsCastable =
|
static constexpr bool IsCastable =
|
||||||
((traits::IsTypeOrDerived<TYPES, CastableBase> || std::is_same_v<TYPES, Ignore>)&&...) &&
|
((utils::traits::IsTypeOrDerived<TYPES, CastableBase> || std::is_same_v<TYPES, Ignore>)&&...) &&
|
||||||
!(std::is_same_v<TYPES, Ignore> && ...);
|
!(std::is_same_v<TYPES, Ignore> && ...);
|
||||||
|
|
||||||
/// Helper macro to instantiate the TypeInfo<T> template for `CLASS`.
|
/// Helper macro to instantiate the TypeInfo<T> template for `CLASS`.
|
||||||
|
@ -220,8 +220,8 @@ struct TypeInfo {
|
||||||
return HashCodeOf<std::remove_cv_t<std::tuple_element_t<0, TUPLE>>>();
|
return HashCodeOf<std::remove_cv_t<std::tuple_element_t<0, TUPLE>>>();
|
||||||
} else {
|
} else {
|
||||||
constexpr auto kMid = kCount / 2;
|
constexpr auto kMid = kCount / 2;
|
||||||
return CombinedHashCodeOfTuple<traits::SliceTuple<0, kMid, TUPLE>>() |
|
return CombinedHashCodeOfTuple<utils::traits::SliceTuple<0, kMid, TUPLE>>() |
|
||||||
CombinedHashCodeOfTuple<traits::SliceTuple<kMid, kCount - kMid, TUPLE>>();
|
CombinedHashCodeOfTuple<utils::traits::SliceTuple<kMid, kCount - kMid, TUPLE>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +245,8 @@ struct TypeInfo {
|
||||||
// Possibly one of the types in `TUPLE`.
|
// Possibly one of the types in `TUPLE`.
|
||||||
// Split the search in two, and scan each block.
|
// Split the search in two, and scan each block.
|
||||||
static constexpr auto kMid = kCount / 2;
|
static constexpr auto kMid = kCount / 2;
|
||||||
return IsAnyOfTuple<traits::SliceTuple<0, kMid, TUPLE>>() ||
|
return IsAnyOfTuple<utils::traits::SliceTuple<0, kMid, TUPLE>>() ||
|
||||||
IsAnyOfTuple<traits::SliceTuple<kMid, kCount - kMid, TUPLE>>();
|
IsAnyOfTuple<utils::traits::SliceTuple<kMid, kCount - kMid, TUPLE>>();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ class Castable : public BASE {
|
||||||
/// object is of, or derives from the class `TO`.
|
/// object is of, or derives from the class `TO`.
|
||||||
template <int FLAGS = 0, typename Pred = detail::Infer>
|
template <int FLAGS = 0, typename Pred = detail::Infer>
|
||||||
inline bool Is(Pred&& pred) const {
|
inline bool Is(Pred&& pred) const {
|
||||||
using TO = typename std::remove_pointer<traits::ParameterType<Pred, 0>>::type;
|
using TO = typename std::remove_pointer<utils::traits::ParameterType<Pred, 0>>::type;
|
||||||
return tint::Is<TO, FLAGS>(static_cast<const CLASS*>(this), std::forward<Pred>(pred));
|
return tint::Is<TO, FLAGS>(static_cast<const CLASS*>(this), std::forward<Pred>(pred));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +512,7 @@ struct CastableCommonBaseImpl<Ignore, T> {
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct CastableCommonBaseImpl<A, B> {
|
struct CastableCommonBaseImpl<A, B> {
|
||||||
/// The common base class for A, B and OTHERS
|
/// The common base class for A, B and OTHERS
|
||||||
using type = std::conditional_t<traits::IsTypeOrDerived<A, B>,
|
using type = std::conditional_t<utils::traits::IsTypeOrDerived<A, B>,
|
||||||
B, // A derives from B
|
B, // A derives from B
|
||||||
CastableCommonBase<A, typename B::TrueBase>>;
|
CastableCommonBase<A, typename B::TrueBase>>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
#include "src/tint/debug.h"
|
#include "src/tint/debug.h"
|
||||||
#include "src/tint/program_id.h"
|
#include "src/tint/program_id.h"
|
||||||
#include "src/tint/symbol.h"
|
#include "src/tint/symbol.h"
|
||||||
#include "src/tint/traits.h"
|
|
||||||
#include "src/tint/utils/compiler_macros.h"
|
#include "src/tint/utils/compiler_macros.h"
|
||||||
#include "src/tint/utils/hashmap.h"
|
#include "src/tint/utils/hashmap.h"
|
||||||
#include "src/tint/utils/hashset.h"
|
#include "src/tint/utils/hashset.h"
|
||||||
|
#include "src/tint/utils/traits.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
|
@ -74,8 +74,8 @@ class CloneContext {
|
||||||
/// ParamTypeIsPtrOf<F, T> is true iff the first parameter of
|
/// ParamTypeIsPtrOf<F, T> is true iff the first parameter of
|
||||||
/// F is a pointer of (or derives from) type T.
|
/// F is a pointer of (or derives from) type T.
|
||||||
template <typename F, typename T>
|
template <typename F, typename T>
|
||||||
static constexpr bool ParamTypeIsPtrOf =
|
static constexpr bool ParamTypeIsPtrOf = utils::traits::
|
||||||
traits::IsTypeOrDerived<typename std::remove_pointer<traits::ParameterType<F, 0>>::type, T>;
|
IsTypeOrDerived<typename std::remove_pointer<utils::traits::ParameterType<F, 0>>::type, T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// SymbolTransform is a function that takes a symbol and returns a new
|
/// SymbolTransform is a function that takes a symbol and returns a new
|
||||||
|
@ -303,8 +303,9 @@ class CloneContext {
|
||||||
/// `T* (T*)`, where `T` derives from Cloneable
|
/// `T* (T*)`, where `T` derives from Cloneable
|
||||||
/// @returns this CloneContext so calls can be chained
|
/// @returns this CloneContext so calls can be chained
|
||||||
template <typename F>
|
template <typename F>
|
||||||
traits::EnableIf<ParamTypeIsPtrOf<F, Cloneable>, CloneContext>& ReplaceAll(F&& replacer) {
|
utils::traits::EnableIf<ParamTypeIsPtrOf<F, Cloneable>, CloneContext>& ReplaceAll(
|
||||||
using TPtr = traits::ParameterType<F, 0>;
|
F&& replacer) {
|
||||||
|
using TPtr = utils::traits::ParameterType<F, 0>;
|
||||||
using T = typename std::remove_pointer<TPtr>::type;
|
using T = typename std::remove_pointer<TPtr>::type;
|
||||||
for (auto& transform : transforms_) {
|
for (auto& transform : transforms_) {
|
||||||
bool already_registered = transform.typeinfo->Is(&TypeInfo::Of<T>()) ||
|
bool already_registered = transform.typeinfo->Is(&TypeInfo::Of<T>()) ||
|
||||||
|
@ -355,7 +356,9 @@ class CloneContext {
|
||||||
/// references of the original object. A type mismatch will result in an
|
/// references of the original object. A type mismatch will result in an
|
||||||
/// assertion in debug builds, and undefined behavior in release builds.
|
/// assertion in debug builds, and undefined behavior in release builds.
|
||||||
/// @returns this CloneContext so calls can be chained
|
/// @returns this CloneContext so calls can be chained
|
||||||
template <typename WHAT, typename WITH, typename = traits::EnableIfIsType<WITH, Cloneable>>
|
template <typename WHAT,
|
||||||
|
typename WITH,
|
||||||
|
typename = utils::traits::EnableIfIsType<WITH, Cloneable>>
|
||||||
CloneContext& Replace(const WHAT* what, const WITH* with) {
|
CloneContext& Replace(const WHAT* what, const WITH* with) {
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, what);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, what);
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, with);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, with);
|
||||||
|
|
|
@ -90,7 +90,8 @@ class Builder {
|
||||||
/// @param args the arguments
|
/// @param args the arguments
|
||||||
/// @returns the new constant value
|
/// @returns the new constant value
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIf<traits::IsTypeOrDerived<T, constant::Value>, const T>* create(ARGS&&... args) {
|
utils::traits::EnableIf<utils::traits::IsTypeOrDerived<T, constant::Value>, const T>* create(
|
||||||
|
ARGS&&... args) {
|
||||||
return ir.constants.Create<T>(std::forward<ARGS>(args)...);
|
return ir.constants.Create<T>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "src/tint/traits.h"
|
|
||||||
#include "src/tint/utils/compiler_macros.h"
|
#include "src/tint/utils/compiler_macros.h"
|
||||||
#include "src/tint/utils/result.h"
|
#include "src/tint/utils/result.h"
|
||||||
#include "src/tint/utils/string_stream.h"
|
#include "src/tint/utils/string_stream.h"
|
||||||
|
#include "src/tint/utils/traits.h"
|
||||||
|
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -274,7 +274,7 @@ using f32 = Number<float>;
|
||||||
/// However since C++ don't have native binary16 type, the value is stored as float.
|
/// However since C++ don't have native binary16 type, the value is stored as float.
|
||||||
using f16 = Number<detail::NumberKindF16>;
|
using f16 = Number<detail::NumberKindF16>;
|
||||||
|
|
||||||
template <typename T, traits::EnableIf<IsFloatingPoint<T>>* = nullptr>
|
template <typename T, utils::traits::EnableIf<IsFloatingPoint<T>>* = nullptr>
|
||||||
inline const auto kPi = T(UnwrapNumber<T>(3.14159265358979323846));
|
inline const auto kPi = T(UnwrapNumber<T>(3.14159265358979323846));
|
||||||
|
|
||||||
/// True iff T is an abstract number type
|
/// True iff T is an abstract number type
|
||||||
|
@ -282,7 +282,7 @@ template <typename T>
|
||||||
constexpr bool IsAbstract = std::is_same_v<T, AInt> || std::is_same_v<T, AFloat>;
|
constexpr bool IsAbstract = std::is_same_v<T, AInt> || std::is_same_v<T, AFloat>;
|
||||||
|
|
||||||
/// @returns the friendly name of Number type T
|
/// @returns the friendly name of Number type T
|
||||||
template <typename T, traits::EnableIf<IsNumber<T>>* = nullptr>
|
template <typename T, utils::traits::EnableIf<IsNumber<T>>* = nullptr>
|
||||||
const char* FriendlyName() {
|
const char* FriendlyName() {
|
||||||
if constexpr (std::is_same_v<T, AInt>) {
|
if constexpr (std::is_same_v<T, AInt>) {
|
||||||
return "abstract-int";
|
return "abstract-int";
|
||||||
|
@ -302,7 +302,7 @@ const char* FriendlyName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns the friendly name of T when T is bool
|
/// @returns the friendly name of T when T is bool
|
||||||
template <typename T, traits::EnableIf<std::is_same_v<T, bool>>* = nullptr>
|
template <typename T, utils::traits::EnableIf<std::is_same_v<T, bool>>* = nullptr>
|
||||||
const char* FriendlyName() {
|
const char* FriendlyName() {
|
||||||
return "bool";
|
return "bool";
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,8 @@ inline std::optional<AInt> CheckedAdd(AInt a, AInt b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns a + b, or an empty optional if the resulting value overflowed the float value
|
/// @returns a + b, or an empty optional if the resulting value overflowed the float value
|
||||||
template <typename FloatingPointT, typename = traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
template <typename FloatingPointT,
|
||||||
|
typename = utils::traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
||||||
inline std::optional<FloatingPointT> CheckedAdd(FloatingPointT a, FloatingPointT b) {
|
inline std::optional<FloatingPointT> CheckedAdd(FloatingPointT a, FloatingPointT b) {
|
||||||
auto result = FloatingPointT{a.value + b.value};
|
auto result = FloatingPointT{a.value + b.value};
|
||||||
if (!std::isfinite(result.value)) {
|
if (!std::isfinite(result.value)) {
|
||||||
|
@ -470,7 +471,8 @@ inline std::optional<AInt> CheckedSub(AInt a, AInt b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns a + b, or an empty optional if the resulting value overflowed the float value
|
/// @returns a + b, or an empty optional if the resulting value overflowed the float value
|
||||||
template <typename FloatingPointT, typename = traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
template <typename FloatingPointT,
|
||||||
|
typename = utils::traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
||||||
inline std::optional<FloatingPointT> CheckedSub(FloatingPointT a, FloatingPointT b) {
|
inline std::optional<FloatingPointT> CheckedSub(FloatingPointT a, FloatingPointT b) {
|
||||||
auto result = FloatingPointT{a.value - b.value};
|
auto result = FloatingPointT{a.value - b.value};
|
||||||
if (!std::isfinite(result.value)) {
|
if (!std::isfinite(result.value)) {
|
||||||
|
@ -514,7 +516,8 @@ inline std::optional<AInt> CheckedMul(AInt a, AInt b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns a * b, or an empty optional if the resulting value overflowed the float value
|
/// @returns a * b, or an empty optional if the resulting value overflowed the float value
|
||||||
template <typename FloatingPointT, typename = traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
template <typename FloatingPointT,
|
||||||
|
typename = utils::traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
||||||
inline std::optional<FloatingPointT> CheckedMul(FloatingPointT a, FloatingPointT b) {
|
inline std::optional<FloatingPointT> CheckedMul(FloatingPointT a, FloatingPointT b) {
|
||||||
auto result = FloatingPointT{a.value * b.value};
|
auto result = FloatingPointT{a.value * b.value};
|
||||||
if (!std::isfinite(result.value)) {
|
if (!std::isfinite(result.value)) {
|
||||||
|
@ -537,7 +540,8 @@ inline std::optional<AInt> CheckedDiv(AInt a, AInt b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns a / b, or an empty optional if the resulting value overflowed the float value
|
/// @returns a / b, or an empty optional if the resulting value overflowed the float value
|
||||||
template <typename FloatingPointT, typename = traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
template <typename FloatingPointT,
|
||||||
|
typename = utils::traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
||||||
inline std::optional<FloatingPointT> CheckedDiv(FloatingPointT a, FloatingPointT b) {
|
inline std::optional<FloatingPointT> CheckedDiv(FloatingPointT a, FloatingPointT b) {
|
||||||
if (b == FloatingPointT{0.0} || b == FloatingPointT{-0.0}) {
|
if (b == FloatingPointT{0.0} || b == FloatingPointT{-0.0}) {
|
||||||
return {};
|
return {};
|
||||||
|
@ -577,7 +581,8 @@ inline std::optional<AInt> CheckedMod(AInt a, AInt b) {
|
||||||
|
|
||||||
/// @returns the remainder of a / b, or an empty optional if the resulting value overflowed the
|
/// @returns the remainder of a / b, or an empty optional if the resulting value overflowed the
|
||||||
/// float value
|
/// float value
|
||||||
template <typename FloatingPointT, typename = traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
template <typename FloatingPointT,
|
||||||
|
typename = utils::traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
||||||
inline std::optional<FloatingPointT> CheckedMod(FloatingPointT a, FloatingPointT b) {
|
inline std::optional<FloatingPointT> CheckedMod(FloatingPointT a, FloatingPointT b) {
|
||||||
if (b == FloatingPointT{0.0} || b == FloatingPointT{-0.0}) {
|
if (b == FloatingPointT{0.0} || b == FloatingPointT{-0.0}) {
|
||||||
return {};
|
return {};
|
||||||
|
@ -599,7 +604,8 @@ inline std::optional<AInt> CheckedMadd(AInt a, AInt b, AInt c) {
|
||||||
|
|
||||||
/// @returns the value of `base` raised to the power `exp`, or an empty optional if the operation
|
/// @returns the value of `base` raised to the power `exp`, or an empty optional if the operation
|
||||||
/// cannot be performed.
|
/// cannot be performed.
|
||||||
template <typename FloatingPointT, typename = traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
template <typename FloatingPointT,
|
||||||
|
typename = utils::traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
|
||||||
inline std::optional<FloatingPointT> CheckedPow(FloatingPointT base, FloatingPointT exp) {
|
inline std::optional<FloatingPointT> CheckedPow(FloatingPointT base, FloatingPointT exp) {
|
||||||
static_assert(IsNumber<FloatingPointT>);
|
static_assert(IsNumber<FloatingPointT>);
|
||||||
if ((base < 0) || (base == 0 && exp <= 0)) {
|
if ((base < 0) || (base == 0 && exp <= 0)) {
|
||||||
|
|
|
@ -170,53 +170,53 @@ class ProgramBuilder {
|
||||||
|
|
||||||
/// Evaluates to true if T can be converted to an identifier.
|
/// Evaluates to true if T can be converted to an identifier.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static constexpr const bool IsIdentifierLike = std::is_same_v<T, Symbol> || // Symbol
|
static constexpr const bool IsIdentifierLike = std::is_same_v<T, Symbol> || // Symbol
|
||||||
std::is_enum_v<T> || // Enum
|
std::is_enum_v<T> || // Enum
|
||||||
traits::IsStringLike<T>; // String
|
utils::traits::IsStringLike<T>; // String
|
||||||
|
|
||||||
/// A helper used to disable overloads if the first type in `TYPES` is a Source. Used to avoid
|
/// A helper used to disable overloads if the first type in `TYPES` is a Source. Used to avoid
|
||||||
/// ambiguities in overloads that take a Source as the first parameter and those that
|
/// ambiguities in overloads that take a Source as the first parameter and those that
|
||||||
/// perfectly-forward the first argument.
|
/// perfectly-forward the first argument.
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
using DisableIfSource =
|
using DisableIfSource = utils::traits::EnableIf<
|
||||||
traits::EnableIf<!IsSource<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
|
!IsSource<utils::traits::Decay<utils::traits::NthTypeOf<0, TYPES..., void>>>>;
|
||||||
|
|
||||||
/// A helper used to disable overloads if the first type in `TYPES` is a scalar type. Used to
|
/// A helper used to disable overloads if the first type in `TYPES` is a scalar type. Used to
|
||||||
/// avoid ambiguities in overloads that take a scalar as the first parameter and those that
|
/// avoid ambiguities in overloads that take a scalar as the first parameter and those that
|
||||||
/// perfectly-forward the first argument.
|
/// perfectly-forward the first argument.
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
using DisableIfScalar =
|
using DisableIfScalar = utils::traits::EnableIf<
|
||||||
traits::EnableIf<!IsScalar<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
|
!IsScalar<utils::traits::Decay<utils::traits::NthTypeOf<0, TYPES..., void>>>>;
|
||||||
|
|
||||||
/// A helper used to enable overloads if the first type in `TYPES` is a scalar type. Used to
|
/// A helper used to enable overloads if the first type in `TYPES` is a scalar type. Used to
|
||||||
/// avoid ambiguities in overloads that take a scalar as the first parameter and those that
|
/// avoid ambiguities in overloads that take a scalar as the first parameter and those that
|
||||||
/// perfectly-forward the first argument.
|
/// perfectly-forward the first argument.
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
using EnableIfScalar =
|
using EnableIfScalar = utils::traits::EnableIf<
|
||||||
traits::EnableIf<IsScalar<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
|
IsScalar<utils::traits::Decay<utils::traits::NthTypeOf<0, TYPES..., void>>>>;
|
||||||
|
|
||||||
/// A helper used to disable overloads if the first type in `TYPES` is a utils::Vector,
|
/// A helper used to disable overloads if the first type in `TYPES` is a utils::Vector,
|
||||||
/// utils::VectorRef or utils::VectorRef.
|
/// utils::VectorRef or utils::VectorRef.
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
using DisableIfVectorLike = traits::EnableIf<
|
using DisableIfVectorLike = utils::traits::EnableIf<!detail::IsVectorLike<
|
||||||
!detail::IsVectorLike<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>::value>;
|
utils::traits::Decay<utils::traits::NthTypeOf<0, TYPES..., void>>>::value>;
|
||||||
|
|
||||||
/// A helper used to enable overloads if the first type in `TYPES` is identifier-like.
|
/// A helper used to enable overloads if the first type in `TYPES` is identifier-like.
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
using EnableIfIdentifierLike =
|
using EnableIfIdentifierLike = utils::traits::EnableIf<
|
||||||
traits::EnableIf<IsIdentifierLike<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
|
IsIdentifierLike<utils::traits::Decay<utils::traits::NthTypeOf<0, TYPES..., void>>>>;
|
||||||
|
|
||||||
/// A helper used to disable overloads if the first type in `TYPES` is Infer or an abstract
|
/// A helper used to disable overloads if the first type in `TYPES` is Infer or an abstract
|
||||||
/// numeric.
|
/// numeric.
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
using DisableIfInferOrAbstract =
|
using DisableIfInferOrAbstract = utils::traits::EnableIf<
|
||||||
traits::EnableIf<!IsInferOrAbstract<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
|
!IsInferOrAbstract<utils::traits::Decay<utils::traits::NthTypeOf<0, TYPES..., void>>>>;
|
||||||
|
|
||||||
/// A helper used to enable overloads if the first type in `TYPES` is Infer or an abstract
|
/// A helper used to enable overloads if the first type in `TYPES` is Infer or an abstract
|
||||||
/// numeric.
|
/// numeric.
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
using EnableIfInferOrAbstract =
|
using EnableIfInferOrAbstract = utils::traits::EnableIf<
|
||||||
traits::EnableIf<IsInferOrAbstract<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
|
IsInferOrAbstract<utils::traits::Decay<utils::traits::NthTypeOf<0, TYPES..., void>>>>;
|
||||||
|
|
||||||
/// VarOptions is a helper for accepting an arbitrary number of order independent options for
|
/// VarOptions is a helper for accepting an arbitrary number of order independent options for
|
||||||
/// constructing an ast::Var.
|
/// constructing an ast::Var.
|
||||||
|
@ -258,7 +258,8 @@ class ProgramBuilder {
|
||||||
template <typename... ARGS>
|
template <typename... ARGS>
|
||||||
explicit LetOptions(ARGS&&... args) {
|
explicit LetOptions(ARGS&&... args) {
|
||||||
static constexpr bool has_init =
|
static constexpr bool has_init =
|
||||||
(traits::IsTypeOrDerived<traits::PtrElTy<ARGS>, ast::Expression> || ...);
|
(utils::traits::IsTypeOrDerived<utils::traits::PtrElTy<ARGS>, ast::Expression> ||
|
||||||
|
...);
|
||||||
static_assert(has_init, "Let() must be constructed with an initializer expression");
|
static_assert(has_init, "Let() must be constructed with an initializer expression");
|
||||||
(Set(std::forward<ARGS>(args)), ...);
|
(Set(std::forward<ARGS>(args)), ...);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +282,8 @@ class ProgramBuilder {
|
||||||
template <typename... ARGS>
|
template <typename... ARGS>
|
||||||
explicit ConstOptions(ARGS&&... args) {
|
explicit ConstOptions(ARGS&&... args) {
|
||||||
static constexpr bool has_init =
|
static constexpr bool has_init =
|
||||||
(traits::IsTypeOrDerived<traits::PtrElTy<ARGS>, ast::Expression> || ...);
|
(utils::traits::IsTypeOrDerived<utils::traits::PtrElTy<ARGS>, ast::Expression> ||
|
||||||
|
...);
|
||||||
static_assert(has_init, "Const() must be constructed with an initializer expression");
|
static_assert(has_init, "Const() must be constructed with an initializer expression");
|
||||||
(Set(std::forward<ARGS>(args)), ...);
|
(Set(std::forward<ARGS>(args)), ...);
|
||||||
}
|
}
|
||||||
|
@ -476,7 +478,7 @@ class ProgramBuilder {
|
||||||
/// @param args the arguments to pass to the constructor
|
/// @param args the arguments to pass to the constructor
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIfIsType<T, ast::Node>* create(const Source& source, ARGS&&... args) {
|
utils::traits::EnableIfIsType<T, ast::Node>* create(const Source& source, ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return ast_nodes_.Create<T>(id_, AllocateNodeID(), source, std::forward<ARGS>(args)...);
|
return ast_nodes_.Create<T>(id_, AllocateNodeID(), source, std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
@ -488,7 +490,7 @@ class ProgramBuilder {
|
||||||
/// destructed.
|
/// destructed.
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T>
|
template <typename T>
|
||||||
traits::EnableIfIsType<T, ast::Node>* create() {
|
utils::traits::EnableIfIsType<T, ast::Node>* create() {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return ast_nodes_.Create<T>(id_, AllocateNodeID(), source_);
|
return ast_nodes_.Create<T>(id_, AllocateNodeID(), source_);
|
||||||
}
|
}
|
||||||
|
@ -502,10 +504,10 @@ class ProgramBuilder {
|
||||||
/// @param args the remaining arguments to pass to the constructor
|
/// @param args the remaining arguments to pass to the constructor
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T, typename ARG0, typename... ARGS>
|
template <typename T, typename ARG0, typename... ARGS>
|
||||||
traits::EnableIf</* T is ast::Node and ARG0 is not Source */
|
utils::traits::EnableIf</* T is ast::Node and ARG0 is not Source */
|
||||||
traits::IsTypeOrDerived<T, ast::Node> &&
|
utils::traits::IsTypeOrDerived<T, ast::Node> &&
|
||||||
!traits::IsTypeOrDerived<ARG0, Source>,
|
!utils::traits::IsTypeOrDerived<ARG0, Source>,
|
||||||
T>*
|
T>*
|
||||||
create(ARG0&& arg0, ARGS&&... args) {
|
create(ARG0&& arg0, ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return ast_nodes_.Create<T>(id_, AllocateNodeID(), source_, std::forward<ARG0>(arg0),
|
return ast_nodes_.Create<T>(id_, AllocateNodeID(), source_, std::forward<ARG0>(arg0),
|
||||||
|
@ -517,9 +519,9 @@ class ProgramBuilder {
|
||||||
/// @param args the arguments to pass to the constructor
|
/// @param args the arguments to pass to the constructor
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIf<traits::IsTypeOrDerived<T, sem::Node> &&
|
utils::traits::EnableIf<utils::traits::IsTypeOrDerived<T, sem::Node> &&
|
||||||
!traits::IsTypeOrDerived<T, type::Node>,
|
!utils::traits::IsTypeOrDerived<T, type::Node>,
|
||||||
T>*
|
T>*
|
||||||
create(ARGS&&... args) {
|
create(ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return sem_nodes_.Create<T>(std::forward<ARGS>(args)...);
|
return sem_nodes_.Create<T>(std::forward<ARGS>(args)...);
|
||||||
|
@ -530,10 +532,10 @@ class ProgramBuilder {
|
||||||
/// @param args the arguments to pass to the constructor
|
/// @param args the arguments to pass to the constructor
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIf<traits::IsTypeOrDerived<T, constant::Value> &&
|
utils::traits::EnableIf<utils::traits::IsTypeOrDerived<T, constant::Value> &&
|
||||||
!traits::IsTypeOrDerived<T, constant::Composite> &&
|
!utils::traits::IsTypeOrDerived<T, constant::Composite> &&
|
||||||
!traits::IsTypeOrDerived<T, constant::Splat>,
|
!utils::traits::IsTypeOrDerived<T, constant::Splat>,
|
||||||
T>*
|
T>*
|
||||||
create(ARGS&&... args) {
|
create(ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return constant_nodes_.Create<T>(std::forward<ARGS>(args)...);
|
return constant_nodes_.Create<T>(std::forward<ARGS>(args)...);
|
||||||
|
@ -547,9 +549,10 @@ class ProgramBuilder {
|
||||||
/// @param type the composite type
|
/// @param type the composite type
|
||||||
/// @param elements the composite elements
|
/// @param elements the composite elements
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T,
|
template <
|
||||||
typename = traits::EnableIf<traits::IsTypeOrDerived<T, constant::Composite> ||
|
typename T,
|
||||||
traits::IsTypeOrDerived<T, constant::Splat>>>
|
typename = utils::traits::EnableIf<utils::traits::IsTypeOrDerived<T, constant::Composite> ||
|
||||||
|
utils::traits::IsTypeOrDerived<T, constant::Splat>>>
|
||||||
const constant::Value* create(const type::Type* type,
|
const constant::Value* create(const type::Type* type,
|
||||||
utils::VectorRef<const constant::Value*> elements) {
|
utils::VectorRef<const constant::Value*> elements) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
|
@ -561,7 +564,9 @@ class ProgramBuilder {
|
||||||
/// @param element the splat element
|
/// @param element the splat element
|
||||||
/// @param n the number of elements
|
/// @param n the number of elements
|
||||||
/// @returns the node pointer
|
/// @returns the node pointer
|
||||||
template <typename T, typename = traits::EnableIf<traits::IsTypeOrDerived<T, constant::Splat>>>
|
template <
|
||||||
|
typename T,
|
||||||
|
typename = utils::traits::EnableIf<utils::traits::IsTypeOrDerived<T, constant::Splat>>>
|
||||||
const constant::Splat* create(const type::Type* type,
|
const constant::Splat* create(const type::Type* type,
|
||||||
const constant::Value* element,
|
const constant::Value* element,
|
||||||
size_t n) {
|
size_t n) {
|
||||||
|
@ -576,7 +581,7 @@ class ProgramBuilder {
|
||||||
/// @param args the arguments to pass to the constructor
|
/// @param args the arguments to pass to the constructor
|
||||||
/// @returns the new, or existing node
|
/// @returns the new, or existing node
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIfIsType<T, type::Node>* create(ARGS&&... args) {
|
utils::traits::EnableIfIsType<T, type::Node>* create(ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return types_.Get<T>(std::forward<ARGS>(args)...);
|
return types_.Get<T>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
@ -615,7 +620,8 @@ class ProgramBuilder {
|
||||||
typename = DisableIfSource<NAME>,
|
typename = DisableIfSource<NAME>,
|
||||||
typename = std::enable_if_t<!std::is_same_v<std::decay_t<NAME>, ast::Type>>>
|
typename = std::enable_if_t<!std::is_same_v<std::decay_t<NAME>, ast::Type>>>
|
||||||
ast::Type operator()(NAME&& name, ARGS&&... args) const {
|
ast::Type operator()(NAME&& name, ARGS&&... args) const {
|
||||||
if constexpr (traits::IsTypeOrDerived<traits::PtrElTy<NAME>, ast::Expression>) {
|
if constexpr (utils::traits::IsTypeOrDerived<utils::traits::PtrElTy<NAME>,
|
||||||
|
ast::Expression>) {
|
||||||
static_assert(sizeof...(ARGS) == 0);
|
static_assert(sizeof...(ARGS) == 0);
|
||||||
return {name};
|
return {name};
|
||||||
} else {
|
} else {
|
||||||
|
@ -1479,7 +1485,8 @@ class ProgramBuilder {
|
||||||
/// @return an ast::Identifier with the given symbol
|
/// @return an ast::Identifier with the given symbol
|
||||||
template <typename IDENTIFIER>
|
template <typename IDENTIFIER>
|
||||||
const ast::Identifier* Ident(IDENTIFIER&& identifier) {
|
const ast::Identifier* Ident(IDENTIFIER&& identifier) {
|
||||||
if constexpr (traits::IsTypeOrDerived<traits::PtrElTy<IDENTIFIER>, ast::Identifier>) {
|
if constexpr (utils::traits::IsTypeOrDerived<utils::traits::PtrElTy<IDENTIFIER>,
|
||||||
|
ast::Identifier>) {
|
||||||
return identifier; // Passthrough
|
return identifier; // Passthrough
|
||||||
} else {
|
} else {
|
||||||
return Ident(source_, std::forward<IDENTIFIER>(identifier));
|
return Ident(source_, std::forward<IDENTIFIER>(identifier));
|
||||||
|
@ -1518,7 +1525,7 @@ class ProgramBuilder {
|
||||||
|
|
||||||
/// @param expr the expression
|
/// @param expr the expression
|
||||||
/// @return expr (passthrough)
|
/// @return expr (passthrough)
|
||||||
template <typename T, typename = traits::EnableIfIsType<T, ast::Expression>>
|
template <typename T, typename = utils::traits::EnableIfIsType<T, ast::Expression>>
|
||||||
const T* Expr(const T* expr) {
|
const T* Expr(const T* expr) {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
@ -2734,8 +2741,9 @@ class ProgramBuilder {
|
||||||
const ast::MemberAccessorExpression* MemberAccessor(const Source& source,
|
const ast::MemberAccessorExpression* MemberAccessor(const Source& source,
|
||||||
OBJECT&& object,
|
OBJECT&& object,
|
||||||
MEMBER&& member) {
|
MEMBER&& member) {
|
||||||
static_assert(!traits::IsType<traits::PtrElTy<MEMBER>, ast::TemplatedIdentifier>,
|
static_assert(
|
||||||
"it is currently invalid for a structure to hold a templated member");
|
!utils::traits::IsType<utils::traits::PtrElTy<MEMBER>, ast::TemplatedIdentifier>,
|
||||||
|
"it is currently invalid for a structure to hold a templated member");
|
||||||
return create<ast::MemberAccessorExpression>(source, Expr(std::forward<OBJECT>(object)),
|
return create<ast::MemberAccessorExpression>(source, Expr(std::forward<OBJECT>(object)),
|
||||||
Ident(std::forward<MEMBER>(member)));
|
Ident(std::forward<MEMBER>(member)));
|
||||||
}
|
}
|
||||||
|
@ -2882,8 +2890,8 @@ class ProgramBuilder {
|
||||||
utils::VectorRef<const ast::Attribute*> attributes = utils::Empty,
|
utils::VectorRef<const ast::Attribute*> attributes = utils::Empty,
|
||||||
utils::VectorRef<const ast::Attribute*> return_type_attributes = utils::Empty) {
|
utils::VectorRef<const ast::Attribute*> return_type_attributes = utils::Empty) {
|
||||||
const ast::BlockStatement* block = nullptr;
|
const ast::BlockStatement* block = nullptr;
|
||||||
using BODY_T = traits::PtrElTy<BODY>;
|
using BODY_T = utils::traits::PtrElTy<BODY>;
|
||||||
if constexpr (traits::IsTypeOrDerived<BODY_T, ast::BlockStatement> ||
|
if constexpr (utils::traits::IsTypeOrDerived<BODY_T, ast::BlockStatement> ||
|
||||||
std::is_same_v<BODY_T, std::nullptr_t>) {
|
std::is_same_v<BODY_T, std::nullptr_t>) {
|
||||||
block = body;
|
block = body;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3753,8 +3761,9 @@ class ProgramBuilder {
|
||||||
const ast::DiagnosticAttribute* DiagnosticAttribute(const Source& source,
|
const ast::DiagnosticAttribute* DiagnosticAttribute(const Source& source,
|
||||||
builtin::DiagnosticSeverity severity,
|
builtin::DiagnosticSeverity severity,
|
||||||
NAME&& rule_name) {
|
NAME&& rule_name) {
|
||||||
static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
|
static_assert(
|
||||||
"it is invalid for a diagnostic rule name to be templated");
|
!utils::traits::IsType<utils::traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
|
||||||
|
"it is invalid for a diagnostic rule name to be templated");
|
||||||
return create<ast::DiagnosticAttribute>(
|
return create<ast::DiagnosticAttribute>(
|
||||||
source, ast::DiagnosticControl(severity, Ident(std::forward<NAME>(rule_name))));
|
source, ast::DiagnosticControl(severity, Ident(std::forward<NAME>(rule_name))));
|
||||||
}
|
}
|
||||||
|
@ -3872,7 +3881,7 @@ class ProgramBuilder {
|
||||||
/// @param args a mix of ast::Expression, ast::Statement, ast::Variables.
|
/// @param args a mix of ast::Expression, ast::Statement, ast::Variables.
|
||||||
/// @returns the function
|
/// @returns the function
|
||||||
template <typename... ARGS,
|
template <typename... ARGS,
|
||||||
typename = traits::EnableIf<(CanWrapInStatement<ARGS>::value && ...)>>
|
typename = utils::traits::EnableIf<(CanWrapInStatement<ARGS>::value && ...)>>
|
||||||
const ast::Function* WrapInFunction(ARGS&&... args) {
|
const ast::Function* WrapInFunction(ARGS&&... args) {
|
||||||
utils::Vector stmts{
|
utils::Vector stmts{
|
||||||
WrapInStatement(std::forward<ARGS>(args))...,
|
WrapInStatement(std::forward<ARGS>(args))...,
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
#ifndef SRC_TINT_REFLECTION_H_
|
#ifndef SRC_TINT_REFLECTION_H_
|
||||||
#define SRC_TINT_REFLECTION_H_
|
#define SRC_TINT_REFLECTION_H_
|
||||||
|
|
||||||
#include "src/tint/traits.h"
|
#include <type_traits>
|
||||||
|
|
||||||
#include "src/tint/utils/concat.h"
|
#include "src/tint/utils/concat.h"
|
||||||
#include "src/tint/utils/foreach_macro.h"
|
#include "src/tint/utils/foreach_macro.h"
|
||||||
|
|
||||||
|
|
|
@ -447,7 +447,8 @@ ConstEval::Result TransformElements(ProgramBuilder& builder,
|
||||||
auto* ty = First(cs...)->Type();
|
auto* ty = First(cs...)->Type();
|
||||||
auto* el_ty = type::Type::ElementOf(ty, &n);
|
auto* el_ty = type::Type::ElementOf(ty, &n);
|
||||||
if (el_ty == ty) {
|
if (el_ty == ty) {
|
||||||
constexpr bool kHasIndexParam = traits::IsType<size_t, traits::LastParameterType<F>>;
|
constexpr bool kHasIndexParam =
|
||||||
|
utils::traits::IsType<size_t, utils::traits::LastParameterType<F>>;
|
||||||
if constexpr (kHasIndexParam) {
|
if constexpr (kHasIndexParam) {
|
||||||
return f(cs..., index);
|
return f(cs..., index);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
#include "src/tint/sem/statement.h"
|
#include "src/tint/sem/statement.h"
|
||||||
#include "src/tint/sem/value_expression.h"
|
#include "src/tint/sem/value_expression.h"
|
||||||
#include "src/tint/sem/variable.h"
|
#include "src/tint/sem/variable.h"
|
||||||
#include "src/tint/traits.h"
|
|
||||||
#include "src/tint/type/abstract_float.h"
|
#include "src/tint/type/abstract_float.h"
|
||||||
#include "src/tint/type/abstract_int.h"
|
#include "src/tint/type/abstract_int.h"
|
||||||
|
#include "src/tint/utils/traits.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
namespace tint::resolver {
|
namespace tint::resolver {
|
||||||
|
@ -587,7 +587,7 @@ struct DataType<alias<T, ID>> {
|
||||||
/// @param args the value nested elements will be initialized with
|
/// @param args the value nested elements will be initialized with
|
||||||
/// @return a new AST expression of the alias type
|
/// @return a new AST expression of the alias type
|
||||||
template <bool IS_COMPOSITE = is_composite>
|
template <bool IS_COMPOSITE = is_composite>
|
||||||
static inline traits::EnableIf<!IS_COMPOSITE, const ast::Expression*> Expr(
|
static inline utils::traits::EnableIf<!IS_COMPOSITE, const ast::Expression*> Expr(
|
||||||
ProgramBuilder& b,
|
ProgramBuilder& b,
|
||||||
utils::VectorRef<Scalar> args) {
|
utils::VectorRef<Scalar> args) {
|
||||||
// Cast
|
// Cast
|
||||||
|
@ -598,7 +598,7 @@ struct DataType<alias<T, ID>> {
|
||||||
/// @param args the value nested elements will be initialized with
|
/// @param args the value nested elements will be initialized with
|
||||||
/// @return a new AST expression of the alias type
|
/// @return a new AST expression of the alias type
|
||||||
template <bool IS_COMPOSITE = is_composite>
|
template <bool IS_COMPOSITE = is_composite>
|
||||||
static inline traits::EnableIf<IS_COMPOSITE, const ast::Expression*> Expr(
|
static inline utils::traits::EnableIf<IS_COMPOSITE, const ast::Expression*> Expr(
|
||||||
ProgramBuilder& b,
|
ProgramBuilder& b,
|
||||||
utils::VectorRef<Scalar> args) {
|
utils::VectorRef<Scalar> args) {
|
||||||
// Construct
|
// Construct
|
||||||
|
@ -819,7 +819,7 @@ constexpr bool IsValue = std::is_same_v<T, Value>;
|
||||||
/// Creates a Value of DataType<T> from a scalar `v`
|
/// Creates a Value of DataType<T> from a scalar `v`
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Value Val(T v) {
|
Value Val(T v) {
|
||||||
static_assert(traits::IsTypeIn<T, Scalar>, "v must be a Number of bool");
|
static_assert(utils::traits::IsTypeIn<T, Scalar>, "v must be a Number of bool");
|
||||||
return Value::Create<T>(utils::Vector<Scalar, 1>{v});
|
return Value::Create<T>(utils::Vector<Scalar, 1>{v});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ class Info {
|
||||||
typename RESULT = GetResultType<SEM, AST>>
|
typename RESULT = GetResultType<SEM, AST>>
|
||||||
const RESULT* Get(const AST* ast_node) const {
|
const RESULT* Get(const AST* ast_node) const {
|
||||||
static_assert(std::is_same_v<SEM, InferFromAST> ||
|
static_assert(std::is_same_v<SEM, InferFromAST> ||
|
||||||
!traits::IsTypeOrDerived<SemanticNodeTypeFor<AST>, SEM>,
|
!utils::traits::IsTypeOrDerived<SemanticNodeTypeFor<AST>, SEM>,
|
||||||
"explicit template argument is unnecessary");
|
"explicit template argument is unnecessary");
|
||||||
if (ast_node && ast_node->node_id.value < nodes_.size()) {
|
if (ast_node && ast_node->node_id.value < nodes_.size()) {
|
||||||
return As<RESULT>(nodes_[ast_node->node_id.value]);
|
return As<RESULT>(nodes_[ast_node->node_id.value]);
|
||||||
|
|
|
@ -43,13 +43,14 @@ namespace tint::detail {
|
||||||
/// @note does not handle the Default case
|
/// @note does not handle the Default case
|
||||||
/// @see Switch().
|
/// @see Switch().
|
||||||
template <typename FN>
|
template <typename FN>
|
||||||
using SwitchCaseType = std::remove_pointer_t<traits::ParameterType<std::remove_reference_t<FN>, 0>>;
|
using SwitchCaseType =
|
||||||
|
std::remove_pointer_t<utils::traits::ParameterType<std::remove_reference_t<FN>, 0>>;
|
||||||
|
|
||||||
/// Evaluates to true if the function `FN` has the signature of a Default case in a Switch().
|
/// Evaluates to true if the function `FN` has the signature of a Default case in a Switch().
|
||||||
/// @see Switch().
|
/// @see Switch().
|
||||||
template <typename FN>
|
template <typename FN>
|
||||||
inline constexpr bool IsDefaultCase =
|
inline constexpr bool IsDefaultCase =
|
||||||
std::is_same_v<traits::ParameterType<std::remove_reference_t<FN>, 0>, Default>;
|
std::is_same_v<utils::traits::ParameterType<std::remove_reference_t<FN>, 0>, Default>;
|
||||||
|
|
||||||
/// Searches the list of Switch cases for a Default case, returning the index of the Default case.
|
/// Searches the list of Switch cases for a Default case, returning the index of the Default case.
|
||||||
/// If the a Default case is not found in the tuple, then -1 is returned.
|
/// If the a Default case is not found in the tuple, then -1 is returned.
|
||||||
|
@ -163,7 +164,7 @@ namespace tint {
|
||||||
/// consistent case type.
|
/// consistent case type.
|
||||||
template <typename RETURN_TYPE = detail::Infer, typename T = CastableBase, typename... CASES>
|
template <typename RETURN_TYPE = detail::Infer, typename T = CastableBase, typename... CASES>
|
||||||
inline auto Switch(T* object, CASES&&... cases) {
|
inline auto Switch(T* object, CASES&&... cases) {
|
||||||
using ReturnType = detail::SwitchReturnType<RETURN_TYPE, traits::ReturnType<CASES>...>;
|
using ReturnType = detail::SwitchReturnType<RETURN_TYPE, utils::traits::ReturnType<CASES>...>;
|
||||||
static constexpr int kDefaultIndex = detail::IndexOfDefaultCase<std::tuple<CASES...>>();
|
static constexpr int kDefaultIndex = detail::IndexOfDefaultCase<std::tuple<CASES...>>();
|
||||||
static constexpr bool kHasDefaultCase = kDefaultIndex >= 0;
|
static constexpr bool kHasDefaultCase = kDefaultIndex >= 0;
|
||||||
static constexpr bool kHasReturnType = !std::is_same_v<ReturnType, void>;
|
static constexpr bool kHasReturnType = !std::is_same_v<ReturnType, void>;
|
||||||
|
|
|
@ -65,9 +65,9 @@ class Manager final {
|
||||||
/// constructed, then the same pointer is returned.
|
/// constructed, then the same pointer is returned.
|
||||||
template <typename NODE, typename... ARGS>
|
template <typename NODE, typename... ARGS>
|
||||||
NODE* Get(ARGS&&... args) {
|
NODE* Get(ARGS&&... args) {
|
||||||
if constexpr (traits::IsTypeOrDerived<NODE, Type>) {
|
if constexpr (utils::traits::IsTypeOrDerived<NODE, Type>) {
|
||||||
return types_.Get<NODE>(std::forward<ARGS>(args)...);
|
return types_.Get<NODE>(std::forward<ARGS>(args)...);
|
||||||
} else if constexpr (traits::IsTypeOrDerived<NODE, UniqueNode>) {
|
} else if constexpr (utils::traits::IsTypeOrDerived<NODE, UniqueNode>) {
|
||||||
return unique_nodes_.Get<NODE>(std::forward<ARGS>(args)...);
|
return unique_nodes_.Get<NODE>(std::forward<ARGS>(args)...);
|
||||||
} else {
|
} else {
|
||||||
return nodes_.Create<NODE>(std::forward<ARGS>(args)...);
|
return nodes_.Create<NODE>(std::forward<ARGS>(args)...);
|
||||||
|
@ -78,7 +78,7 @@ class Manager final {
|
||||||
/// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
|
/// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
|
||||||
/// was not found.
|
/// was not found.
|
||||||
template <typename TYPE,
|
template <typename TYPE,
|
||||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, Type>>,
|
typename _ = std::enable_if<utils::traits::IsTypeOrDerived<TYPE, Type>>,
|
||||||
typename... ARGS>
|
typename... ARGS>
|
||||||
TYPE* Find(ARGS&&... args) const {
|
TYPE* Find(ARGS&&... args) const {
|
||||||
return types_.Find<TYPE>(std::forward<ARGS>(args)...);
|
return types_.Find<TYPE>(std::forward<ARGS>(args)...);
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
#include "src/tint/castable.h"
|
#include "src/tint/castable.h"
|
||||||
#include "src/tint/traits.h"
|
|
||||||
#include "src/tint/utils/bitcast.h"
|
#include "src/tint/utils/bitcast.h"
|
||||||
|
#include "src/tint/utils/traits.h"
|
||||||
|
|
||||||
namespace tint::utils {
|
namespace tint::utils {
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ struct CanReinterpretSlice {
|
||||||
// or
|
// or
|
||||||
// derives from TO
|
// derives from TO
|
||||||
(std::is_same_v<std::remove_const_t<FROM_EL>, std::remove_const_t<TO_EL>> ||
|
(std::is_same_v<std::remove_const_t<FROM_EL>, std::remove_const_t<TO_EL>> ||
|
||||||
(IsCastable<FROM_EL, TO_EL> &&
|
(IsCastable<FROM_EL, TO_EL> && (MODE == ReinterpretMode::kUnsafe ||
|
||||||
(MODE == ReinterpretMode::kUnsafe || traits::IsTypeOrDerived<FROM_EL, TO_EL>)))));
|
utils::traits::IsTypeOrDerived<FROM_EL, TO_EL>)))));
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Specialization of 'CanReinterpretSlice' for when TO and FROM are equal types.
|
/// Specialization of 'CanReinterpretSlice' for when TO and FROM are equal types.
|
||||||
|
|
|
@ -12,15 +12,15 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef SRC_TINT_TRAITS_H_
|
#ifndef SRC_TINT_UTILS_TRAITS_H_
|
||||||
#define SRC_TINT_TRAITS_H_
|
#define SRC_TINT_UTILS_TRAITS_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace tint::traits {
|
namespace tint::utils::traits {
|
||||||
|
|
||||||
/// Convience type definition for std::decay<T>::type
|
/// Convience type definition for std::decay<T>::type
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -183,6 +183,6 @@ static constexpr bool IsStringLike =
|
||||||
std::is_same_v<Decay<T>, std::string> || std::is_same_v<Decay<T>, std::string_view> ||
|
std::is_same_v<Decay<T>, std::string> || std::is_same_v<Decay<T>, std::string_view> ||
|
||||||
std::is_same_v<Decay<T>, const char*>;
|
std::is_same_v<Decay<T>, const char*>;
|
||||||
|
|
||||||
} // namespace tint::traits
|
} // namespace tint::utils::traits
|
||||||
|
|
||||||
#endif // SRC_TINT_TRAITS_H_
|
#endif // SRC_TINT_UTILS_TRAITS_H_
|
|
@ -12,11 +12,11 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "src/tint/traits.h"
|
#include "src/tint/utils/traits.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
namespace tint::traits {
|
namespace tint::utils::traits {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -241,4 +241,4 @@ TEST(SliceTuple, MixedTupleSliceHighPart) {
|
||||||
static_assert(std::is_same_v<std::tuple_element_t<1, sliced>, float>);
|
static_assert(std::is_same_v<std::tuple_element_t<1, sliced>, float>);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint::traits
|
} // namespace tint::utils::traits
|
|
@ -20,7 +20,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/tint/traits.h"
|
#include "src/tint/utils/traits.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
namespace tint::utils {
|
namespace tint::utils {
|
||||||
|
|
Loading…
Reference in New Issue