mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
312 lines
8.0 KiB
Plaintext
312 lines
8.0 KiB
Plaintext
/*
|
|
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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <initializer_list>
|
|
#include <functional>
|
|
#include <algorithm>
|
|
#include <compare>
|
|
#include <memory>
|
|
|
|
#warning "std::set not implemented; Do not use"
|
|
|
|
namespace std
|
|
{
|
|
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>>
|
|
class multiset;
|
|
|
|
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>>
|
|
class set
|
|
{
|
|
public:
|
|
template <class Iter, class NodeType>
|
|
struct __set_return_type
|
|
{
|
|
Iter position;
|
|
bool inserted;
|
|
NodeType node;
|
|
};
|
|
|
|
using key_type = Key;
|
|
using value_type = Key;
|
|
using size_type = std::size_t;
|
|
using difference_type = std::ptrdiff_t;
|
|
using key_compare = Compare;
|
|
using value_compare = Compare;
|
|
using allocator_type = Allocator;
|
|
using reference = value_type &;
|
|
using const_reference = const value_type &;
|
|
using pointer = std::allocator_traits<Allocator>::pointer;
|
|
using const_pointer = std::allocator_traits<Allocator>::const_pointer;
|
|
using iterator = value_type;
|
|
using const_iterator = const value_type;
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
using node_type = std::unique_ptr<value_type>;
|
|
using insert_return_type = __set_return_type<iterator, node_type>;
|
|
|
|
private:
|
|
public:
|
|
#pragma region Constructors
|
|
|
|
set() : set(Compare()) {}
|
|
|
|
explicit set(const Compare &comp, const Allocator &alloc = Allocator());
|
|
|
|
explicit set(const Allocator &alloc);
|
|
|
|
template <class InputIt>
|
|
set(InputIt first, InputIt last, const Compare &comp = Compare(), const Allocator &alloc = Allocator());
|
|
|
|
template <class InputIt>
|
|
set(InputIt first, InputIt last, const Allocator &alloc) : set(first, last, Compare(), alloc) {}
|
|
|
|
set(const set &other);
|
|
|
|
set(const set &other, const Allocator &alloc);
|
|
|
|
set(set &&other);
|
|
|
|
set(set &&other, const Allocator &alloc);
|
|
|
|
set(std::initializer_list<value_type> init, const Compare &comp = Compare(), const Allocator &alloc = Allocator());
|
|
|
|
set(std::initializer_list<value_type> init, const Allocator &alloc) : set(init, Compare(), alloc) {}
|
|
|
|
~set();
|
|
|
|
#pragma endregion Constructors
|
|
|
|
#pragma region Assignment
|
|
|
|
set &operator=(const set &other);
|
|
|
|
set &operator=(set &&other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value && std::is_nothrow_move_assignable<Compare>::value);
|
|
|
|
set &operator=(std::initializer_list<value_type> ilist);
|
|
|
|
allocator_type get_allocator() const noexcept;
|
|
|
|
#pragma endregion Assignment
|
|
|
|
#pragma region Iterators
|
|
|
|
iterator begin() noexcept;
|
|
|
|
const_iterator begin() const noexcept;
|
|
|
|
const_iterator cbegin() const noexcept;
|
|
|
|
iterator end() noexcept;
|
|
|
|
const_iterator end() const noexcept;
|
|
|
|
const_iterator cend() const noexcept;
|
|
|
|
reverse_iterator rbegin() noexcept;
|
|
|
|
const_reverse_iterator rbegin() const noexcept;
|
|
|
|
const_reverse_iterator crbegin() const noexcept;
|
|
|
|
reverse_iterator rend() noexcept;
|
|
|
|
const_reverse_iterator rend() const noexcept;
|
|
|
|
const_reverse_iterator crend() const noexcept;
|
|
|
|
#pragma endregion Iterators
|
|
|
|
#pragma region Capacity
|
|
|
|
bool empty() const noexcept;
|
|
|
|
size_type size() const noexcept;
|
|
|
|
size_type max_size() const noexcept;
|
|
|
|
#pragma endregion Capacity
|
|
|
|
#pragma region Modifiers
|
|
|
|
void clear() noexcept;
|
|
|
|
std::pair<iterator, bool> insert(const value_type &value);
|
|
|
|
std::pair<iterator, bool> insert(value_type &&value);
|
|
|
|
iterator insert(const_iterator pos, const value_type &value);
|
|
|
|
iterator insert(const_iterator pos, value_type &&value);
|
|
|
|
template <class InputIt>
|
|
void insert(InputIt first, InputIt last);
|
|
|
|
void insert(std::initializer_list<value_type> ilist);
|
|
|
|
insert_return_type insert(node_type &&nh);
|
|
|
|
iterator insert(const_iterator pos, node_type &&nh);
|
|
|
|
template <class... Args>
|
|
std::pair<iterator, bool> emplace(Args &&...args);
|
|
|
|
template <class... Args>
|
|
iterator emplace_hint(const_iterator hint, Args &&...args);
|
|
|
|
iterator erase(const_iterator pos);
|
|
|
|
iterator erase(const_iterator first, const_iterator last);
|
|
|
|
size_type erase(const Key &key);
|
|
|
|
void swap(set &other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value && std::is_nothrow_swappable<Compare>::value);
|
|
|
|
node_type extract(const_iterator position);
|
|
|
|
node_type extract(const Key &k);
|
|
|
|
template <class C2>
|
|
void merge(std::set<Key, C2, Allocator> &source);
|
|
|
|
template <class C2>
|
|
void merge(std::set<Key, C2, Allocator> &&source);
|
|
|
|
template <class C2>
|
|
void merge(std::multiset<Key, C2, Allocator> &source);
|
|
|
|
template <class C2>
|
|
void merge(std::multiset<Key, C2, Allocator> &&source);
|
|
|
|
#pragma endregion Modifiers
|
|
|
|
#pragma region Lookup
|
|
|
|
size_type count(const Key &key) const;
|
|
|
|
template <class K>
|
|
size_type count(const K &x) const;
|
|
|
|
iterator find(const Key &key);
|
|
|
|
const_iterator find(const Key &key) const;
|
|
|
|
template <class K>
|
|
iterator find(const K &x);
|
|
|
|
template <class K>
|
|
const_iterator find(const K &x) const;
|
|
|
|
bool contains(const Key &key) const;
|
|
|
|
template <class K>
|
|
bool contains(const K &x) const;
|
|
|
|
std::pair<iterator, iterator> equal_range(const Key &key);
|
|
|
|
std::pair<const_iterator, const_iterator> equal_range(const Key &key) const;
|
|
|
|
template <class K>
|
|
std::pair<iterator, iterator> equal_range(const K &x);
|
|
|
|
template <class K>
|
|
std::pair<const_iterator, const_iterator> equal_range(const K &x) const;
|
|
|
|
iterator lower_bound(const Key &key);
|
|
|
|
const_iterator lower_bound(const Key &key) const;
|
|
|
|
template <class K>
|
|
iterator lower_bound(const K &x);
|
|
|
|
template <class K>
|
|
const_iterator lower_bound(const K &x) const;
|
|
|
|
iterator upper_bound(const Key &key);
|
|
|
|
const_iterator upper_bound(const Key &key) const;
|
|
|
|
template <class K>
|
|
iterator upper_bound(const K &x);
|
|
|
|
template <class K>
|
|
const_iterator upper_bound(const K &x) const;
|
|
|
|
#pragma endregion Lookup
|
|
|
|
#pragma region Observers
|
|
|
|
key_compare key_comp() const;
|
|
|
|
set::value_compare value_comp() const;
|
|
|
|
#pragma endregion Observers
|
|
};
|
|
|
|
template <class Key, class Compare, class Alloc>
|
|
bool operator==(const std::set<Key, Compare, Alloc> &lhs, const std::set<Key, Compare, Alloc> &rhs)
|
|
{
|
|
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
|
}
|
|
|
|
template <class Key, class Compare, class Alloc>
|
|
std::strong_ordering operator<=>(const std::set<Key, Compare, Alloc> &lhs, const std::set<Key, Compare, Alloc> &rhs)
|
|
{
|
|
// return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), __synth_three_way);
|
|
|
|
auto it1 = lhs.begin();
|
|
auto it2 = rhs.begin();
|
|
auto end1 = lhs.end();
|
|
auto end2 = rhs.end();
|
|
|
|
while (it1 != end1 && it2 != end2)
|
|
{
|
|
if (*it1 < *it2)
|
|
return std::strong_ordering::less;
|
|
if (*it2 < *it1)
|
|
return std::strong_ordering::greater;
|
|
++it1;
|
|
++it2;
|
|
}
|
|
|
|
if (it1 == end1 && it2 == end2)
|
|
return std::strong_ordering::equal;
|
|
return (it1 == end1) ? std::strong_ordering::less : std::strong_ordering::greater;
|
|
}
|
|
|
|
template <class Key, class Compare, class Alloc>
|
|
void swap(std::set<Key, Compare, Alloc> &lhs, std::set<Key, Compare, Alloc> &rhs) noexcept(noexcept(lhs.swap(rhs)))
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
template <class Key, class Compare, class Alloc, class Pred>
|
|
std::set<Key, Compare, Alloc>::size_type erase_if(std::set<Key, Compare, Alloc> &c, Pred pred)
|
|
{
|
|
auto old_size = c.size();
|
|
for (auto first = c.begin(), last = c.end(); first != last;)
|
|
{
|
|
if (pred(*first))
|
|
first = c.erase(first);
|
|
else
|
|
++first;
|
|
}
|
|
return old_size - c.size();
|
|
}
|
|
}
|