forked from Bananymous/banan-os
				
			BAN: Implement ConstIteratorDouble and add it to HashMap
This is same as IteratorDouble except it uses const_iterator and does not return non-const references.
This commit is contained in:
		
							parent
							
								
									65424a6769
								
							
						
					
					
						commit
						9eab6710ce
					
				|  | @ -31,6 +31,7 @@ namespace BAN | ||||||
| 		using key_type = Key; | 		using key_type = Key; | ||||||
| 		using value_type = T; | 		using value_type = T; | ||||||
| 		using iterator = IteratorDouble<Entry, Vector, LinkedList, HashMap>; | 		using iterator = IteratorDouble<Entry, Vector, LinkedList, HashMap>; | ||||||
|  | 		using const_iterator = ConstIteratorDouble<Entry, Vector, LinkedList, HashMap>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		HashMap() = default; | 		HashMap() = default; | ||||||
|  | @ -48,6 +49,8 @@ namespace BAN | ||||||
| 
 | 
 | ||||||
| 		iterator begin() { return iterator(m_buckets.end(), m_buckets.begin()); } | 		iterator begin() { return iterator(m_buckets.end(), m_buckets.begin()); } | ||||||
| 		iterator end()   { return iterator(m_buckets.end(), m_buckets.end()); } | 		iterator end()   { return iterator(m_buckets.end(), m_buckets.end()); } | ||||||
|  | 		const_iterator begin() const { return const_iterator(m_buckets.end(), m_buckets.begin()); } | ||||||
|  | 		const_iterator end() const   { return const_iterator(m_buckets.end(), m_buckets.end()); } | ||||||
| 
 | 
 | ||||||
| 		ErrorOr<void> reserve(size_type); | 		ErrorOr<void> reserve(size_type); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -266,4 +266,105 @@ namespace BAN | ||||||
| 		friend Container; | 		friend Container; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	template<typename T, template <typename> typename OuterContainer, template <typename> typename InnerContainer, typename Container> | ||||||
|  | 	class ConstIteratorDouble | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		using Inner = InnerContainer<T>; | ||||||
|  | 		using Outer = OuterContainer<Inner>; | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		ConstIteratorDouble() = default; | ||||||
|  | 		ConstIteratorDouble(const IteratorDouble<T, OuterContainer, InnerContainer, Container>& other) | ||||||
|  | 			: m_outer_end(other.m_outer_end) | ||||||
|  | 			, m_outer_current(other.m_outer_current) | ||||||
|  | 			, m_inner_current(other.m_inner_current) | ||||||
|  | 		{ | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		const T& operator*() const | ||||||
|  | 		{ | ||||||
|  | 			ASSERT(*this); | ||||||
|  | 			ASSERT(m_outer_current != m_outer_end); | ||||||
|  | 			ASSERT(m_inner_current); | ||||||
|  | 			return m_inner_current.operator*(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		const T* operator->() const | ||||||
|  | 		{ | ||||||
|  | 			ASSERT(*this); | ||||||
|  | 			ASSERT(m_outer_current != m_outer_end); | ||||||
|  | 			ASSERT(m_inner_current); | ||||||
|  | 			return m_inner_current.operator->(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ConstIteratorDouble& operator++() | ||||||
|  | 		{ | ||||||
|  | 			ASSERT(*this); | ||||||
|  | 			ASSERT(m_outer_current != m_outer_end); | ||||||
|  | 			ASSERT(m_inner_current); | ||||||
|  | 			m_inner_current++; | ||||||
|  | 			find_valid_or_end(); | ||||||
|  | 			return *this; | ||||||
|  | 		} | ||||||
|  | 		ConstIteratorDouble operator++(int) | ||||||
|  | 		{ | ||||||
|  | 			auto temp = *this; | ||||||
|  | 			++(*this); | ||||||
|  | 			return temp; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		bool operator==(const ConstIteratorDouble& other) const | ||||||
|  | 		{ | ||||||
|  | 			if (!*this || !other) | ||||||
|  | 				return false; | ||||||
|  | 			if (m_outer_end != other.m_outer_end) | ||||||
|  | 				return false; | ||||||
|  | 			if (m_outer_current != other.m_outer_current) | ||||||
|  | 				return false; | ||||||
|  | 			if (m_outer_current == m_outer_end) | ||||||
|  | 				return true; | ||||||
|  | 			return m_inner_current == other.m_inner_current; | ||||||
|  | 		} | ||||||
|  | 		bool operator!=(const ConstIteratorDouble& other) const | ||||||
|  | 		{ | ||||||
|  | 			return !(*this == other); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		operator bool() const | ||||||
|  | 		{ | ||||||
|  | 			return m_outer_end && m_outer_current; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		ConstIteratorDouble(Outer::const_iterator outer_end, Outer::const_iterator outer_current) | ||||||
|  | 			: m_outer_end(outer_end) | ||||||
|  | 			, m_outer_current(outer_current) | ||||||
|  | 		{ | ||||||
|  | 			if (outer_current != outer_end) | ||||||
|  | 			{ | ||||||
|  | 				m_inner_current = m_outer_current->begin(); | ||||||
|  | 				find_valid_or_end(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		void find_valid_or_end() | ||||||
|  | 		{ | ||||||
|  | 			while (m_inner_current == m_outer_current->end()) | ||||||
|  | 			{ | ||||||
|  | 				m_outer_current++; | ||||||
|  | 				if (m_outer_current == m_outer_end) | ||||||
|  | 					break; | ||||||
|  | 				m_inner_current = m_outer_current->begin(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		Outer::const_iterator m_outer_end; | ||||||
|  | 		Outer::const_iterator m_outer_current; | ||||||
|  | 		Inner::const_iterator m_inner_current; | ||||||
|  | 
 | ||||||
|  | 		friend Container; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue