Browse Source

* Added support for different compilers (for now gcc 4.9)

master
bergmann 4 years ago
parent
commit
a2e28134dc
16 changed files with 803 additions and 166 deletions
  1. +185
    -0
      include/cppmp/config.h
  2. +311
    -45
      include/cppmp/core/checker.h
  3. +14
    -14
      include/cppmp/core/checker.inl
  4. +14
    -10
      include/cppmp/core/constants.h
  5. +96
    -5
      include/cppmp/core/modifier.h
  6. +3
    -0
      include/cppmp/core/types.h
  7. +15
    -9
      include/cppmp/misc/generic_predicate.h
  8. +2
    -0
      include/cppmp/misc/getter.h
  9. +29
    -26
      include/cppmp/misc/getter.inl
  10. +2
    -0
      include/cppmp/misc/setter.h
  11. +18
    -17
      include/cppmp/misc/setter.inl
  12. +5
    -1
      include/cppmp/traits/lambda_traits.inl
  13. +26
    -0
      test/cppmp/cppmp_checker_tests.cpp
  14. +39
    -0
      test/cppmp/cppmp_generic_predicate_tests.cpp
  15. +10
    -5
      test/cppmp/cppmp_getter_tests.cpp
  16. +34
    -34
      test/cppmp/cppmp_traits_test.cpp

+ 185
- 0
include/cppmp/config.h View File

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

+ 311
- 45
include/cppmp/core/checker.h View File

@@ -1,30 +1,45 @@
#pragma once

#include "types.h"
#include "../config.h"


#define cppmp_define_checker(name) \
template<typename... T> \
struct name \
: 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 __impl
{

template<typename T>
struct is_valid;

}

/**
* @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.
@@ -32,11 +47,10 @@ namespace cppmp
template<typename T, template <typename...> class T_template>
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>
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.
@@ -44,93 +58,345 @@ namespace cppmp
template<bool... B>
struct is_true;

/**
* @brief Evaluates to true if all passed parameters are true, false otherwise.
*/
#ifdef cppmp_supports_variable_templates
template<bool... B>
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);
#endif

#ifdef cppmp_std_supports_is_null_pointer
cppmp_define_checker(is_null_pointer);
#endif

#ifdef cppmp_std_supports_is_integral
cppmp_define_checker(is_integral);
#endif

#ifdef cppmp_std_supports_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_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);
#endif

#ifdef cppmp_std_supports_is_lvalue_reference
cppmp_define_checker(is_lvalue_reference);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_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_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);
#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_reference);
#endif

#ifdef cppmp_std_supports_is_member_pointer
cppmp_define_checker(is_member_pointer);
#endif

/* type properties */

#ifdef cppmp_std_supports_is_const
cppmp_define_checker(is_const);
#endif

#ifdef cppmp_std_supports_is_volatile
cppmp_define_checker(is_volatile);
#endif

#ifdef cppmp_std_supports_is_trivial
cppmp_define_checker(is_trivial);
#endif

#ifdef cppmp_std_supports_is_trivially_copyable
cppmp_define_checker(is_trivially_copyable);
#endif

#ifdef cppmp_std_supports_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_literal_type);
#endif

#ifdef cppmp_std_supports_is_empty
cppmp_define_checker(is_empty);
#endif

#ifdef cppmp_std_supports_is_polymorphic
cppmp_define_checker(is_polymorphic);
#endif

#ifdef cppmp_std_supports_is_abstract
cppmp_define_checker(is_abstract);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_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_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_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_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_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_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_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_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);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_rank
cppmp_define_checker(rank);
#endif

#ifdef cppmp_std_supports_extent
cppmp_define_checker(extent);
#endif

/* type relations */

#ifdef cppmp_std_supports_is_same
cppmp_define_checker(is_same);
#endif

#ifdef cppmp_std_supports_is_base_of
cppmp_define_checker(is_base_of);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_is_invocable_r
cppmp_define_checker(is_invocable_r);
#endif

#ifdef cppmp_std_supports_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);
#endif

}

#undef cppmp_define_checker
#undef cppmp_define_checker_var

#include "checker.inl"

+ 14
- 14
include/cppmp/core/checker.inl View File

@@ -25,24 +25,24 @@ namespace cppmp
: 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 */



+ 14
- 10
include/cppmp/core/constants.h View File

@@ -5,12 +5,6 @@
namespace cppmp
{

/**
* @brief Boolean constant value.
*/
template<bool B>
constexpr bool_t<B> bool_c;

/**
* @brief True boolean constant value.
*/
@@ -21,15 +15,25 @@ namespace cppmp
*/
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.
*/
template<std::size_t I>
constexpr size_t<I> size_c;

/**
* @brief Zero size constant value,
*/
constexpr zero_t zero_c;
#endif

}

+ 96
- 5
include/cppmp/core/modifier.h View File

@@ -1,5 +1,7 @@
#pragma once

#include <cstddef>

#define cppmp_define_modifier(name) \
template<typename... T> \
struct name \
@@ -18,29 +20,118 @@ namespace cppmp
template<typename T>
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);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_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(remove_pointer);
cppmp_define_modifier(add_pointer);
#endif

/* sign modifications */

#ifdef cppmp_std_supports_make_signed
cppmp_define_modifier(make_signed);
#endif

#ifdef cppmp_std_supports_make_unsigned
cppmp_define_modifier(make_unsigned);
#endif

/* array modifications */

#ifdef cppmp_std_supports_remove_extent
cppmp_define_modifier(remove_extent);
#endif

#ifdef cppmp_std_supports_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);
#endif

#ifdef cppmp_std_supports_underlying_type
cppmp_define_modifier(underlying_type);
#endif

