/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #pragma once #include #include #include namespace std { struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr std::piecewise_construct_t piecewise_construct{}; template typename std::remove_reference::type &&move(T &&arg) { return static_cast::type &&>(arg); } template void __utility_swap(T &a, T &b) { T temp = std::move(a); a = std::move(b); b = std::move(temp); } template class integer_sequence { public: typedef T value_type; static constexpr std::size_t size() noexcept { return sizeof...(Ints); } }; template using index_sequence = std::integer_sequence; template using make_integer_sequence = std::integer_sequence; template using make_index_sequence = std::make_integer_sequence; template using index_sequence_for = std::make_index_sequence; template constexpr T &&forward(std::remove_reference_t &t) noexcept { return static_cast(t); } template constexpr T &&forward(std::remove_reference_t &&t) noexcept { static_assert(!std::is_lvalue_reference::value, "Can't forward an rvalue as an lvalue."); return static_cast(t); } template struct pair { typedef T1 first_type; typedef T2 second_type; first_type first; second_type second; template ::value && std::is_default_constructible::value, int>::type = true> constexpr pair() : first(), second() { } template ::value || !std::is_default_constructible::value, int>::type = false> explicit constexpr pair() : first(), second() { } template ::value && std::is_copy_constructible::value, int>::type = true> constexpr pair(const T1 &x, const T2 &y) : first(x), second(y) { } template ::value || !std::is_copy_constructible::value, int>::type = false> explicit constexpr pair(const T1 &x, const T2 &y) : first(x), second(y) { } template ::value && std::is_move_constructible::value, int>::type = true> constexpr pair(U1 &&x, U2 &&y) : first(std::forward(x)), second(std::forward(y)) { } template ::value || !std::is_move_constructible::value, int>::type = false> explicit constexpr pair(T1 &&x, T2 &&y) : first(std::forward(x)), second(std::forward(y)){}; template ::value && std::is_copy_constructible::value, int>::type = true> constexpr pair(const pair &p) : first(p.first), second(p.second) { } template ::value || !std::is_copy_constructible::value, int>::type = false> explicit constexpr pair(const pair &p) : first(p.first), second(p.second) { } template ::value && std::is_move_constructible::value, int>::type = true> constexpr pair(pair &&p) : first(std::forward(p.first)), second(std::forward(p.second)) { } template ::value || !std::is_move_constructible::value, int>::type = false> explicit constexpr pair(pair &&p) : first(std::forward(p.first)), second(std::forward(p.second)) { } template constexpr pair(std::piecewise_construct_t, std::tuple first_args, std::tuple second_args) : pair(first_args, second_args, std::index_sequence_for(), std::index_sequence_for()) { } pair(const pair &p) = default; pair(pair &&p) = default; constexpr pair &operator=(const pair &other) { first = other.first; second = other.second; return *this; } template constexpr pair &operator=(const pair &other) { first = other.first; second = other.second; return *this; } constexpr pair &operator=(pair &&other) noexcept(std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value) { first = std::move(other.first); second = std::move(other.second); return *this; } template constexpr pair &operator=(pair &&p) { first = std::forward(p.first); second = std::forward(p.second); return *this; } constexpr void swap(pair &other) noexcept(std::is_nothrow_swappable_v && std::is_nothrow_swappable_v) { __utility_swap(first, other.first); __utility_swap(second, other.second); } }; template std::pair::type, typename std::decay::type> make_pair(T1 &&t, T2 &&u) { typedef typename std::decay::type first_type; typedef typename std::decay::type second_type; typedef pair pair_type; return pair_type(std::forward(t), std::forward(u)); } }