diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e183c3..6639423 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,20 @@ cmake_minimum_required(VERSION 3.27) project(utempl) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) find_package(fmt REQUIRED) +find_package(Boost 1.84.0 REQUIRED) set(CMAKE_CXX_STANDART 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CXX_EXTENSIONS NO) -FIND_PACKAGE(Boost 1.84.0 REQUIRED) add_library(utempl INTERFACE) target_link_libraries(utempl INTERFACE fmt::fmt-header-only ${Boost_LIBRARIES}) +if(ENABLE_TESTS) + find_package(GTest REQUIRED) + enable_testing() + file(GLOB SOURCES tests/* tests/*/* tests/*/*/*) + add_executable(utempl_tests ${SOURCES}) + target_link_libraries(utempl_tests GTest::gtest_main utempl) + set_property(TARGET utempl_tests PROPERTY CXX_STANDARD 20) + include(GoogleTest) + gtest_discover_tests(utempl_tests) +endif() target_include_directories(utempl INTERFACE include) diff --git a/include/utempl/go_interface.hpp b/include/utempl/go_interface.hpp index b5ca77c..a3d7911 100644 --- a/include/utempl/go_interface.hpp +++ b/include/utempl/go_interface.hpp @@ -68,9 +68,22 @@ struct GoInterface : Value { Value(impl::Transform(Transformer{}, std::forward(value))) {}; inline constexpr auto operator=(const GoInterface&) -> GoInterface& = default; inline constexpr auto operator=(GoInterface&&) -> GoInterface& = default; - inline constexpr auto operator==(const GoInterface& other) const -> bool - requires requires {static_cast(*this) == static_cast(other);} { - return static_cast(*this) == static_cast(other); + inline constexpr auto operator==(const Value& other) const -> bool + requires requires(const Value& a){a == a;} { + return static_cast(*this) == other; + }; + inline constexpr auto operator==(const GoInterface& other) const -> bool { + return *this == static_cast(other); + }; + template + inline constexpr auto operator==(T&& other) const -> bool { + return [&](std::index_sequence){ + using Type = std::remove_cvref_t; + Transformer transformer; + // + 1 - NULL Terminator + return ((boost::pfr::get(static_cast(*this)) == + transformer(impl::TryGet().size() + 1>{boost::pfr::get_name().begin()}>(other))) && ...); + }(std::make_index_sequence>()); }; }; diff --git a/tests/go_interface.cpp b/tests/go_interface.cpp new file mode 100644 index 0000000..7d5a317 --- /dev/null +++ b/tests/go_interface.cpp @@ -0,0 +1,22 @@ +#include +#include + +struct SomeInterface { + int field; +}; + +struct SomeStruct { + int field; +}; + +TEST(GoInterface, Basic) { + utempl::GoInterface obj(SomeStruct{1}); + EXPECT_EQ(obj.field, 1); +}; + +TEST(GoInterface, Equal) { + utempl::GoInterface obj(SomeStruct{1}); + EXPECT_EQ(obj, utempl::GoInterface{SomeInterface{1}}); + EXPECT_EQ(obj, SomeInterface{1}); + EXPECT_EQ(obj, SomeStruct{1}); +}; diff --git a/tests/overloaded.cpp b/tests/overloaded.cpp new file mode 100644 index 0000000..93e0f87 --- /dev/null +++ b/tests/overloaded.cpp @@ -0,0 +1,16 @@ +#include +#include + +namespace utempl { + +TEST(Overloaded, Basic) { + constexpr auto f = utempl::Overloaded([](int){ + return 1; + }, [](auto&&){ + return 2; + }); + EXPECT_EQ(f(1), 1); + EXPECT_EQ(f(""), 2); +}; + +} // namespace utempl