From c04383b471f04f0b4a90ea11ed1b0dc8186302d1 Mon Sep 17 00:00:00 2001 From: Brett Date: Sat, 26 Apr 2025 16:35:56 -0400 Subject: [PATCH] tested concrete types. everything works --- CMakeLists.txt | 2 +- include/blt/meta/function.h | 73 +++++++++++++++-------------- tests/variant_tests.cpp | 91 +++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78add7b..93b5f95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 5.4.13) +set(BLT_VERSION 5.4.14) set(BLT_TARGET BLT) diff --git a/include/blt/meta/function.h b/include/blt/meta/function.h index e71e680..0c09fc4 100644 --- a/include/blt/meta/function.h +++ b/include/blt/meta/function.h @@ -99,48 +99,47 @@ namespace blt::meta using class_type = Class; }; + template + struct lambda_traits + {}; + + template + struct lambda_traits + { + using return_type = Return; + using args_tuple = std::tuple; + using class_type = Class; + }; + + template + struct lambda_traits + { + using return_type = Return; + using args_tuple = std::tuple; + using class_type = Class; + }; + + template + struct lambda_traits + { + using return_type = Return; + using args_tuple = std::tuple; + using class_type = Class; + }; + + template + struct lambda_traits + { + using return_type = Return; + using args_tuple = std::tuple; + using class_type = Class; + }; + template struct function_like { private: - template - struct lambda_traits - {}; - - template - struct lambda_traits - { - using return_type = Return; - using args_tuple = std::tuple; - using class_type = Class; - }; - - template - struct lambda_traits - { - using return_type = Return; - using args_tuple = std::tuple; - using class_type = Class; - }; - - template - struct lambda_traits - { - using return_type = Return; - using args_tuple = std::tuple; - using class_type = Class; - }; - - template - struct lambda_traits - { - using return_type = Return; - using args_tuple = std::tuple; - using class_type = Class; - }; - using lambda_trait = lambda_traits::operator())>; - public: using tag_type = lambda_tag; using return_type = typename lambda_trait::return_type; diff --git a/tests/variant_tests.cpp b/tests/variant_tests.cpp index 67b62eb..7d3e2c5 100644 --- a/tests/variant_tests.cpp +++ b/tests/variant_tests.cpp @@ -122,6 +122,76 @@ struct no_members int hello; }; +struct concrete_visitor +{ + [[nodiscard]] std::string operator()(const type1& t1) const + { + return t1.to_string(); + } + + [[nodiscard]] std::string operator()(const type2& t2) const + { + return t2.to_string(); + } + + [[nodiscard]] std::string operator()(const type3& t3) const + { + return t3.to_string(); + } +}; + +struct concrete_visitor_with_state +{ + concrete_visitor_with_state(std::function func1, std::function func2, + std::function func3): func1(std::move(func1)), func2(std::move(func2)), + func3(std::move(func3)) + {} + + [[nodiscard]] std::string operator()(const type1& t1) const + { + return func1(t1); + } + + [[nodiscard]] std::string operator()(const type2& t2) const + { + return func2(t2); + } + + [[nodiscard]] std::string operator()(const type3& t3) const + { + return func3(t3); + } + +private: + std::function func1; + std::function func2; + std::function func3; +}; + +/* + * ********** + * This is not allowed! BLT's visitor is only able to change return types if you provide functions as lambdas, + * otherwise it is not possible to change the return of these functions + * ********** + */ +struct concrete_void +{ + [[nodiscard]] std::string operator()(const type1& t1) const + { + return t1.to_string(); + } + + [[nodiscard]] std::string operator()(const type2& t2) const + { + return t2.to_string(); + } + + void operator()(const type3&) const + { + + } +}; + int main() { blt::variant_t v1{type1{}}; @@ -221,5 +291,26 @@ int main() BLT_ASSERT(provided_visitor == type3{}.to_string()); BLT_TRACE("Provided visitor: {}", provided_visitor); + concrete_visitor visit{}; + auto concrete_visitor_result = v3.visit(visit); + BLT_TRACE("Concrete Result: {}", concrete_visitor_result); + BLT_ASSERT(concrete_visitor_result == type3{}.to_string()); + + auto concrete_visitor_result2 = v2.visit(visit); + BLT_TRACE("Concrete Result: {}", concrete_visitor_result2); + BLT_ASSERT(concrete_visitor_result2 == type2{}.to_string()); + + concrete_visitor_with_state concrete_visitor_state{[](const auto& type) { + return type.to_string(); + }, [](const auto& type) { + return type.to_string(); + }, [](const auto& type) { + return type.to_string(); + }}; + + auto concrete_visitor_state_result = v1.visit(blt::black_box_ret(concrete_visitor_state)); + BLT_TRACE("Concrete State Result: {}", concrete_visitor_state_result); + BLT_ASSERT(concrete_visitor_state_result == type1{}.to_string()); + BLT_INFO("Variant tests passed!"); }