C++20 -> C++23 and add Switch

This commit is contained in:
sha512sum 2024-07-15 13:54:41 +00:00
parent 0336a5ab33
commit e7cf38e2a9
3 changed files with 53 additions and 4 deletions

View file

@ -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()

23
examples/src/switch.cpp Normal file
View file

@ -0,0 +1,23 @@
#include <utempl/utils.hpp>
auto main() -> int {
static_assert(utempl::Switch<int>(utempl::Tuple{2, 1, 0}, utempl::Tuple{0, 1, 2}, 0, [](int value) {
return value + 1;
}) == 3);
static_assert(utempl::Switch<int>(utempl::Tuple{2, 1, 0}, utempl::Tuple{0, 1, 2}, 3, [](int value) {
return value + 1;
}) == 0);
static_assert(utempl::Switch<std::optional<int>>(utempl::Tuple{2, 1, 0}, utempl::Tuple{0, 1, 2}, 3, [](int value) {
return value + 1;
}) == std::nullopt);
static_assert(utempl::Switch<int>(
utempl::Tuple{2, 1, 0},
utempl::Tuple{0, 1, 2},
3,
[](int value) {
return value + 1;
},
[] {
return 42;
}) == 42);
};

View file

@ -606,4 +606,30 @@ constexpr auto Enumerate(Tuple&& tuple) {
});
};
template <typename T>
constexpr auto kDefaultCreator = [] {
return T{};
};
template <typename R,
TupleLike KeysTuple,
TupleLike ValuesTuple,
typename Key,
typename F,
std::invocable Default = decltype(kDefaultCreator<R>)>
constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& key, F&& f, Default&& def = {}) {
return Unpack(std::forward<KeysTuple>(keysTuple), [&]<typename... Keys>(Keys&&... keys) {
return Unpack(std::forward<ValuesTuple>(valuesTuple), [&]<typename... Values>(Values&&... values) {
return *FirstOf(Tuple{[&] {
return std::forward<Keys>(keys) == std::forward<Key>(key) ? std::forward<F>(f)(std::forward<Values>(values))
: std::optional<R>{};
}...},
std::optional<R>{})
.or_else([&] -> std::optional<R> {
return std::forward<Default>(def)();
});
});
});
};
} // namespace utempl