2014-12-15 17:36:20 +01:00
|
|
|
/*
|
|
|
|
* InspIRCd -- Internet Relay Chat Daemon
|
|
|
|
*
|
2024-07-14 11:58:57 +01:00
|
|
|
* Copyright (C) 2019-2021, 2024 Sadie Powell <sadie@witchery.services>
|
2014-12-15 17:36:20 +01:00
|
|
|
* Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com>
|
|
|
|
*
|
|
|
|
* This file is part of InspIRCd. InspIRCd 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, version 2.
|
|
|
|
*
|
|
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
namespace insp
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename T, typename Comp>
|
2021-12-20 20:00:03 +00:00
|
|
|
class map_pair_compare final
|
|
|
|
: public Comp
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
|
|
|
typedef T value_type;
|
|
|
|
typedef typename value_type::first_type key_type;
|
|
|
|
|
2022-01-25 13:59:42 +00:00
|
|
|
public:
|
2014-12-15 17:36:20 +01:00
|
|
|
bool operator()(const value_type& x, const value_type& y) const
|
|
|
|
{
|
|
|
|
return Comp::operator()(x.first, y.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator()(const value_type& x, const key_type& y) const
|
|
|
|
{
|
|
|
|
return Comp::operator()(x.first, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator()(const key_type& x, const value_type& y) const
|
|
|
|
{
|
|
|
|
return Comp::operator()(x, y.first);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Val, typename Comp>
|
2021-06-07 07:43:03 +01:00
|
|
|
class map_value_compare
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
2022-01-25 13:59:42 +00:00
|
|
|
public:
|
2014-12-15 17:36:20 +01:00
|
|
|
bool operator()(const Val& x, const Val& y) const
|
|
|
|
{
|
|
|
|
Comp c;
|
|
|
|
return c(x.first, y.first);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename Comp, typename Key = T, typename ElementComp = Comp>
|
|
|
|
class flat_map_base
|
|
|
|
{
|
2022-01-25 13:59:42 +00:00
|
|
|
protected:
|
2014-12-15 17:36:20 +01:00
|
|
|
typedef std::vector<T> storage_type;
|
|
|
|
storage_type vect;
|
|
|
|
|
2022-01-25 13:59:42 +00:00
|
|
|
public:
|
2014-12-15 17:36:20 +01:00
|
|
|
typedef typename storage_type::iterator iterator;
|
|
|
|
typedef typename storage_type::const_iterator const_iterator;
|
|
|
|
typedef typename storage_type::reverse_iterator reverse_iterator;
|
|
|
|
typedef typename storage_type::const_reverse_iterator const_reverse_iterator;
|
|
|
|
|
|
|
|
typedef typename storage_type::size_type size_type;
|
|
|
|
typedef typename storage_type::difference_type difference_type;
|
|
|
|
typedef Key key_type;
|
|
|
|
typedef T value_type;
|
|
|
|
|
|
|
|
typedef Comp key_compare;
|
|
|
|
typedef ElementComp value_compare;
|
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_map_base() = default;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
|
|
|
flat_map_base(const flat_map_base& other)
|
|
|
|
: vect(other.vect)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_map_base& operator=(const flat_map_base& other) = default;
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
size_type size() const { return vect.size(); }
|
|
|
|
bool empty() const { return vect.empty(); }
|
|
|
|
size_type capacity() const { return vect.capacity(); }
|
|
|
|
size_type max_size() const { return vect.max_size(); }
|
|
|
|
|
|
|
|
void clear() { vect.clear(); }
|
|
|
|
void reserve(size_type n) { vect.reserve(n); }
|
2024-07-07 16:56:36 +01:00
|
|
|
void shrink_to_fit() { vect.shrink_to_fit(); }
|
2014-12-15 17:36:20 +01:00
|
|
|
|
|
|
|
iterator begin() { return vect.begin(); }
|
|
|
|
iterator end() { return vect.end(); }
|
|
|
|
reverse_iterator rbegin() { return vect.rbegin(); }
|
|
|
|
reverse_iterator rend() { return vect.rend(); }
|
|
|
|
|
|
|
|
const_iterator begin() const { return vect.begin(); }
|
|
|
|
const_iterator end() const { return vect.end(); }
|
|
|
|
const_reverse_iterator rbegin() const { return vect.rbegin(); }
|
|
|
|
const_reverse_iterator rend() const { return vect.rend(); }
|
|
|
|
|
|
|
|
key_compare key_comp() const { return Comp(); }
|
|
|
|
|
|
|
|
iterator erase(iterator it) { return vect.erase(it); }
|
|
|
|
iterator erase(iterator first, iterator last) { return vect.erase(first, last); }
|
|
|
|
size_type erase(const key_type& x)
|
|
|
|
{
|
|
|
|
size_type n = vect.size();
|
|
|
|
std::pair<iterator, iterator> itpair = equal_range(x);
|
|
|
|
vect.erase(itpair.first, itpair.second);
|
|
|
|
return n - vect.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator find(const key_type& x)
|
|
|
|
{
|
|
|
|
value_compare c;
|
|
|
|
iterator it = std::lower_bound(vect.begin(), vect.end(), x, c);
|
|
|
|
if ((it != vect.end()) && (!c(x, *it)))
|
|
|
|
return it;
|
|
|
|
return vect.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
const_iterator find(const key_type& x) const
|
|
|
|
{
|
|
|
|
// Same as above but this time we return a const_iterator
|
|
|
|
value_compare c;
|
|
|
|
const_iterator it = std::lower_bound(vect.begin(), vect.end(), x, c);
|
|
|
|
if ((it != vect.end()) && (!c(x, *it)))
|
|
|
|
return it;
|
|
|
|
return vect.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<iterator, iterator> equal_range(const key_type& x)
|
|
|
|
{
|
|
|
|
return std::equal_range(vect.begin(), vect.end(), x, value_compare());
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
|
|
|
|
{
|
|
|
|
return std::equal_range(vect.begin(), vect.end(), x, value_compare());
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator lower_bound(const key_type& x)
|
|
|
|
{
|
|
|
|
return std::lower_bound(vect.begin(), vect.end(), x, value_compare());
|
|
|
|
}
|
|
|
|
|
|
|
|
const_iterator lower_bound(const key_type& x) const
|
|
|
|
{
|
|
|
|
return std::lower_bound(vect.begin(), vect.end(), x, value_compare());
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator upper_bound(const key_type& x)
|
|
|
|
{
|
|
|
|
return std::upper_bound(vect.begin(), vect.end(), x, value_compare());
|
|
|
|
}
|
|
|
|
|
|
|
|
const_iterator upper_bound(const key_type& x) const
|
|
|
|
{
|
|
|
|
return std::upper_bound(vect.begin(), vect.end(), x, value_compare());
|
|
|
|
}
|
|
|
|
|
|
|
|
size_type count(const key_type& x) const
|
|
|
|
{
|
|
|
|
std::pair<const_iterator, const_iterator> itpair = equal_range(x);
|
|
|
|
return std::distance(itpair.first, itpair.second);
|
|
|
|
}
|
|
|
|
|
2022-01-25 13:59:42 +00:00
|
|
|
protected:
|
2014-12-15 17:36:20 +01:00
|
|
|
std::pair<iterator, bool> insert_single(const value_type& x)
|
|
|
|
{
|
|
|
|
bool inserted = false;
|
|
|
|
|
|
|
|
value_compare c;
|
|
|
|
iterator it = std::lower_bound(vect.begin(), vect.end(), x, c);
|
|
|
|
if ((it == vect.end()) || (c(x, *it)))
|
|
|
|
{
|
|
|
|
inserted = true;
|
|
|
|
it = vect.insert(it, x);
|
|
|
|
}
|
|
|
|
return std::make_pair(it, inserted);
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator insert_multi(const value_type& x)
|
|
|
|
{
|
|
|
|
iterator it = std::lower_bound(vect.begin(), vect.end(), x, value_compare());
|
|
|
|
return vect.insert(it, x);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
2019-02-19 18:22:00 +00:00
|
|
|
template <typename T, typename Comp = std::less<T>, typename ElementComp = Comp>
|
2021-12-20 20:00:03 +00:00
|
|
|
class flat_set
|
|
|
|
: public detail::flat_map_base<T, Comp, T, ElementComp>
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef detail::flat_map_base<T, Comp, T, ElementComp> base_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2022-01-25 13:59:42 +00:00
|
|
|
public:
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef typename base_type::iterator iterator;
|
|
|
|
typedef typename base_type::value_type value_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_set() = default;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
flat_set(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
this->insert(first, last);
|
|
|
|
}
|
|
|
|
|
2021-04-14 23:35:51 +01:00
|
|
|
flat_set(std::initializer_list<value_type> init)
|
|
|
|
{
|
|
|
|
for (const auto& elem : init)
|
|
|
|
insert(elem);
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
flat_set(const flat_set& other)
|
2021-04-17 22:36:39 +01:00
|
|
|
: base_type(other)
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_set& operator=(const flat_set& other) = default;
|
|
|
|
|
2021-04-18 04:37:51 +01:00
|
|
|
template <typename... Args>
|
|
|
|
std::pair<iterator, bool> emplace(Args&&... args)
|
|
|
|
{
|
|
|
|
return insert(value_type(std::forward<Args>(args)...));
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
std::pair<iterator, bool> insert(const value_type& x)
|
|
|
|
{
|
|
|
|
return this->insert_single(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
void insert(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
for (; first != last; ++first)
|
|
|
|
this->insert_single(*first);
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(flat_set& other)
|
|
|
|
{
|
2021-04-17 22:36:39 +01:00
|
|
|
base_type::vect.swap(other.vect);
|
2014-12-15 17:36:20 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-02-19 18:22:00 +00:00
|
|
|
template <typename T, typename Comp = std::less<T>, typename ElementComp = Comp>
|
2021-12-20 20:00:03 +00:00
|
|
|
class flat_multiset
|
|
|
|
: public detail::flat_map_base<T, Comp, T, ElementComp>
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef detail::flat_map_base<T, Comp, T, ElementComp> base_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2022-01-25 13:59:42 +00:00
|
|
|
public:
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef typename base_type::iterator iterator;
|
|
|
|
typedef typename base_type::value_type value_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_multiset() = default;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
flat_multiset(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
this->insert(first, last);
|
|
|
|
}
|
|
|
|
|
2021-04-14 23:35:51 +01:00
|
|
|
flat_multiset(std::initializer_list<value_type> init)
|
|
|
|
{
|
|
|
|
for (const auto& elem : init)
|
|
|
|
insert(elem);
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
flat_multiset(const flat_multiset& other)
|
2021-04-17 22:36:39 +01:00
|
|
|
: base_type(other)
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_multiset& operator=(const flat_multiset& other) = default;
|
|
|
|
|
2021-04-18 04:37:51 +01:00
|
|
|
template <typename... Args>
|
|
|
|
iterator emplace(Args&&... args)
|
|
|
|
{
|
|
|
|
return insert(value_type(std::forward<Args>(args)...));
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
iterator insert(const value_type& x)
|
|
|
|
{
|
|
|
|
return this->insert_multi(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
void insert(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
for (; first != last; ++first)
|
|
|
|
insert_multi(*first);
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(flat_multiset& other)
|
|
|
|
{
|
2021-04-17 22:36:39 +01:00
|
|
|
base_type::vect.swap(other.vect);
|
2014-12-15 17:36:20 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-02-19 18:22:00 +00:00
|
|
|
template <typename T, typename U, typename Comp = std::less<T>, typename ElementComp = Comp >
|
2021-12-20 20:00:03 +00:00
|
|
|
class flat_map
|
2022-06-23 21:22:04 +01:00
|
|
|
: public detail::flat_map_base<std::pair<T, U>, Comp, T, detail::map_pair_compare<std::pair<T, U>, ElementComp>>
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
2022-06-23 21:22:04 +01:00
|
|
|
typedef detail::flat_map_base<std::pair<T, U>, Comp, T, detail::map_pair_compare<std::pair<T, U>, ElementComp>> base_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2022-01-25 13:59:42 +00:00
|
|
|
public:
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef typename base_type::iterator iterator;
|
|
|
|
typedef typename base_type::key_type key_type;
|
|
|
|
typedef typename base_type::value_type value_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
typedef U mapped_type;
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef typename base_type::value_compare value_compare;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_map() = default;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
flat_map(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
insert(first, last);
|
|
|
|
}
|
|
|
|
|
2021-04-14 23:35:51 +01:00
|
|
|
flat_map(std::initializer_list<value_type> init)
|
|
|
|
{
|
|
|
|
for (const auto& elem : init)
|
|
|
|
insert(elem);
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
flat_map(const flat_map& other)
|
2021-04-17 22:36:39 +01:00
|
|
|
: base_type(other)
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_map& operator=(const flat_map& other) = default;
|
|
|
|
|
2021-04-18 04:37:51 +01:00
|
|
|
template <typename... Args>
|
|
|
|
std::pair<iterator, bool> emplace(Args&&... args)
|
|
|
|
{
|
|
|
|
return insert(value_type(std::forward<Args>(args)...));
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
std::pair<iterator, bool> insert(const value_type& x)
|
|
|
|
{
|
|
|
|
return this->insert_single(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
void insert(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
for (; first != last; ++first)
|
|
|
|
this->insert_single(*first);
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(flat_map& other)
|
|
|
|
{
|
2021-04-17 22:36:39 +01:00
|
|
|
base_type::vect.swap(other.vect);
|
2014-12-15 17:36:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mapped_type& operator[](const key_type& x)
|
|
|
|
{
|
2021-04-18 04:37:51 +01:00
|
|
|
return insert(value_type(x, mapped_type())).first->second;
|
2014-12-15 17:36:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
value_compare value_comp() const
|
|
|
|
{
|
|
|
|
return value_compare();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-02-19 18:22:00 +00:00
|
|
|
template <typename T, typename U, typename Comp = std::less<T>, typename ElementComp = Comp >
|
2021-12-20 20:00:03 +00:00
|
|
|
class flat_multimap
|
2022-06-23 21:22:04 +01:00
|
|
|
: public detail::flat_map_base<std::pair<T, U>, Comp, T, detail::map_pair_compare<std::pair<T, U>, ElementComp>>
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
2022-06-23 21:22:04 +01:00
|
|
|
typedef detail::flat_map_base<std::pair<T, U>, Comp, T, detail::map_pair_compare<std::pair<T, U>, ElementComp>> base_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2022-01-25 13:59:42 +00:00
|
|
|
public:
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef typename base_type::iterator iterator;
|
|
|
|
typedef typename base_type::value_type value_type;
|
2014-12-15 17:36:20 +01:00
|
|
|
typedef U mapped_type;
|
2021-04-17 22:36:39 +01:00
|
|
|
typedef typename base_type::value_compare value_compare;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_multimap() = default;
|
2014-12-15 17:36:20 +01:00
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
flat_multimap(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
this->insert(first, last);
|
|
|
|
}
|
|
|
|
|
2021-04-14 23:35:51 +01:00
|
|
|
flat_multimap(std::initializer_list<value_type> init)
|
|
|
|
{
|
|
|
|
for (const auto& elem : init)
|
|
|
|
insert(elem);
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
flat_multimap(const flat_multimap& other)
|
2021-04-17 22:36:39 +01:00
|
|
|
: base_type(other)
|
2014-12-15 17:36:20 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-11 14:25:32 +01:00
|
|
|
flat_multimap& operator=(const flat_multimap& other) = default;
|
|
|
|
|
2021-04-18 04:37:51 +01:00
|
|
|
template <typename... Args>
|
|
|
|
iterator emplace(Args&&... args)
|
|
|
|
{
|
|
|
|
return insert(value_type(std::forward<Args>(args)...));
|
|
|
|
}
|
|
|
|
|
2014-12-15 17:36:20 +01:00
|
|
|
iterator insert(const value_type& x)
|
|
|
|
{
|
|
|
|
return this->insert_multi(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename InputIterator>
|
|
|
|
void insert(InputIterator first, InputIterator last)
|
|
|
|
{
|
|
|
|
for (; first != last; ++first)
|
|
|
|
this->insert_multi(*first);
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(flat_multimap& other)
|
|
|
|
{
|
2021-04-17 22:36:39 +01:00
|
|
|
base_type::vect.swap(other.vect);
|
2014-12-15 17:36:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
value_compare value_comp() const
|
|
|
|
{
|
|
|
|
return value_compare();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace insp
|