// -*-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> class map { class EntryCompare { public: explicit EntryCompare(Compare comp = Compare()) : comp_(comp) { } bool operator()(const ctl::pair& lhs, const ctl::pair& rhs) const { return comp_(lhs.first, rhs.first); } private: Compare comp_; }; ctl::set, EntryCompare> data_; public: using key_type = Key; using mapped_type = Value; using value_type = ctl::pair; using size_type = typename ctl::set::size_type; using difference_type = typename ctl::set::difference_type; using key_compare = Compare; using value_compare = EntryCompare; using iterator = typename ctl::set::iterator; using const_iterator = typename ctl::set::const_iterator; using reverse_iterator = typename ctl::set::reverse_iterator; using const_reverse_iterator = typename ctl::set::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 init, const Compare& comp = Compare()) : data_(init, EntryCompare(comp)) { } template 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 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()) throw ctl::out_of_range(); return it->second; } const Value& at(const Key& key) const { auto it = find(key); if (it == end()) throw ctl::out_of_range(); return it->second; } ctl::pair insert(const value_type& value) { return data_.insert(value); } ctl::pair insert(value_type&& value) { return data_.insert(ctl::move(value)); } template ctl::pair insert(P&& value) { return data_.insert(value_type(ctl::forward

(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 iterator insert(const_iterator hint, P&& value) { return data_.insert(hint, value_type(ctl::forward

(value))); } template void insert(InputIt first, InputIt last) { data_.insert(first, last); } void insert(std::initializer_list ilist) { data_.insert(ilist); } template ctl::pair emplace(Args&&... args) { return data_.emplace(ctl::forward(args)...); } template iterator emplace_hint(const_iterator hint, Args&&... args) { return data_.emplace_hint(hint, ctl::forward(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 equal_range(const Key& key) { return data_.equal_range(make_pair(key, Value())); } ctl::pair 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_