| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 | 
							- #ifndef __GBLIBCPP_UTILITY__
 
- #define __GBLIBCPP_UTILITY__
 
- #include <cstddef>
 
- #include <bits/forward>
 
- #include <bits/sequence>
 
- #include <bits/tuple_tools>
 
- #include <type_traits>
 
- namespace std {
 
- template <typename T, typename U = T>
 
- constexpr T exchange(T& dst, U&& val)
 
- {
 
-     T tmp = move(dst);
 
-     dst = forward<U>(val);
 
-     return tmp;
 
- }
 
- template <typename T>
 
- constexpr void swap(T& a, T& b)
 
- {
 
-     T tmp(std::move(a));
 
-     a = std::move(b);
 
-     b = std::move(tmp);
 
- }
 
- 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 <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 <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 <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 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
 
- #endif
 
 
  |