Browse Source

fix(type_traits): fix decay

greatbridf 1 year ago
parent
commit
2e38e5e6de
1 changed files with 39 additions and 11 deletions
  1. 39 11
      gblibstdc++/include/type_traits

+ 39 - 11
gblibstdc++/include/type_traits

@@ -67,6 +67,16 @@ 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_extent { using type = T; };
+template <typename T>
+struct remove_extent<T[]> { using type = T; };
+template <typename T, size_t N>
+struct remove_extent<T[N]> { using type = T; };
+
+template <typename T>
+using remove_extent_t = typename remove_extent<T>::type;
+
 template <typename T>
 struct remove_cv { using type = T; };
 template <typename T>
@@ -93,17 +103,6 @@ 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;
@@ -165,6 +164,16 @@ 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_array : public false_type {};
+template <typename T>
+struct is_array<T[]> : public true_type {};
+template <typename T, size_t N>
+struct is_array<T[N]> : public true_type {};
+
+template <typename T>
+inline constexpr bool is_array_v = is_array<T>::value;
+
 template <typename T>
 struct is_const : public false_type {};
 template <typename T>
@@ -183,6 +192,25 @@ struct is_function<T&&> : public false_type {};
 template <typename T>
 inline constexpr bool is_function_v = is_function<T>::value;
 
+template <typename T>
+struct decay {
+private:
+    using U = remove_reference_t<T>;
+public:
+    using type = conditional_t<
+        is_array_v<U>,
+        add_pointer_t<remove_extent_t<U>>,
+        conditional_t<
+            is_function_v<U>,
+            add_pointer_t<U>,
+            remove_cv_t<U>
+        >
+    >;
+};
+
+template <typename T>
+using decay_t = typename decay<T>::type;
+
 template <bool B, typename T = void>
 struct enable_if {};
 template <typename T>