From e7cf38e2a920a0549ab6d00cee257773347ebb4a Mon Sep 17 00:00:00 2001 From: sha512sum Date: Mon, 15 Jul 2024 13:54:41 +0000 Subject: [PATCH] C++20 -> C++23 and add Switch --- CMakeLists.txt | 8 ++++---- examples/src/switch.cpp | 23 +++++++++++++++++++++++ include/utempl/utils.hpp | 26 ++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 examples/src/switch.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 54d226a..3847aed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.27) project(utempl VERSION 0.1) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_CXX_STANDART 20) +set(CMAKE_CXX_STANDART 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CXX_EXTENSIONS NO) set(BOOST_INCLUDE_LIBRARIES "pfr") @@ -50,7 +50,7 @@ else() find_package(Boost 1.85.0 REQUIRED) target_link_libraries(utempl INTERFACE fmt::fmt-header-only ${Boost_LIBRARIES}) endif() -target_compile_features(utempl INTERFACE cxx_std_20) +target_compile_features(utempl INTERFACE cxx_std_23) install(TARGETS utempl EXPORT utemplTargets @@ -89,7 +89,7 @@ if(ENABLE_TESTS) 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) + set_property(TARGET utempl_tests PROPERTY CXX_STANDARD 23) include(GoogleTest) gtest_discover_tests(utempl_tests) endif() @@ -99,7 +99,7 @@ if(ENABLE_EXAMPLES) get_filename_component(EXAMPLE_NAME ${EXAMPLE_SRC} NAME_WE) add_executable(${EXAMPLE_NAME} ${EXAMPLE_SRC}) target_link_libraries(${EXAMPLE_NAME} utempl) - set_property(TARGET ${EXAMPLE_NAME} PROPERTY CXX_STANDARD 20) + set_property(TARGET ${EXAMPLE_NAME} PROPERTY CXX_STANDARD 23) set_target_properties(${EXAMPLE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/examples/output") endforeach() diff --git a/examples/src/switch.cpp b/examples/src/switch.cpp new file mode 100644 index 0000000..927c082 --- /dev/null +++ b/examples/src/switch.cpp @@ -0,0 +1,23 @@ +#include + +auto main() -> int { + static_assert(utempl::Switch(utempl::Tuple{2, 1, 0}, utempl::Tuple{0, 1, 2}, 0, [](int value) { + return value + 1; + }) == 3); + static_assert(utempl::Switch(utempl::Tuple{2, 1, 0}, utempl::Tuple{0, 1, 2}, 3, [](int value) { + return value + 1; + }) == 0); + static_assert(utempl::Switch>(utempl::Tuple{2, 1, 0}, utempl::Tuple{0, 1, 2}, 3, [](int value) { + return value + 1; + }) == std::nullopt); + static_assert(utempl::Switch( + utempl::Tuple{2, 1, 0}, + utempl::Tuple{0, 1, 2}, + 3, + [](int value) { + return value + 1; + }, + [] { + return 42; + }) == 42); +}; diff --git a/include/utempl/utils.hpp b/include/utempl/utils.hpp index e3a78f4..aca9248 100644 --- a/include/utempl/utils.hpp +++ b/include/utempl/utils.hpp @@ -606,4 +606,30 @@ constexpr auto Enumerate(Tuple&& tuple) { }); }; +template +constexpr auto kDefaultCreator = [] { + return T{}; +}; + +template )> +constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& key, F&& f, Default&& def = {}) { + return Unpack(std::forward(keysTuple), [&](Keys&&... keys) { + return Unpack(std::forward(valuesTuple), [&](Values&&... values) { + return *FirstOf(Tuple{[&] { + return std::forward(keys) == std::forward(key) ? std::forward(f)(std::forward(values)) + : std::optional{}; + }...}, + std::optional{}) + .or_else([&] -> std::optional { + return std::forward(def)(); + }); + }); + }); +}; + } // namespace utempl