// Copyright 2025-present the zvec project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include using namespace zvec::ailego; TEST(Cube, TypeInfo) { std::cout << "* bool: " << typeid(bool).name() << std::endl; std::cout << "* int8_t: " << typeid(int8_t).name() << std::endl; std::cout << "* char: " << typeid(char).name() << std::endl; std::cout << "* signed char: " << typeid(signed char).name() << std::endl; std::cout << "* uint8_t: " << typeid(uint8_t).name() << std::endl; std::cout << "* unsigned char: " << typeid(unsigned char).name() << std::endl; std::cout << "* int16_t: " << typeid(int16_t).name() << std::endl; std::cout << "* short: " << typeid(short).name() << std::endl; std::cout << "* signed short: " << typeid(signed short).name() << std::endl; std::cout << "* uint16_t: " << typeid(uint16_t).name() << std::endl; std::cout << "* unsigned short: " << typeid(unsigned short).name() << std::endl; std::cout << "* int32_t: " << typeid(int32_t).name() << std::endl; std::cout << "* int: " << typeid(int).name() << std::endl; std::cout << "* signed int: " << typeid(signed int).name() << std::endl; std::cout << "* uint32_t: " << typeid(uint32_t).name() << std::endl; std::cout << "* unsigned int: " << typeid(unsigned int).name() << std::endl; std::cout << "* int64_t: " << typeid(int64_t).name() << std::endl; std::cout << "* long: " << typeid(long).name() << std::endl; std::cout << "* signed long: " << typeid(signed long).name() << std::endl; std::cout << "* uint64_t: " << typeid(uint64_t).name() << std::endl; std::cout << "* unsigned long: " << typeid(unsigned long).name() << std::endl; std::cout << "* long long: " << typeid(long).name() << std::endl; std::cout << "* signed long long: " << typeid(signed long).name() << std::endl; std::cout << "* unsigned long long: " << typeid(unsigned long).name() << std::endl; } TEST(Cube, General) { Cube cube1 = 11111; EXPECT_EQ(11111, cube1.unsafe_cast()); EXPECT_EQ(11111, cube1.cast()); int int1 = cube1; EXPECT_EQ(11111, int1); EXPECT_TRUE(!cube1.empty()); EXPECT_EQ(sizeof(int), cube1.size()); Cube cube2 = 22222; EXPECT_EQ(22222, cube2.unsafe_cast()); EXPECT_EQ(22222, cube2.cast()); int int2 = (const int &)cube2; EXPECT_EQ(22222, int2); EXPECT_TRUE(!cube2.empty()); EXPECT_EQ(sizeof(int), cube2.size()); Cube cube3 = std::vector(); cube3.unsafe_cast>().push_back(1); cube3.unsafe_cast>().push_back(2); cube3.unsafe_cast>().push_back(3); EXPECT_EQ(3u, cube3.unsafe_cast>().size()); EXPECT_EQ(3u, cube3.cast>().size()); std::vector &vec3 = cube3; EXPECT_EQ(3u, vec3.size()); EXPECT_TRUE(!cube3.empty()); EXPECT_EQ(sizeof(std::vector), cube3.size()); std::vector vec4; vec4.push_back(1); vec4.push_back(2); vec4.push_back(3); vec4.push_back(4); Cube cube4 = vec4; EXPECT_EQ(4u, cube4.unsafe_cast>().size()); EXPECT_EQ(4u, cube4.cast>().size()); const std::vector &vec44 = cube4; EXPECT_EQ(4u, vec44.size()); EXPECT_TRUE(!cube4.empty()); EXPECT_EQ(sizeof(std::vector), cube4.size()); Cube cube5, cube6; EXPECT_TRUE(cube5.empty()); EXPECT_TRUE(cube6.empty()); EXPECT_EQ(cube5.type(), cube6.type()); EXPECT_EQ(0u, cube5.size()); EXPECT_EQ(0u, cube6.size()); EXPECT_EQ(cube1.type(), cube2.type()); EXPECT_NE(cube3.type(), cube4.type()); EXPECT_NE(cube1.type(), cube3.type()); EXPECT_NE(cube2.type(), cube4.type()); EXPECT_NE(cube1.type(), cube5.type()); EXPECT_NE(cube2.type(), cube5.type()); EXPECT_NE(cube3.type(), cube5.type()); EXPECT_NE(cube4.type(), cube5.type()); EXPECT_TRUE(cube1.compatible(cube2)); EXPECT_TRUE(cube5.compatible(cube6)); EXPECT_FALSE(cube1.compatible(cube3)); EXPECT_FALSE(cube3.compatible(cube5)); cube1.reset(); cube3.reset(); cube5.reset(); cube6.reset(); EXPECT_TRUE(cube1.empty()); EXPECT_TRUE(cube3.empty()); EXPECT_TRUE(cube5.empty()); EXPECT_TRUE(cube6.empty()); } TEST(Cube, LargeObject) { std::string str1("1111111"); std::string str2("2222222"); std::string str3("3333333"); std::string str4("4444444"); std::string str5("5555555"); std::string str6("6666666"); std::string str7("7777777"); Cube cube1(str1); Cube cube2; cube2 = str2; Cube cube3 = str3; EXPECT_EQ(str1, cube1.cast()); EXPECT_EQ(str2, cube2.cast()); EXPECT_TRUE(cube1.compatible(cube2)); cube1 = std::move(cube2); EXPECT_EQ(str2, cube1.cast()); EXPECT_TRUE(cube2.empty()); EXPECT_FALSE(cube1.compatible(cube2)); EXPECT_EQ(str3, cube3.cast()); cube3 = cube1; EXPECT_EQ(str2, cube3.cast()); EXPECT_EQ(str2, cube1.cast()); // Test Constructor Cube(T &&rhs) / Cube(const T &rhs) Cube cube41(std::string("444444")); Cube cube42(str4); EXPECT_NE(std::string(""), str4); Cube cube43(std::move(str4)); EXPECT_EQ(std::string(""), str4); const std::string str41 = str4; Cube cube44(str41); EXPECT_EQ(str41, str4); EXPECT_EQ(str4, cube44.cast()); // Test Assignment operator=(T &&rhs) / operator=(const T &rhs) Cube cube51, cube52, cube53, cube54; cube51 = std::string("55555"); cube52 = str5; EXPECT_NE(std::string(""), str5); cube53 = std::move(str5); EXPECT_EQ(std::string(""), str5); const std::string str51 = str5; cube54 = str51; EXPECT_EQ(str51, str5); EXPECT_EQ(str5, cube54.cast()); // Test Constructor Cube(Cube &&rhs) / Cube(const Cube &rhs) Cube cube6(str6); Cube cube61(cube6); EXPECT_EQ(str6, cube61.cast()); EXPECT_FALSE(cube6.empty()); Cube cube62(std::move(cube6)); EXPECT_EQ(str6, cube62.cast()); EXPECT_TRUE(cube6.empty()); const Cube cube63 = cube62; Cube cube64(cube63); EXPECT_EQ(str6, cube64.cast()); EXPECT_FALSE(cube63.empty()); // Test Assignment operator=(Cube &&rhs) / operator=(const Cube &rhs) Cube cube7(str7), cube71, cube72; cube71 = cube7; EXPECT_EQ(str7, cube71.cast()); EXPECT_FALSE(cube7.empty()); cube72 = std::move(cube7); EXPECT_EQ(str7, cube72.cast()); EXPECT_TRUE(cube7.empty()); const Cube cube73(cube72); Cube cube74; cube74 = cube73; EXPECT_EQ(str7, cube74.cast()); EXPECT_EQ(str7, cube73.cast()); EXPECT_FALSE(cube74.empty()); } struct SmallObject { SmallObject() { ++assign_count; } SmallObject(const SmallObject &) { ++clone_count; } SmallObject(SmallObject &&) { ++move_count; } ~SmallObject() { ++cleanup_count; } int val{0}; static int assign_count; static int clone_count; static int move_count; static int cleanup_count; }; int SmallObject::assign_count = 0; int SmallObject::clone_count = 0; int SmallObject::move_count = 0; int SmallObject::cleanup_count = 0; TEST(Cube, CubePolicy) { EXPECT_EQ(0, SmallObject::assign_count); EXPECT_EQ(0, SmallObject::clone_count); EXPECT_EQ(0, SmallObject::move_count); EXPECT_EQ(0, SmallObject::cleanup_count); SmallObject obj1, obj2, obj3, obj4, obj5; EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(0, SmallObject::clone_count); EXPECT_EQ(0, SmallObject::move_count); EXPECT_EQ(0, SmallObject::cleanup_count); Cube cube1(obj1); EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(1, SmallObject::clone_count); EXPECT_EQ(0, SmallObject::move_count); EXPECT_EQ(0, SmallObject::cleanup_count); Cube cube2(std::move(obj2)); EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(1, SmallObject::clone_count); EXPECT_EQ(1, SmallObject::move_count); EXPECT_EQ(0, SmallObject::cleanup_count); { Cube cube3(std::move(obj3)); EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(1, SmallObject::clone_count); EXPECT_EQ(2, SmallObject::move_count); EXPECT_EQ(0, SmallObject::cleanup_count); } EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(1, SmallObject::clone_count); EXPECT_EQ(2, SmallObject::move_count); EXPECT_EQ(1, SmallObject::cleanup_count); { Cube cube4(obj4); EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(2, SmallObject::clone_count); EXPECT_EQ(2, SmallObject::move_count); EXPECT_EQ(1, SmallObject::cleanup_count); } EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(2, SmallObject::clone_count); EXPECT_EQ(2, SmallObject::move_count); EXPECT_EQ(2, SmallObject::cleanup_count); { Cube cube5(obj5); EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(3, SmallObject::clone_count); EXPECT_EQ(2, SmallObject::move_count); EXPECT_EQ(2, SmallObject::cleanup_count); } EXPECT_EQ(5, SmallObject::assign_count); EXPECT_EQ(3, SmallObject::clone_count); EXPECT_EQ(2, SmallObject::move_count); EXPECT_EQ(3, SmallObject::cleanup_count); } TEST(Cube, SmallObject) { uint64_t uint1 = 1111111; uint64_t uint2 = 2222222; uint64_t uint3 = 3333333; uint64_t uint4 = 4444444; uint64_t uint5 = 5555555; uint64_t uint6 = 6666666; uint64_t uint7 = 7777777; Cube cube1(uint1); Cube cube2; cube2 = uint2; Cube cube3 = uint3; EXPECT_EQ(uint1, cube1.cast()); EXPECT_EQ(uint2, cube2.cast()); EXPECT_TRUE(cube1.compatible(cube2)); cube1 = std::move(cube2); EXPECT_EQ(uint2, cube1.cast()); EXPECT_TRUE(cube2.empty()); EXPECT_FALSE(cube1.compatible(cube2)); EXPECT_EQ(uint3, cube3.cast()); cube3 = cube1; EXPECT_EQ(uint2, cube3.cast()); EXPECT_EQ(uint2, cube1.cast()); // Test Conuintuctor Cube(T &&rhs) / Cube(const T &rhs) Cube cube41(uint64_t(444444)); Cube cube42(uint4); EXPECT_NE(uint64_t(0), uint4); Cube cube43(std::move(uint4)); EXPECT_NE(uint64_t(0), uint4); const uint64_t uint41 = uint4; Cube cube44(uint41); EXPECT_EQ(uint41, uint4); EXPECT_EQ(uint4, cube44.cast()); // Test Assignment operator=(T &&rhs) / operator=(const T &rhs) Cube cube51, cube52, cube53, cube54; cube51 = uint64_t(55555); cube52 = uint5; EXPECT_NE(uint64_t(0), uint5); cube53 = std::move(uint5); EXPECT_NE(uint64_t(0), uint5); const uint64_t uint51 = uint5; cube54 = uint51; EXPECT_EQ(uint51, uint5); EXPECT_EQ(uint5, cube54.cast()); // Test Conuintuctor Cube(Cube &&rhs) / Cube(const Cube &rhs) Cube cube6(uint6); Cube cube61(cube6); EXPECT_EQ(uint6, cube61.cast()); EXPECT_FALSE(cube6.empty()); Cube cube62(std::move(cube6)); EXPECT_EQ(uint6, cube62.cast()); EXPECT_TRUE(cube6.empty()); const Cube cube63 = cube62; Cube cube64(cube63); EXPECT_EQ(uint6, cube64.cast()); EXPECT_FALSE(cube63.empty()); // Test Assignment operator=(Cube &&rhs) / operator=(const Cube &rhs) Cube cube7(uint7), cube71, cube72; cube71 = cube7; EXPECT_EQ(uint7, cube71.cast()); EXPECT_FALSE(cube7.empty()); cube72 = std::move(cube7); EXPECT_EQ(uint7, cube72.cast()); EXPECT_TRUE(cube7.empty()); const Cube cube73(cube72); Cube cube74; cube74 = cube73; EXPECT_EQ(uint7, cube74.cast()); EXPECT_EQ(uint7, cube73.cast()); EXPECT_FALSE(cube74.empty()); } enum EnumValueType { Unknown, Binary, Float, Double }; enum class EnumClassType { Unknown, RED, GREEN, BLUE }; TEST(Cube, EnumObject) { std::cout << "* uint32_t: " << typeid(uint32_t).name() << std::endl; std::cout << "* int32_t: " << typeid(int32_t).name() << std::endl; std::cout << "* EnumValueType: " << typeid(EnumValueType).name() << std::endl; std::cout << "* EnumValueType (underlying_type): " << typeid(typename std::underlying_type::type).name() << std::endl; std::cout << "* EnumClassType: " << typeid(EnumClassType).name() << std::endl; std::cout << "* EnumClassType (underlying_type): " << typeid(typename std::underlying_type::type).name() << std::endl; EnumValueType a(EnumValueType::Binary), c(EnumValueType::Unknown); EnumClassType b(EnumClassType::RED), d(EnumClassType::Unknown); Cube cubeA(a); Cube cubeB(b); EXPECT_EQ(a, cubeA.cast()); EXPECT_NE(c, cubeA.cast()); c = cubeA.cast(); EXPECT_EQ(a, c); EXPECT_EQ(b, cubeB.cast()); EXPECT_NE(d, cubeB.cast()); d = cubeB.cast(); EXPECT_EQ(b, d); Cube cubeC((std::underlying_type::type)1); Cube cubeD((std::underlying_type::type)1); std::cout << "* cubeA: " << cubeA.type().name() << std::endl; std::cout << "* cubeB: " << cubeB.type().name() << std::endl; std::cout << "* cubeC: " << cubeC.type().name() << std::endl; std::cout << "* cubeD: " << cubeD.type().name() << std::endl; // EXPECT_TRUE(typeid(std::underlying_type::type) == // typeid(uint32_t)); // EXPECT_TRUE(typeid(std::underlying_type::type) == // typeid(int32_t)); EXPECT_TRUE(cubeA.compatible()); EXPECT_TRUE(cubeB.compatible()); EXPECT_TRUE(cubeA.compatible::type>()); EXPECT_TRUE(cubeB.compatible::type>()); EXPECT_TRUE(cubeC.compatible::type>()); EXPECT_TRUE(cubeD.compatible::type>()); EnumValueType e = (EnumValueType)cubeA.cast::type>(); EnumClassType f = (EnumClassType)cubeB.cast::type>(); EXPECT_EQ(a, e); EXPECT_EQ(b, f); }