| @@ -0,0 +1 @@ | |||||
| build/ | |||||
| @@ -1,3 +1,3 @@ | |||||
| [submodule "cmake/modules"] | [submodule "cmake/modules"] | ||||
| path = cmake/modules | path = cmake/modules | ||||
| url = b3rgmann@git.bergmann89.de:cpp/CmakeModules.git | |||||
| url = https://git.bergmann89.de/cpp/CmakeModules.git | |||||
| @@ -20,7 +20,6 @@ EndIf ( ) | |||||
| # Project ######################################################################################### | # Project ######################################################################################### | ||||
| Include ( CTest ) | |||||
| Include ( GNUInstallDirs ) | Include ( GNUInstallDirs ) | ||||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cppmp-options.cmake ) | Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cppmp-options.cmake ) | ||||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cppmp-const.cmake ) | Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cppmp-const.cmake ) | ||||
| @@ -28,6 +27,7 @@ Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cppmp-var. | |||||
| Project ( ${CPPMP_PROJECT_NAME} | Project ( ${CPPMP_PROJECT_NAME} | ||||
| DESCRIPTION "${CPPMP_PROJECT_DESCRIPTION}" | DESCRIPTION "${CPPMP_PROJECT_DESCRIPTION}" | ||||
| VERSION "${CPPMP_VERSION}" ) | VERSION "${CPPMP_VERSION}" ) | ||||
| Include ( CTest ) | |||||
| # Subdirectories | # Subdirectories | ||||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src ) | Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src ) | ||||
| @@ -23,6 +23,6 @@ Set ( CPPMP_INSTALL_DIR_SHARE "${CMAKE_INSTALL | |||||
| # C Standard | # C Standard | ||||
| Set ( CMAKE_C_STANDARD 11 ) | Set ( CMAKE_C_STANDARD 11 ) | ||||
| Set ( CMAKE_CXX_STANDARD 17 ) | |||||
| Set ( CMAKE_CXX_STANDARD 14 ) | |||||
| Set ( CMAKE_C_STANDARD_REQUIRED ON ) | Set ( CMAKE_C_STANDARD_REQUIRED ON ) | ||||
| Set ( CMAKE_CXX_STANDARD_REQUIRED ON ) | Set ( CMAKE_CXX_STANDARD_REQUIRED ON ) | ||||
| @@ -1,4 +1,4 @@ | |||||
| #pragma onec | |||||
| #pragma once | |||||
| #include "types.h" | #include "types.h" | ||||
| @@ -84,8 +84,8 @@ namespace cppmp | |||||
| struct getter_member_func | struct getter_member_func | ||||
| : public tag_getter | : public tag_getter | ||||
| { | { | ||||
| using object_type = T_object; | |||||
| using value_type = T_value; | |||||
| using object_type = decay_t<T_object>; | |||||
| using value_type = decay_t<T_value>; | |||||
| using member_type = T_member; | using member_type = T_member; | ||||
| member_type member; | member_type member; | ||||
| @@ -168,6 +168,55 @@ namespace cppmp | |||||
| { return getter_lambda(std::forward<lambda_type>(lambda)); } | { return getter_lambda(std::forward<lambda_type>(lambda)); } | ||||
| }; | }; | ||||
| /* getter_builder - chain */ | |||||
| template<typename T_first, typename T_second, typename... T_rest> | |||||
| struct getter_builder< | |||||
| list<T_first, T_second, T_rest...>, | |||||
| enable_if_t< | |||||
| is_valid_v<decltype(make_getter(std::declval<T_first>()))> | |||||
| && is_valid_v<decltype(make_getter(std::declval<T_second>(), std::declval<T_rest>()...))> | |||||
| > | |||||
| > | |||||
| { | |||||
| struct getter_chain | |||||
| : public tag_getter | |||||
| { | |||||
| using first_getter_type = decltype(make_getter(std::declval<T_first>())); | |||||
| using second_getter_type = decltype(make_getter(std::declval<T_second>(), std::declval<T_rest>()...)); | |||||
| using object_type = typename first_getter_type::object_type; | |||||
| using value_type = typename second_getter_type::value_type;; | |||||
| first_getter_type first; | |||||
| second_getter_type second; | |||||
| constexpr getter_chain( | |||||
| first_getter_type&& p_first, | |||||
| second_getter_type&& p_second) | |||||
| : first (std::move(p_first)) | |||||
| , second(std::move(p_second)) | |||||
| { } | |||||
| constexpr getter_chain(getter_chain&&) = default; | |||||
| constexpr getter_chain(const getter_chain&) = default; | |||||
| constexpr getter_chain& operator = (getter_chain&&) = default; | |||||
| constexpr getter_chain& operator = (const getter_chain&) = default; | |||||
| template<typename X_object> | |||||
| constexpr decltype(auto) operator()(X_object&& obj) const | |||||
| { return second(first(std::forward<X_object>(obj))); } | |||||
| }; | |||||
| template<typename X_first, typename... X_rest> | |||||
| static constexpr decltype(auto) apply(X_first&& first, X_rest&&... rest) | |||||
| { | |||||
| return getter_chain( | |||||
| make_getter(std::forward<X_first>(first)), | |||||
| make_getter(std::forward<X_rest>(rest)...)); | |||||
| } | |||||
| }; | |||||
| } | } | ||||
| /* is_getter */ | /* is_getter */ | ||||
| @@ -83,8 +83,8 @@ namespace cppmp | |||||
| struct setter_member_func | struct setter_member_func | ||||
| : public tag_setter | : public tag_setter | ||||
| { | { | ||||
| using object_type = T_object; | |||||
| using value_type = T_value; | |||||
| using object_type = decay_t<T_object>; | |||||
| using value_type = decay_t<T_value>; | |||||
| using member_type = T_member; | using member_type = T_member; | ||||
| member_type member; | member_type member; | ||||
| @@ -101,7 +101,7 @@ namespace cppmp | |||||
| template<typename X_object, typename X_value> | template<typename X_object, typename X_value> | ||||
| constexpr void operator()(X_object&& obj, X_value&& value) const | constexpr void operator()(X_object&& obj, X_value&& value) const | ||||
| { (std::forward<X_object>(obj).*member)(value); } | |||||
| { (std::forward<X_object>(obj).*member)(std::forward<X_value>(value)); } | |||||
| }; | }; | ||||
| using object_type = T_object; | using object_type = T_object; | ||||
| @@ -45,7 +45,7 @@ ForEach ( FILE IN LISTS CPPMP_TEST_SOURCE_FILES ) | |||||
| # test | # test | ||||
| If ( HAS_CMAKE_TESTS ) | If ( HAS_CMAKE_TESTS ) | ||||
| Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} ) | |||||
| Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} GROUP cppmp ) | |||||
| Else ( ) | Else ( ) | ||||
| Add_Test ( NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) | Add_Test ( NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) | ||||
| EndIf ( ) | EndIf ( ) | ||||
| @@ -12,44 +12,62 @@ struct test_obj | |||||
| static std::string sget(); | static std::string sget(); | ||||
| }; | }; | ||||
| constexpr decltype(auto) cpp_traits_lambda = [](std::string, int)->bool { return true; }; | |||||
| const test_obj& static_fuu() | |||||
| { | |||||
| static const test_obj value; | |||||
| return value; | |||||
| } | |||||
| decltype(auto) cpp_traits_lambda = [](std::string, int)->bool { return true; }; | |||||
| using type0 = ::cppmp::lambda_traits<decltype(&test_obj::test)>; | using type0 = ::cppmp::lambda_traits<decltype(&test_obj::test)>; | ||||
| using type1 = ::cppmp::lambda_traits<decltype(&test_obj::ctest)>; | using type1 = ::cppmp::lambda_traits<decltype(&test_obj::ctest)>; | ||||
| using type2 = ::cppmp::lambda_traits<decltype(&test_obj::sget)>; | using type2 = ::cppmp::lambda_traits<decltype(&test_obj::sget)>; | ||||
| using type3 = ::cppmp::lambda_traits<std::string(*)(bool)>; | using type3 = ::cppmp::lambda_traits<std::string(*)(bool)>; | ||||
| using type4 = ::cppmp::lambda_traits<decltype(cpp_traits_lambda)>; | using type4 = ::cppmp::lambda_traits<decltype(cpp_traits_lambda)>; | ||||
| using type5 = ::cppmp::lambda_traits<decltype(&static_fuu)>; | |||||
| static_assert(is_same_v<typename type0::object_type, test_obj>, ""); | |||||
| static_assert(is_same_v<typename type0::return_type, int>, ""); | |||||
| static_assert(is_same_v<typename type0::arguments_type, std::tuple<int>>, ""); | |||||
| static_assert( type0::is_mutable_v == true, ""); | |||||
| static_assert( type0::is_static_v == false, ""); | |||||
| static_assert( type0::argument_count_v == 1, ""); | |||||
| static_assert(is_same_v<typename type1::object_type, test_obj>, ""); | |||||
| static_assert(is_same_v<typename type1::return_type, double>, ""); | |||||
| static_assert(is_same_v<typename type1::arguments_type, std::tuple<float, std::string>>, ""); | |||||
| static_assert( type1::is_mutable_v == false, ""); | |||||
| static_assert( type1::is_static_v == false, ""); | |||||
| static_assert( type1::argument_count_v == 2, ""); | |||||
| static_assert(is_same_v<typename type2::object_type, void>, ""); | |||||
| static_assert(is_same_v<typename type2::return_type, std::string>, ""); | |||||
| static_assert(is_same_v<typename type2::arguments_type, std::tuple<>>, ""); | |||||
| static_assert( type2::is_mutable_v == false, ""); | |||||
| static_assert( type2::is_static_v == true, ""); | |||||
| static_assert( type2::argument_count_v == 0, ""); | |||||
| static_assert(is_same_v<typename type0::object_type, test_obj>); | |||||
| static_assert(is_same_v<typename type0::return_type, int>); | |||||
| static_assert(is_same_v<typename type0::arguments_type, std::tuple<int>>); | |||||
| static_assert( type0::is_mutable_v == true); | |||||
| static_assert( type0::is_static_v == false); | |||||
| static_assert( type0::argument_count_v == 1); | |||||
| static_assert(is_same_v<typename type1::object_type, test_obj>); | |||||
| static_assert(is_same_v<typename type1::return_type, double>); | |||||
| static_assert(is_same_v<typename type1::arguments_type, std::tuple<float, std::string>>); | |||||
| static_assert( type1::is_mutable_v == false); | |||||
| static_assert( type1::is_static_v == false); | |||||
| static_assert( type1::argument_count_v == 2); | |||||
| static_assert(is_same_v<typename type2::object_type, void>); | |||||
| static_assert(is_same_v<typename type2::return_type, std::string>); | |||||
| static_assert(is_same_v<typename type2::arguments_type, std::tuple<>>); | |||||
| static_assert( type2::is_mutable_v == false); | |||||
| static_assert( type2::is_static_v == true); | |||||
| static_assert( type2::argument_count_v == 0); | |||||
| static_assert(is_same_v<typename type3::object_type, void>); | |||||
| static_assert(is_same_v<typename type3::return_type, std::string>); | |||||
| static_assert(is_same_v<typename type3::arguments_type, std::tuple<bool>>); | |||||
| static_assert( type3::is_mutable_v == false); | |||||
| static_assert( type3::is_static_v == true); | |||||
| static_assert( type3::argument_count_v == 1); | |||||
| static_assert(is_same_v<typename type4::return_type, bool>); | |||||
| static_assert(is_same_v<typename type4::arguments_type, std::tuple<std::string, int>>); | |||||
| static_assert( type4::is_mutable_v == false); | |||||
| static_assert( type4::is_static_v == false); | |||||
| static_assert( type4::argument_count_v == 2); | |||||
| static_assert(is_same_v<typename type3::object_type, void>, ""); | |||||
| static_assert(is_same_v<typename type3::return_type, std::string>, ""); | |||||
| static_assert(is_same_v<typename type3::arguments_type, std::tuple<bool>>, ""); | |||||
| static_assert( type3::is_mutable_v == false, ""); | |||||
| static_assert( type3::is_static_v == true, ""); | |||||
| static_assert( type3::argument_count_v == 1, ""); | |||||
| static_assert(is_same_v<typename type4::return_type, bool>, ""); | |||||
| static_assert(is_same_v<typename type4::arguments_type, std::tuple<std::string, int>>, ""); | |||||
| static_assert( type4::is_mutable_v == false, ""); | |||||
| static_assert( type4::is_static_v == false, ""); | |||||
| static_assert( type4::argument_count_v == 2, ""); | |||||
| static_assert(is_same_v<typename type5::return_type, const test_obj&>, ""); | |||||
| static_assert(is_same_v<typename type5::arguments_type, std::tuple<>>, ""); | |||||
| static_assert( type5::is_mutable_v == false, ""); | |||||
| static_assert( type5::is_static_v == true, ""); | |||||
| static_assert( type5::argument_count_v == 0, ""); | |||||
| TEST(cppmp_traits_test, dummy) | |||||
| { | |||||
| (void)cpp_traits_lambda; | |||||
| } | |||||