value_iterators.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_VALUE_ITERATORS_H_
  5. #define BASE_VALUE_ITERATORS_H_
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include "base/base_export.h"
  10. #include "base/containers/flat_map.h"
  11. #include "base/memory/raw_ptr.h"
  12. namespace base {
  13. class Value;
  14. namespace detail {
  15. using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>;
  16. // This iterator closely resembles DictStorage::iterator, with one
  17. // important exception. It abstracts the underlying unique_ptr away, meaning its
  18. // value_type is std::pair<const std::string, Value>. It's reference type is a
  19. // std::pair<const std::string&, Value&>, so that callers have read-write
  20. // access without incurring a copy.
  21. class BASE_EXPORT dict_iterator {
  22. public:
  23. using difference_type = DictStorage::iterator::difference_type;
  24. using value_type = std::pair<const std::string, Value>;
  25. using reference = std::pair<const std::string&, Value&>;
  26. using iterator_category = std::bidirectional_iterator_tag;
  27. class pointer {
  28. public:
  29. explicit pointer(const reference& ref);
  30. pointer(const pointer& ptr);
  31. pointer& operator=(const pointer& ptr) = delete;
  32. reference* operator->() { return &ref_; }
  33. private:
  34. reference ref_;
  35. };
  36. explicit dict_iterator(DictStorage::iterator dict_iter);
  37. dict_iterator(const dict_iterator& dict_iter);
  38. dict_iterator& operator=(const dict_iterator& dict_iter);
  39. ~dict_iterator();
  40. reference operator*();
  41. pointer operator->();
  42. dict_iterator& operator++();
  43. dict_iterator operator++(int);
  44. dict_iterator& operator--();
  45. dict_iterator operator--(int);
  46. BASE_EXPORT friend bool operator==(const dict_iterator& lhs,
  47. const dict_iterator& rhs);
  48. BASE_EXPORT friend bool operator!=(const dict_iterator& lhs,
  49. const dict_iterator& rhs);
  50. // Currently, there is no easy way to friend Value::Dict. Once dictionary
  51. // storage is updated to not require a proxy iterator, the implementation can
  52. // be folded into //base/values.h and a standard friend declaration can be
  53. // used instead.
  54. const DictStorage::iterator& GetUnderlyingIteratorDoNotUse() {
  55. return dict_iter_;
  56. }
  57. private:
  58. DictStorage::iterator dict_iter_;
  59. };
  60. // This iterator closely resembles DictStorage::const_iterator, with one
  61. // important exception. It abstracts the underlying unique_ptr away, meaning its
  62. // value_type is std::pair<const std::string, Value>. It's reference type is a
  63. // std::pair<const std::string&, const Value&>, so that callers have read-only
  64. // access without incurring a copy.
  65. class BASE_EXPORT const_dict_iterator {
  66. public:
  67. using difference_type = DictStorage::const_iterator::difference_type;
  68. using value_type = std::pair<const std::string, Value>;
  69. using reference = std::pair<const std::string&, const Value&>;
  70. using iterator_category = std::bidirectional_iterator_tag;
  71. class pointer {
  72. public:
  73. explicit pointer(const reference& ref);
  74. pointer(const pointer& ptr);
  75. pointer& operator=(const pointer& ptr) = delete;
  76. const reference* operator->() const { return &ref_; }
  77. private:
  78. const reference ref_;
  79. };
  80. explicit const_dict_iterator(DictStorage::const_iterator dict_iter);
  81. const_dict_iterator(const const_dict_iterator& dict_iter);
  82. const_dict_iterator& operator=(const const_dict_iterator& dict_iter);
  83. ~const_dict_iterator();
  84. reference operator*() const;
  85. pointer operator->() const;
  86. const_dict_iterator& operator++();
  87. const_dict_iterator operator++(int);
  88. const_dict_iterator& operator--();
  89. const_dict_iterator operator--(int);
  90. BASE_EXPORT friend bool operator==(const const_dict_iterator& lhs,
  91. const const_dict_iterator& rhs);
  92. BASE_EXPORT friend bool operator!=(const const_dict_iterator& lhs,
  93. const const_dict_iterator& rhs);
  94. // Currently, there is no easy way to friend Value::Dict. Once dictionary
  95. // storage is updated to not require a proxy iterator, the implementation can
  96. // be folded into //base/values.h and a standard friend declaration can be
  97. // used instead.
  98. const DictStorage::const_iterator& GetUnderlyingIteratorDoNotUse() {
  99. return dict_iter_;
  100. }
  101. private:
  102. DictStorage::const_iterator dict_iter_;
  103. };
  104. // This class wraps the various |begin| and |end| methods of the underlying
  105. // DictStorage in dict_iterators and const_dict_iterators. This allows callers
  106. // to use this class for easy iteration over the underlying values, granting
  107. // them either read-only or read-write access, depending on the
  108. // const-qualification.
  109. class BASE_EXPORT dict_iterator_proxy {
  110. public:
  111. using key_type = DictStorage::key_type;
  112. using mapped_type = DictStorage::mapped_type::element_type;
  113. using value_type = std::pair<key_type, mapped_type>;
  114. using key_compare = DictStorage::key_compare;
  115. using size_type = DictStorage::size_type;
  116. using difference_type = DictStorage::difference_type;
  117. using iterator = dict_iterator;
  118. using const_iterator = const_dict_iterator;
  119. using reverse_iterator = std::reverse_iterator<iterator>;
  120. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  121. explicit dict_iterator_proxy(DictStorage* storage);
  122. size_type size() const;
  123. iterator begin();
  124. const_iterator begin() const;
  125. iterator end();
  126. const_iterator end() const;
  127. reverse_iterator rbegin();
  128. const_reverse_iterator rbegin() const;
  129. reverse_iterator rend();
  130. const_reverse_iterator rend() const;
  131. const_dict_iterator cbegin() const;
  132. const_dict_iterator cend() const;
  133. const_reverse_iterator crbegin() const;
  134. const_reverse_iterator crend() const;
  135. private:
  136. raw_ptr<DictStorage> storage_;
  137. };
  138. // This class wraps the various const |begin| and |end| methods of the
  139. // underlying DictStorage in const_dict_iterators. This allows callers to use
  140. // this class for easy iteration over the underlying values, granting them
  141. // either read-only access.
  142. class BASE_EXPORT const_dict_iterator_proxy {
  143. public:
  144. using key_type = const DictStorage::key_type;
  145. using mapped_type = const DictStorage::mapped_type::element_type;
  146. using value_type = std::pair<key_type, mapped_type>;
  147. using key_compare = DictStorage::key_compare;
  148. using size_type = DictStorage::size_type;
  149. using difference_type = DictStorage::difference_type;
  150. using iterator = const_dict_iterator;
  151. using const_iterator = const_dict_iterator;
  152. using reverse_iterator = std::reverse_iterator<iterator>;
  153. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  154. explicit const_dict_iterator_proxy(const DictStorage* storage);
  155. size_type size() const;
  156. const_iterator begin() const;
  157. const_iterator end() const;
  158. const_reverse_iterator rbegin() const;
  159. const_reverse_iterator rend() const;
  160. const_iterator cbegin() const;
  161. const_iterator cend() const;
  162. const_reverse_iterator crbegin() const;
  163. const_reverse_iterator crend() const;
  164. private:
  165. raw_ptr<const DictStorage> storage_;
  166. };
  167. } // namespace detail
  168. } // namespace base
  169. #endif // BASE_VALUE_ITERATORS_H_