diff --git a/libc/test/src/__support/CPP/CMakeLists.txt b/libc/test/src/__support/CPP/CMakeLists.txt index be2bc20d7804..5772a83a65ca 100644 --- a/libc/test/src/__support/CPP/CMakeLists.txt +++ b/libc/test/src/__support/CPP/CMakeLists.txt @@ -106,3 +106,13 @@ add_libc_test( libc.src.__support.CPP.string libc.src.__support.CPP.string_view ) + +add_libc_test( + type_traits_test + SUITE + libc-cpp-utils-tests + SRCS + type_traits_test.cpp + DEPENDS + libc.src.__support.CPP.type_traits +) diff --git a/libc/test/src/__support/CPP/type_traits_test.cpp b/libc/test/src/__support/CPP/type_traits_test.cpp new file mode 100644 index 000000000000..a48d646d29e5 --- /dev/null +++ b/libc/test/src/__support/CPP/type_traits_test.cpp @@ -0,0 +1,300 @@ +//===-- Unittests for type_traits -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/CPP/type_traits.h" +#include "test/UnitTest/Test.h" + +// TODO: Split this file if it becomes too big. + +namespace __llvm_libc::cpp { + +class Class {}; +union Union {}; +struct Struct {}; +enum Enum {}; +enum class EnumClass {}; + +using UnqualObjectTypes = testing::TypeList; + +TYPED_TEST(LlvmLibcTypeTraitsTest, add_lvalue_reference, UnqualObjectTypes) { + // non-ref cv, adds ref + EXPECT_TRUE((is_same_v, T &>)); + EXPECT_TRUE((is_same_v, const T &>)); + EXPECT_TRUE((is_same_v, volatile T &>)); + EXPECT_TRUE(( + is_same_v, const volatile T &>)); + + // pointer cv, adds ref + EXPECT_TRUE((is_same_v, T *&>)); + EXPECT_TRUE((is_same_v, const T *&>)); + EXPECT_TRUE((is_same_v, volatile T *&>)); + EXPECT_TRUE((is_same_v, + const volatile T *&>)); + + // ref cv, returns same type + EXPECT_TRUE((is_same_v, T &>)); + EXPECT_TRUE((is_same_v, const T &>)); + EXPECT_TRUE((is_same_v, volatile T &>)); + EXPECT_TRUE((is_same_v, + const volatile T &>)); +} + +TEST(LlvmLibcTypeTraitsTest, add_lvalue_reference_void) { + // void cannot be referenced + EXPECT_TRUE((is_same_v, void>)); + EXPECT_TRUE((is_same_v, const void>)); + EXPECT_TRUE( + (is_same_v, volatile void>)); + EXPECT_TRUE((is_same_v, + const volatile void>)); +} + +TYPED_TEST(LlvmLibcTypeTraitsTest, add_pointer, UnqualObjectTypes) { + // object types -> pointer type + EXPECT_TRUE((is_same_v, T *>)); + EXPECT_TRUE((is_same_v, const T *>)); + EXPECT_TRUE((is_same_v, volatile T *>)); + EXPECT_TRUE((is_same_v, const volatile T *>)); + + // pointer types -> pointer type + EXPECT_TRUE((is_same_v, T **>)); + EXPECT_TRUE((is_same_v, const T **>)); + EXPECT_TRUE((is_same_v, volatile T **>)); + EXPECT_TRUE( + (is_same_v, const volatile T **>)); + + // reference type -> pointer type + EXPECT_TRUE((is_same_v, T *>)); + EXPECT_TRUE((is_same_v, const T *>)); + EXPECT_TRUE((is_same_v, volatile T *>)); + EXPECT_TRUE( + (is_same_v, const volatile T *>)); +} + +TEST(LlvmLibcTypeTraitsTest, add_pointer_void) { + // void -> pointer type + EXPECT_TRUE((is_same_v, void *>)); + EXPECT_TRUE((is_same_v, const void *>)); + EXPECT_TRUE((is_same_v, volatile void *>)); + EXPECT_TRUE( + (is_same_v, const volatile void *>)); +} + +TYPED_TEST(LlvmLibcTypeTraitsTest, add_rvalue_reference, UnqualObjectTypes) { + + // non-ref cv, adds ref + EXPECT_TRUE((is_same_v, T &&>)); + EXPECT_TRUE((is_same_v, const T &&>)); + EXPECT_TRUE((is_same_v, volatile T &&>)); + EXPECT_TRUE((is_same_v, + const volatile T &&>)); + + // ref cv, returns same type + EXPECT_TRUE((is_same_v, T &>)); + EXPECT_TRUE((is_same_v, const T &>)); + EXPECT_TRUE((is_same_v, volatile T &>)); + EXPECT_TRUE((is_same_v, + const volatile T &>)); +} + +TEST(LlvmLibcTypeTraitsTest, add_rvalue_reference_void) { + // void cannot be referenced + EXPECT_TRUE((is_same_v, void>)); + EXPECT_TRUE((is_same_v, const void>)); + EXPECT_TRUE( + (is_same_v, volatile void>)); + EXPECT_TRUE((is_same_v, + const volatile void>)); +} + +TEST(LlvmLibcTypeTraitsTest, bool_constant) { + EXPECT_TRUE((bool_constant::value)); + EXPECT_FALSE((bool_constant::value)); +} + +TEST(LlvmLibcTypeTraitsTest, conditional_t) { + EXPECT_TRUE((is_same_v, int>)); + EXPECT_TRUE((is_same_v, float>)); +} + +TEST(LlvmLibcTypeTraitsTest, decay) { + EXPECT_TRUE((is_same_v, int>)); + + // array decay + EXPECT_TRUE((is_same_v, int *>)); + EXPECT_TRUE((is_same_v, int *>)); + EXPECT_TRUE((is_same_v, int(*)[4]>)); + + // cv ref decay + EXPECT_TRUE((is_same_v, int>)); + EXPECT_TRUE((is_same_v, int>)); + EXPECT_TRUE((is_same_v, int>)); + EXPECT_TRUE((is_same_v, int>)); +} + +// TODO enable_if + +TEST(LlvmLibcTypeTraitsTest, false_type) { EXPECT_FALSE((false_type::value)); } + +TEST(LlvmLibcTypeTraitsTest, integral_constant) { + EXPECT_EQ((integral_constant::value), 4); +} + +using IntegralAndFloatingTypes = + testing::TypeList; + +TYPED_TEST(LlvmLibcTypeTraitsTest, is_arithmetic, IntegralAndFloatingTypes) { + EXPECT_TRUE((is_arithmetic_v)); + EXPECT_TRUE((is_arithmetic_v)); + EXPECT_TRUE((is_arithmetic_v)); + EXPECT_TRUE((is_arithmetic_v)); + + EXPECT_FALSE((is_arithmetic_v)); + EXPECT_FALSE((is_arithmetic_v)); +} + +TEST(LlvmLibcTypeTraitsTest, is_arithmetic_non_integral) { + EXPECT_FALSE((is_arithmetic_v)); + EXPECT_FALSE((is_arithmetic_v)); + EXPECT_FALSE((is_arithmetic_v)); + EXPECT_FALSE((is_arithmetic_v)); +} + +TEST(LlvmLibcTypeTraitsTest, is_array) { + EXPECT_FALSE((is_array_v)); + EXPECT_FALSE((is_array_v)); + EXPECT_FALSE((is_array_v)); + EXPECT_FALSE((is_array_v)); + + EXPECT_TRUE((is_array_v)); + EXPECT_TRUE((is_array_v)); +} + +TEST(LlvmLibcTypeTraitsTest, is_base_of) { + struct A {}; + EXPECT_TRUE((is_base_of_v)); + + // Test public, protected and private inheritance. + struct B : public A {}; + EXPECT_TRUE((is_base_of_v)); + EXPECT_FALSE((is_base_of_v)); + + struct C : protected A {}; + EXPECT_TRUE((is_base_of_v)); + EXPECT_FALSE((is_base_of_v)); + + struct D : private A {}; + EXPECT_TRUE((is_base_of_v)); + EXPECT_FALSE((is_base_of_v)); + + // Test inheritance chain. + struct E : private B {}; + EXPECT_TRUE((is_base_of_v)); +} + +TEST(LlvmLibcTypeTraitsTest, is_class) { + EXPECT_TRUE((is_class_v)); + EXPECT_TRUE((is_class_v)); + + // Pointer or ref do not qualify. + EXPECT_FALSE((is_class_v)); + EXPECT_FALSE((is_class_v)); + + // Neither other types. + EXPECT_FALSE((is_class_v)); + EXPECT_FALSE((is_class_v)); + EXPECT_FALSE((is_class_v)); +} + +TYPED_TEST(LlvmLibcTypeTraitsTest, is_const, UnqualObjectTypes) { + EXPECT_FALSE((is_const_v)); + EXPECT_TRUE((is_const_v)); + + using Aliased = const T; + EXPECT_TRUE((is_const_v)); +} + +// TODO is_convertible + +TYPED_TEST(LlvmLibcTypeTraitsTest, is_destructible, UnqualObjectTypes) { + EXPECT_TRUE((is_destructible_v)); +} +TEST(LlvmLibcTypeTraitsTest, is_destructible_no_destructor) { + struct S { + ~S() = delete; + }; + EXPECT_FALSE((is_destructible_v)); +} + +TYPED_TEST(LlvmLibcTypeTraitsTest, is_enum, UnqualObjectTypes) { + EXPECT_FALSE((is_enum_v)); +} +TEST(LlvmLibcTypeTraitsTest, is_enum_enum) { + EXPECT_TRUE((is_enum_v)); + EXPECT_TRUE((is_enum_v)); +} + +// TODO is_floating_point + +// TODO is_function + +// TODO is_integral + +// TODO is_lvalue_reference + +// TODO is_member_pointer + +// TODO is_null_pointer + +// TODO is_pointer + +// TODO is_reference + +// TODO is_rvalue_reference + +// TODO is_same + +// TODO is_scalar + +// TODO is_signed + +// TODO is_trivially_constructible + +// TODO is_trivially_copyable + +// TODO is_trivially_destructible + +// TODO is_union + +// TODO is_unsigned + +// TODO is_void + +// TODO make_signed + +// TODO make_unsigned + +// TODO remove_all_extents + +// TODO remove_cv + +// TODO remove_cvref + +// TODO remove_extent + +// TODO remove_reference + +TEST(LlvmLibcTypeTraitsTest, true_type) { EXPECT_TRUE((true_type::value)); } + +// TODO type_identity + +// TODO void_t + +} // namespace __llvm_libc::cpp diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/__support/CPP/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/__support/CPP/BUILD.bazel index c74f9821849a..5ebd82600357 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/__support/CPP/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/__support/CPP/BUILD.bazel @@ -110,3 +110,13 @@ cc_test( "//libc/test/UnitTest:LibcUnitTest", ], ) + +cc_test( + name = "type_traits_test", + srcs = ["type_traits_test.cpp"], + deps = [ + "//libc:__support_cpp_type_traits", + "//libc:libc_root", + "//libc/test/UnitTest:LibcUnitTest", + ], +)