Эх сурвалжийг харах

feat(libstdc++): add pair

greatbridf 1 жил өмнө
parent
commit
5444b2ee83

+ 34 - 0
gblibstdc++/include/bits/forward

@@ -0,0 +1,34 @@
+#ifndef __GBLIBCPP_BITS_FORWARD__
+#define __GBLIBCPP_BITS_FORWARD__
+
+#include <bits/type_traits/remove_add>
+
+namespace std {
+
+template <typename T>
+constexpr std::remove_reference_t<T>&& move(T&& val) noexcept
+{
+    return static_cast<std::remove_reference_t<T>&&>(val);
+}
+
+template <typename T>
+constexpr T&& forward(std::remove_reference_t<T>& val) noexcept
+{
+    return static_cast<T&&>(val);
+}
+template <typename T>
+constexpr T&& forward(std::remove_reference_t<T>&& val) noexcept
+{
+    return static_cast<T&&>(val);
+}
+
+template <typename T>
+add_rvalue_reference_t<T> declval(void) noexcept
+{
+    static_assert(__helpers::template_false_type<T>::value,
+        "declval cannot be evaluated.");
+}
+
+} // namespace std
+
+#endif

+ 27 - 0
gblibstdc++/include/bits/sequence

@@ -0,0 +1,27 @@
+#ifndef __GBLIBCPP_BITS_SEQUENCE__
+#define __GBLIBCPP_BITS_SEQUENCE__
+
+#include <cstddef>
+
+namespace std {
+
+template <typename T, T... Ints>
+struct integer_sequence {
+    static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
+};
+
+template <std::size_t... Indicies>
+using index_sequence = integer_sequence<std::size_t, Indicies...>;
+
+template <std::size_t N, std::size_t... Indicies>
+struct make_index_sequence : public make_index_sequence<N-1, N-1, Indicies...> {};
+
+template <std::size_t... Indicies>
+struct make_index_sequence<0, Indicies...> : public index_sequence<Indicies...> {};
+
+template <typename... Ts>
+using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
+
+} // namespace std
+
+#endif

+ 82 - 0
gblibstdc++/include/bits/tuple_tools

@@ -0,0 +1,82 @@
+#ifndef __GBLIBCPP_BITS_TUPLE_TOOLS__
+#define __GBLIBCPP_BITS_TUPLE_TOOLS__
+
+#include <cstddef>
+
+#include <bits/type_traits/remove_add>
+
+#include <bits/forward>
+#include <bits/sequence>
+
+#include <bits/fwd_functional>
+
+namespace std {
+
+template <typename... Types>
+class tuple;
+
+template <std::size_t I, typename T>
+struct tuple_element;
+
+template <std::size_t I, typename T>
+using tuple_element_t = typename tuple_element<I, T>::type;
+
+template <typename T>
+struct tuple_size;
+
+template <typename T>
+inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;
+
+template <std::size_t I, typename... Types>
+constexpr auto get(std::tuple<Types...>& tpl) noexcept
+    -> tuple_element_t<I, std::tuple<Types...>>&
+{ return tpl.template _getl<I>(); }
+
+template <std::size_t I, typename... Types>
+constexpr auto get(std::tuple<Types...>&& tpl) noexcept
+    -> tuple_element_t<I, std::tuple<Types...>>&&
+{ return tpl.template _getr<I>(); }
+
+template <std::size_t I, typename... Types>
+constexpr auto get(const std::tuple<Types...>& tpl) noexcept
+    -> tuple_element_t<I, std::tuple<Types...>> const&
+{ return tpl.template _getl<I>(); }
+
+template <std::size_t I, typename... Types>
+constexpr auto get(const std::tuple<Types...>&& tpl) noexcept
+    -> tuple_element_t<I, std::tuple<Types...>> const&&
+{ return tpl.template _getr<I>(); }
+
+namespace __helpers {
+
+template <typename T, typename Tuple, std::size_t... I>
+constexpr T make_from_tuple_impl(Tuple&& tpl, std::index_sequence<I...>)
+{
+    return T(std::get<I>(std::forward<Tuple>(tpl))...);
+}
+
+template <typename _T, typename T = std::decay_t<_T>>
+struct __to_tuple_type { using type = T; };
+
+template <typename _T, typename T>
+struct __to_tuple_type<_T, std::reference_wrapper<T>>
+{ using type = std::add_lvalue_reference_t<T>; };
+
+template <typename T>
+using to_tuple_type_t = typename __to_tuple_type<T>::type;
+
+} // namespace __helpers
+
+template <typename T, typename Tuple>
+constexpr T make_from_tuple(Tuple&& tpl)
+{
+    return __helpers::make_from_tuple_impl<T>(
+        std::forward<Tuple>(tpl),
+        std::make_index_sequence<
+            std::tuple_size_v<std::remove_cvref_t<Tuple>>> {}
+    );
+}
+
+}
+
+#endif

