| @@ -0,0 +1,185 @@ | |||||
| #pragma once | |||||
| /* C++ standards */ | |||||
| #if __cplusplus >= 201103L | |||||
| #define cppmp_supports_cpp11 1 | |||||
| #endif | |||||
| #if __cplusplus >= 201402L | |||||
| #define cppmp_supports_cpp14 1 | |||||
| #endif | |||||
| #if __cplusplus >= 201703L | |||||
| #define cppmp_supports_cpp17 1 | |||||
| #endif | |||||
| /* C++ features */ | |||||
| #if __cpp_variable_templates >= 201304L | |||||
| #define cppmp_supports_variable_templates 1 | |||||
| #endif | |||||
| #if __cpp_constexpr >= 201603L | |||||
| #define cppmp_supports_constexpr_lambda 1 | |||||
| #endif | |||||
| /* GCC */ | |||||
| #ifdef __GNUC__ | |||||
| #define cppmp_gcc_version (__GNUC__ * 10000 \ | |||||
| + __GNUC_MINOR__ * 100 \ | |||||
| + __GNUC_PATCHLEVEL__) | |||||
| #endif | |||||
| /* Macros */ | |||||
| #ifdef cppmp_supports_constexpr_lambda | |||||
| #define cppmp_constexpr_lambda constexpr | |||||
| #else | |||||
| #define cppmp_constexpr_lambda | |||||
| #endif | |||||
| /* Supported Traits */ | |||||
| #ifdef cppmp_supports_cpp11 | |||||
| #define cppmp_std_supports_remove_const 1 | |||||
| #define cppmp_std_supports_remove_volatile 1 | |||||
| #define cppmp_std_supports_remove_cv 1 | |||||
| #define cppmp_std_supports_add_const 1 | |||||
| #define cppmp_std_supports_add_volatile 1 | |||||
| #define cppmp_std_supports_add_cv 1 | |||||
| #define cppmp_std_supports_remove_reference 1 | |||||
| #define cppmp_std_supports_add_lvalue_reference 1 | |||||
| #define cppmp_std_supports_add_rvalue_reference 1 | |||||
| #define cppmp_std_supports_make_signed 1 | |||||
| #define cppmp_std_supports_make_unsigned 1 | |||||
| #define cppmp_std_supports_remove_extent 1 | |||||
| #define cppmp_std_supports_remove_all_extents 1 | |||||
| #define cppmp_std_supports_add_pointer 1 | |||||
| #define cppmp_std_supports_remove_pointer 1 | |||||
| #define cppmp_std_supports_decay 1 | |||||
| #define cppmp_std_supports_common_type 1 | |||||
| #define cppmp_std_supports_underlying_type 1 | |||||
| #define cppmp_std_supports_aligned_storage 1 | |||||
| #if !defined(cppmp_gcc_version) or cppmp_gcc_version >= 50000 | |||||
| #define cppmp_std_supports_aligned_union 1 | |||||
| #endif | |||||
| #ifndef cppmp_supports_cpp20 | |||||
| #define cppmp_std_supports_result_of 1 | |||||
| #endif | |||||
| #define cppmp_std_supports_enable_if 1 | |||||
| #define cppmp_std_supports_conditional 1 | |||||
| #define cppmp_std_supports_is_void 1 | |||||
| #define cppmp_std_supports_is_integral 1 | |||||
| #define cppmp_std_supports_is_floating_point 1 | |||||
| #define cppmp_std_supports_is_array 1 | |||||
| #define cppmp_std_supports_is_pointer 1 | |||||
| #define cppmp_std_supports_is_lvalue_reference 1 | |||||
| #define cppmp_std_supports_is_rvalue_reference 1 | |||||
| #define cppmp_std_supports_is_member_object_pointer 1 | |||||
| #define cppmp_std_supports_is_member_function_pointer 1 | |||||
| #define cppmp_std_supports_is_enum 1 | |||||
| #define cppmp_std_supports_is_union 1 | |||||
| #define cppmp_std_supports_is_class 1 | |||||
| #define cppmp_std_supports_is_function 1 | |||||
| #define cppmp_std_supports_is_reference 1 | |||||
| #define cppmp_std_supports_is_arithmetic 1 | |||||
| #define cppmp_std_supports_is_fundamental 1 | |||||
| #define cppmp_std_supports_is_object 1 | |||||
| #define cppmp_std_supports_is_scalar 1 | |||||
| #define cppmp_std_supports_is_compound 1 | |||||
| #define cppmp_std_supports_is_member_pointer 1 | |||||
| #define cppmp_std_supports_is_const 1 | |||||
| #define cppmp_std_supports_is_volatile 1 | |||||
| #define cppmp_std_supports_is_trivial 1 | |||||
| #define cppmp_std_supports_is_standard_layout 1 | |||||
| #define cppmp_std_supports_is_pod 1 | |||||
| #define cppmp_std_supports_is_empty 1 | |||||
| #define cppmp_std_supports_is_polymorphic 1 | |||||
| #define cppmp_std_supports_is_abstract 1 | |||||
| #define cppmp_std_supports_is_signed 1 | |||||
| #define cppmp_std_supports_is_unsigned 1 | |||||
| #define cppmp_std_supports_is_constructible 1 | |||||
| #define cppmp_std_supports_is_default_constructible 1 | |||||
| #define cppmp_std_supports_is_copy_constructible 1 | |||||
| #define cppmp_std_supports_is_move_constructible 1 | |||||
| #define cppmp_std_supports_is_assignable 1 | |||||
| #define cppmp_std_supports_is_copy_assignable 1 | |||||
| #define cppmp_std_supports_is_move_assignable 1 | |||||
| #define cppmp_std_supports_is_destructible 1 | |||||
| #if !defined(cppmp_gcc_version) or cppmp_gcc_version >= 50000 | |||||
| #define cppmp_std_supports_is_trivially_constructible 1 | |||||
| #define cppmp_std_supports_is_trivially_default_constructible 1 | |||||
| #define cppmp_std_supports_is_trivially_copy_constructible 1 | |||||
| #define cppmp_std_supports_is_trivially_move_constructible 1 | |||||
| #define cppmp_std_supports_is_trivially_assignable 1 | |||||
| #define cppmp_std_supports_is_trivially_copy_assignable 1 | |||||
| #define cppmp_std_supports_is_trivially_move_assignable 1 | |||||
| #define cppmp_std_supports_is_trivially_destructible 1 | |||||
| #define cppmp_std_supports_is_trivially_copyable 1 | |||||
| #endif | |||||
| #define cppmp_std_supports_is_nothrow_constructible 1 | |||||
| #define cppmp_std_supports_is_nothrow_default_constructible 1 | |||||
| #define cppmp_std_supports_is_nothrow_copy_constructible 1 | |||||
| #define cppmp_std_supports_is_nothrow_move_constructible 1 | |||||
| #define cppmp_std_supports_is_nothrow_assignable 1 | |||||
| #define cppmp_std_supports_is_nothrow_copy_assignable 1 | |||||
| #define cppmp_std_supports_is_nothrow_move_assignable 1 | |||||
| #define cppmp_std_supports_is_nothrow_destructible 1 | |||||
| #define cppmp_std_supports_has_virtual_destructor 1 | |||||
| #define cppmp_std_supports_alignment_of 1 | |||||
| #define cppmp_std_supports_rank 1 | |||||
| #define cppmp_std_supports_extent 1 | |||||
| #define cppmp_std_supports_is_same 1 | |||||
| #define cppmp_std_supports_is_base_of 1 | |||||
| #define cppmp_std_supports_is_convertible 1 | |||||
| #endif | |||||
| #ifdef cppmp_supports_cpp14 | |||||
| #define cppmp_std_supports_is_null_pointer 1 | |||||
| #define cppmp_std_supports_is_final 1 | |||||
| #endif | |||||
| #ifdef cppmp_supports_cpp17 | |||||
| #define cppmp_std_supports_invoke_result 1 | |||||
| #define cppmp_std_supports_conjunction 1 | |||||
| #define cppmp_std_supports_disjunction 1 | |||||
| #define cppmp_std_supports_negation 1 | |||||
| #define cppmp_std_supports_is_aggregate 1 | |||||
| #define cppmp_std_supports_is_swappable_with 1 | |||||
| #define cppmp_std_supports_is_swappable 1 | |||||
| #define cppmp_std_supports_is_nothrow_swappable_with 1 | |||||
| #define cppmp_std_supports_is_nothrow_swappable 1 | |||||
| #define cppmp_std_supports_has_unique_object_representations 1 | |||||
| #define cppmp_std_supports_is_invocable 1 | |||||
| #define cppmp_std_supports_is_invocable_r 1 | |||||
| #define cppmp_std_supports_is_nothrow_invocable 1 | |||||
| #define cppmp_std_supports_is_nothrow_invocable_r 1 | |||||
| #endif | |||||
| #ifdef cppmp_supports_cpp20 | |||||
| #define cppmp_std_supports_remove_cvref 1 | |||||
| #define cppmp_std_supports_is_bounded_array 1 | |||||
| #define cppmp_std_supports_is_unbounded_array 1 | |||||
| #define cppmp_std_supports_has_strong_structural_equality 1 | |||||
| #define cppmp_std_supports_is_nothrow_convertible 1 | |||||
| #define cppmp_std_supports_is_layout_compatible 1 | |||||
| #define cppmp_std_supports_is_pointer_interconvertible_base_of 1 | |||||
| #endif | |||||
| @@ -1,30 +1,45 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "types.h" | |||||
| #include "../config.h" | |||||
| #define cppmp_define_checker(name) \ | #define cppmp_define_checker(name) \ | ||||
| template<typename... T> \ | template<typename... T> \ | ||||
| struct name \ | struct name \ | ||||
| : public integral_constant<decltype(std::name<T...>::value), std::name<T...>::value> \ | : public integral_constant<decltype(std::name<T...>::value), std::name<T...>::value> \ | ||||
| { }; \ | { }; \ | ||||
| \ | \ | ||||
| template<typename... T> \ | |||||
| constexpr decltype(auto) name ## _v = name<T...>::value; | |||||
| cppmp_define_checker_var(name) | |||||
| #include "types.h" | |||||
| #ifdef cppmp_supports_variable_templates | |||||
| #define cppmp_define_checker_var(name) \ | |||||
| template<typename... T> \ | |||||
| constexpr decltype(auto) name ## _v = name<T...>::value; | |||||
| #else | |||||
| #define cppmp_define_checker_var(name) | |||||
| #endif | |||||
| namespace cppmp | namespace cppmp | ||||
| { | { | ||||
| namespace __impl | |||||
| { | |||||
| template<typename T> | |||||
| struct is_valid; | |||||
| } | |||||
| /** | /** | ||||
| * @brief Evaluates to true_t if the passed template parameters are valid, false_t otherwise. | * @brief Evaluates to true_t if the passed template parameters are valid, false_t otherwise. | ||||
| */ | */ | ||||
| template<typename T, typename = void> | |||||
| struct is_valid; | |||||
| template<typename T> | |||||
| struct is_valid | |||||
| : public __impl::is_valid<T> | |||||
| { }; | |||||
| /** | |||||
| * @brief Is true if the passed template parameters are valid, false otherwise. | |||||
| */ | |||||
| template<typename... T> | |||||
| constexpr decltype(auto) is_valid_v = is_valid<T...>::value; | |||||
| cppmp_define_checker_var(is_valid) | |||||
| /** | /** | ||||
| * @brief Evaluates to true_t if T is a specialization if T_template, false_t otherwise. | * @brief Evaluates to true_t if T is a specialization if T_template, false_t otherwise. | ||||
| @@ -32,11 +47,10 @@ namespace cppmp | |||||
| template<typename T, template <typename...> class T_template> | template<typename T, template <typename...> class T_template> | ||||
| struct is_specialization_of; | struct is_specialization_of; | ||||
| /** | |||||
| * @brief Evaluates to true if T is a specialization if T_template, false otherwise. | |||||
| */ | |||||
| #ifdef cppmp_supports_variable_templates | |||||
| template<typename T, template <typename...> class T_template> | template<typename T, template <typename...> class T_template> | ||||
| constexpr decltype(auto) is_specialization_of_v = is_specialization_of<T, T_template>::value; | constexpr decltype(auto) is_specialization_of_v = is_specialization_of<T, T_template>::value; | ||||
| #endif | |||||
| /** | /** | ||||
| * @brief Evaluates to true_t if all passed parameters are true, false_t otherwise. | * @brief Evaluates to true_t if all passed parameters are true, false_t otherwise. | ||||
| @@ -44,93 +58,345 @@ namespace cppmp | |||||
| template<bool... B> | template<bool... B> | ||||
| struct is_true; | struct is_true; | ||||
| /** | |||||
| * @brief Evaluates to true if all passed parameters are true, false otherwise. | |||||
| */ | |||||
| #ifdef cppmp_supports_variable_templates | |||||
| template<bool... B> | template<bool... B> | ||||
| constexpr decltype(auto) is_true_v = is_true<B...>::value; | constexpr decltype(auto) is_true_v = is_true<B...>::value; | ||||
| #endif | |||||
| /* primary type categories */ | |||||
| #ifdef cppmp_std_supports_is_void | |||||
| cppmp_define_checker(is_void); | cppmp_define_checker(is_void); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_null_pointer | |||||
| cppmp_define_checker(is_null_pointer); | cppmp_define_checker(is_null_pointer); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_integral | |||||
| cppmp_define_checker(is_integral); | cppmp_define_checker(is_integral); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_floating_point | |||||
| cppmp_define_checker(is_floating_point); | cppmp_define_checker(is_floating_point); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_array | |||||
| cppmp_define_checker(is_array); | cppmp_define_checker(is_array); | ||||
| cppmp_define_checker(is_enum); | |||||
| cppmp_define_checker(is_union); | |||||
| cppmp_define_checker(is_class); | |||||
| cppmp_define_checker(is_function); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_pointer | |||||
| cppmp_define_checker(is_pointer); | cppmp_define_checker(is_pointer); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_lvalue_reference | |||||
| cppmp_define_checker(is_lvalue_reference); | cppmp_define_checker(is_lvalue_reference); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_rvalue_reference | |||||
| cppmp_define_checker(is_rvalue_reference); | cppmp_define_checker(is_rvalue_reference); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_member_object_pointer | |||||
| cppmp_define_checker(is_member_object_pointer); | cppmp_define_checker(is_member_object_pointer); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_member_function_pointer | |||||
| cppmp_define_checker(is_member_function_pointer); | cppmp_define_checker(is_member_function_pointer); | ||||
| cppmp_define_checker(is_fundamental); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_enum | |||||
| cppmp_define_checker(is_enum); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_union | |||||
| cppmp_define_checker(is_union); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_class | |||||
| cppmp_define_checker(is_class); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_function | |||||
| cppmp_define_checker(is_function); | |||||
| #endif | |||||
| /* composite type categories */ | |||||
| #ifdef cppmp_std_supports_is_reference | |||||
| cppmp_define_checker(is_reference); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_arithmetic | |||||
| cppmp_define_checker(is_arithmetic); | cppmp_define_checker(is_arithmetic); | ||||
| cppmp_define_checker(is_scalar); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_fundamental | |||||
| cppmp_define_checker(is_fundamental); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_object | |||||
| cppmp_define_checker(is_object); | cppmp_define_checker(is_object); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_scalar | |||||
| cppmp_define_checker(is_scalar); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_compound | |||||
| cppmp_define_checker(is_compound); | cppmp_define_checker(is_compound); | ||||
| cppmp_define_checker(is_reference); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_member_pointer | |||||
| cppmp_define_checker(is_member_pointer); | cppmp_define_checker(is_member_pointer); | ||||
| #endif | |||||
| /* type properties */ | |||||
| #ifdef cppmp_std_supports_is_const | |||||
| cppmp_define_checker(is_const); | cppmp_define_checker(is_const); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_volatile | |||||
| cppmp_define_checker(is_volatile); | cppmp_define_checker(is_volatile); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivial | |||||
| cppmp_define_checker(is_trivial); | cppmp_define_checker(is_trivial); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_copyable | |||||
| cppmp_define_checker(is_trivially_copyable); | cppmp_define_checker(is_trivially_copyable); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_standard_layout | |||||
| cppmp_define_checker(is_standard_layout); | cppmp_define_checker(is_standard_layout); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_pod | |||||
| cppmp_define_checker(is_pod); | cppmp_define_checker(is_pod); | ||||
| cppmp_define_checker(is_literal_type); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_empty | |||||
| cppmp_define_checker(is_empty); | cppmp_define_checker(is_empty); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_polymorphic | |||||
| cppmp_define_checker(is_polymorphic); | cppmp_define_checker(is_polymorphic); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_abstract | |||||
| cppmp_define_checker(is_abstract); | cppmp_define_checker(is_abstract); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_final | |||||
| cppmp_define_checker(is_final); | cppmp_define_checker(is_final); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_aggregate | |||||
| cppmp_define_checker(is_aggregate); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_signed | |||||
| cppmp_define_checker(is_signed); | cppmp_define_checker(is_signed); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_unsigned | |||||
| cppmp_define_checker(is_unsigned); | cppmp_define_checker(is_unsigned); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_bounded_array | |||||
| cppmp_define_checker(is_bounded_array); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_unbounded_array | |||||
| cppmp_define_checker(is_unbounded_array); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_constructible | |||||
| cppmp_define_checker(is_constructible); | cppmp_define_checker(is_constructible); | ||||
| cppmp_define_checker(is_trivially_constructible); | |||||
| cppmp_define_checker(is_nothrow_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_default_constructible | |||||
| cppmp_define_checker(is_default_constructible); | cppmp_define_checker(is_default_constructible); | ||||
| cppmp_define_checker(is_trivially_default_constructible); | |||||
| cppmp_define_checker(is_nothrow_default_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_copy_constructible | |||||
| cppmp_define_checker(is_copy_constructible); | cppmp_define_checker(is_copy_constructible); | ||||
| cppmp_define_checker(is_trivially_copy_constructible); | |||||
| cppmp_define_checker(is_nothrow_copy_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_move_constructible | |||||
| cppmp_define_checker(is_move_constructible); | cppmp_define_checker(is_move_constructible); | ||||
| cppmp_define_checker(is_trivially_move_constructible); | |||||
| cppmp_define_checker(is_nothrow_move_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_assignable | |||||
| cppmp_define_checker(is_assignable); | cppmp_define_checker(is_assignable); | ||||
| cppmp_define_checker(is_trivially_assignable); | |||||
| cppmp_define_checker(is_nothrow_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_copy_assignable | |||||
| cppmp_define_checker(is_copy_assignable); | cppmp_define_checker(is_copy_assignable); | ||||
| cppmp_define_checker(is_trivially_copy_assignable); | |||||
| cppmp_define_checker(is_nothrow_copy_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_move_assignable | |||||
| cppmp_define_checker(is_move_assignable); | cppmp_define_checker(is_move_assignable); | ||||
| cppmp_define_checker(is_trivially_move_assignable); | |||||
| cppmp_define_checker(is_nothrow_move_assignable); | |||||
| cppmp_define_checker(is_destructible); | |||||
| cppmp_define_checker(is_trivially_destructible); | |||||
| cppmp_define_checker(is_nothrow_destructible); | |||||
| cppmp_define_checker(has_virtual_destructor); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_swappable_with | |||||
| cppmp_define_checker(is_swappable_with); | cppmp_define_checker(is_swappable_with); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_swappable | |||||
| cppmp_define_checker(is_swappable); | cppmp_define_checker(is_swappable); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_destructible | |||||
| cppmp_define_checker(is_destructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_constructible | |||||
| cppmp_define_checker(is_trivially_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_default_constructible | |||||
| cppmp_define_checker(is_trivially_default_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_copy_constructible | |||||
| cppmp_define_checker(is_trivially_copy_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_move_constructible | |||||
| cppmp_define_checker(is_trivially_move_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_assignable | |||||
| cppmp_define_checker(is_trivially_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_copy_assignable | |||||
| cppmp_define_checker(is_trivially_copy_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_move_assignable | |||||
| cppmp_define_checker(is_trivially_move_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_trivially_destructible | |||||
| cppmp_define_checker(is_trivially_destructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_constructible | |||||
| cppmp_define_checker(is_nothrow_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_default_constructible | |||||
| cppmp_define_checker(is_nothrow_default_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_copy_constructible | |||||
| cppmp_define_checker(is_nothrow_copy_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_move_constructible | |||||
| cppmp_define_checker(is_nothrow_move_constructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_assignable | |||||
| cppmp_define_checker(is_nothrow_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_copy_assignable | |||||
| cppmp_define_checker(is_nothrow_copy_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_move_assignable | |||||
| cppmp_define_checker(is_nothrow_move_assignable); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_swappable_with | |||||
| cppmp_define_checker(is_nothrow_swappable_with); | cppmp_define_checker(is_nothrow_swappable_with); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_swappable | |||||
| cppmp_define_checker(is_nothrow_swappable); | cppmp_define_checker(is_nothrow_swappable); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_destructible | |||||
| cppmp_define_checker(is_nothrow_destructible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_has_virtual_destructor | |||||
| cppmp_define_checker(has_virtual_destructor); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_has_unique_object_representations | |||||
| cppmp_define_checker(has_unique_object_representations); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_has_strong_structural_equality | |||||
| cppmp_define_checker(has_strong_structural_equality); | |||||
| #endif | |||||
| /* type property queries */ | |||||
| #ifdef cppmp_std_supports_alignment_of | |||||
| cppmp_define_checker(alignment_of); | cppmp_define_checker(alignment_of); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_rank | |||||
| cppmp_define_checker(rank); | cppmp_define_checker(rank); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_extent | |||||
| cppmp_define_checker(extent); | cppmp_define_checker(extent); | ||||
| #endif | |||||
| /* type relations */ | |||||
| #ifdef cppmp_std_supports_is_same | |||||
| cppmp_define_checker(is_same); | cppmp_define_checker(is_same); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_base_of | |||||
| cppmp_define_checker(is_base_of); | cppmp_define_checker(is_base_of); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_convertible | |||||
| cppmp_define_checker(is_convertible); | cppmp_define_checker(is_convertible); | ||||
| #endif | |||||
| #if __cplusplus >= 201703L | |||||
| cppmp_define_checker(has_unique_object_representations); | |||||
| cppmp_define_checker(is_aggregate); | |||||
| #ifdef cppmp_std_supports_is_nothrow_convertible | |||||
| cppmp_define_checker(is_nothrow_convertible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_layout_compatible | |||||
| cppmp_define_checker(is_layout_compatible); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_pointer_interconvertible_base_of | |||||
| cppmp_define_checker(is_pointer_interconvertible_base_of); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_invocable | |||||
| cppmp_define_checker(is_invocable); | cppmp_define_checker(is_invocable); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_invocable_r | |||||
| cppmp_define_checker(is_invocable_r); | cppmp_define_checker(is_invocable_r); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_invocable | |||||
| cppmp_define_checker(is_nothrow_invocable); | cppmp_define_checker(is_nothrow_invocable); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_is_nothrow_invocable_r | |||||
| cppmp_define_checker(is_nothrow_invocable_r); | cppmp_define_checker(is_nothrow_invocable_r); | ||||
| #endif | #endif | ||||
| } | } | ||||
| #undef cppmp_define_checker | #undef cppmp_define_checker | ||||
| #undef cppmp_define_checker_var | |||||
| #include "checker.inl" | #include "checker.inl" | ||||
| @@ -25,24 +25,24 @@ namespace cppmp | |||||
| : public true_t | : public true_t | ||||
| { }; | { }; | ||||
| } | |||||
| /* is_valid */ | |||||
| /* is_valid */ | |||||
| template<typename T, std::size_t = sizeof(T)> | |||||
| std::true_type is_valid_impl(T *); | |||||
| template<typename T, typename> | |||||
| struct is_valid | |||||
| : public false_t | |||||
| { }; | |||||
| std::false_type is_valid_impl(...); | |||||
| template<typename T> | |||||
| struct is_valid<T, void_t<decltype(sizeof(T))>> | |||||
| : public true_t | |||||
| { }; | |||||
| template<typename T> | |||||
| struct is_valid | |||||
| : public decltype(is_valid_impl(std::declval<T*>())) | |||||
| { }; | |||||
| template<> | |||||
| struct is_valid<void, void> | |||||
| : public true_t | |||||
| { }; | |||||
| template<> | |||||
| struct is_valid<void> | |||||
| : public true_t | |||||
| { }; | |||||
| } | |||||
| /* is_specialization_of */ | /* is_specialization_of */ | ||||
| @@ -5,12 +5,6 @@ | |||||
| namespace cppmp | namespace cppmp | ||||
| { | { | ||||
| /** | |||||
| * @brief Boolean constant value. | |||||
| */ | |||||
| template<bool B> | |||||
| constexpr bool_t<B> bool_c; | |||||
| /** | /** | ||||
| * @brief True boolean constant value. | * @brief True boolean constant value. | ||||
| */ | */ | ||||
| @@ -21,15 +15,25 @@ namespace cppmp | |||||
| */ | */ | ||||
| constexpr false_t false_c; | constexpr false_t false_c; | ||||
| /** | |||||
| * @brief Zero size constant value, | |||||
| */ | |||||
| constexpr zero_t zero_c; | |||||
| #ifdef cppmp_supports_variable_templates | |||||
| /** | |||||
| * @brief Boolean constant value. | |||||
| */ | |||||
| template<bool B> | |||||
| constexpr bool_t<B> bool_c; | |||||
| /** | /** | ||||
| * @brief Size constant value. | * @brief Size constant value. | ||||
| */ | */ | ||||
| template<std::size_t I> | template<std::size_t I> | ||||
| constexpr size_t<I> size_c; | constexpr size_t<I> size_c; | ||||
| /** | |||||
| * @brief Zero size constant value, | |||||
| */ | |||||
| constexpr zero_t zero_c; | |||||
| #endif | |||||
| } | } | ||||
| @@ -1,5 +1,7 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <cstddef> | |||||
| #define cppmp_define_modifier(name) \ | #define cppmp_define_modifier(name) \ | ||||
| template<typename... T> \ | template<typename... T> \ | ||||
| struct name \ | struct name \ | ||||
| @@ -18,29 +20,118 @@ namespace cppmp | |||||
| template<typename T> | template<typename T> | ||||
| using decay_t = typename decay<T>::type; | using decay_t = typename decay<T>::type; | ||||
| cppmp_define_modifier(remove_cv); | |||||
| /* const-volatile modifications */ | |||||
| #ifdef cppmp_std_supports_remove_const | |||||
| cppmp_define_modifier(remove_const); | cppmp_define_modifier(remove_const); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_remove_volatile | |||||
| cppmp_define_modifier(remove_volatile); | cppmp_define_modifier(remove_volatile); | ||||
| cppmp_define_modifier(add_cv); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_remove_cv | |||||
| cppmp_define_modifier(remove_cv); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_add_const | |||||
| cppmp_define_modifier(add_const); | cppmp_define_modifier(add_const); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_add_volatile | |||||
| cppmp_define_modifier(add_volatile); | cppmp_define_modifier(add_volatile); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_add_cv | |||||
| cppmp_define_modifier(add_cv); | |||||
| #endif | |||||
| /* reference modifications */ | |||||
| #ifdef cppmp_std_supports_remove_reference | |||||
| cppmp_define_modifier(remove_reference); | cppmp_define_modifier(remove_reference); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_add_lvalue_reference | |||||
| cppmp_define_modifier(add_lvalue_reference); | cppmp_define_modifier(add_lvalue_reference); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_add_rvalue_reference | |||||
| cppmp_define_modifier(add_rvalue_reference); | cppmp_define_modifier(add_rvalue_reference); | ||||
| cppmp_define_modifier(remove_pointer); | |||||
| cppmp_define_modifier(add_pointer); | |||||
| #endif | |||||
| /* sign modifications */ | |||||
| #ifdef cppmp_std_supports_make_signed | |||||
| cppmp_define_modifier(make_signed); | cppmp_define_modifier(make_signed); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_make_unsigned | |||||
| cppmp_define_modifier(make_unsigned); | cppmp_define_modifier(make_unsigned); | ||||
| #endif | |||||
| /* array modifications */ | |||||
| #ifdef cppmp_std_supports_remove_extent | |||||
| cppmp_define_modifier(remove_extent); | cppmp_define_modifier(remove_extent); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_remove_all_extents | |||||
| cppmp_define_modifier(remove_all_extents); | cppmp_define_modifier(remove_all_extents); | ||||
| #endif | |||||
| /* pointer modifications */ | |||||
| #ifdef cppmp_std_supports_add_pointer | |||||
| cppmp_define_modifier(add_pointer); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_remove_pointer | |||||
| cppmp_define_modifier(remove_pointer); | |||||
| #endif | |||||
| /* other transformations */ | |||||
| #ifdef cppmp_std_supports_remove_cvref | |||||
| cppmp_define_modifier(remove_cvref); | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_common_type | |||||
| cppmp_define_modifier(common_type); | cppmp_define_modifier(common_type); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_underlying_type | |||||
| cppmp_define_modifier(underlying_type); | cppmp_define_modifier(underlying_type); | ||||
| #endif | |||||
| #ifdef cppmp_std_supports_result_of | |||||
| cppmp_define_modifier(result_of); | cppmp_define_modifier(result_of); | ||||
| #endif | |||||
| #if __cplusplus >= 201703L | |||||
| #ifdef cppmp_std_supports_invoke_result | |||||
| cppmp_define_modifier(invoke_result); | cppmp_define_modifier(invoke_result); | ||||
| #endif | #endif | ||||
| #ifdef cppmp_std_supports_aligned_storage | |||||
| template <std::size_t Len, std::size_t Align> | |||||
| struct aligned_storage | |||||
| : public std::aligned_storage<Len, Align> | |||||
| { }; | |||||
| template <std::size_t Len, std::size_t Align> | |||||
| using aligned_storage_t = typename aligned_storage<Len, Align>::type; | |||||
| #endif | |||||
| #ifdef cppmp_std_supports_aligned_union | |||||
| template <std::size_t Len, class... Types> | |||||
| struct aligned_union | |||||
| : public std::aligned_union<Len, Types...> | |||||
| { }; | |||||
| template <std::size_t Len, class... Types> | |||||
| using aligned_union_t = typename aligned_union<Len, Types...>::type; | |||||
| #endif | |||||
| } | } | ||||
| #undef cppmp_define_modifier | #undef cppmp_define_modifier | ||||
| @@ -1,5 +1,6 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <cstddef> | |||||
| #include <type_traits> | #include <type_traits> | ||||
| namespace cppmp | namespace cppmp | ||||
| @@ -18,8 +19,10 @@ namespace cppmp | |||||
| struct type_t | struct type_t | ||||
| { }; | { }; | ||||
| #ifdef cppmp_supports_variable_templates | |||||
| template<typename X> | template<typename X> | ||||
| constexpr decltype(auto) type_v = type_t<X> { }; | constexpr decltype(auto) type_v = type_t<X> { }; | ||||
| #endif | |||||
| /** | /** | ||||
| * @brief Simple type list. | * @brief Simple type list. | ||||
| @@ -1,5 +1,6 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <utility> | |||||
| #include <cppmp/core/types.h> | #include <cppmp/core/types.h> | ||||
| #include <cppmp/core/checker.h> | #include <cppmp/core/checker.h> | ||||
| @@ -8,16 +9,19 @@ namespace cppmp | |||||
| namespace __impl | namespace __impl | ||||
| { | { | ||||
| template<typename T> | |||||
| struct is_default_impl | |||||
| { | |||||
| private: | |||||
| template<typename X> | |||||
| static void impl(decltype(typename X::is_default(), int())); | |||||
| template<typename X, typename = void> | |||||
| struct is_valid_builder | |||||
| : public cppmp::true_t | |||||
| { }; | |||||
| template<typename X> | |||||
| static bool impl(char); | |||||
| template<typename X> | |||||
| struct is_valid_builder<X, cppmp::void_t<typename X::is_default>> | |||||
| : public cppmp::false_t | |||||
| { }; | |||||
| public: | |||||
| static const bool value = std::is_same<void, decltype(impl<T>(0))>::value; | |||||
| }; | |||||
| } | } | ||||
| @@ -34,14 +38,16 @@ namespace cppmp | |||||
| */ | */ | ||||
| template<typename... T_args> | template<typename... T_args> | ||||
| struct is_valid | struct is_valid | ||||
| : public __impl::is_valid_builder<T_builder<list<T_args...>>> | |||||
| : public bool_t<!__impl::is_default_impl<T_builder<list<T_args...>>>::value> | |||||
| { }; | { }; | ||||
| #ifdef cppmp_supports_variable_templates | |||||
| /** | /** | ||||
| * @brief Evaluates to true if the passed arguments would create a valid object, false otherwise. | * @brief Evaluates to true if the passed arguments would create a valid object, false otherwise. | ||||
| */ | */ | ||||
| template<typename... T_args> | template<typename... T_args> | ||||
| static constexpr bool is_valid_v = is_valid<T_args...>::value; | static constexpr bool is_valid_v = is_valid<T_args...>::value; | ||||
| #endif | |||||
| /** | /** | ||||
| * @brief Invoke the builder to create the requested object. | * @brief Invoke the builder to create the requested object. | ||||
| @@ -29,11 +29,13 @@ namespace cppmp | |||||
| template<typename T> | template<typename T> | ||||
| struct is_getter; | struct is_getter; | ||||
| #ifdef cppmp_supports_variable_templates | |||||
| /** | /** | ||||
| * @brief Is true if the passed type is an getter, false otherwise. | * @brief Is true if the passed type is an getter, false otherwise. | ||||
| */ | */ | ||||
| template<typename T> | template<typename T> | ||||
| constexpr decltype(auto) is_getter_v = is_getter<T>::value; | constexpr decltype(auto) is_getter_v = is_getter<T>::value; | ||||
| #endif | |||||
| /** | /** | ||||
| * @brief Predicate to create new getter objects. | * @brief Predicate to create new getter objects. | ||||
| @@ -28,7 +28,8 @@ namespace cppmp | |||||
| template<typename T_getter> | template<typename T_getter> | ||||
| struct getter_builder< | struct getter_builder< | ||||
| list<T_getter>, | list<T_getter>, | ||||
| enable_if_t<is_getter_v<decay_t<T_getter>>>> | |||||
| enable_if_t<is_getter<decay_t<T_getter>>::value | |||||
| >> | |||||
| { | { | ||||
| static constexpr decltype(auto) apply(T_getter&& getter) | static constexpr decltype(auto) apply(T_getter&& getter) | ||||
| { return std::forward<T_getter>(getter); } | { return std::forward<T_getter>(getter); } | ||||
| @@ -40,7 +41,7 @@ namespace cppmp | |||||
| struct getter_builder< | struct getter_builder< | ||||
| list<T_value T_object::*>, | list<T_value T_object::*>, | ||||
| enable_if_t< | enable_if_t< | ||||
| !is_valid_v<lambda_traits<T_value T_object::*>> | |||||
| !is_valid<lambda_traits<T_value T_object::*>>::value | |||||
| > | > | ||||
| > | > | ||||
| { | { | ||||
| @@ -54,15 +55,15 @@ namespace cppmp | |||||
| member_type member; | member_type member; | ||||
| constexpr getter_member_var(member_type p_member) | |||||
| inline getter_member_var(member_type p_member) | |||||
| : member(p_member) | : member(p_member) | ||||
| { } | { } | ||||
| constexpr getter_member_var(getter_member_var&&) = default; | |||||
| constexpr getter_member_var(const getter_member_var&) = default; | |||||
| inline getter_member_var(getter_member_var&&) = default; | |||||
| inline getter_member_var(const getter_member_var&) = default; | |||||
| constexpr getter_member_var& operator = (getter_member_var&&) = default; | |||||
| constexpr getter_member_var& operator = (const getter_member_var&) = default; | |||||
| inline getter_member_var& operator = (getter_member_var&&) = default; | |||||
| inline getter_member_var& operator = (const getter_member_var&) = default; | |||||
| template<typename X_object> | template<typename X_object> | ||||
| constexpr decltype(auto) operator()(X_object&& obj) const | constexpr decltype(auto) operator()(X_object&& obj) const | ||||
| @@ -92,15 +93,15 @@ namespace cppmp | |||||
| member_type member; | member_type member; | ||||
| constexpr getter_member_func(member_type p_member) | |||||
| inline getter_member_func(member_type p_member) | |||||
| : member(p_member) | : member(p_member) | ||||
| { } | { } | ||||
| constexpr getter_member_func(getter_member_func&&) = default; | |||||
| constexpr getter_member_func(const getter_member_func&) = default; | |||||
| inline getter_member_func(getter_member_func&&) = default; | |||||
| inline getter_member_func(const getter_member_func&) = default; | |||||
| constexpr getter_member_func& operator = (getter_member_func&&) = default; | |||||
| constexpr getter_member_func& operator = (const getter_member_func&) = default; | |||||
| inline getter_member_func& operator = (getter_member_func&&) = default; | |||||
| inline getter_member_func& operator = (const getter_member_func&) = default; | |||||
| template<typename X_object> | template<typename X_object> | ||||
| constexpr decltype(auto) operator()(X_object&& obj) const | constexpr decltype(auto) operator()(X_object&& obj) const | ||||
| @@ -135,9 +136,11 @@ namespace cppmp | |||||
| struct getter_builder< | struct getter_builder< | ||||
| list<T_lambda>, | list<T_lambda>, | ||||
| enable_if_t< | enable_if_t< | ||||
| is_valid_v<lambda_traits<decay_t<T_lambda>>> | |||||
| is_valid<lambda_traits<decay_t<T_lambda>>>::value | |||||
| && lambda_traits<decay_t<T_lambda>>::argument_count_v == 1 | && lambda_traits<decay_t<T_lambda>>::argument_count_v == 1 | ||||
| && !is_void_v<typename lambda_traits<decay_t<T_lambda>>::return_type>>> | |||||
| && !is_void<typename lambda_traits<decay_t<T_lambda>>::return_type>::value | |||||
| > | |||||
| > | |||||
| { | { | ||||
| struct getter_lambda | struct getter_lambda | ||||
| : public tag_getter | : public tag_getter | ||||
| @@ -150,15 +153,15 @@ namespace cppmp | |||||
| lambda_type lambda; | lambda_type lambda; | ||||
| constexpr getter_lambda(lambda_type&& p_lambda) | |||||
| inline getter_lambda(lambda_type&& p_lambda) | |||||
| : lambda(std::forward<lambda_type>(p_lambda)) | : lambda(std::forward<lambda_type>(p_lambda)) | ||||
| { } | { } | ||||
| constexpr getter_lambda(getter_lambda&&) = default; | |||||
| constexpr getter_lambda(const getter_lambda&) = default; | |||||
| inline getter_lambda(getter_lambda&&) = default; | |||||
| inline getter_lambda(const getter_lambda&) = default; | |||||
| constexpr getter_lambda& operator = (getter_lambda&&) = default; | |||||
| constexpr getter_lambda& operator = (const getter_lambda&) = default; | |||||
| inline getter_lambda& operator = (getter_lambda&&) = default; | |||||
| inline getter_lambda& operator = (const getter_lambda&) = default; | |||||
| template<typename X_object> | template<typename X_object> | ||||
| constexpr decltype(auto) operator()(X_object&& obj) const | constexpr decltype(auto) operator()(X_object&& obj) const | ||||
| @@ -177,8 +180,8 @@ namespace cppmp | |||||
| struct getter_builder< | struct getter_builder< | ||||
| list<T_first, T_second, T_rest...>, | list<T_first, T_second, T_rest...>, | ||||
| enable_if_t< | 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>()...))> | |||||
| is_valid<decltype(make_getter(std::declval<T_first>()))>::value | |||||
| && is_valid<decltype(make_getter(std::declval<T_second>(), std::declval<T_rest>()...))>::value | |||||
| > | > | ||||
| > | > | ||||
| { | { | ||||
| @@ -194,18 +197,18 @@ namespace cppmp | |||||
| first_getter_type first; | first_getter_type first; | ||||
| second_getter_type second; | second_getter_type second; | ||||
| constexpr getter_chain( | |||||
| inline getter_chain( | |||||
| first_getter_type&& p_first, | first_getter_type&& p_first, | ||||
| second_getter_type&& p_second) | second_getter_type&& p_second) | ||||
| : first (std::move(p_first)) | : first (std::move(p_first)) | ||||
| , second(std::move(p_second)) | , second(std::move(p_second)) | ||||
| { } | { } | ||||
| constexpr getter_chain(getter_chain&&) = default; | |||||
| constexpr getter_chain(const getter_chain&) = default; | |||||
| inline getter_chain(getter_chain&&) = default; | |||||
| inline getter_chain(const getter_chain&) = default; | |||||
| constexpr getter_chain& operator = (getter_chain&&) = default; | |||||
| constexpr getter_chain& operator = (const getter_chain&) = default; | |||||
| inline getter_chain& operator = (getter_chain&&) = default; | |||||
| inline getter_chain& operator = (const getter_chain&) = default; | |||||
| template<typename X_object> | template<typename X_object> | ||||
| constexpr decltype(auto) operator()(X_object&& obj) const | constexpr decltype(auto) operator()(X_object&& obj) const | ||||
| @@ -28,11 +28,13 @@ namespace cppmp | |||||
| template<typename T> | template<typename T> | ||||
| struct is_setter; | struct is_setter; | ||||
| #ifdef cppmp_supports_variable_templates | |||||
| /** | /** | ||||
| * @brief Is true if the passed type is an setter, false otherwise. | * @brief Is true if the passed type is an setter, false otherwise. | ||||
| */ | */ | ||||
| template<typename T> | template<typename T> | ||||
| constexpr decltype(auto) is_setter_v = is_setter<T>::value; | constexpr decltype(auto) is_setter_v = is_setter<T>::value; | ||||
| #endif | |||||
| /** | /** | ||||
| * @brief Predicate to create new setter objects. | * @brief Predicate to create new setter objects. | ||||
| @@ -27,7 +27,8 @@ namespace cppmp | |||||
| template<typename T_setter> | template<typename T_setter> | ||||
| struct setter_builder< | struct setter_builder< | ||||
| list<T_setter>, | list<T_setter>, | ||||
| enable_if_t<is_setter_v<decay_t<T_setter>>>> | |||||
| enable_if_t<is_setter<decay_t<T_setter>>::value | |||||
| >> | |||||
| { | { | ||||
| static constexpr decltype(auto) apply(T_setter&& setter) | static constexpr decltype(auto) apply(T_setter&& setter) | ||||
| { return std::forward<T_setter>(setter); } | { return std::forward<T_setter>(setter); } | ||||
| @@ -50,15 +51,15 @@ namespace cppmp | |||||
| member_type member; | member_type member; | ||||
| constexpr setter_member_var(member_type p_member) | |||||
| inline setter_member_var(member_type p_member) | |||||
| : member(p_member) | : member(p_member) | ||||
| { } | { } | ||||
| constexpr setter_member_var(setter_member_var&&) = default; | |||||
| constexpr setter_member_var(const setter_member_var&) = default; | |||||
| inline setter_member_var(setter_member_var&&) = default; | |||||
| inline setter_member_var(const setter_member_var&) = default; | |||||
| constexpr setter_member_var& operator = (setter_member_var&&) = default; | |||||
| constexpr setter_member_var& operator = (const setter_member_var&) = default; | |||||
| inline setter_member_var& operator = (setter_member_var&&) = default; | |||||
| inline setter_member_var& operator = (const setter_member_var&) = default; | |||||
| 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 | ||||
| @@ -88,15 +89,15 @@ namespace cppmp | |||||
| member_type member; | member_type member; | ||||
| constexpr setter_member_func(member_type p_member) | |||||
| inline setter_member_func(member_type p_member) | |||||
| : member(p_member) | : member(p_member) | ||||
| { } | { } | ||||
| constexpr setter_member_func(setter_member_func&&) = default; | |||||
| constexpr setter_member_func(const setter_member_func&) = default; | |||||
| inline setter_member_func(setter_member_func&&) = default; | |||||
| inline setter_member_func(const setter_member_func&) = default; | |||||
| constexpr setter_member_func& operator = (setter_member_func&&) = default; | |||||
| constexpr setter_member_func& operator = (const setter_member_func&) = default; | |||||
| inline setter_member_func& operator = (setter_member_func&&) = default; | |||||
| inline setter_member_func& operator = (const setter_member_func&) = default; | |||||
| 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 | ||||
| @@ -131,7 +132,7 @@ namespace cppmp | |||||
| struct setter_builder< | struct setter_builder< | ||||
| list<T_lambda>, | list<T_lambda>, | ||||
| enable_if_t< | enable_if_t< | ||||
| is_valid_v<lambda_traits<decay_t<T_lambda>>> | |||||
| is_valid<lambda_traits<decay_t<T_lambda>>>::value | |||||
| && lambda_traits<decay_t<T_lambda>>::argument_count_v == 2>> | && lambda_traits<decay_t<T_lambda>>::argument_count_v == 2>> | ||||
| { | { | ||||
| struct setter_lambda | struct setter_lambda | ||||
| @@ -145,15 +146,15 @@ namespace cppmp | |||||
| lambda_type lambda; | lambda_type lambda; | ||||
| constexpr setter_lambda(lambda_type&& p_lambda) | |||||
| inline cppmp_constexpr_lambda setter_lambda(lambda_type&& p_lambda) | |||||
| : lambda(std::forward<lambda_type>(p_lambda)) | : lambda(std::forward<lambda_type>(p_lambda)) | ||||
| { } | { } | ||||
| constexpr setter_lambda(setter_lambda&&) = default; | |||||
| constexpr setter_lambda(const setter_lambda&) = default; | |||||
| inline cppmp_constexpr_lambda setter_lambda(setter_lambda&&) = default; | |||||
| inline cppmp_constexpr_lambda setter_lambda(const setter_lambda&) = default; | |||||
| constexpr setter_lambda& operator = (setter_lambda&&) = default; | |||||
| constexpr setter_lambda& operator = (const setter_lambda&) = default; | |||||
| inline cppmp_constexpr_lambda setter_lambda& operator = (setter_lambda&&) = default; | |||||
| inline cppmp_constexpr_lambda setter_lambda& operator = (const setter_lambda&) = default; | |||||
| 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 | ||||
| @@ -42,7 +42,11 @@ namespace cppmp | |||||
| /* lambda_traits */ | /* lambda_traits */ | ||||
| template<typename T_lambda> | template<typename T_lambda> | ||||
| struct lambda_traits<T_lambda, enable_if_t<is_valid_v<decltype(&T_lambda::operator())>>> | |||||
| struct lambda_traits< | |||||
| T_lambda, | |||||
| enable_if_t< | |||||
| is_valid<decltype(&T_lambda::operator())>::value | |||||
| >> | |||||
| : public lambda_traits<decltype(&T_lambda::operator())> | : public lambda_traits<decltype(&T_lambda::operator())> | ||||
| { }; | { }; | ||||
| @@ -0,0 +1,26 @@ | |||||
| #include <cppmp/core/checker.h> | |||||
| template<typename X, typename = void> | |||||
| struct tpl; | |||||
| template<> | |||||
| struct tpl<char, void> | |||||
| { | |||||
| using is_default = cppmp::true_t; | |||||
| }; | |||||
| template<> | |||||
| struct tpl<int, void> | |||||
| { }; | |||||
| static_assert( | |||||
| cppmp::is_valid<void>::value, | |||||
| "Expected is_valid to be true"); | |||||
| static_assert( | |||||
| cppmp::is_valid<tpl<int>>::value, | |||||
| "Expected is_valid to be true"); | |||||
| static_assert( | |||||
| !cppmp::is_valid<tpl<float>>::value, | |||||
| "Expected is_valid to be false"); | |||||
| @@ -0,0 +1,39 @@ | |||||
| #include <gtest/gtest.h> | |||||
| #include <cppmp/misc/generic_predicate.h> | |||||
| template<typename X, typename = void> | |||||
| struct builder | |||||
| { | |||||
| using is_default = cppmp::true_t; | |||||
| template<typename... T_args> | |||||
| static constexpr decltype(auto) apply(T_args&&...) | |||||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for build(...)!"); } | |||||
| }; | |||||
| template<> | |||||
| struct builder< | |||||
| cppmp::list<int>, | |||||
| void> | |||||
| { | |||||
| static constexpr decltype(auto) apply(int i) | |||||
| { return i; } | |||||
| }; | |||||
| constexpr decltype(auto) build = cppmp::generic_predicate<builder> { }; | |||||
| static_assert( | |||||
| !decltype(build)::is_valid<void>::value, | |||||
| "Expected build to be invalid"); | |||||
| static_assert( | |||||
| decltype(build)::is_valid<int>::value, | |||||
| "Expected build to be valid"); | |||||
| TEST(generic_predicate_tests, simple) | |||||
| { | |||||
| auto i = build(5); | |||||
| EXPECT_EQ(5, i); | |||||
| } | |||||
| @@ -24,8 +24,9 @@ TEST(cppmp_getter_tests, member_var) | |||||
| test_obj o { 1 }; | test_obj o { 1 }; | ||||
| auto g = make_getter(&test_obj::value); | auto g = make_getter(&test_obj::value); | ||||
| auto i = g(o); | |||||
| EXPECT_EQ(1, g(o)); | |||||
| EXPECT_EQ(1, i); | |||||
| } | } | ||||
| TEST(cppmp_getter_tests, member_func) | TEST(cppmp_getter_tests, member_func) | ||||
| @@ -33,8 +34,9 @@ TEST(cppmp_getter_tests, member_func) | |||||
| test_obj o { 1 }; | test_obj o { 1 }; | ||||
| auto g = make_getter(&test_obj::get); | auto g = make_getter(&test_obj::get); | ||||
| auto i = g(o); | |||||
| EXPECT_EQ(1, g(o)); | |||||
| EXPECT_EQ(1, i); | |||||
| } | } | ||||
| TEST(cppmp_getter_tests, const_member_func) | TEST(cppmp_getter_tests, const_member_func) | ||||
| @@ -42,8 +44,9 @@ TEST(cppmp_getter_tests, const_member_func) | |||||
| test_obj o { 1 }; | test_obj o { 1 }; | ||||
| auto g = make_getter(&test_obj::cget); | auto g = make_getter(&test_obj::cget); | ||||
| auto i = g(o); | |||||
| EXPECT_EQ(1, g(o)); | |||||
| EXPECT_EQ(1, i); | |||||
| } | } | ||||
| TEST(cppmp_getter_tests, static_func) | TEST(cppmp_getter_tests, static_func) | ||||
| @@ -51,8 +54,9 @@ TEST(cppmp_getter_tests, static_func) | |||||
| test_obj o { 1 }; | test_obj o { 1 }; | ||||
| auto g = make_getter(&test_obj::sget); | auto g = make_getter(&test_obj::sget); | ||||
| auto i = g(o); | |||||
| EXPECT_EQ(1, g(o)); | |||||
| EXPECT_EQ(1, i); | |||||
| } | } | ||||
| TEST(cppmp_getter_tests, lambda) | TEST(cppmp_getter_tests, lambda) | ||||
| @@ -62,6 +66,7 @@ TEST(cppmp_getter_tests, lambda) | |||||
| auto g = make_getter([](test_obj& o){ | auto g = make_getter([](test_obj& o){ | ||||
| return o.value; | return o.value; | ||||
| }); | }); | ||||
| auto i = g(obj); | |||||
| EXPECT_EQ(1, g(obj)); | |||||
| EXPECT_EQ(1, i); | |||||
| } | } | ||||
| @@ -27,45 +27,45 @@ 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)>; | 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<typename type0::object_type, test_obj>::value, ""); | |||||
| static_assert(is_same<typename type0::return_type, int>::value, ""); | |||||
| static_assert(is_same<typename type0::arguments_type, std::tuple<int>>::value, ""); | |||||
| 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, const 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<typename type1::object_type, const test_obj>::value, ""); | |||||
| static_assert(is_same<typename type1::return_type, double>::value, ""); | |||||
| static_assert(is_same<typename type1::arguments_type, std::tuple<float, std::string>>::value, ""); | |||||
| 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<typename type2::object_type, void>::value, ""); | |||||
| static_assert(is_same<typename type2::return_type, std::string>::value, ""); | |||||
| static_assert(is_same<typename type2::arguments_type, std::tuple<>>::value, ""); | |||||
| 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<typename type3::object_type, void>::value, ""); | |||||
| static_assert(is_same<typename type3::return_type, std::string>::value, ""); | |||||
| static_assert(is_same<typename type3::arguments_type, std::tuple<bool>>::value, ""); | |||||
| 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<typename type4::return_type, bool>::value, ""); | |||||
| static_assert(is_same<typename type4::arguments_type, std::tuple<std::string, int>>::value, ""); | |||||
| 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, ""); | |||||
| static_assert(is_same<typename type5::return_type, const test_obj&>::value, ""); | |||||
| static_assert(is_same<typename type5::arguments_type, std::tuple<>>::value, ""); | |||||
| 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) | TEST(cppmp_traits_test, dummy) | ||||
| { | { | ||||