aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h')
-rw-r--r--Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h191
1 files changed, 191 insertions, 0 deletions
diff --git a/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h b/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h
new file mode 100644
index 0000000..36f3967
--- /dev/null
+++ b/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2018 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_ITERATOR_H_
+#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_ITERATOR_H_
+
+#include <utility>
+
+#include "Firestore/core/src/firebase/firestore/immutable/array_sorted_map.h"
+#include "Firestore/core/src/firebase/firestore/immutable/tree_sorted_map.h"
+
+namespace firebase {
+namespace firestore {
+namespace immutable {
+namespace impl {
+
+template <typename V, typename ArrayIter, typename TreeIter>
+class SortedMapIterator {
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = V;
+ using pointer = const value_type*;
+ using reference = const value_type&;
+ using difference_type = std::ptrdiff_t;
+
+ public:
+ // Default constructor to conform to the requirements of ForwardIterator
+ SortedMapIterator() : tag_{Tag::Array}, array_iter_{} {
+ }
+
+ explicit SortedMapIterator(ArrayIter&& delegate)
+ : tag_{Tag::Array}, array_iter_{std::move(delegate)} {
+ }
+
+ explicit SortedMapIterator(TreeIter&& delegate)
+ : tag_{Tag::Tree}, tree_iter_{std::move(delegate)} {
+ }
+
+ SortedMapIterator(const SortedMapIterator& other) : tag_(other.tag_) {
+ switch (tag_) {
+ case Tag::Array:
+ new (&array_iter_) ArrayIter{other.array_iter_};
+ break;
+ case Tag::Tree:
+ new (&tree_iter_) TreeIter{other.tree_iter_};
+ break;
+ }
+ }
+
+ SortedMapIterator(SortedMapIterator&& other) : tag_(other.tag_) {
+ switch (tag_) {
+ case Tag::Array:
+ new (&array_iter_) ArrayIter{std::move(other.array_iter_)};
+ break;
+ case Tag::Tree:
+ new (&tree_iter_) TreeIter{std::move(other.tree_iter_)};
+ break;
+ }
+ }
+
+ ~SortedMapIterator() {
+ switch (tag_) {
+ case Tag::Array:
+ array_iter_.~ArrayIter();
+ break;
+ case Tag::Tree:
+ tree_iter_.~TreeIter();
+ break;
+ }
+ }
+
+ SortedMapIterator& operator=(const SortedMapIterator& other) {
+ if (tag_ == other.tag_) {
+ switch (tag_) {
+ case Tag::Array:
+ array_iter_ = other.array_iter_;
+ break;
+ case Tag::Tree:
+ tree_iter_ = other.tree_iter_;
+ break;
+ }
+ } else {
+ this->~SortedMapIterator();
+ new (this) SortedMapIterator(other);
+ }
+ return *this;
+ }
+
+ SortedMapIterator& operator=(SortedMapIterator&& other) {
+ if (tag_ == other.tag_) {
+ switch (tag_) {
+ case Tag::Array:
+ array_iter_ = std::move(other.array_iter_);
+ break;
+ case Tag::Tree:
+ tree_iter_ = std::move(other.tree_iter_);
+ break;
+ }
+ } else {
+ this->~SortedMapIterator();
+ new (this) SortedMapIterator(std::move(other));
+ }
+ return *this;
+ }
+
+ pointer get() const {
+ switch (tag_) {
+ case Tag::Array:
+ return array_iter_;
+ case Tag::Tree:
+ return tree_iter_.get();
+ }
+ }
+
+ reference operator*() const {
+ return *get();
+ }
+
+ pointer operator->() const {
+ return get();
+ }
+
+ SortedMapIterator& operator++() {
+ switch (tag_) {
+ case Tag::Array:
+ ++array_iter_;
+ break;
+ case Tag::Tree:
+ ++tree_iter_;
+ break;
+ }
+ return *this;
+ }
+
+ SortedMapIterator operator++(int /*unused*/) {
+ SortedMapIterator result = *this;
+ ++*this;
+ return result;
+ }
+
+ friend bool operator==(const SortedMapIterator& a,
+ const SortedMapIterator& b) {
+ if (a.tag_ != b.tag_) {
+ return false;
+ }
+
+ switch (a.tag_) {
+ case Tag::Array:
+ return a.array_iter_ == b.array_iter_;
+ case Tag::Tree:
+ return a.tree_iter_ == b.tree_iter_;
+ }
+ FIREBASE_UNREACHABLE();
+ }
+
+ bool operator!=(const SortedMapIterator& b) const {
+ return !(*this == b);
+ }
+
+ private:
+ enum class Tag {
+ Array,
+ Tree,
+ };
+
+ Tag tag_;
+ union {
+ ArrayIter array_iter_;
+ TreeIter tree_iter_;
+ };
+};
+
+} // namespace impl
+} // namespace immutable
+} // namespace firestore
+} // namespace firebase
+
+#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_ITERATOR_H_