123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- #include "typetraits.h"
- #include <library/cpp/testing/unittest/registar.h>
- #include <vector>
- #include <tuple>
- namespace {
- enum ETestEnum {
- };
- class TPodClass {
- };
- class TNonPodClass {
- TNonPodClass() {
- }
- };
- class TEmptyClass {
- void operator()() const {
- }
- };
- class TAnotherEmptyClass {
- };
- class TEmptyDerivedClass: public TEmptyClass {
- };
- class TEmptyMultiDerivedClass: public TEmptyDerivedClass, public TAnotherEmptyClass {
- /* Not empty under MSVC.
- * MSVC's EBCO implementation can handle only one empty base class. */
- };
- struct TNonEmptyClass {
- TEmptyClass member;
- };
- class TNonEmptyDerivedClass: public TNonEmptyClass {
- };
- class TStdLayoutClass1: public TEmptyClass {
- public:
- int Value1;
- int Value2;
- };
- class TStdLayoutClass2: public TNonEmptyClass {
- };
- class TNonStdLayoutClass1 {
- public:
- int Value1;
- protected:
- int Value2;
- };
- class TNonStdLayoutClass2 {
- public:
- virtual void Func() {
- }
- };
- class TNonStdLayoutClass3: public TNonStdLayoutClass2 {
- };
- class TNonStdLayoutClass4: public TEmptyClass {
- public:
- TEmptyClass Base;
- };
- }
- #define ASSERT_SAME_TYPE(x, y) \
- { \
- const bool x_ = std::is_same<x, y>::value; \
- UNIT_ASSERT_C(x_, #x " != " #y); \
- }
- Y_UNIT_TEST_SUITE(TTypeTraitsTest) {
- Y_UNIT_TEST(TestIsSame) {
- UNIT_ASSERT((std::is_same<int, int>::value));
- UNIT_ASSERT(!(std::is_same<signed int, unsigned int>::value));
- }
- Y_UNIT_TEST(TestRemoveReference) {
- ASSERT_SAME_TYPE(std::remove_reference_t<int>, int);
- ASSERT_SAME_TYPE(std::remove_reference_t<const int>, const int);
- ASSERT_SAME_TYPE(std::remove_reference_t<int&>, int);
- ASSERT_SAME_TYPE(std::remove_reference_t<const int&>, const int);
- ASSERT_SAME_TYPE(std::remove_reference_t<int&&>, int);
- ASSERT_SAME_TYPE(std::remove_reference_t<const int&&>, const int);
- class TIncompleteType;
- ASSERT_SAME_TYPE(std::remove_reference_t<TIncompleteType&>, TIncompleteType);
- }
- Y_UNIT_TEST(TestRemoveConst) {
- ASSERT_SAME_TYPE(std::remove_const_t<const int>, int);
- }
- Y_UNIT_TEST(TestRemoveVolatile) {
- ASSERT_SAME_TYPE(std::remove_volatile_t<volatile int>, int);
- }
- Y_UNIT_TEST(TestRemoveCV) {
- ASSERT_SAME_TYPE(std::remove_cv_t<const volatile int>, int);
- }
- Y_UNIT_TEST(TestAddCV) {
- ASSERT_SAME_TYPE(std::add_cv_t<int>, const volatile int);
- }
- Y_UNIT_TEST(TestClass) {
- UNIT_ASSERT(std::is_class<TString>::value);
- UNIT_ASSERT(!std::is_class<ETestEnum>::value);
- UNIT_ASSERT(!std::is_class<int>::value);
- UNIT_ASSERT(!std::is_class<void*>::value);
- }
- template <class T>
- inline void TestArithmeticType() {
- UNIT_ASSERT(std::is_arithmetic<T>::value);
- UNIT_ASSERT(std::is_arithmetic<const T>::value);
- UNIT_ASSERT(std::is_arithmetic<volatile T>::value);
- UNIT_ASSERT(std::is_arithmetic<const volatile T>::value);
- UNIT_ASSERT(!std::is_arithmetic<T&>::value);
- UNIT_ASSERT(!std::is_arithmetic<T&&>::value);
- UNIT_ASSERT(!std::is_arithmetic<T*>::value);
- bool a;
- a = std::is_same<typename TTypeTraits<T>::TFuncParam, T>::value;
- UNIT_ASSERT(a);
- a = std::is_same<typename TTypeTraits<const volatile T>::TFuncParam, const volatile T>::value;
- UNIT_ASSERT(a);
- }
- template <class T>
- inline void TestUnsignedIntType() {
- UNIT_ASSERT(std::is_unsigned<T>::value);
- UNIT_ASSERT(std::is_unsigned<const T>::value);
- UNIT_ASSERT(std::is_unsigned<volatile T>::value);
- UNIT_ASSERT(std::is_unsigned<const volatile T>::value);
- UNIT_ASSERT(!std::is_unsigned<T&>::value);
- UNIT_ASSERT(!std::is_unsigned<T&&>::value);
- UNIT_ASSERT(!std::is_unsigned<T*>::value);
- enum ETypedEnum: T {};
- UNIT_ASSERT(!std::is_unsigned<ETypedEnum>::value);
- }
- template <class T>
- inline void TestSignedIntType() {
- UNIT_ASSERT(std::is_signed<T>::value);
- UNIT_ASSERT(std::is_signed<const T>::value);
- UNIT_ASSERT(std::is_signed<volatile T>::value);
- UNIT_ASSERT(std::is_signed<const volatile T>::value);
- UNIT_ASSERT(!std::is_signed<T&>::value);
- UNIT_ASSERT(!std::is_signed<T&&>::value);
- UNIT_ASSERT(!std::is_signed<T*>::value);
- enum ETypedEnum: T {};
- UNIT_ASSERT(!std::is_signed<ETypedEnum>::value);
- }
- Y_UNIT_TEST(TestBool) {
- TestArithmeticType<bool>();
- TestUnsignedIntType<bool>();
- }
- Y_UNIT_TEST(TestUnsignedChar) {
- TestArithmeticType<unsigned char>();
- TestUnsignedIntType<unsigned char>();
- }
- Y_UNIT_TEST(TestSizeT) {
- TestArithmeticType<size_t>();
- TestUnsignedIntType<size_t>();
- }
- Y_UNIT_TEST(TestInt) {
- TestArithmeticType<int>();
- TestSignedIntType<int>();
- }
- Y_UNIT_TEST(TestDouble) {
- TestArithmeticType<double>();
- }
- Y_UNIT_TEST(TestLongDouble) {
- TestArithmeticType<long double>();
- }
- Y_UNIT_TEST(TestAddRValueReference) {
- ASSERT_SAME_TYPE(std::add_rvalue_reference_t<int>, int&&);
- ASSERT_SAME_TYPE(std::add_rvalue_reference_t<int const&>, int const&);
- ASSERT_SAME_TYPE(std::add_rvalue_reference_t<int*>, int*&&);
- ASSERT_SAME_TYPE(std::add_rvalue_reference_t<int*&>, int*&);
- ASSERT_SAME_TYPE(std::add_rvalue_reference_t<int&&>, int&&);
- ASSERT_SAME_TYPE(std::add_rvalue_reference_t<void>, void);
- }
- Y_UNIT_TEST(TestIsEmpty) {
- UNIT_ASSERT(std::is_empty<TEmptyClass>::value);
- UNIT_ASSERT(std::is_empty<TEmptyDerivedClass>::value);
- UNIT_ASSERT(std::is_empty<TAnotherEmptyClass>::value);
- #ifdef _MSC_VER
- UNIT_ASSERT(!std::is_empty<TEmptyMultiDerivedClass>::value);
- #else
- UNIT_ASSERT(std::is_empty<TEmptyMultiDerivedClass>::value);
- #endif
- UNIT_ASSERT(!std::is_empty<TNonEmptyClass>::value);
- UNIT_ASSERT(!std::is_empty<TNonEmptyDerivedClass>::value);
- }
- Y_UNIT_TEST(TestIsStandardLayout) {
- UNIT_ASSERT(std::is_standard_layout<TStdLayoutClass1>::value);
- UNIT_ASSERT(std::is_standard_layout<TStdLayoutClass2>::value);
- UNIT_ASSERT(!std::is_standard_layout<TNonStdLayoutClass1>::value);
- UNIT_ASSERT(!std::is_standard_layout<TNonStdLayoutClass2>::value);
- UNIT_ASSERT(!std::is_standard_layout<TNonStdLayoutClass3>::value);
- UNIT_ASSERT(!std::is_standard_layout<TNonStdLayoutClass4>::value);
- }
- template <class T>
- using TTrySum = decltype(std::declval<T>() + std::declval<T>());
- Y_UNIT_TEST(TestIsTriviallyCopyable) {
- struct TPod {
- int value;
- };
- struct TNontriviallyCopyAssignable {
- TNontriviallyCopyAssignable(const TNontriviallyCopyAssignable&) = default;
- TNontriviallyCopyAssignable& operator=(const TNontriviallyCopyAssignable&);
- };
- struct TNonTriviallyCopyConstructible {
- TNonTriviallyCopyConstructible(const TNonTriviallyCopyConstructible&);
- TNonTriviallyCopyConstructible& operator=(const TNonTriviallyCopyConstructible&) = default;
- };
- struct TNonTriviallyDestructible {
- TNonTriviallyDestructible(const TNonTriviallyDestructible&) = default;
- TNonTriviallyDestructible& operator=(const TNonTriviallyDestructible&) = default;
- ~TNonTriviallyDestructible();
- };
- UNIT_ASSERT(std::is_trivially_copyable<int>::value);
- UNIT_ASSERT(std::is_trivially_copyable<TPod>::value);
- UNIT_ASSERT(!std::is_trivially_copyable<TNontriviallyCopyAssignable>::value);
- UNIT_ASSERT(!std::is_trivially_copyable<TNonTriviallyCopyConstructible>::value);
- UNIT_ASSERT(!std::is_trivially_copyable<TNonTriviallyDestructible>::value);
- }
- }
- namespace {
- template <typename T>
- struct TTypeTraitsExpected;
- template <>
- struct TTypeTraitsExpected<void> {
- enum { IsIntegral = false };
- enum { IsArithmetic = false };
- enum { IsPod = true };
- enum { IsVolatile = false };
- enum { IsConstant = false };
- enum { IsPointer = false };
- enum { IsReference = false };
- enum { IsLvalueReference = false };
- enum { IsRvalueReference = false };
- enum { IsArray = false };
- enum { IsClassType = false };
- enum { IsVoid = true };
- enum { IsEnum = false };
- };
- template <>
- struct TTypeTraitsExpected<int>: public TTypeTraitsExpected<void> {
- enum { IsIntegral = true };
- enum { IsArithmetic = true };
- enum { IsVoid = false };
- };
- template <>
- struct TTypeTraitsExpected<size_t>: public TTypeTraitsExpected<int> {
- };
- template <>
- struct TTypeTraitsExpected<float>: public TTypeTraitsExpected<int> {
- enum { IsIntegral = false };
- };
- template <>
- struct TTypeTraitsExpected<long double>: public TTypeTraitsExpected<float> {
- };
- template <>
- struct TTypeTraitsExpected<const int>: public TTypeTraitsExpected<int> {
- enum { IsConstant = true };
- };
- template <>
- struct TTypeTraitsExpected<volatile int>: public TTypeTraitsExpected<int> {
- enum { IsVolatile = true };
- };
- template <>
- struct TTypeTraitsExpected<ETestEnum>: public TTypeTraitsExpected<int> {
- enum { IsIntegral = false };
- enum { IsArithmetic = false };
- enum { IsEnum = true };
- };
- template <>
- struct TTypeTraitsExpected<TPodClass>: public TTypeTraitsExpected<void> {
- enum { IsClassType = true };
- enum { IsVoid = false };
- };
- template <>
- struct TTypeTraitsExpected<TNonPodClass>: public TTypeTraitsExpected<TPodClass> {
- enum { IsPod = false };
- };
- template <>
- struct TTypeTraitsExpected<TNonPodClass&>: public TTypeTraitsExpected<TNonPodClass> {
- enum { IsClassType = false };
- enum { IsReference = true };
- enum { IsLvalueReference = true };
- };
- template <>
- struct TTypeTraitsExpected<TNonPodClass&&>: public TTypeTraitsExpected<TNonPodClass> {
- enum { IsClassType = false };
- enum { IsReference = true };
- enum { IsRvalueReference = true };
- };
- template <>
- struct TTypeTraitsExpected<const TNonPodClass&>: public TTypeTraitsExpected<TNonPodClass&> {
- };
- template <>
- struct TTypeTraitsExpected<float*>: public TTypeTraitsExpected<int> {
- enum { IsIntegral = false };
- enum { IsArithmetic = false };
- enum { IsPointer = true };
- };
- template <>
- struct TTypeTraitsExpected<float&>: public TTypeTraitsExpected<float*> {
- enum { IsPointer = false };
- enum { IsReference = true };
- enum { IsLvalueReference = true };
- };
- template <>
- struct TTypeTraitsExpected<float&&>: public TTypeTraitsExpected<float*> {
- enum { IsPointer = false };
- enum { IsReference = true };
- enum { IsRvalueReference = true };
- };
- template <>
- struct TTypeTraitsExpected<const float&>: public TTypeTraitsExpected<float&> {
- };
- template <>
- struct TTypeTraitsExpected<float[17]>: public TTypeTraitsExpected<int> {
- enum { IsIntegral = false };
- enum { IsArithmetic = false };
- enum { IsArray = true };
- };
- }
- #define UNIT_ASSERT_EQUAL_ENUM(expected, actual) UNIT_ASSERT_VALUES_EQUAL((bool)(expected), (bool)(actual))
- Y_UNIT_TEST_SUITE(TTypeTraitsTestNg) {
- template <typename T>
- void TestImpl() {
- //UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsPod, TTypeTraits<T>::IsPod);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsVoid, std::is_void<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsEnum, std::is_enum<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsIntegral, std::is_integral<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsArithmetic, std::is_arithmetic<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsVolatile, std::is_volatile<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsConstant, std::is_const<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsPointer, std::is_pointer<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsReference, std::is_reference<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsLvalueReference, std::is_lvalue_reference<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsRvalueReference, std::is_rvalue_reference<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsArray, std::is_array<T>::value);
- UNIT_ASSERT_EQUAL_ENUM(TTypeTraitsExpected<T>::IsClassType, std::is_class<T>::value);
- }
- #define TYPE_TEST(name, type) \
- Y_UNIT_TEST(name) { \
- TestImpl<type>(); \
- }
- TYPE_TEST(Void, void)
- TYPE_TEST(Int, int)
- TYPE_TEST(Float, float)
- TYPE_TEST(LongDouble, long double)
- TYPE_TEST(SizeT, size_t)
- TYPE_TEST(VolatileInt, volatile int)
- TYPE_TEST(ConstInt, const int)
- TYPE_TEST(Enum, ETestEnum)
- TYPE_TEST(FloatPointer, float*)
- TYPE_TEST(FloatReference, float&)
- TYPE_TEST(FloatConstReference, const float&)
- TYPE_TEST(FloatArray, float[17])
- TYPE_TEST(PodClass, TPodClass)
- TYPE_TEST(NonPodClass, TNonPodClass)
- TYPE_TEST(NonPodClassReference, TNonPodClass&)
- TYPE_TEST(NonPodClassConstReference, const TNonPodClass&)
- }
- enum E4 {
- X
- };
- enum class E64: ui64 {
- X
- };
- enum class E8: ui8 {
- X
- };
- // test for std::underlying_type_t
- static_assert(sizeof(std::underlying_type_t<E4>) == sizeof(int), "");
- static_assert(sizeof(std::underlying_type_t<E64>) == sizeof(ui64), "");
- static_assert(sizeof(std::underlying_type_t<E8>) == sizeof(ui8), "");
- // tests for TFixedWidthUnsignedInt
- static_assert(std::is_same<ui8, TFixedWidthUnsignedInt<i8>>::value, "");
- static_assert(std::is_same<ui16, TFixedWidthUnsignedInt<i16>>::value, "");
- static_assert(std::is_same<ui32, TFixedWidthUnsignedInt<i32>>::value, "");
- static_assert(std::is_same<ui64, TFixedWidthUnsignedInt<i64>>::value, "");
- // tests for TFixedWidthSignedInt
- static_assert(std::is_same<i8, TFixedWidthSignedInt<ui8>>::value, "");
- static_assert(std::is_same<i16, TFixedWidthSignedInt<ui16>>::value, "");
- static_assert(std::is_same<i32, TFixedWidthSignedInt<ui32>>::value, "");
- static_assert(std::is_same<i64, TFixedWidthSignedInt<ui64>>::value, "");
- // test for TIsSpecializationOf
- static_assert(TIsSpecializationOf<std::vector, std::vector<int>>::value, "");
- static_assert(TIsSpecializationOf<std::tuple, std::tuple<int, double, char>>::value, "");
- static_assert(!TIsSpecializationOf<std::vector, std::tuple<int, double, char>>::value, "");
- static_assert(!TIsSpecializationOf<std::pair, std::vector<int>>::value, "");
- // test for TIsTemplateBaseOf
- static_assert(TIsTemplateBaseOf<std::vector, std::vector<int>>::value);
- static_assert(TIsTemplateBaseOf<std::tuple, std::tuple<int, double, char>>::value);
- static_assert(TIsTemplateBaseOf<std::basic_string_view, std::wstring_view>::value);
- static_assert(TIsTemplateBaseOf<std::vector, TVector<int>>::value);
- static_assert(!TIsTemplateBaseOf<TVector, std::vector<int>>::value);
- static_assert(TIsTemplateBaseOf<TBasicStringBuf, TWtringBuf>::value);
- static_assert(TIsTemplateBaseOf<std::basic_string_view, TUtf32StringBuf>::value);
- static_assert(TIsTemplateBaseOf<std::basic_string_view, TWtringBuf>::value);
- // test for TIsIterable
- static_assert(TIsIterable<std::vector<int>>::value, "");
- static_assert(!TIsIterable<int>::value, "");
- static_assert(TIsIterable<int[42]>::value, "");
- // test for TDependentFalse
- static_assert(TDependentFalse<int> == false);
- static_assert(TDependentFalse<TNonPodClass> == false);
- static_assert(TValueDependentFalse<0x1000> == false);
|