cosmopolitan/ctl/map.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

354 lines
7.7 KiB
C
Raw Normal View History

// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef CTL_MAP_H_
#define CTL_MAP_H_
#include "out_of_range.h"
#include "set.h"
namespace ctl {
template<typename Key, typename Value, typename Compare = ctl::less<Key>>
class map
{
class EntryCompare
{
public:
explicit EntryCompare(Compare comp = Compare()) : comp_(comp)
{
}
bool operator()(const ctl::pair<const Key, Value>& lhs,
const ctl::pair<const Key, Value>& rhs) const
{
return comp_(lhs.first, rhs.first);
}
private:
Compare comp_;
};
ctl::set<ctl::pair<const Key, Value>, EntryCompare> data_;
public:
using key_type = Key;
using mapped_type = Value;
using value_type = ctl::pair<const Key, Value>;
using size_type = typename ctl::set<value_type, EntryCompare>::size_type;
using difference_type =
typename ctl::set<value_type, EntryCompare>::difference_type;
using key_compare = Compare;
using value_compare = EntryCompare;
using iterator = typename ctl::set<value_type, EntryCompare>::iterator;
using const_iterator =
typename ctl::set<value_type, EntryCompare>::const_iterator;
using reverse_iterator =
typename ctl::set<value_type, EntryCompare>::reverse_iterator;
using const_reverse_iterator =
typename ctl::set<value_type, EntryCompare>::const_reverse_iterator;
map() : data_(EntryCompare())
{
}
explicit map(const Compare& comp) : data_(EntryCompare(comp))
{
}
map(const map& other) = default;
map(map&& other) noexcept = default;
map(std::initializer_list<value_type> init, const Compare& comp = Compare())
: data_(init, EntryCompare(comp))
{
}
template<typename InputIt>
map(InputIt first, InputIt last, const Compare& comp = Compare())
: data_(first, last, EntryCompare(comp))
{
}
map& operator=(const map& other) = default;
map& operator=(map&& other) noexcept = default;
map& operator=(std::initializer_list<value_type> ilist)
{
data_ = ilist;
return *this;
}
iterator begin() noexcept
{
return data_.begin();
}
const_iterator begin() const noexcept
{
return data_.begin();
}
const_iterator cbegin() const noexcept
{
return data_.cbegin();
}
iterator end() noexcept
{
return data_.end();
}
const_iterator end() const noexcept
{
return data_.end();
}
const_iterator cend() const noexcept
{
return data_.cend();
}
reverse_iterator rbegin() noexcept
{
return data_.rbegin();
}
const_reverse_iterator rbegin() const noexcept
{
return data_.rbegin();
}
const_reverse_iterator crbegin() const noexcept
{
return data_.crbegin();
}
reverse_iterator rend() noexcept
{
return data_.rend();
}
const_reverse_iterator rend() const noexcept
{
return data_.rend();
}
const_reverse_iterator crend() const noexcept
{
return data_.crend();
}
bool empty() const noexcept
{
return data_.empty();
}
size_type size() const noexcept
{
return data_.size();
}
size_type max_size() const noexcept
{
return data_.max_size();
}
Value& operator[](const Key& key)
{
return ((data_.insert(make_pair(key, Value()))).first)->second;
}
Value& operator[](Key&& key)
{
return ((data_.insert(make_pair(ctl::move(key), Value()))).first)
->second;
}
Value& at(const Key& key)
{
auto it = find(key);
if (it == end())
2024-06-30 09:26:38 +00:00
throw ctl::out_of_range();
return it->second;
}
const Value& at(const Key& key) const
{
auto it = find(key);
if (it == end())
2024-06-30 09:26:38 +00:00
throw ctl::out_of_range();
return it->second;
}
ctl::pair<iterator, bool> insert(const value_type& value)
{
return data_.insert(value);
}
ctl::pair<iterator, bool> insert(value_type&& value)
{
return data_.insert(ctl::move(value));
}
template<typename P>
ctl::pair<iterator, bool> insert(P&& value)
{
return data_.insert(value_type(ctl::forward<P>(value)));
}
iterator insert(const_iterator hint, const value_type& value)
{
return data_.insert(hint, value);
}
iterator insert(const_iterator hint, value_type&& value)
{
return data_.insert(hint, ctl::move(value));
}
template<typename P>
iterator insert(const_iterator hint, P&& value)
{
return data_.insert(hint, value_type(ctl::forward<P>(value)));
}
template<typename InputIt>
void insert(InputIt first, InputIt last)
{
data_.insert(first, last);
}
void insert(std::initializer_list<value_type> ilist)
{
data_.insert(ilist);
}
template<typename... Args>
ctl::pair<iterator, bool> emplace(Args&&... args)
{
return data_.emplace(ctl::forward<Args>(args)...);
}
template<typename... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return data_.emplace_hint(hint, ctl::forward<Args>(args)...);
}
iterator erase(const_iterator pos)
{
return data_.erase(pos);
}
iterator erase(const_iterator first, const_iterator last)
{
return data_.erase(first, last);
}
size_type erase(const Key& key)
{
return data_.erase(make_pair(key, Value()));
}
void swap(map& other) noexcept
{
data_.swap(other.data_);
}
void clear() noexcept
{
data_.clear();
}
iterator find(const Key& key)
{
return data_.find(make_pair(key, Value()));
}
const_iterator find(const Key& key) const
{
return data_.find(make_pair(key, Value()));
}
size_type count(const Key& key) const
{
return data_.count(make_pair(key, Value()));
}
iterator lower_bound(const Key& key)
{
return data_.lower_bound(make_pair(key, Value()));
}
const_iterator lower_bound(const Key& key) const
{
return data_.lower_bound(make_pair(key, Value()));
}
iterator upper_bound(const Key& key)
{
return data_.upper_bound(make_pair(key, Value()));
}
const_iterator upper_bound(const Key& key) const
{
return data_.upper_bound(make_pair(key, Value()));
}
ctl::pair<iterator, iterator> equal_range(const Key& key)
{
return data_.equal_range(make_pair(key, Value()));
}
ctl::pair<const_iterator, const_iterator> equal_range(const Key& key) const
{
return data_.equal_range(make_pair(key, Value()));
}
key_compare key_comp() const
{
return data_.value_comp().comp;
}
value_compare value_comp() const
{
return data_.value_comp();
}
friend bool operator==(const map& lhs, const map& rhs)
{
return lhs.data_ == rhs.data_;
}
friend bool operator!=(const map& lhs, const map& rhs)
{
return !(lhs == rhs);
}
friend bool operator<(const map& lhs, const map& rhs)
{
return lhs.data_ < rhs.data_;
}
friend bool operator<=(const map& lhs, const map& rhs)
{
return !(rhs < lhs);
}
friend bool operator>(const map& lhs, const map& rhs)
{
return rhs < lhs;
}
friend bool operator>=(const map& lhs, const map& rhs)
{
return !(lhs < rhs);
}
friend void swap(map& lhs, map& rhs) noexcept
{
lhs.swap(rhs);
}
};
} // namespace ctl
#endif // CTL_MAP_H_