9 #ifndef EAGINE_FLAT_SET_HPP
10 #define EAGINE_FLAT_SET_HPP
23 typename Compare = std::less<Key>,
24 class Allocator = std::allocator<Key>>
25 class flat_set :
private Compare {
27 using _vec_t = std::vector<Key, Allocator>;
30 auto _find_insert_pos(
const Key& k)
const noexcept {
31 const auto b = _vec.begin();
32 const auto e = _vec.end();
33 const auto p = std::lower_bound(b, e, k, key_comp());
35 return std::pair{p, (p == e) || (k != *p)};
39 auto _find_insert_pos(I p,
const Key& k)
const noexcept {
40 auto b = _vec.begin();
43 if(_vec.empty() || value_comp()(_vec.back(), k)) {
44 return std::pair{p,
true};
46 p = std::lower_bound(b, e, k, key_comp());
49 return std::pair{p,
false};
51 if(key_comp()(k, *p)) {
53 p = std::lower_bound(b, p, k, key_comp());
56 p = std::lower_bound(p, e, k, key_comp());
58 return std::pair{p,
true};
62 auto _do_insert(I ip,
const Key& value) -> I {
64 ip.first = _vec.insert(ip.first, value);
72 using size_type =
typename _vec_t::size_type;
73 using difference_type =
typename _vec_t::difference_type;
74 using iterator =
typename _vec_t::const_iterator;
75 using const_iterator =
typename _vec_t::const_iterator;
76 using allocator_type = Allocator;
80 flat_set() noexcept = default;
81 flat_set(const flat_set&) = default;
82 flat_set(flat_set&&) noexcept = default;
83 auto operator=(const flat_set&) -> flat_set& = default;
84 auto operator=(flat_set&&) noexcept -> flat_set& = default;
85 ~flat_set() noexcept = default;
87 flat_set(std::initializer_list<Key> il) {
91 flat_set(
const std::vector<value_type>& v) {
95 void assign(std::initializer_list<Key> il) {
97 std::sort(_vec.begin(), _vec.end(), value_comp());
100 void assign(
const std::vector<value_type>& v) {
101 _vec = _vec_t(v.begin(), v.end());
102 std::sort(_vec.begin(), _vec.end(), value_comp());
105 auto key_comp() const noexcept -> const Compare& {
109 auto value_comp() const noexcept -> const Compare& {
113 auto empty() const noexcept {
117 auto size() const noexcept {
121 auto max_size() const noexcept {
122 return _vec.max_size();
125 auto begin() -> iterator {
129 auto begin() const -> const_iterator {
133 auto end() -> iterator {
137 auto end() const -> const_iterator {
141 auto lower_bound(
const Key& key)
const noexcept {
142 return ::std::lower_bound(begin(), end(), key, value_comp());
145 auto upper_bound(
const Key& key)
const noexcept {
146 return ::std::upper_bound(begin(), end(), key, value_comp());
149 auto equal_range(
const Key& key)
const noexcept {
150 return ::std::equal_range(begin(), end(), key, value_comp());
153 auto find(
const Key& key)
const noexcept {
154 auto [p, i] = _find_insert_pos(key);
155 return i ? _vec.end() : p;
158 auto contains(
const Key& key)
const noexcept {
159 return !_find_insert_pos(key).second;
162 auto clear() noexcept {
166 auto insert(
const value_type& value) -> std::pair<iterator, bool> {
167 auto ip = _find_insert_pos(value);
168 ip = _do_insert(ip, value);
169 return {ip.first, ip.second};
172 auto insert(iterator p,
const value_type& value) -> iterator {
173 const auto ip = _find_insert_pos(p, value);
174 return _do_insert(ip, value).first;
177 auto erase(iterator p) -> iterator {
178 return _vec.erase(p);
181 auto erase(iterator f, iterator t) -> iterator {
182 return _vec.erase(f, t);
185 auto erase(
const Key& key) -> size_type {
187 std::equal_range(_vec.begin(), _vec.end(), key, key_comp());
188 const auto res = size_type(
std::distance(p.first, p.second));
189 EAGINE_ASSERT(res <= 1);
190 _vec.erase(p.first, p.second);