Index: cc/base/pyramid_sequence.h |
diff --git a/cc/base/pyramid_sequence.h b/cc/base/pyramid_sequence.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a22614022e09feeec383f4feca19471a3d5973fc |
--- /dev/null |
+++ b/cc/base/pyramid_sequence.h |
@@ -0,0 +1,703 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CC_BASE_PYRAMID_SEQUENCE_H_ |
+#define CC_BASE_PYRAMID_SEQUENCE_H_ |
+ |
+#include <vector> |
+ |
+#include "base/logging.h" |
+#include "cc/base/cc_export.h" |
+#include "cc/base/index_rect.h" |
+ |
+namespace cc { |
+ |
+// The pyramid sequence covers following 4 directions while iterating, where R |
+// is right, T is top, L is left and B is bottom. |
+// T |
+// L * R |
+// B |
+enum class CoverageDirection : int { |
+ NONE = -1, |
+ RIGHT = 0, |
+ TOP, |
+ LEFT, |
+ BOTTOM, |
+ SIZE |
+}; |
+ |
+// This class provides iterating mechanism for numbers between defined bounds. |
+// e.g. For interval having bounds 3 as start and 6 as end, represented as |
+// [3, 6], the interval returns 3, 4, 5, 6 sequence for Iterator traversal and |
+// returns 6, 5, 4, 3 for ReverseIterator traversal. |
+// |
+// start end |
+// | | |
+// V V |
+// ┌───┬───┬───┬───┐ |
+// │ 3 │ 4 │ 5 │ 6 │ |
+// └───┴───┴───┴───┘ |
+class CC_EXPORT Interval { |
+ public: |
+ class Iterator; |
+ class ReverseIterator; |
+ |
+ Interval() : empty_(true) {} |
+ Interval(int start, int end) : empty_(false), start_(start), end_(end) {} |
+ |
+ Iterator Begin(); |
+ ReverseIterator ReverseBegin(); |
+ |
+ // Return the bounds of the interval. |
+ int start() const { return start_; } |
+ int end() const { return end_; } |
+ |
+ // Returns true if interval is empty. Empty interval does not return any |
+ // index on traversing. |
+ bool IsEmpty() const { return empty_; } |
+ |
+ // Returns the distance between |start_| and |end_| which includes both |
+ // |start_| and |end_|. |
+ int GetSpan() const; |
+ |
+ // Return clamped indices for the given indices. |
+ int GetForwardClampedIndex(int index) const; |
+ int GetBackwardClampedIndex(int index) const; |
+ |
+ // Clamp this interval to the given interval. For these functions, interval |
+ // and other interval to which this interval is to be clammped should be in |
+ // the same direction, i.e. both intervals should have either |
+ // |start_| <= |end_| or |start_| >= |end_|. |
+ void ForwardClampTo(const Interval& other); |
+ void BackwardClampTo(const Interval& other); |
+ |
+ // Return the inflated intervals for the given |level|. |
+ Interval GetForwardInflatedInterval(int level) const; |
+ Interval GetBackwardInflatedInterval(int level) const; |
+ |
+ // Returns true if interval contains the given index. |
+ bool Contains(int index) const; |
+ |
+ // For these functions, interval and other interval to which first one is to |
+ // be intersected should be in the same direction, i.e. both intervals should |
+ // have |start_| <= |end_| or |start_| >= |end_|. |
+ bool Intersects(const Interval& interval) const; |
+ void Intersect(const Interval& interval); |
+ |
+ // Iterators. |
+ class IteratorBase { |
+ public: |
+ IteratorBase(); |
+ |
+ operator bool() const { return within_bounds_; } |
+ IteratorBase& operator++(); |
+ int index() { return current_index_; } |
+ |
+ protected: |
+ explicit IteratorBase(Interval* interval); |
+ |
+ virtual bool IsWithinBounds() = 0; |
+ |
+ Interval* interval_; |
+ bool within_bounds_; |
+ int step_; |
+ int current_index_; |
+ }; |
+ |
+ class Iterator : public IteratorBase { |
+ public: |
+ Iterator(); |
+ |
+ private: |
+ explicit Iterator(Interval* interval); |
+ |
+ bool IsWithinBounds() override; |
+ |
+ friend class Interval; |
+ }; |
+ |
+ class ReverseIterator : public IteratorBase { |
+ public: |
+ ReverseIterator(); |
+ |
+ private: |
+ explicit ReverseIterator(Interval* interval); |
+ |
+ bool IsWithinBounds() override; |
+ |
+ friend class Interval; |
+ }; |
+ |
+ private: |
+ bool empty_; |
+ int start_; |
+ int end_; |
+}; |
+ |
+// This class provides affinity based interating mechanism for the given |
+// |interval| [start, end] with functionality of inflating the |interval|. |
+// The interval inflation means expanding the start and end by n steps forward |
+// or backward, based on |forward_direction| argument provided. Suppose the |
+// LinearSequence has interval [3, 3] i.e. start = 3 and end = 3, the interval |
+// inflated by 1 step in forward direction would be [2, 4] and that of in |
+// backward direction would be [4, 2]. |
+// The affinity based traversing means portion of |interval| that intersects |
+// with |affinity_interval| is traversed before remaining two portions of |
+// |interval|. Internally the |interval| is split up into three sub-intervals |
+// before traversing as |affinity_sub_interval_|, |before_sub_interval_| and |
+// |after_sub_interval_|. These sub-intervals are traversed instead of directly |
+// traversing |interval|. First |affinity_sub_interval_| is traversed fully, |
+// then remaining two sub-intervals are traversed in alternative fashion. |
+// |
+// e.g. Suppose LinearSequence has interval [0, 9] and affinity interval |
+// [4, 6], then the interval is splitted into three sub-intervals viz. [4, 6], |
+// [3, 0], [7, 9]. |
+// |
+// affinity_sub_interval |
+// ┌─────^─────┐ |
+// ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ |
+// │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ |
+// └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ |
+// └───────v───────┘ └─────v─────┘ |
+// before_sub_interval after_sub_interval |
+// |
+// On traversal, Iterator returns the sequence as 4, 5, 6, 3, 7, 2, 8, 1, 9, 0 |
+// and RerverseIterator returns the sequence as 0, 9, 1, 8, 2, 7, 3, 6, 5, 4. |
+class CC_EXPORT LinearSequence { |
+ public: |
+ class Iterator; |
+ class ReverseIterator; |
+ |
+ LinearSequence(); |
+ // The |interval| is used for actual traversal. The |affinity_interval| is |
+ // used for defining affinity in the |interval|. While traversing portion of |
+ // |interval| which intersects |affinity_interval| is traversed before |
+ // remaining portions of the interval. The |inflate_limit| is used to clamp |
+ // the |interval|, when it is inflated to any given |level|. |
+ LinearSequence(bool forward_direction, |
+ Interval interval, |
+ Interval affinity_interval, |
+ Interval inflate_limit); |
+ LinearSequence(const LinearSequence& other); |
+ LinearSequence(LinearSequence&& other); |
+ ~LinearSequence(); |
+ |
+ LinearSequence& operator=(const LinearSequence& other); |
+ LinearSequence& operator=(LinearSequence&& other); |
+ |
+ Iterator Begin(); |
+ ReverseIterator ReverseBegin(); |
+ |
+ // This function inflates the original |interval| to the given |level|, |
+ // where level >= 0. |
+ void InflateToLevel(int level); |
+ |
+ // Iterators. |
+ class IteratorBase { |
+ public: |
+ IteratorBase(); |
+ IteratorBase(const IteratorBase& other); |
+ IteratorBase(IteratorBase&& other); |
+ ~IteratorBase(); |
+ |
+ IteratorBase& operator=(const IteratorBase& other); |
+ IteratorBase& operator=(IteratorBase&& other); |
+ |
+ operator bool() const { return within_bounds_; } |
+ IteratorBase& operator++(); |
+ int index() { return current_index_; } |
+ |
+ protected: |
+ enum class SubIntervalIteratorType : unsigned int { |
+ AFFINITY, |
+ BEFORE, |
+ AFTER |
+ }; |
+ |
+ explicit IteratorBase(LinearSequence* level_sequence); |
+ |
+ virtual void Setup() = 0; |
+ virtual SubIntervalIteratorType GetCurrentSubIntervalIteratorType() = 0; |
+ virtual bool IsWithinBounds() = 0; |
+ |
+ LinearSequence* level_sequence_; |
+ bool within_bounds_; |
+ int current_index_; |
+ Interval::IteratorBase* sub_interval_iterators_[3]; |
+ SubIntervalIteratorType current_sub_interval_iterator_; |
+ }; |
+ |
+ class Iterator : public IteratorBase { |
+ public: |
+ Iterator(); |
+ Iterator(const Iterator& other); |
+ Iterator(Iterator&& other); |
+ ~Iterator(); |
+ |
+ Iterator& operator=(const Iterator& other); |
+ Iterator& operator=(Iterator&& other); |
+ |
+ private: |
+ explicit Iterator(LinearSequence* level_sequence); |
+ |
+ void Setup() override; |
+ SubIntervalIteratorType GetCurrentSubIntervalIteratorType() override; |
+ bool IsWithinBounds() override; |
+ |
+ Interval::Iterator affinity_sub_interval_iterator_; |
+ Interval::Iterator before_sub_interval_iterator_; |
+ Interval::Iterator after_sub_interval_iterator_; |
+ bool before_first_; |
+ |
+ friend class LinearSequence; |
+ }; |
+ |
+ class ReverseIterator : public IteratorBase { |
+ public: |
+ ReverseIterator(); |
+ ReverseIterator(const ReverseIterator& other); |
+ ReverseIterator(ReverseIterator&& other); |
+ ~ReverseIterator(); |
+ |
+ ReverseIterator& operator=(const ReverseIterator& other); |
+ ReverseIterator& operator=(ReverseIterator&& other); |
+ |
+ private: |
+ explicit ReverseIterator(LinearSequence* level_sequence); |
+ |
+ void Setup() override; |
+ SubIntervalIteratorType GetCurrentSubIntervalIteratorType() override; |
+ bool IsWithinBounds() override; |
+ |
+ Interval::ReverseIterator affinity_sub_interval_reverse_iterator_; |
+ Interval::ReverseIterator before_sub_interval_reverse_iterator_; |
+ Interval::ReverseIterator after_sub_interval_reverse_iterator_; |
+ bool after_first_; |
+ int before_sub_interval_span_; |
+ int after_sub_interval_span_; |
+ |
+ friend class LinearSequence; |
+ }; |
+ |
+ private: |
+ void TrisectInterval(); |
+ |
+ bool forward_direction_; |
+ Interval interval_; |
+ Interval inflate_limit_; |
+ Interval affinity_interval_; |
+ |
+ Interval initial_interval_; |
+ |
+ // The |interval_| is split up into following sub-intervals such a way that |
+ // they are non-intersecting, adjacent and union of these three sub-intervals |
+ // is |interval_|. |
+ Interval affinity_sub_interval_; |
+ Interval before_sub_interval_; |
+ Interval after_sub_interval_; |
+}; |
+ |
+// This class implements the 2D sequence (x, y) which uses LinearSequence and |
+// Interval to represent the co-ordinates. The linear sequence |
+// |traversal_sequence| is used for traversing the actual sequence cross the |
+// direction and |level_interval| is used for computing the number of levels in |
+// the |traversal_sequence|. The interval in |traversal_sequence| can be |
+// inflated max to the levels given by |level_interval|. |
+// This class uses LevelDistance structure to represent the distance associated |
+// with the level. The first level has distance 0, to represent the minimum |
+// distance for the origin level, and increments by the step of |distance| |
+// given in LevelDistance for every level. Suppose there are 5 levels and |
+// distance is 10, then the levels would have distances as 0, 10, 20, 30, 40. |
+// The distances are stored in the sorted order in vector, so that the distance |
+// at front is minimum, while the distance at back is maximum. The layout of |
+// the level distance vector for the example would be (0, 0), (1, 10), (2, 20), |
+// (3, 30), (4, 40). |
+// |
+// e.g. If traversal sequence has interval [3, 4], number of levels is 3 and |
+// distance is 10, then the Iterator would give following data on traversal. |
+// |
+// traversal_sequence level_index |
+// [3, 4] 0 |
+// [2, 5] 1 |
+// [1, 6] 2 |
+// |
+// The order of iteration for ReverseIterator would be as given below. |
+// |
+// traversal_sequence level index |
+// [1, 6] 2 |
+// [2, 5] 1 |
+// [3, 4] 0 |
+// |
+// The indices (x, y) for the iterator are as given below. |
+// |
+// (3, 0), (4, 0) (level 1) |
+// (2, 1), (3, 1), (4, 1), (5, 1), (level 2) |
+// (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2) (level 3) |
+// |
+// In a way the original interval in |traversal_sequence| and inflated |
+// intervals form triangular geometry in co-ordinate space as given below, |
+// hence the name TriangularSequence. |
+// |
+// x 0 1 2 3 4 5 6 |
+// y ┌───┬───┬───┬───┬───┬───┬───┐ |
+// 0 │ │ │ │ 3 │ 4 │ │ │ (level 1, distance 0) |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 1 │ │ │ 2 │ 3 │ 4 │ 5 │ │ (level 2, distance 10) |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 2 │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ (level 3, distance 20) |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 3 │ │ │ │ │ │ │ │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 4 │ │ │ │ │ │ │ │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 5 │ │ │ │ │ │ │ │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 6 │ │ │ │ │ │ │ │ |
+// └───┴───┴───┴───┴───┴───┴───┘ |
+class CC_EXPORT TriangularSequence { |
+ public: |
+ class Iterator; |
+ class ReverseIterator; |
+ |
+ TriangularSequence(); |
+ // The |traversal_sequence| defines the sequence for traversal and |
+ // |level_interval| defines the number of levels for |traversal_sequence|. |
+ // If |should_swap_index_representation| is false, then the indices in |
+ // |traversal_sequence| represent the x indices and level indices in |
+ // |level_interval| represent the y indices, otherwise vice-versa. The |
+ // |levels_to_skip| defines the number of levels which should be skipped to |
+ // avoid unnecessary traversing. Check PyramidSequence::PyramidSequence() for |
+ // more details on level skipping. The |distance| defines the length for the |
+ // index. |
+ TriangularSequence(CoverageDirection coverage_direction, |
+ LinearSequence&& traversal_sequence, |
+ Interval&& level_interval, |
+ bool should_swap_index_representation, |
+ int levels_to_skip, |
+ int distance); |
+ TriangularSequence(const TriangularSequence& other); |
+ TriangularSequence(TriangularSequence&& other); |
+ ~TriangularSequence(); |
+ |
+ TriangularSequence& operator=(const TriangularSequence& other); |
+ TriangularSequence& operator=(TriangularSequence&& other); |
+ |
+ Iterator Begin(); |
+ ReverseIterator ReverseBegin(); |
+ |
+ CoverageDirection coverage_direction() const { return coverage_direction_; } |
+ |
+ struct LevelDistance { |
+ LevelDistance(int interval_level, int level_index, int distance) |
+ : interval_level(interval_level), |
+ level_index(level_index), |
+ distance(distance) {} |
+ |
+ int interval_level; |
+ int level_index; |
+ int distance; |
+ }; |
+ |
+ class IteratorBase { |
+ public: |
+ IteratorBase(); |
+ IteratorBase(const IteratorBase& other); |
+ IteratorBase(IteratorBase&& other); |
+ ~IteratorBase(); |
+ |
+ IteratorBase& operator=(const IteratorBase& other); |
+ IteratorBase& operator=(IteratorBase&& other); |
+ |
+ operator bool() const { return !level_distances_.empty(); } |
+ IteratorBase& operator++(); |
+ LinearSequence* traversal_sequence() { |
+ DCHECK(*this); |
+ return &traversal_sequence_; |
+ } |
+ int level_index() { |
+ DCHECK(*this); |
+ return current_level_index_; |
+ } |
+ |
+ bool is_index_representation_swapped() const { |
+ return should_swap_index_representation_; |
+ } |
+ |
+ virtual int GetNextDistance() const = 0; |
+ |
+ protected: |
+ explicit IteratorBase(TriangularSequence* triangular_sequence); |
+ |
+ virtual void Advance() = 0; |
+ virtual void UpdateCurrent() = 0; |
+ |
+ LinearSequence traversal_sequence_; |
+ bool should_swap_index_representation_; |
+ std::vector<LevelDistance> level_distances_; |
+ int current_level_index_; |
+ }; |
+ |
+ class Iterator : public IteratorBase { |
+ public: |
+ Iterator(); |
+ |
+ // Returns next minimum distance. |
+ int GetNextDistance() const override; |
+ |
+ private: |
+ explicit Iterator(TriangularSequence* triangular_sequence); |
+ |
+ void Advance() override; |
+ void UpdateCurrent() override; |
+ |
+ friend class TriangularSequence; |
+ }; |
+ |
+ class ReverseIterator : public IteratorBase { |
+ public: |
+ ReverseIterator(); |
+ |
+ // Returns next maximum distance. |
+ int GetNextDistance() const override; |
+ |
+ private: |
+ explicit ReverseIterator(TriangularSequence* triangular_sequence); |
+ |
+ void Advance() override; |
+ void UpdateCurrent() override; |
+ |
+ friend class TriangularSequence; |
+ }; |
+ |
+ typedef std::vector<TriangularSequence> Vector; |
+ typedef std::vector<TriangularSequence::IteratorBase> IteratorVector; |
+ |
+ private: |
+ CoverageDirection coverage_direction_; |
+ LinearSequence traversal_sequence_; |
+ Interval level_interval_; |
+ bool should_swap_index_representation_; |
+ int levels_to_skip_; |
+ int distance_; |
+}; |
+ |
+// The pyramid sequence consists of 4 triangular sequences, one for each of |
+// the directions considered counter-clockwise or clockwise. The ideal pyramid |
+// sequence is as given below where it has all triangular sequences in 4 |
+// directions. |
+// |
+// ┌───┬───┬───┬───┬───┬───┬───┐ |
+// │ L │ T │ T │ T │ T │ T │ R │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// │ L │ L │ T │ T │ T │ R │ R │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// │ L │ L │ L │ T │ R │ R │ R │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// │ L │ L │ L │ * │ R │ R │ R │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// │ L │ L │ L │ B │ R │ R │ R │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// │ L │ L │ B │ B │ B │ R │ R │ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// │ L │ B │ B │ B │ B │ B │ R │ |
+// └───┴───┴───┴───┴───┴───┴───┘ |
+// |
+// The triangular sequences for the above pyramid sequence are shown below. |
+// * represents the center. |
+// |
+// (T = top) |
+// ┌───┬───┬───┬───┬───┐ |
+// │ T │ T │ T │ T │ T │ |
+// ┌───┐ └───┼───┼───┼───┼───┘ ┌───┐ |
+// │ L │ │ T │ T │ T │ │ R │ |
+// ├───┼───┐ └───┼───┼───┘ ┌───┼───┤ |
+// │ L │ L │ │ T │ │ R │ R │ |
+// ├───┼───┼───┐ └───┘ ┌───┼───┼───┤ |
+// │ L │ L │ L │ │ R │ R │ R │ |
+// ├───┼───┼───┤ ┌───┐ ├───┼───┼───┤ |
+// (L = left) │ L │ L │ L │ │ * │ │ R │ R │ R │ (R = right) |
+// ├───┼───┼───┤ └───┘ ├───┼───┼───┤ |
+// │ L │ L │ L │ │ R │ R │ R │ |
+// ├───┼───┼───┘ ┌───┐ └───┼───┼───┤ |
+// │ L │ L │ │ B │ │ R │ R │ |
+// ├───┼───┘ ┌───┼───┼───┐ └───┼───┤ |
+// │ L │ │ B │ B │ B │ │ R │ |
+// └───┘ ┌───┼───┼───┼───┼───┐ └───┘ |
+// │ B │ B │ B │ B │ B │ |
+// └───┴───┴───┴───┴───┘ |
+// (B = bottom) |
+// |
+// This sequence iterates over all the underlined triangular sequences level by |
+// level in increasing or decreasing order of distances. The increasing order of |
+// distances can be iterated using Iterator, while the decreasing order of |
+// distances can be iterated using ReverseIterator. The default coverage for |
+// internal triangular sequences is R, T, L, B forming spiral order. |
+// The iteration sequence generated by Iterator is as given below. |
+// (Iteration is considered counter-clockwise.) |
+// |
+// x 0 1 2 3 4 5 6 |
+// y ┌───┬───┬───┬───┬───┬───┬───┐ |
+// 0 │ 42│ 36│ 34│ 32│ 33│ 35│ 31│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 1 │ 40│ 20│ 16│ 14│ 15│ 13│ 29│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 2 │ 38│ 18│ 6│ 4│ 3│ 11│ 27│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 3 │ 37│ 17│ 5│ *│ 1│ 9│ 25│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 4 │ 39│ 19│ 7│ 8│ 2│ 10│ 26│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 5 │ 41│ 21│ 23│ 22│ 24│ 12│ 28│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 6 │ 43│ 47│ 45│ 44│ 46│ 48│ 30│ |
+// └───┴───┴───┴───┴───┴───┴───┘ |
+// |
+// The iteration sequence generated by ReverseIterator is as given below. |
+// (Iteration is considered clockwise.) |
+// |
+// x 0 1 2 3 4 5 6 |
+// y ┌───┬───┬───┬───┬───┬───┬───┐ |
+// 0 │ 7│ 13│ 15│ 17│ 16│ 14│ 18│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 1 │ 9│ 29│ 33│ 35│ 34│ 36│ 20│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 2 │ 11│ 31│ 43│ 45│ 46│ 38│ 22│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 3 │ 12│ 32│ 44│ *│ 48│ 40│ 24│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 4 │ 10│ 30│ 42│ 41│ 47│ 39│ 23│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 5 │ 8│ 28│ 26│ 27│ 25│ 37│ 21│ |
+// ├───┼───┼───┼───┼───┼───┼───┤ |
+// 6 │ 6│ 2│ 4│ 5│ 3│ 1│ 19│ |
+// └───┴───┴───┴───┴───┴───┴───┘ |
+class CC_EXPORT PyramidSequence { |
+ public: |
+ class Iterator; |
+ class ReverseIterator; |
+ |
+ PyramidSequence(); |
+ // The |around_index_rect| is the index rect computed around some index rect, |
+ // called as center index rect. In the above example, center index rect is |
+ // (3, 3, 3, 3), so around index rect for it is (2, 4, 2, 4). |
+ // The |consider_index_rect| is used to limit the coverage and the |
+ // |ignore_index_rect| is used to ignore the indices from coverage. For above |
+ // example consider index rect is (0, 6, 0, 6) and ignore index rect is |
+ // (-1, -1, -1, -1). |
+ // The width and height specify the width and height of the single index. This |
+ // is used for traversing indices based on their distances from center index |
+ // rect. |
+ PyramidSequence(const IndexRect& around_index_rect, |
+ const IndexRect& consider_index_rect, |
+ const IndexRect& ignore_index_rect, |
+ int width, |
+ int height); |
+ PyramidSequence(const PyramidSequence& other); |
+ PyramidSequence(PyramidSequence&& other); |
+ virtual ~PyramidSequence(); |
+ |
+ PyramidSequence& operator=(const PyramidSequence& other); |
+ PyramidSequence& operator=(PyramidSequence&& other); |
+ |
+ Iterator Begin(); |
+ ReverseIterator ReverseBegin(); |
+ |
+ class IteratorBase { |
+ public: |
+ IteratorBase(); |
+ IteratorBase(const IteratorBase& other); |
+ IteratorBase(IteratorBase&& other); |
+ ~IteratorBase(); |
+ |
+ IteratorBase& operator=(const IteratorBase& other); |
+ IteratorBase& operator=(IteratorBase&& other); |
+ |
+ operator bool() const; |
+ IteratorBase& operator++(); |
+ int index_x() const { return index_x_; } |
+ int index_y() const { return index_y_; } |
+ |
+ protected: |
+ explicit IteratorBase(const IndexRect& consider_index_rect, |
+ const IndexRect& ignore_index_rect); |
+ |
+ virtual void Setup() = 0; |
+ virtual bool IsEmpty() const = 0; |
+ virtual void Advance() = 0; |
+ virtual void UpdateCurrent() = 0; |
+ |
+ IndexRect consider_index_rect_; |
+ IndexRect ignore_index_rect_; |
+ int index_x_; |
+ int index_y_; |
+ |
+ TriangularSequence::IteratorBase* current_triangular_sequence_it_; |
+ }; |
+ |
+ class Iterator : public IteratorBase { |
+ public: |
+ Iterator(); |
+ Iterator(const Iterator& other); |
+ Iterator(Iterator&& other); |
+ ~Iterator(); |
+ |
+ Iterator& operator=(const Iterator& other); |
+ Iterator& operator=(Iterator&& other); |
+ |
+ private: |
+ explicit Iterator(PyramidSequence* pyramid_sequence); |
+ |
+ void Setup() override; |
+ bool IsEmpty() const override; |
+ void Advance() override; |
+ void UpdateCurrent() override; |
+ |
+ TriangularSequence::IteratorBase* GetNextTriangularSequenceIterator(); |
+ |
+ LinearSequence::Iterator current_traversal_sequence_iterator_; |
+ std::vector<TriangularSequence::Iterator> triangular_sequence_iterators_; |
+ |
+ friend class PyramidSequence; |
+ }; |
+ |
+ class ReverseIterator : public IteratorBase { |
+ public: |
+ ReverseIterator(); |
+ ReverseIterator(const ReverseIterator& other); |
+ ReverseIterator(ReverseIterator&& other); |
+ ~ReverseIterator(); |
+ |
+ ReverseIterator& operator=(const ReverseIterator& other); |
+ ReverseIterator& operator=(ReverseIterator&& other); |
+ |
+ private: |
+ explicit ReverseIterator(PyramidSequence* pyramid_sequence); |
+ |
+ void Setup() override; |
+ bool IsEmpty() const override; |
+ void Advance() override; |
+ void UpdateCurrent() override; |
+ |
+ TriangularSequence::IteratorBase* |
+ GetNextTriangularSequenceReverseIterator(); |
+ |
+ LinearSequence::ReverseIterator |
+ current_traversal_sequence_reverse_iterator_; |
+ std::vector<TriangularSequence::ReverseIterator> |
+ triangular_sequence_reverse_iterators_; |
+ |
+ friend class PyramidSequence; |
+ }; |
+ |
+ private: |
+ void EmplaceAt(int position, TriangularSequence&& triangular_sequence); |
+ |
+ IndexRect consider_index_rect_; |
+ IndexRect ignore_index_rect_; |
+ TriangularSequence::Vector triangular_sequences_; |
+}; |
+ |
+} // namespace cc |
+ |
+#endif // CC_BASE_PYRAMID_SEQUENCE_H_ |