#pragma once #include #include #include namespace hex { template struct is_integral_helper : public std::false_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template<> struct is_integral_helper : public std::true_type { }; template struct is_integral : public is_integral_helper>::type { }; template struct is_signed_helper : public std::false_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template<> struct is_signed_helper : public std::true_type { }; template struct is_signed : public is_signed_helper>::type { }; template struct is_floating_point_helper : public std::false_type { }; template<> struct is_floating_point_helper : public std::true_type { }; template<> struct is_floating_point_helper : public std::true_type { }; template<> struct is_floating_point_helper : public std::true_type { }; template struct is_floating_point : public is_floating_point_helper>::type { }; } #if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 12000 #if __has_include() // Make sure we break when derived_from is implemented in libc++. Then we can fix a compatibility version above #include #endif // libcxx 12 still doesn't have many default concepts implemented, as a result we need to define it ourself using clang built-ins. // [concept.derived] (patch from https://reviews.llvm.org/D74292) namespace hex { template concept derived_from = __is_base_of(_Bp, _Dp) && __is_convertible_to(const volatile _Dp *, const volatile _Bp *); } #else // Assume supported #include namespace hex { using std::derived_from; } #endif // [concepts.arithmetic] namespace hex { template concept integral = hex::is_integral::value; template concept signed_integral = integral && hex::is_signed::value; template concept unsigned_integral = integral && !signed_integral; template concept floating_point = std::is_floating_point::value; } namespace hex { template struct always_false : std::false_type { }; template concept has_size = sizeof(T) == Size; } namespace hex { template class Cloneable { public: [[nodiscard]] virtual std::unique_ptr clone() const = 0; }; }