C++20 -> C++23 and add Switch
This commit is contained in:
parent
0336a5ab33
commit
e7cf38e2a9
3 changed files with 53 additions and 4 deletions
|
@ -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
23
examples/src/switch.cpp
Normal 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);
|
||||
};
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue