#ifndef BASE_VALUE_ITERATORS_H_
#define BASE_VALUE_ITERATORS_H_
#include <memory>
#include <string>
#include <utility>
#include "base/containers/flat_map.h"
namespace base {
class Value;
namespace detail {
using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>;
class dict_iterator {
public:
using difference_type = DictStorage::iterator::difference_type;
using value_type = std::pair<const std::string, Value>;
using reference = std::pair<const std::string&, Value&>;
using iterator_category = std::bidirectional_iterator_tag;
class pointer {
public:
explicit pointer(const reference& ref);
pointer(const pointer& ptr);
pointer& operator=(const pointer& ptr) = delete;
reference* operator->() { return &ref_; }
private:
reference ref_;
};
explicit dict_iterator(DictStorage::iterator dict_iter);
dict_iterator(const dict_iterator& dict_iter);
dict_iterator& operator=(const dict_iterator& dict_iter);
~dict_iterator();
reference operator*();
pointer operator->();
dict_iterator& operator++();
dict_iterator operator++(int);
dict_iterator& operator--();
dict_iterator operator--(int);
friend bool operator==(const dict_iterator& lhs, const dict_iterator& rhs);
friend bool operator!=(const dict_iterator& lhs, const dict_iterator& rhs);
private:
DictStorage::iterator dict_iter_;
};
class const_dict_iterator {
public:
using difference_type = DictStorage::const_iterator::difference_type;
using value_type = std::pair<const std::string, Value>;
using reference = std::pair<const std::string&, const Value&>;
using iterator_category = std::bidirectional_iterator_tag;
class pointer {
public:
explicit pointer(const reference& ref);
pointer(const pointer& ptr);
pointer& operator=(const pointer& ptr) = delete;
const reference* operator->() const { return &ref_; }
private:
const reference ref_;
};
explicit const_dict_iterator(DictStorage::const_iterator dict_iter);
const_dict_iterator(const const_dict_iterator& dict_iter);
const_dict_iterator& operator=(const const_dict_iterator& dict_iter);
~const_dict_iterator();
reference operator*() const;
pointer operator->() const;
const_dict_iterator& operator++();
const_dict_iterator operator++(int);
const_dict_iterator& operator--();
const_dict_iterator operator--(int);
friend bool operator==(const const_dict_iterator& lhs,
const const_dict_iterator& rhs);
friend bool operator!=(const const_dict_iterator& lhs,
const const_dict_iterator& rhs);
private:
DictStorage::const_iterator dict_iter_;
};
class dict_iterator_proxy {
public:
using key_type = DictStorage::key_type;
using mapped_type = DictStorage::mapped_type::element_type;
using value_type = std::pair<key_type, mapped_type>;
using key_compare = DictStorage::key_compare;
using size_type = DictStorage::size_type;
using difference_type = DictStorage::difference_type;
using iterator = dict_iterator;
using const_iterator = const_dict_iterator;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
explicit dict_iterator_proxy(DictStorage* storage);
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
const_dict_iterator cbegin() const;
const_dict_iterator cend() const;
const_reverse_iterator crbegin() const;
const_reverse_iterator crend() const;
private:
DictStorage* storage_;
};
class const_dict_iterator_proxy {
public:
using key_type = const DictStorage::key_type;
using mapped_type = const DictStorage::mapped_type::element_type;
using value_type = std::pair<key_type, mapped_type>;
using key_compare = DictStorage::key_compare;
using size_type = DictStorage::size_type;
using difference_type = DictStorage::difference_type;
using iterator = const_dict_iterator;
using const_iterator = const_dict_iterator;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
explicit const_dict_iterator_proxy(const DictStorage* storage);
const_iterator begin() const;
const_iterator end() const;
const_reverse_iterator rbegin() const;
const_reverse_iterator rend() const;
const_iterator cbegin() const;
const_iterator cend() const;
const_reverse_iterator crbegin() const;
const_reverse_iterator crend() const;
private:
const DictStorage* storage_;
};
}
}
#endif