+ 46 - 0
gblibstdc++/include/bits/type_traits/base

@@ -0,0 +1,46 @@
+#ifndef __GBLIBCPP_BITS_TYPE_TRAITS_BASE__
+#define __GBLIBCPP_BITS_TYPE_TRAITS_BASE__
+
+#include <cstddef>
+
+namespace std {
+
+template <typename... Ts>
+using void_t = void;
+
+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>;
+
+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;
+
+namespace __helpers {
+
+template <typename>
+struct template_true_type : public true_type {};
+template <typename>
+struct template_false_type : public false_type {};
+
+} // namespace __helpers
+
+} // namespace std
+
+#endif

+ 40 - 0
gblibstdc++/include/bits/type_traits/is_es

@@ -0,0 +1,40 @@
+#ifndef __GBLIBCPP_BITS_TYPE_TRAITS_IS_ES__
+#define __GBLIBCPP_BITS_TYPE_TRAITS_IS_ES__
+
+#include <cstddef>
+
+#include <bits/type_traits/base>
+
+namespace std {
+
+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>
+struct is_const<T const> : public true_type {};
+
+template <typename T>
+inline constexpr bool is_const_v = is_const<T>::value;
+
+template <typename T>
+struct is_function : public bool_constant<!is_const_v<const T>> {};
+template <typename T>
+struct is_function<T&> : public false_type {};
+template <typename T>
+struct is_function<T&&> : public false_type {};
+
+template <typename T>
+inline constexpr bool is_function_v = is_function<T>::value;
+
+} // namespace std
+
+#endif

+ 123 - 0
gblibstdc++/include/bits/type_traits/remove_add

@@ -0,0 +1,123 @@
+#ifndef __GBLIBCPP_BITS_TYPE_TRAITS_REMOVE_ADD__
+#define __GBLIBCPP_BITS_TYPE_TRAITS_REMOVE_ADD__
+
+#include <cstddef>
+
+#include <bits/type_traits/is_es>
+
+namespace std {
+
+// REMOVES
+
+template <typename T>
+struct remove_reference { using type = T; };
+template <typename T>
+struct remove_reference<T&> { using type = T; };
+template <typename T>
+struct remove_reference<T&&> { using type = T; };
+
+template <typename T>
+using remove_reference_t = typename remove_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 remove_extent { using type = T; };
+template <typename T>
+struct remove_extent<T[]> { using type = T; };
+template <typename T, std::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>
+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 remove_cvref {
+    using type = remove_cv_t<remove_reference_t<T>>;
+};
+
+template <typename T>
+using remove_cvref_t = typename remove_cvref<T>::type;
+
+// ADDS
+
+template <typename T>
+struct add_pointer { using type = remove_reference_t<T>*; };
+
+template <typename T>
+using add_pointer_t = typename add_pointer<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 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;
+
+} // namespace std
+
+#endif

+ 119 - 67
gblibstdc++/include/tuple

@@ -7,19 +7,10 @@
 
 #include <functional>
 
