An index for specifying a particular nested subshape within a shape. Used in ShapeUtil::GetSubshape and other interfaces. Shapes are recursive data structures (trees) and ShapeIndex defines a path through the tree where each element of ShapeIndex indexes into a tuple (or nested tuple) within the shape. For a non-nested tuple, an index has a single element. For example, given a 3-element tuple (a,
| 65 | // ShapeIndex is a trivial wrapper around std::vector with a minimum number of |
| 66 | // methods implemented. |
| 67 | class ShapeIndex { |
| 68 | public: |
| 69 | ShapeIndex() = default; |
| 70 | ShapeIndex(std::initializer_list<int64> init) : indices_(init) {} |
| 71 | template <typename InputIt> |
| 72 | ShapeIndex(InputIt start, InputIt end) : indices_(start, end) {} |
| 73 | |
| 74 | explicit ShapeIndex(ShapeIndexView v); |
| 75 | |
| 76 | bool empty() const { return indices_.empty(); } |
| 77 | size_t size() const { return indices_.size(); } |
| 78 | void push_back(int64 value) { indices_.push_back(value); } |
| 79 | void pop_back() { indices_.pop_back(); } |
| 80 | |
| 81 | // push_front is O(n), but shapes don't usually have a ton of dimensions. |
| 82 | void push_front(int64 value) { indices_.insert(indices_.begin(), value); } |
| 83 | |
| 84 | using container_type = absl::InlinedVector<int64, 2>; |
| 85 | |
| 86 | container_type::const_iterator begin() const { return indices_.begin(); } |
| 87 | container_type::const_iterator end() const { return indices_.end(); } |
| 88 | container_type::iterator begin() { return indices_.begin(); } |
| 89 | container_type::iterator end() { return indices_.end(); } |
| 90 | |
| 91 | const int64* data() const { return indices_.data(); } |
| 92 | |
| 93 | int64 back() const { return indices_.back(); } |
| 94 | int64& back() { return indices_.back(); } |
| 95 | |
| 96 | const int64& operator[](size_t i) const { return indices_[i]; } |
| 97 | int64& operator[](size_t i) { return indices_[i]; } |
| 98 | |
| 99 | bool operator==(const ShapeIndex& other) const { |
| 100 | return indices_ == other.indices_; |
| 101 | } |
| 102 | bool operator!=(const ShapeIndex& other) const { return !(*this == other); } |
| 103 | bool operator<(const ShapeIndex& other) const { |
| 104 | return indices_ < other.indices_; |
| 105 | } |
| 106 | |
| 107 | string ToString() const; |
| 108 | |
| 109 | template <typename H> |
| 110 | friend H AbslHashValue(H h, const ShapeIndex& index) { |
| 111 | return H::combine(std::move(h), index.indices_); |
| 112 | } |
| 113 | |
| 114 | private: |
| 115 | container_type indices_; |
| 116 | }; |
| 117 | |
| 118 | // A view into a ShapeIndex as above, with the cheap/easy ability to consume the |
| 119 | // value at the front of the view. |