diff options
author | Vitaly Buka <vitalybuka@google.com> | 2021-11-17 15:05:16 -0800 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2021-11-17 17:52:40 -0800 |
commit | 02eca53a50ea306d2d4fb305364fd538b2cfc0be (patch) | |
tree | 2ef3c91f93cb50f69200734902f6f056324eae60 | |
parent | af9f3c6d86b4afc93fb0a29ee430fc42f593800f (diff) | |
download | llvm-02eca53a50ea306d2d4fb305364fd538b2cfc0be.tar.gz |
[sanitizer] Add a few of type_traits tools
For D114047
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_type_traits.h | 79 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/tests/sanitizer_type_traits_test.cpp | 53 |
2 files changed, 131 insertions, 1 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_type_traits.h b/compiler-rt/lib/sanitizer_common/sanitizer_type_traits.h index 2a58d9874d2c..06a44d1b5c7a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_type_traits.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_type_traits.h @@ -13,6 +13,8 @@ #ifndef SANITIZER_TYPE_TRAITS_H #define SANITIZER_TYPE_TRAITS_H +#include "sanitizer_common/sanitizer_internal_defs.h" + namespace __sanitizer { struct true_type { @@ -57,6 +59,83 @@ struct conditional<false, T, F> { using type = F; }; +template <class T> +struct remove_reference { + using type = T; +}; +template <class T> +struct remove_reference<T&> { + using type = T; +}; +template <class T> +struct remove_reference<T&&> { + using type = T; +}; + +template <class T> +WARN_UNUSED_RESULT inline typename remove_reference<T>::type&& move(T&& t) { + return static_cast<typename remove_reference<T>::type&&>(t); +} + +template <class T> +WARN_UNUSED_RESULT inline constexpr T&& forward( + typename remove_reference<T>::type& t) { + return static_cast<T&&>(t); +} + +template <class T> +WARN_UNUSED_RESULT inline constexpr T&& forward( + typename remove_reference<T>::type&& t) { + return static_cast<T&&>(t); +} + +template <class T, T v> +struct integral_constant { + static constexpr const T value = v; + typedef T value_type; + typedef integral_constant type; + constexpr operator value_type() const { return value; } + constexpr value_type operator()() const { return value; } +}; + +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +#if __has_builtin(__is_trivially_destructible) + +template <class T> +struct is_trivially_destructible + : public integral_constant<bool, __is_trivially_destructible(T)> {}; + +#elif __has_builtin(__has_trivial_destructor) + +template <class T> +struct is_trivially_destructible + : public integral_constant<bool, __has_trivial_destructor(T)> {}; + +#else + +template <class T> +struct is_trivially_destructible + : public integral_constant<bool, /* less efficient fallback */ false> {}; + +#endif + +#if __has_builtin(__is_trivially_copyable) + +template <class T> +struct is_trivially_copyable + : public integral_constant<bool, __is_trivially_copyable(T)> {}; + +#else + +template <class T> +struct is_trivially_copyable + : public integral_constant<bool, /* less efficient fallback */ false> {}; + +#endif + } // namespace __sanitizer #endif diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_type_traits_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_type_traits_test.cpp index 40f6e47e526f..d6c3ad4b8661 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_type_traits_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_type_traits_test.cpp @@ -10,10 +10,13 @@ // //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_type_traits.h" + +#include <vector> + #include "gtest/gtest.h" #include "sanitizer_common/sanitizer_internal_defs.h" -using namespace __sanitizer; +namespace __sanitizer { TEST(SanitizerCommon, IsSame) { ASSERT_TRUE((is_same<unsigned, unsigned>::value)); @@ -30,3 +33,51 @@ TEST(SanitizerCommon, Conditional) { ASSERT_TRUE((is_same<int, conditional<true, int, double>::type>::value)); ASSERT_TRUE((is_same<double, conditional<false, int, double>::type>::value)); } + +TEST(SanitizerCommon, RemoveReference) { + ASSERT_TRUE((is_same<int, remove_reference<int>::type>::value)); + ASSERT_TRUE((is_same<const int, remove_reference<const int>::type>::value)); + ASSERT_TRUE((is_same<int, remove_reference<int&>::type>::value)); + ASSERT_TRUE((is_same<const int, remove_reference<const int&>::type>::value)); + ASSERT_TRUE((is_same<int, remove_reference<int&&>::type>::value)); +} + +TEST(SanitizerCommon, Move) { + std::vector<int> v = {1, 2, 3}; + auto v2 = __sanitizer::move(v); + EXPECT_EQ(3u, v2.size()); + EXPECT_TRUE(v.empty()); +} + +TEST(SanitizerCommon, Forward) { + std::vector<int> v = {1, 2, 3}; + auto v2 = __sanitizer::forward<std::vector<int>>(v); + EXPECT_EQ(3u, v2.size()); + EXPECT_TRUE(v.empty()); +} + +TEST(SanitizerCommon, ForwardConst) { + const std::vector<int> v = {1, 2, 3}; + auto v2 = __sanitizer::forward<const std::vector<int>&>(v); + EXPECT_EQ(3u, v2.size()); + EXPECT_EQ(3u, v.size()); +} + +struct TestStruct { + int a; + float b; +}; + +TEST(SanitizerCommon, IsTriviallyDestructible) { + ASSERT_TRUE((is_trivially_destructible<int>::value)); + ASSERT_TRUE((is_trivially_destructible<TestStruct>::value)); + ASSERT_FALSE((is_trivially_destructible<std::vector<int>>::value)); +} + +TEST(SanitizerCommon, IsTriviallyCopyable) { + ASSERT_TRUE((is_trivially_copyable<int>::value)); + ASSERT_TRUE((is_trivially_copyable<TestStruct>::value)); + ASSERT_FALSE((is_trivially_copyable<std::vector<int>>::value)); +} + +} // namespace __sanitizer
\ No newline at end of file |