-namespace std {
-
-template <std::size_t I, typename T>
-struct tuple_element;
-
-template <std::size_t I, typename T>
-using tuple_element_t = typename tuple_element<I, T>::type;
-
-template <typename T>
-struct tuple_size;
+#include <bits/tuple_tools>
+#include <bits/sequence>
 
-template <typename T>
-inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;
+namespace std {
 
 template <std::size_t I, typename T>
 struct tuple_element<I, const T> {
@@ -62,26 +53,6 @@ template <typename... Types>
 struct tuple_size<std::tuple<Types...>>
     : std::integral_constant<std::size_t, sizeof...(Types)> {};
 
-template <std::size_t I, typename... Types>
-constexpr auto get(std::tuple<Types...>& tpl) noexcept
-    -> tuple_element_t<I, std::tuple<Types...>>&
-{ return tpl.template _getl<I>(); }
-
-template <std::size_t I, typename... Types>
-constexpr auto get(std::tuple<Types...>&& tpl) noexcept
-    -> tuple_element_t<I, std::tuple<Types...>>&&
-{ return tpl.template _getr<I>(); }
-
-template <std::size_t I, typename... Types>
-constexpr auto get(const std::tuple<Types...>& tpl) noexcept
-    -> tuple_element_t<I, std::tuple<Types...>> const&
-{ return tpl.template _getl<I>(); }
-
-template <std::size_t I, typename... Types>
-constexpr auto get(const std::tuple<Types...>&& tpl) noexcept
-    -> tuple_element_t<I, std::tuple<Types...>> const&&
-{ return tpl.template _getr<I>(); }
-
 namespace __helpers {
 
 template <std::size_t I, typename Type, typename... Types>
@@ -218,6 +189,55 @@ public:
     constexpr tuple_impl& operator=(tuple_impl&& other) = default;
 };
 
+template <typename... Types>
+struct tuple_constraints {
+    static constexpr std::size_t Tsize = sizeof...(Types);
+
+    template <std::size_t... I>
+    static constexpr auto idx_seq(std::index_sequence<I...> seq)
+    { return seq; }
+
+    template <typename UTuple, typename Seq, typename... UTypes>
+    struct tuple_copy_move_constructible_impl;
+
+    template <typename UTuple, typename... UTypes, std::size_t... I>
+    struct tuple_copy_move_constructible_impl<UTuple,
+        std::index_sequence<I...>, UTypes...> : std::bool_constant<
+        Tsize == sizeof...(UTypes)
+        && (... && std::is_constructible_v<Types, decltype(
+            std::get<I>(std::declval<UTuple>()))>)
+        && ((Tsize != 1) || (!(... && std::is_convertible_v<UTuple, Types>)
+            && !(... && std::is_constructible_v<Types, UTuple>)
+            && !(... && std::is_same_v<Types, UTypes>)))
+    > {};
+
+    template <typename UTuple, typename... UTypes>
+    struct tuple_copy_move_constructible : tuple_copy_move_constructible_impl<
+        UTuple, decltype(idx_seq(std::index_sequence_for<UTypes...>{})), UTypes...> {};
+
+    template <typename Pair, typename = std::index_sequence<0, 1>>
+    struct tuple_pair_constructible;
+
+    template <typename Pair, std::size_t... I>
+    struct tuple_pair_constructible<Pair, std::index_sequence<I...>>
+        : std::bool_constant<sizeof...(Types) == 2
+            && (... && std::is_constructible_v<Types,
+                decltype(std::get<I>(std::declval<Pair>()))>)
+    > {};
+
+    template <typename... Us>
+    struct tuple_pair_copy_assignable : std::bool_constant<
+        sizeof...(Types) == 2
+        && (... && std::is_assignable_v<Types&, const Us&>)
+    > {};
+
+    template <typename... Us>
+    struct tuple_pair_move_assignable : std::bool_constant<
+        sizeof...(Types) == 2
+        && (... && std::is_assignable_v<Types&, Us>)
+    > {};
+};
+
 } // namespace __helpers
 
 template <typename... Types>
@@ -226,36 +246,69 @@ private:
     using base = __helpers::tuple_impl<0, Types...>;
 
     template <typename... UTypes, std::size_t... I>
-    constexpr void __copy_assignment(const tuple<UTypes...>& other, std::index_sequence<I...>)
+    constexpr void __copy_assignment(
+        const tuple<UTypes...>& other, std::index_sequence<I...>)
     { ((std::get<I>(*this) = std::get<I>(other)), ...); }
 
     template <typename... UTypes, std::size_t... I>
-    constexpr void __move_assignment(tuple<UTypes...>&& other, std::index_sequence<I...>)
-    { ((std::get<I>(*this) = std::forward<UTypes>(std::get<I>(other))), ...); }
+    constexpr void __move_assignment(
+        tuple<UTypes...>&& other, std::index_sequence<I...>)
+    {
+        ((std::get<I>(*this) = std::forward<UTypes>(std::get<I>(other))), ...);
+    }
 
 public:
+    template <typename _ = void, std::enable_if_t<
+        (... && std::is_default_constructible_v<Types>)
+        && __helpers::template_true_type<_>::value
+    , bool> = true>
     constexpr tuple() : base() {}
 
+    template <typename _ = void, std::enable_if_t<
+        sizeof...(Types) >= 1
+        && (... && std::is_copy_constructible_v<Types>)
+        && __helpers::template_true_type<_>::value
+    , bool> = true>
     constexpr tuple(const Types&... args)
         : base(args...) {}
     
-    template <typename... UTypes, enable_if_t<
+    template <typename... UTypes, std::enable_if_t<
         sizeof...(UTypes) == sizeof...(Types)
         && sizeof...(Types) >= 1
-        && !(sizeof...(Types) == 1 && (... && std::is_same_v<tuple, UTypes>))
+        && (... && std::is_constructible_v<Types, UTypes>)
+        && !(sizeof...(Types) == 1
+            && (... && std::is_same_v<tuple, std::remove_cvref_t<UTypes>>))
     , bool> = true>
     constexpr tuple(UTypes&&... args)
         : base(std::forward<UTypes>(args)...) {}
 
-    template <typename... UTypes>
+    template <typename... UTypes, std::enable_if_t<
+        __helpers::tuple_constraints<Types...>::template
+            tuple_copy_move_constructible<const tuple<UTypes...>&, UTypes...>::value
+    , bool> = true>
     constexpr tuple(const tuple<UTypes...>& other)
         : base(other) {}
 
-    template <typename... UTypes>
+    template <typename... UTypes, std::enable_if_t<
+        __helpers::tuple_constraints<Types...>::template
+            tuple_copy_move_constructible<tuple<UTypes...>&&, UTypes...>::value
+    , bool> = true>
     constexpr tuple(tuple<UTypes...>&& other)
         : base(std::move(other)) {}
     
-    // TODO: std::pair constructors
+    template <typename U1, typename U2, std::enable_if_t<
+        __helpers::tuple_constraints<Types...>::template
+            tuple_pair_constructible<const std::pair<U1, U2>&>::value
+    , bool> = true>
+    constexpr tuple(const std::pair<U1, U2>& p)
+        : base(std::get<0>(p), std::get<1>(p)) {}
+    
+    template <typename U1, typename U2, std::enable_if_t<
+        __helpers::tuple_constraints<Types...>::template
+            tuple_pair_constructible<std::pair<U1, U2>&&>::value
+    , bool> = true>
+    constexpr tuple(std::pair<U1, U2>&& p)
+        : base(std::get<0>(std::move(p)), std::get<1>(std::move(p))) {}
 
     constexpr tuple(const tuple&) = default;
     constexpr tuple(tuple&&) = default;
@@ -263,7 +316,7 @@ public:
     constexpr tuple& operator=(const tuple& other) = default;
     constexpr tuple& operator=(tuple&& other) = default;
 
-    template <typename... UTypes, enable_if_t<
+    template <typename... UTypes, std::enable_if_t<
         sizeof...(Types) == sizeof...(UTypes)
         && (... && std::is_assignable_v<Types&, const UTypes&>)
         , bool> = true>
@@ -273,7 +326,7 @@ public:
         return *this;
     }
 
-    template <typename... UTypes, enable_if_t<
+    template <typename... UTypes, std::enable_if_t<
         sizeof...(Types) == sizeof...(UTypes)
         && (... && std::is_assignable_v<Types&, UTypes>)
         , bool> = true>
@@ -283,6 +336,28 @@ public:
         return *this;
     }
 