#ifdef cppmp_std_supports_result_of
cppmp_define_modifier(result_of);
#endif

#if __cplusplus >= 201703L
#ifdef cppmp_std_supports_invoke_result
cppmp_define_modifier(invoke_result);
#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


+ 3
- 0
include/cppmp/core/types.h View File

@@ -1,5 +1,6 @@
#pragma once

#include <cstddef>
#include <type_traits>

namespace cppmp
@@ -18,8 +19,10 @@ namespace cppmp
struct type_t
{ };

#ifdef cppmp_supports_variable_templates
template<typename X>
constexpr decltype(auto) type_v = type_t<X> { };
#endif

/**
* @brief Simple type list.


+ 15
- 9
include/cppmp/misc/generic_predicate.h View File

@@ -1,5 +1,6 @@
#pragma once

#include <utility>
#include <cppmp/core/types.h>
#include <cppmp/core/checker.h>

@@ -8,16 +9,19 @@ namespace cppmp

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>
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.
*/
template<typename... T_args>
static constexpr bool is_valid_v = is_valid<T_args...>::value;
#endif

/**
* @brief Invoke the builder to create the requested object.


+ 2
- 0
include/cppmp/misc/getter.h View File

@@ -29,11 +29,13 @@ namespace cppmp
template<typename T>
struct is_getter;

#ifdef cppmp_supports_variable_templates
/**
* @brief Is true if the passed type is an getter, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_getter_v = is_getter<T>::value;
#endif

/**
* @brief Predicate to create new getter objects.


+ 29
- 26
include/cppmp/misc/getter.inl View File

@@ -28,7 +28,8 @@ namespace cppmp
template<typename T_getter>
struct getter_builder<
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)
{ return std::forward<T_getter>(getter); }
@@ -40,7 +41,7 @@ namespace cppmp
struct getter_builder<
list<T_value T_object::*>,
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;

constexpr getter_member_var(member_type p_member)
inline getter_member_var(member_type 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>
constexpr decltype(auto) operator()(X_object&& obj) const
@@ -92,15 +93,15 @@ namespace cppmp

member_type member;

constexpr getter_member_func(member_type p_member)
inline getter_member_func(member_type 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>
constexpr decltype(auto) operator()(X_object&& obj) const
@@ -135,9 +136,11 @@ namespace cppmp
struct getter_builder<
list<T_lambda>,
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
&& !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
: public tag_getter
@@ -150,15 +153,15 @@ namespace cppmp

lambda_type lambda;

constexpr getter_lambda(lambda_type&& p_lambda)
inline getter_lambda(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>
constexpr decltype(auto) operator()(X_object&& obj) const
@@ -177,8 +180,8 @@ namespace cppmp
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>()...))>
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;
second_getter_type second;

constexpr getter_chain(
inline 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;
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>
constexpr decltype(auto) operator()(X_object&& obj) const


+ 2
- 0
include/cppmp/misc/setter.h View File

@@ -28,11 +28,13 @@ namespace cppmp
template<typename T>
struct is_setter;

#ifdef cppmp_supports_variable_templates
/**
* @brief Is true if the passed type is an setter, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_setter_v = is_setter<T>::value;
#endif

/**
* @brief Predicate to create new setter objects.


+ 18
- 17
include/cppmp/misc/setter.inl View File

@@ -27,7 +27,8 @@ namespace cppmp
template<typename T_setter>
struct setter_builder<
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)
{ return std::forward<T_setter>(setter); }
@@ -50,15 +51,15 @@ namespace cppmp

member_type member;

constexpr setter_member_var(member_type p_member)
inline setter_member_var(member_type 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>
constexpr void operator()(X_object&& obj, X_value&& value) const
@@ -88,15 +89,15 @@ namespace cppmp

member_type member;

constexpr setter_member_func(member_type p_member)
inline setter_member_func(member_type 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>
constexpr void operator()(X_object&& obj, X_value&& value) const
@@ -131,7 +132,7 @@ namespace cppmp
struct setter_builder<
list<T_lambda>,
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>>
{
struct setter_lambda
@@ -145,15 +146,15 @@ namespace cppmp

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))
{ }

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>
constexpr void operator()(X_object&& obj, X_value&& value) const


+ 5
- 1
include/cppmp/traits/lambda_traits.inl View File

@@ -42,7 +42,11 @@ namespace cppmp
/* lambda_traits */

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())>
{ };



+ 26
- 0
test/cppmp/cppmp_checker_tests.cpp View File

@@ -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");

+ 39
- 0
test/cppmp/cppmp_generic_predicate_tests.cpp View File

@@ -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);
}

+ 10
- 5
test/cppmp/cppmp_getter_tests.cpp View File

@@ -24,8 +24,9 @@ TEST(cppmp_getter_tests, member_var)
test_obj o { 1 };

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)
@@ -33,8 +34,9 @@ TEST(cppmp_getter_tests, member_func)
test_obj o { 1 };

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)
@@ -42,8 +44,9 @@ TEST(cppmp_getter_tests, const_member_func)
test_obj o { 1 };

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)
@@ -51,8 +54,9 @@ TEST(cppmp_getter_tests, static_func)
test_obj o { 1 };

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)
@@ -62,6 +66,7 @@ TEST(cppmp_getter_tests, lambda)
auto g = make_getter([](test_obj& o){
return o.value;
});
auto i = g(obj);

EXPECT_EQ(1, g(obj));
EXPECT_EQ(1, i);
}

+ 34
- 34
test/cppmp/cppmp_traits_test.cpp View File

@@ -27,45 +27,45 @@ using type3 = ::cppmp::lambda_traits<std::string(*)(bool)>;
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<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)
{


Loading…
Cancel
Save