|
@@ -3,6 +3,9 @@
|
|
|
|
|
|
namespace std {
|
|
|
|
|
|
+template <typename... Ts>
|
|
|
+using void_t = void;
|
|
|
+
|
|
|
template <typename T>
|
|
|
struct remove_reference { using type = T; };
|
|
|
template <typename T>
|
|
@@ -13,6 +16,215 @@ struct remove_reference<T&&> { using type = T; };
|
|
|
template <typename T>
|
|
|
using remove_reference_t = typename remove_reference<T>::type;
|
|
|
|
|
|
+namespace __helpers {
|
|
|
+
|
|
|
+template <typename T, typename = void> // for cv-void
|
|
|
+struct add_rvalue_reference { using type = T; };
|
|
|
+template <typename T> // cv-void will fail in substitution
|
|
|
+struct add_rvalue_reference<T, void_t<T&&> > { using type = T&&; };
|
|
|
+
|
|
|
+template <typename T, typename = void> // for cv-void
|
|
|
+struct add_lvalue_reference { using type = T; };
|
|
|
+template <typename T> // cv-void will fail in substitution
|
|
|
+struct add_lvalue_reference<T, void_t<T&> > { using type = T&; };
|
|
|
+
|
|
|
+} // namespace __helpers
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct add_rvalue_reference {
|
|
|
+ using type = typename __helpers::add_rvalue_reference<T>::type;
|
|
|
+};
|
|
|
+template <typename T>
|
|
|
+struct add_lvalue_reference {
|
|
|
+ using type = typename __helpers::add_lvalue_reference<T>::type;
|
|
|
+};
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
|
|
|
+template <typename T>
|
|
|
+using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct remove_pointer { using type = T; };
|
|
|
+template <typename T>
|
|
|
+struct remove_pointer<T*> { using type = T; };
|
|
|
+template <typename T>
|
|
|
+struct remove_pointer<T* const> { using type = T; };
|
|
|
+template <typename T>
|
|
|
+struct remove_pointer<T* volatile> { using type = T; };
|
|
|
+template <typename T>
|
|
|
+struct remove_pointer<T* const volatile> { using type = T; };
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+using remove_pointer_t = typename remove_pointer<T>::type;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct add_pointer { using type = remove_reference_t<T>*; };
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+using add_pointer_t = typename add_pointer<T>::type;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct remove_cv { using type = T; };
|
|
|
+template <typename T>
|
|
|
+struct remove_cv<T const> { using type = T; };
|
|
|
+template <typename T>
|
|
|
+struct remove_cv<T volatile> { using type = T; };
|
|
|
+template <typename T>
|
|
|
+struct remove_cv<T const volatile> { using type = T; };
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+using remove_cv_t = typename remove_cv<T>::type;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct add_const { using type = T const; };
|
|
|
+template <typename T>
|
|
|
+struct add_volatile { using type = T volatile; };
|
|
|
+template <typename T>
|
|
|
+struct add_cv { using type = T const volatile; };
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+using add_const_t = typename add_const<T>::type;
|
|
|
+template <typename T>
|
|
|
+using add_volatile_t = typename add_volatile<T>::type;
|
|
|
+template <typename T>
|
|
|
+using add_cv_t = typename add_cv<T>::type;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct decay {
|
|
|
+private:
|
|
|
+ using U = remove_reference_t<T>;
|
|
|
+public:
|
|
|
+ using type = remove_cv_t<U>;
|
|
|
+};
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+using decay_t = typename decay<T>::type;
|
|
|
+
|
|
|
+template <typename T, T _value>
|
|
|
+struct integral_constant {
|
|
|
+ using value_type = T;
|
|
|
+ using type = integral_constant;
|
|
|
+
|
|
|
+ static constexpr value_type value = _value;
|
|
|
+ constexpr operator value_type() const noexcept { return value; }
|
|
|
+ constexpr value_type operator()() const noexcept { return value; }
|
|
|
+};
|
|
|
+
|
|
|
+template <bool _value>
|
|
|
+using bool_constant = integral_constant<bool, _value>;
|
|
|
+
|
|
|
+using true_type = bool_constant<true>;
|
|
|
+using false_type = bool_constant<false>;
|
|
|
+
|
|
|
+namespace __helpers {
|
|
|
+
|
|
|
+template <typename>
|
|
|
+struct template_true_type : public true_type {};
|
|
|
+template <typename>
|
|
|
+struct template_false_type : public false_type {};
|
|
|
+
|
|
|
+} // namespace __helpers
|
|
|
+
|
|
|
+template <bool condition, typename T, typename F>
|
|
|
+struct conditional { using type = F; };
|
|
|
+template <typename T, typename F>
|
|
|
+struct conditional<true, T, F> { using type = T; };
|
|
|
+
|
|
|
+template <bool condition, typename T, typename F>
|
|
|
+using conditional_t = typename conditional<condition, T, F>::type;
|
|
|
+
|
|
|
+template <typename T, typename U>
|
|
|
+struct is_same : public false_type {};
|
|
|
+template <typename T>
|
|
|
+struct is_same<T, T> : public true_type {};
|
|
|
+
|
|
|
+template <typename T, typename U>
|
|
|
+inline constexpr bool is_same_v = is_same<T, U>::value;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct is_void : public is_same<remove_cv_t<T>, void> {};
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+inline constexpr bool is_void_v = is_void<T>::value;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct is_pointer : public false_type {};
|
|
|
+template <typename T>
|
|
|
+struct is_pointer<T*> : public true_type {};
|
|
|
+template <typename T>
|
|
|
+struct is_pointer<T* const> : public true_type {};
|
|
|
+template <typename T>
|
|
|
+struct is_pointer<T* volatile> : public true_type {};
|
|
|
+template <typename T>
|
|
|
+struct is_pointer<T* const volatile> : public true_type {};
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+inline constexpr bool is_pointer_v = is_pointer<T>::value;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+struct is_const : public false_type {};
|
|
|
+template <typename T>
|
|
|
+struct is_const<T const> : public true_type {};
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+inline constexpr bool is_const_v = is_const<T>::value;
|
|
|
+
|
|
|
+template <bool B, typename T = void>
|
|
|
+struct enable_if {};
|
|
|
+template <typename T>
|
|
|
+struct enable_if<true, T> { using type = T; };
|
|
|
+
|
|
|
+template <bool B, typename T = void>
|
|
|
+using enable_if_t = typename enable_if<B, T>::type;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+add_rvalue_reference_t<T> declval(void) noexcept
|
|
|
+{
|
|
|
+ static_assert(__helpers::template_false_type<T>::value, "declval cannot be evaluated.");
|
|
|
+}
|
|
|
+
|
|
|
+namespace __helpers {
|
|
|
+
|
|
|
+template <typename From, typename To, typename = void>
|
|
|
+struct is_convertible : public false_type {};
|
|
|
+template <typename From, typename To>
|
|
|
+struct is_convertible<From, To,
|
|
|
+ decltype(declval<void(*)(To)>()(declval<From>()))
|
|
|
+> : public true_type {};
|
|
|
+template <typename Void1, typename Void2>
|
|
|
+struct is_convertible<Void1, Void2,
|
|
|
+ enable_if_t<is_void_v<Void1> && is_void_v<Void2> >
|
|
|
+> : public true_type {};
|
|
|
+
|
|
|
+} // namespace __helpers
|
|
|
+
|
|
|
+template <typename From, typename To>
|
|
|
+struct is_convertible : public __helpers::is_convertible<From, To> {};
|
|
|
+
|
|
|
+template <typename From, typename To>
|
|
|
+inline constexpr bool is_convertible_v = is_convertible<From, To>::value;
|
|
|
+
|
|
|
+#define __CPP_GREATBRIDF
|
|
|
+#ifdef __CPP_GREATBRIDF
|
|
|
+
|
|
|
+template <typename U, template <typename...> class T, typename...>
|
|
|
+struct is_template_instance : public false_type {
|
|
|
+};
|
|
|
+template <template <typename...> class T, typename... Ts>
|
|
|
+struct is_template_instance<T<Ts...>, T> : public true_type {
|
|
|
+};
|
|
|
+
|
|
|
+template <typename U, template <typename...> class T, typename... Ts>
|
|
|
+inline constexpr bool is_template_instance_v = is_template_instance<U, T, Ts...>::value;
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+using template_false_type = __helpers::template_false_type<T>;
|
|
|
+template <typename T>
|
|
|
+using template_true_type = __helpers::template_true_type<T>;
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
} // namespace std
|
|
|
|
|
|
#endif
|