#pragma once #include #include #include #include #include "gp/algorithm/min_max.hpp" namespace gp{ template struct either { }; template struct either { typedef T type; }; template struct either { typedef U type; }; template struct constexpr_all_of { static constexpr bool value = first && constexpr_all_of::value; }; template struct constexpr_all_of { static constexpr bool value = first; }; template struct constexpr_any_of { static constexpr bool value = first || constexpr_any_of::value; }; template struct constexpr_any_of { static constexpr bool value = first; }; template constexpr bool is_fixed_size() { return std::is_final::value || std::is_fundamental::value; } 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(); }; 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; }; 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(); }; template struct r_index_at { using type = typename either::type>::type; }; 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...>(); } } template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; 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; }; 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; }; 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; }; 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>; }