#ifndef EASTL_VECTOR_MAP_H #define EASTL_VECTOR_MAP_H #include #include #include #include #include #include #include #include #include namespace eastl { namespace detail { template struct compare_impl { typedef Pair pair_type; typedef typename pair_type::first_type first_argument_type; compare_impl() {} compare_impl(Compare const& src) : m_cmp(src) {} bool operator()(first_argument_type const& lhs, first_argument_type const& rhs) const { return Compare()(lhs, rhs); } bool operator()(pair_type const& lhs, pair_type const& rhs) const { return operator()(lhs.first, rhs.first); } bool operator()(pair_type const& lhs, first_argument_type const& rhs) const { return operator()(lhs.first, rhs); } bool operator()(first_argument_type const& lhs, pair_type const& rhs) const { return operator()(lhs, rhs.first); } operator Compare() const { return m_cmp; } void swap(compare_impl& rhs) { using ::eastl::swap; swap(m_cmp, rhs.m_cmp); } private: Compare m_cmp; }; // struct compare_impl } // namespace detail template, class A = EASTLAllocatorType> class vector_map { public: typedef K key_type; typedef V mapped_type; typedef ::eastl::pair value_type; typedef C key_compare; typedef A allocator_type; typedef ::eastl::vector base_type; private: typedef detail::compare_impl compare_impl_type; base_type m_base; detail::compare_impl m_cmp; public: typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reverse_iterator reverse_iterator; typedef typename base_type::const_reverse_iterator const_reverse_iterator; typedef typename base_type::size_type size_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer;; static const size_type kMaxSize = base_type::kMaxSize; class value_compare { friend class vector_map; key_compare const m_cmp; protected: value_compare(key_compare pred) : m_cmp(pred) {} public: bool operator()(value_type const& lhs, value_type const& rhs) const { return m_cmp(lhs.first, rhs.first); } }; // struct value_compare explicit vector_map(key_compare const& cmp = key_compare(), allocator_type const& alloc = EASTL_VECTOR_DEFAULT_ALLOCATOR) : m_base(alloc), m_cmp(cmp) {} template vector_map(InputIterator first, InputIterator last, key_compare const& cmp = key_compare(), allocator_type const& alloc = EASTL_VECTOR_DEFAULT_ALLOCATOR) : m_base(alloc), m_cmp(cmp) { ::eastl::map const tmp(first, last); m_base.reserve(tmp.size()); ::eastl::copy(tmp.begin(), tmp.end(), ::eastl::back_inserter(m_base)); } vector_map& operator =(vector_map const& rhs) { vector_map(rhs).swap(*this); return *this; } iterator begin() { return m_base.begin(); } iterator end() { return m_base.end(); } reverse_iterator rbegin() { return m_base.rbegin(); } reverse_iterator rend() { return m_base.rend(); } const_iterator begin() const { return m_base.begin(); } const_iterator end() const { return m_base.end(); } const_reverse_iterator rbegin() const { return m_base.rbegin(); } const_reverse_iterator rend() const { return m_base.rend(); } void clear() { m_base.clear(); } bool empty() const { return m_base.empty(); } size_type size() const { return m_base.size(); } size_type max_size() { return base_type::kMaxSize; } mapped_type& operator[](key_type const& key) { return insert(value_type(key, mapped_type())).first->second; } ::eastl::pair insert(value_type const& val) { iterator const i(lower_bound(val.first)); return (i == end() || m_cmp(val.first, i->first)) ? ::eastl::make_pair(m_base.insert(i, val), true) : ::eastl::make_pair(i, false) ; } iterator insert(iterator const pos, value_type const& val) { return ((pos == begin() || m_cmp(*(pos-1), val)) && (pos == end() || m_cmp(val, *pos))) ? m_base.insert(pos, val) : insert(val).first ; } template void insert(InputIterator first, InputIterator const last) { for(; first != last; ++first) insert(*first); } void erase(iterator const pos) { m_base.erase(pos); } void erase(iterator const first, iterator const last) { m_base.erase(first, last); } size_type erase(key_type const& k) { iterator const i(find(k)); if(i == end()) return 0; else { erase(i); return 1; } } void swap(vector_map& other) { m_base.swap(other.m_base); m_cmp.swap(other.m_cmp); } allocator_type& get_allocator() { return m_base.get_allocator(); } void set_allocator(allocator_type const& alloc) { m_base.set_allocator(alloc); } key_compare key_comp() const { return static_cast(m_cmp); } value_compare value_comp() const { return value_compare(m_cmp); } iterator find(key_type const& k) { iterator const i(lower_bound(k)); return (i != end() && m_cmp(k, i->first))? end() : i; } const_iterator find(key_type const& k) const { const_iterator const i(lower_bound(k)); return (i != end() && m_cmp(k, i->first))? end() : i; } size_type count(key_type const& k) const { return find(k) != end()? 1 : 0; } iterator lower_bound(key_type const& k) { return ::eastl::lower_bound(begin(), end(), k, m_cmp); } const_iterator lower_bound(key_type const& k) const { return ::eastl::lower_bound(begin(), end(), k, m_cmp); } iterator upper_bound(key_type const& k) { return ::eastl::upper_bound(begin(), end(), k, m_cmp); } const_iterator upper_bound(key_type const& k) const { return ::eastl::upper_bound(begin(), end(), k, m_cmp); } ::eastl::pair equal_range(key_type const& k) { return ::eastl::equal_range(begin(), end(), k, m_cmp); } ::eastl::pair equal_range(key_type const& k) const { return ::eastl::equal_range(begin(), end(), k, m_cmp); } template friend bool operator==(vector_map const& lhs, vector_map const& rhs); template friend bool operator!=(vector_map const& lhs, vector_map const& rhs); template friend bool operator<(vector_map const& lhs, vector_map const& rhs); template friend bool operator>(vector_map const& lhs, vector_map const& rhs); template friend bool operator>=(vector_map const& lhs, vector_map const& rhs); template friend bool operator<=(vector_map const& lhs, vector_map const& rhs); }; // class vector_map template inline bool operator==(vector_map const& lhs, vector_map const& rhs) { return lhs.m_base == rhs.m_base; } template inline bool operator!=(vector_map const& lhs, vector_map const& rhs) { return lhs.m_base != rhs.m_base; } template inline bool operator<(vector_map const& lhs, vector_map const& rhs) { return lhs.m_base < rhs.m_base; } template inline bool operator>(vector_map const& lhs, vector_map const& rhs) { return lhs.m_base > rhs.m_base; } template inline bool operator>=(vector_map const& lhs, vector_map const& rhs) { return lhs.m_base >= rhs.m_base; } template inline bool operator<=(vector_map const& lhs, vector_map const& rhs) { return lhs.m_base <= rhs.m_base; } template void swap(vector_map const& lhs, vector_map const& rhs) { return lhs.swap(rhs); } } // namespace eastl #endif // EASTL_VECTOR_MAP_H