+    template <typename U1, typename U2, std::enable_if_t<
+        __helpers::tuple_constraints<Types...>::template
+            tuple_pair_copy_assignable<U1, U2>::value
+    , bool> = true>
+    constexpr tuple& operator=(const std::pair<U1, U2>& p)
+    {
+        std::get<0>(*this) = p.first;
+        std::get<1>(*this) = p.second;
+        return *this;
+    }
+
+    template <typename U1, typename U2, std::enable_if_t<
+        __helpers::tuple_constraints<Types...>::template
+            tuple_pair_move_assignable<U1, U2>::value
+    , bool> = true>
+    constexpr tuple& operator=(std::pair<U1, U2>&& p)
+    {
+        std::get<0>(*this) = std::forward<U1>(p.first);
+        std::get<1>(*this) = std::forward<U2>(p.second);
+        return *this;
+    }
+
     constexpr void swap(tuple& other) { std::swap(*this, other); }
 };
 
@@ -296,19 +371,6 @@ struct ignore_t {
     constexpr void operator=(T&&) const noexcept {}
 };
 
-template <typename _T, typename T = std::decay_t<_T>>
-struct __to_tuple_type { using type = T; };
-
-template <typename _T, typename T>
-struct __to_tuple_type<_T, std::reference_wrapper<T>>
-{ using type = std::add_lvalue_reference_t<T>; };
-
-template <typename T, typename Tuple, std::size_t... I>
-constexpr T make_from_tuple_impl(Tuple&& tpl, std::index_sequence<I...>)
-{
-    return T { std::get<I>(std::forward<Tuple>(tpl))... };
-}
-
 template <typename Func, typename Tuple, std::size_t... I>
 constexpr auto apply_impl(Func&& func, Tuple&& tpl, std::index_sequence<I...>)
 {
@@ -330,9 +392,9 @@ constexpr void swap(std::tuple<Types...>& lhs, std::tuple<Types...>& rhs)
 
 template <typename... Types>
 constexpr auto make_tuple(Types&&... args)
-    -> std::tuple<typename __helpers::__to_tuple_type<Types>::type...>
+    -> std::tuple<__helpers::to_tuple_type_t<Types>...>
 {
-    return std::tuple<typename __helpers::__to_tuple_type<Types>::type...>
+    return std::tuple<__helpers::to_tuple_type_t<Types>...>
         { std::forward<Types>(args)... };
 }
 
@@ -348,16 +410,6 @@ constexpr std::tuple<Types&&...> forward_as_tuple(Types&&... args) noexcept
     return { std::forward<Types>(args)... };
 }
 
