|  | @@ -63,6 +63,7 @@ class Map {
 | 
	
		
			
				|  |  |    typedef Pair<key_type, mapped_type> value_type;
 | 
	
		
			
				|  |  |    typedef Compare key_compare;
 | 
	
		
			
				|  |  |    class iterator;
 | 
	
		
			
				|  |  | +  class const_iterator;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    Map() = default;
 | 
	
		
			
				|  |  |    ~Map() { clear(); }
 | 
	
	
		
			
				|  | @@ -83,6 +84,22 @@ class Map {
 | 
	
		
			
				|  |  |      return *this;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  // Copyable.
 | 
	
		
			
				|  |  | +  Map(const Map& other) {
 | 
	
		
			
				|  |  | +    for (const auto& p : other) {
 | 
	
		
			
				|  |  | +      emplace(p);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  Map& operator=(const Map& other) {
 | 
	
		
			
				|  |  | +    if (this != &other) {
 | 
	
		
			
				|  |  | +      clear();
 | 
	
		
			
				|  |  | +      for (const auto& p : other) {
 | 
	
		
			
				|  |  | +        emplace(p);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    T& operator[](key_type&& key);
 | 
	
		
			
				|  |  |    T& operator[](const key_type& key);
 | 
	
		
			
				|  |  |    iterator find(const key_type& k);
 | 
	
	
		
			
				|  | @@ -117,6 +134,13 @@ class Map {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    iterator end() { return iterator(this, nullptr); }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  const_iterator begin() const {
 | 
	
		
			
				|  |  | +    Entry* curr = GetMinEntry(root_);
 | 
	
		
			
				|  |  | +    return const_iterator(this, curr);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const_iterator end() const { return const_iterator(this, nullptr); }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    iterator lower_bound(const Key& k) {
 | 
	
		
			
				|  |  |      // This is a workaround for "const key_compare compare;"
 | 
	
		
			
				|  |  |      // because some versions of compilers cannot build this by requiring
 | 
	
	
		
			
				|  | @@ -209,6 +233,53 @@ class Map<Key, T, Compare>::iterator
 | 
	
		
			
				|  |  |    GrpcMap* map_;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +template <class Key, class T, class Compare>
 | 
	
		
			
				|  |  | +class Map<Key, T, Compare>::const_iterator
 | 
	
		
			
				|  |  | +    : public std::iterator<std::input_iterator_tag, Pair<Key, T>, int32_t,
 | 
	
		
			
				|  |  | +                           Pair<Key, T>*, Pair<Key, T>&> {
 | 
	
		
			
				|  |  | + public:
 | 
	
		
			
				|  |  | +  const_iterator(const const_iterator& iter)
 | 
	
		
			
				|  |  | +      : curr_(iter.curr_), map_(iter.map_) {}
 | 
	
		
			
				|  |  | +  bool operator==(const const_iterator& rhs) const {
 | 
	
		
			
				|  |  | +    return (curr_ == rhs.curr_);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  bool operator!=(const const_iterator& rhs) const {
 | 
	
		
			
				|  |  | +    return (curr_ != rhs.curr_);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const_iterator& operator++() {
 | 
	
		
			
				|  |  | +    curr_ = map_->InOrderSuccessor(curr_);
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const_iterator operator++(int) {
 | 
	
		
			
				|  |  | +    Entry* prev = curr_;
 | 
	
		
			
				|  |  | +    curr_ = map_->InOrderSuccessor(curr_);
 | 
	
		
			
				|  |  | +    return const_iterator(map_, prev);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const_iterator& operator=(const const_iterator& other) {
 | 
	
		
			
				|  |  | +    if (this != &other) {
 | 
	
		
			
				|  |  | +      this->curr_ = other.curr_;
 | 
	
		
			
				|  |  | +      this->map_ = other.map_;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // operator*()
 | 
	
		
			
				|  |  | +  const value_type& operator*() const { return curr_->pair; }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // operator->()
 | 
	
		
			
				|  |  | +  const value_type* operator->() const { return &curr_->pair; }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + private:
 | 
	
		
			
				|  |  | +  friend class Map<key_type, mapped_type, key_compare>;
 | 
	
		
			
				|  |  | +  using GrpcMap = typename ::grpc_core::Map<Key, T, Compare>;
 | 
	
		
			
				|  |  | +  const_iterator(const GrpcMap* map, Entry* curr) : curr_(curr), map_(map) {}
 | 
	
		
			
				|  |  | +  Entry* curr_;
 | 
	
		
			
				|  |  | +  const GrpcMap* map_;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  template <class Key, class T, class Compare>
 | 
	
		
			
				|  |  |  T& Map<Key, T, Compare>::operator[](key_type&& key) {
 | 
	
		
			
				|  |  |    auto iter = find(key);
 |