#pragma once #include #include #include #include #include "gp/algorithms/min_max.hpp" namespace gp{ /** * @brief Picks either of the types depending on the condition * * @tparam cond the condition * @tparam T the type picked when the condition is true * @tparam U the type picked when the condition is false */ template struct either { }; template struct either { typedef T type; }; template struct either { typedef U type; }; /** * @brief Checks if the provided booleans are all true at compile time */ template struct constexpr_all_of { static constexpr bool value = first && constexpr_all_of::value; }; template struct constexpr_all_of { static constexpr bool value = first; }; /** * @brief Checks if at least one of the provided booleans is true at compile time */ template struct constexpr_any_of { static constexpr bool value = first || constexpr_any_of::value; }; template struct constexpr_any_of { static constexpr bool value = first; }; /** * @brief Checks if the provided type has a compile time defined size * * @tparam T the tested type * @return true if it has a defined size * @return false if its size may change due to inheritance or other factors */ template constexpr bool is_fixed_size() { return std::is_final::value || std::is_fundamental::value; } /** * @brief Checks if the provided typelist is all of fixed size */ template struct all_of_fixed_size { static constexpr bool value = is_fixed_size() && all_of_fixed_size::value; }; template struct all_of_fixed_size { static constexpr bool value = is_fixed_size(); }; /** * @brief Checks if the provided list contains the provided class * * @tparam Univ the class to look for */ template struct list_contains_class { static constexpr bool value = ( std::is_same::value ) || list_contains_class::value; }; template struct list_contains_class { static constexpr bool value = std::is_same::value; }; /** * @brief gives the index of Univ from the end of the argument list * * @tparam Univ The type to look for */ template struct r_index_of { static constexpr std::size_t value = std::is_same::value ? sizeof...(rest) : r_index_of::value; }; template struct r_index_of { static constexpr std::size_t value = std::is_same::value ? 0 : std::numeric_limits::max(); }; /** * @brief gives the type of the idx value from the end of the argument list * * @tparam idx The index to return the type of */ template struct r_index_at { using type = typename either< idx==sizeof...(rest), T, typename r_index_at::type >::type; }; /** * @brief extracts the first type of the list */ template struct first_of { using type = U; }; /** * @brief gives the size of the largest element in the provided list * * @return constexpr std::size_t equal to the largest size of all */ template constexpr std::size_t max_size() { if constexpr (sizeof...(rest) == 0) { return gp::max(sizeof(T),sizeof(U)); } else { return max_size< typename either< ( sizeof(T) > sizeof(U) ), T, U >::type, rest...>(); } } /** * @brief remove reference state from the provided type */ template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; /** * @brief Has a value of true if the provided type has a size() function member */ template struct has_size_interface { private: typedef std::true_type yes; typedef std::false_type no; template struct SFINAE{}; template static yes test(SFINAE*); template static no test(...); public: static constexpr bool value = std::is_same(nullptr))>::value; }; /** * @brief Has a value of true if the provided type has a begin() function member */ template struct has_begin_interface { private: typedef std::true_type yes; typedef std::false_type no; template struct SFINAE{}; template static yes test(SFINAE*); template static no test(...); public: static constexpr bool value = std::is_same(nullptr))>::value; }; /** * @brief Has a value of true if the provided type has a end() function member */ template struct has_end_interface { private: typedef std::true_type yes; typedef std::false_type no; template struct SFINAE{}; template static yes test(SFINAE*); template static no test(...); public: static constexpr bool value = std::is_same(nullptr))>::value; }; // TODO: Replace those with concepts template using has_range_interface = constexpr_all_of::value,has_end_interface::value>; template using has_measurable_range_interface = constexpr_all_of::value,has_size_interface::value>; template struct has_allocate_interface { private: typedef std::true_type yes; typedef std::false_type no; template struct SFINAE{}; template static yes test(SFINAE*); template static no test(...); public: static constexpr bool value = std::is_same(nullptr))>::value; }; template struct has_deallocate_interface { private: typedef std::true_type yes; typedef std::false_type no; template struct SFINAE{}; template static yes test(SFINAE*); template static no test(...); public: static constexpr bool value = std::is_same(nullptr))>::value; }; template using has_allocator_interface = constexpr_all_of::value,has_deallocate_interface::value>; }