-template <typename T, typename Tuple>
-constexpr T make_from_tuple(Tuple&& tpl)
-{
-    return __helpers::make_from_tuple_impl<T>(
-        std::forward<Tuple>(tpl),
-        std::make_index_sequence<
-            std::tuple_size_v<std::remove_cvref_t<Tuple>>> {}
-    );
-}
-
 template <typename Func, typename Tuple>
 constexpr decltype(auto) apply(Func&& func, Tuple&& tpl)
 {

+ 52 - 178
gblibstdc++/include/type_traits

@@ -2,92 +2,13 @@
 #define __GBLIBCPP_TYPE_TRAITS__
 
 #include <bits/fwd_functional>
-#include <utility>
+#include <bits/forward>
 
-namespace std {
-
-template <typename... Ts>
-using void_t = void;
-
-template <typename T>
-struct remove_reference { using type = T; };
-template <typename T>
-struct remove_reference<T&> { using type = T; };
-template <typename T>
-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; };
+#include <bits/type_traits/base>
+#include <bits/type_traits/is_es>
+#include <bits/type_traits/remove_add>
 
-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_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>
-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;
+namespace std {
 
 template <typename T>
 struct add_const { using type = T const; };
@@ -103,39 +24,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, 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>
@@ -164,61 +52,6 @@ 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>
-struct is_const<T const> : public true_type {};
-
-template <typename T>
-inline constexpr bool is_const_v = is_const<T>::value;
-
-template <typename T>
-struct is_function : public bool_constant<!is_const_v<const T>> {};
-template <typename T>
-struct is_function<T&> : public false_type {};
-template <typename T>
-struct is_function<T&&> : public false_type {};
-
-template <typename T>
-inline constexpr bool is_function_v = is_function<T>::value;
-
-template <typename T>
-struct remove_cvref {
-    using type = remove_cv_t<remove_reference_t<T>>;
-};
-
-template <typename T>
-using remove_cvref_t = typename remove_cvref<T>::type;
-
-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>
@@ -227,12 +60,6 @@ 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>
@@ -457,6 +284,53 @@ struct is_assignable<T, U, void_t<
 template <typename T, typename U>
 inline constexpr bool is_assignable_v = is_assignable<T, U>::value;
 
+#if defined(__GNUC__) or defined(__clang__)
+
+template <typename T, typename... Args>
+struct is_constructible
+    : public bool_constant<__is_constructible(T, Args...)> {};
+
+#else
+
+namespace __helpers {
+
+template <typename T, typename = void, typename... Args>
+struct is_constructible_impl : public false_type {};
+
+template <typename T, typename... Args>
+struct is_constructible_impl<T, void_t<
+    decltype(
+        T { declval<Args>()... }
+    )>, Args...> : public true_type {};
+
+} // namespace __helpers
+
+template <typename T, typename... Args>
+struct is_constructible
+    : public __helpers::is_constructible_impl<T, void, Args...> {};
+
+#endif
+
+template <typename T>
+struct is_default_constructible : public is_constructible<T> {};
+
+template <typename T>
+struct is_copy_constructible
+    : public is_constructible<T, add_lvalue_reference_t<add_const_t<T>>> {};
+
+template <typename T>
+struct is_move_constructible
+    : public is_constructible<T, add_rvalue_reference_t<T>> {};
+
+template <typename T, typename... Args>
+inline constexpr bool is_constructible_v = is_constructible<T, Args...>::value;
+template <typename T>
+inline constexpr bool is_default_constructible_v = is_default_constructible<T>::value;
+template <typename T>
+inline constexpr bool is_copy_constructible_v = is_copy_constructible<T>::value;
+template <typename T>
+inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value;
+
 #define __CPP_GREATBRIDF
 #ifdef __CPP_GREATBRIDF
 

+ 153 - 42
gblibstdc++/include/utility

@@ -2,39 +2,13 @@
 #define __GBLIBCPP_UTILITY__
 
 #include <cstddef>
+#include <bits/forward>
+#include <bits/sequence>
+#include <bits/tuple_tools>
 
-namespace std {
-
-namespace __helpers {
-template <typename T>
-struct __utility_remove_reference { using type = T; };
-template <typename T>
-struct __utility_remove_reference<T&> { using type = T; };
-template <typename T>
-struct __utility_remove_reference<T&&> { using type = T; };
-};
+#include <type_traits>
 
-template <typename T>
-constexpr typename __helpers::__utility_remove_reference<T>::type&&
-move(T&& val) noexcept
-{
-    return static_cast<
-        typename __helpers::__utility_remove_reference<T>::type&&
-        >(val);
-}
-
-template <typename T>
-constexpr T&& forward(
-    typename __helpers::__utility_remove_reference<T>::type& val) noexcept
-{
-    return static_cast<T&&>(val);
-}
-template <typename T>
-constexpr T&& forward(
-    typename __helpers::__utility_remove_reference<T>::type&& val) noexcept
-{
-    return static_cast<T&&>(val);
-}
+namespace std {
 
 template <typename T, typename U = T>
 constexpr T exchange(T& dst, U&& val)
@@ -52,22 +26,159 @@ constexpr void swap(T& a, T& b)
     b = std::move(tmp);
 }
 
-template <typename T, T... Ints>
-struct integer_sequence {
-    static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
+struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
+
+inline constexpr piecewise_construct_t piecewise_construct {};
+
+template <typename... Types>
+class tuple;
+
+template <typename T1, typename T2>
+struct pair;
+
+template <typename T1, typename T2>
+struct tuple_size<std::pair<T1, T2>>
+    : public std::integral_constant<std::size_t, 2> {};
+
+template <typename T1, typename T2>
+struct tuple_element<0, std::pair<T1, T2>> { using type = T1; };
+template <typename T1, typename T2>
+struct tuple_element<1, std::pair<T1, T2>> { using type = T2; };
+template <std::size_t I, typename T1, typename T2>
+struct tuple_element<I, std::pair<T1, T2>> {
+    static_assert(I < 2, "std::pair has only 2 elements");
 };
 
-template <std::size_t... Indicies>
-using index_sequence = integer_sequence<std::size_t, Indicies...>;
+template <typename T1, typename T2>
+struct pair {
+    using first_type = T1;
+    using second_type = T2;
+
+    T1 first;
+    T2 second;
+
+    template <typename U1 = T1, typename U2 = T2, std::enable_if_t<
+        std::is_default_constructible_v<U1>
+        && std::is_default_constructible_v<U2>
+    , bool> = true>
+    constexpr pair() : first(), second() {}
 
-template <std::size_t N, std::size_t... Indicies>
-struct make_index_sequence : public make_index_sequence<N-1, N-1, Indicies...> {};
+    template <typename U1 = T1, typename U2 = T2, std::enable_if_t<
+        std::is_copy_constructible_v<U1>
+        && std::is_copy_constructible_v<U2>
+    , bool> = true>
+    constexpr pair(const T1& t1, const T2& t2)
+        : first(t1), second(t2) {}
 
-template <std::size_t... Indicies>
-struct make_index_sequence<0, Indicies...> : public index_sequence<Indicies...> {};
+    template <typename U1, typename U2, std::enable_if_t<
+        std::is_constructible_v<T1, U1> && std::is_constructible_v<T2, U2>
+    , bool> = true>
+    constexpr pair(U1&& t1, U2&& t2)
+        : first(std::forward<U1>(t1))
+        , second(std::forward<U2>(t2)) {}
 
-template <typename... Ts>
-using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
+    template <typename U1, typename U2, std::enable_if_t<
+        std::is_constructible_v<T1, const U1&>
+        && std::is_constructible_v<T2, const U2&>
+    , bool> = true>
+    constexpr pair(const pair<U1, U2>& p)
+        : first(p.first) , second(p.second) {}
+
+    template <typename U1, typename U2, std::enable_if_t<
+        std::is_constructible_v<T1, U1>
+        && std::is_constructible_v<T2, U2>
+    , bool> = true>
+    constexpr pair(pair<U1, U2>&& p)
+        : first(std::forward<U1>(p.first))
+        , second(std::forward<U2>(p.second)) {}
+
+    template <typename... Args1, typename... Args2>
+    constexpr pair(std::piecewise_construct_t,
+        std::tuple<Args1...> first_args,
+        std::tuple<Args2...> second_args)
+        : first(std::make_from_tuple<T1>(std::move(first_args)))
+        , second(std::make_from_tuple<T2>(std::move(second_args))) {}
+
+    constexpr pair(const pair&) = default;
+    constexpr pair(pair&&) = default;
+
+    constexpr pair& operator=(const pair& other) = default;
+    constexpr pair& operator=(pair&& other) = default;
+
+    template <typename U1, typename U2, std::enable_if_t<
+        std::is_assignable_v<T1&, const U1&>
+        && std::is_assignable_v<T2&, const U2&>
+    , bool> = true>
+    constexpr pair& operator=(const pair<U1, U2>& other)
+    {
+        first = other.first;
+        second = other.second;
+        return *this;
+    }
+
+    template <typename U1, typename U2, std::enable_if_t<
+        std::is_assignable_v<T1&, U1>
+        && std::is_assignable_v<T2&, U2>
+    , bool> = true>
+    constexpr pair& operator=(pair<U1, U2>&& other)
+    {
+        first = std::forward<U1>(other.first);
+        second = std::forward<U2>(other.second);
+        return *this;
+    }
+    
+    constexpr void swap(pair& other)
+    {
+        std::swap(first, other.first);
+        std::swap(second, other.second);
+    }
+};
+
+template <typename T1, typename T2>
+pair(T1, T2) -> pair<T1, T2>;
+
+template <typename T1, typename T2>
+constexpr auto make_pair(T1&& t1, T2&& t2)
+    -> std::pair<__helpers::to_tuple_type_t<T1>, __helpers::to_tuple_type_t<T2>>
+{
+    return { std::forward<T1>(t1), std::forward<T2>(t2) };
+}
+
+template <std::size_t I, typename T1, typename T2>
+constexpr auto get(std::pair<T1, T2>& p) noexcept
+    -> std::tuple_element_t<I, std::pair<T1, T2>>&
+{
+    if constexpr (I == 0) return p.first;
+    else return p.second;
+}
+template <std::size_t I, typename T1, typename T2>
+constexpr auto get(std::pair<T1, T2>&& p) noexcept
+    -> std::tuple_element_t<I, std::pair<T1, T2>>&&
+{
+    if constexpr (I == 0) return std::forward<T1>(p.first);
+    else return std::forward<T2>(p.second);
+}
+template <std::size_t I, typename T1, typename T2>
+constexpr auto get(const std::pair<T1, T2>& p) noexcept
+    -> std::tuple_element_t<I, std::pair<T1, T2>> const&
+{
+    if constexpr (I == 0) return p.first;
+    else return p.second;
+}
+template <std::size_t I, typename T1, typename T2>
+constexpr auto get(const std::pair<T1, T2>&& p) noexcept
+    -> std::tuple_element_t<I, std::pair<T1, T2>> const&&
+{
+    if constexpr (I == 0) return std::forward<T1>(p.first);
+    else return std::forward<T2>(p.second);
+}
+
+template <typename T1, typename T2>
+constexpr void swap(std::pair<T1, T2>& lhs, std::pair<T1, T2>& rhs)
+    noexcept(noexcept(lhs.swap(rhs)))
+{
+    lhs.swap(rhs);
+}
 
 } // namespace std