1*103e46e4SHarish Mahendrakar // Copyright (c) 2016 The WebM project authors. All Rights Reserved. 2*103e46e4SHarish Mahendrakar // 3*103e46e4SHarish Mahendrakar // Use of this source code is governed by a BSD-style license 4*103e46e4SHarish Mahendrakar // that can be found in the LICENSE file in the root of the source 5*103e46e4SHarish Mahendrakar // tree. An additional intellectual property rights grant can be found 6*103e46e4SHarish Mahendrakar // in the file PATENTS. All contributing project authors may 7*103e46e4SHarish Mahendrakar // be found in the AUTHORS file in the root of the source tree. 8*103e46e4SHarish Mahendrakar #ifndef SRC_ANCESTORY_H_ 9*103e46e4SHarish Mahendrakar #define SRC_ANCESTORY_H_ 10*103e46e4SHarish Mahendrakar 11*103e46e4SHarish Mahendrakar #include <cassert> 12*103e46e4SHarish Mahendrakar #include <cstddef> 13*103e46e4SHarish Mahendrakar #include <iterator> 14*103e46e4SHarish Mahendrakar 15*103e46e4SHarish Mahendrakar #include "webm/id.h" 16*103e46e4SHarish Mahendrakar 17*103e46e4SHarish Mahendrakar namespace webm { 18*103e46e4SHarish Mahendrakar 19*103e46e4SHarish Mahendrakar // Represents an element's ancestory in descending order. For example, the 20*103e46e4SHarish Mahendrakar // Id::kTrackNumber element has an ancestory of {Id::kSegment, Id::kTracks, 21*103e46e4SHarish Mahendrakar // Id::kTrackEntry}. 22*103e46e4SHarish Mahendrakar class Ancestory { 23*103e46e4SHarish Mahendrakar public: 24*103e46e4SHarish Mahendrakar // Constructs an empty ancestory. 25*103e46e4SHarish Mahendrakar Ancestory() = default; 26*103e46e4SHarish Mahendrakar 27*103e46e4SHarish Mahendrakar Ancestory(const Ancestory&) = default; 28*103e46e4SHarish Mahendrakar Ancestory(Ancestory&&) = default; 29*103e46e4SHarish Mahendrakar Ancestory& operator=(const Ancestory&) = default; 30*103e46e4SHarish Mahendrakar Ancestory& operator=(Ancestory&&) = default; 31*103e46e4SHarish Mahendrakar 32*103e46e4SHarish Mahendrakar // Returns the ancestory with the top-level parent removed. For example, if 33*103e46e4SHarish Mahendrakar // the current ancestory is {Id::kSegment, Id::kTracks, Id::kTrackEntry}, next 34*103e46e4SHarish Mahendrakar // will return {Id::kTracks, Id::kTrackEntry}. This must not be called if the 35*103e46e4SHarish Mahendrakar // ancestory is empty. next()36*103e46e4SHarish Mahendrakar Ancestory next() const { 37*103e46e4SHarish Mahendrakar assert(begin_ < end_); 38*103e46e4SHarish Mahendrakar Ancestory copy = *this; 39*103e46e4SHarish Mahendrakar ++copy.begin_; 40*103e46e4SHarish Mahendrakar return copy; 41*103e46e4SHarish Mahendrakar } 42*103e46e4SHarish Mahendrakar 43*103e46e4SHarish Mahendrakar // Gets the Id of the top-level parent. For example, if the current ancestory 44*103e46e4SHarish Mahendrakar // is {Id::kSegment, Id::kTracks, Id::kTrackEntry}, id will return 45*103e46e4SHarish Mahendrakar // Id::kSegment. This must not be called if the ancestory is empty. id()46*103e46e4SHarish Mahendrakar Id id() const { 47*103e46e4SHarish Mahendrakar assert(begin_ < end_); 48*103e46e4SHarish Mahendrakar return *begin_; 49*103e46e4SHarish Mahendrakar } 50*103e46e4SHarish Mahendrakar 51*103e46e4SHarish Mahendrakar // Returns true if the ancestory is empty. empty()52*103e46e4SHarish Mahendrakar bool empty() const { return begin_ == end_; } 53*103e46e4SHarish Mahendrakar 54*103e46e4SHarish Mahendrakar // Looks up the ancestory of the given id. Returns true and sets ancestory if 55*103e46e4SHarish Mahendrakar // the element's ancestory could be deduced. Global elements (i.e. Id::kVoid) 56*103e46e4SHarish Mahendrakar // and unknown elements can't have their ancestory deduced. 57*103e46e4SHarish Mahendrakar static bool ById(Id id, Ancestory* ancestory); 58*103e46e4SHarish Mahendrakar 59*103e46e4SHarish Mahendrakar private: 60*103e46e4SHarish Mahendrakar // Constructs an Ancestory using the first count elements of ancestory. 61*103e46e4SHarish Mahendrakar // ancestory must have static storage duration. 62*103e46e4SHarish Mahendrakar template <std::size_t N> Ancestory(const Id (& ancestory)[N],std::size_t count)63*103e46e4SHarish Mahendrakar Ancestory(const Id (&ancestory)[N], std::size_t count) 64*103e46e4SHarish Mahendrakar : begin_(ancestory), end_(ancestory + count) { 65*103e46e4SHarish Mahendrakar assert(count <= N); 66*103e46e4SHarish Mahendrakar } 67*103e46e4SHarish Mahendrakar 68*103e46e4SHarish Mahendrakar // The following invariants apply to begin_ and end_: 69*103e46e4SHarish Mahendrakar // begin_ <= end_ 70*103e46e4SHarish Mahendrakar // (begin_ == end_) || (std::begin(kIds) <= begin_ && end_ <= std::end(kIds)) 71*103e46e4SHarish Mahendrakar 72*103e46e4SHarish Mahendrakar // The beginning (inclusive) of the sequence of IDs in kIds that defines the 73*103e46e4SHarish Mahendrakar // ancestory. 74*103e46e4SHarish Mahendrakar const Id* begin_ = nullptr; 75*103e46e4SHarish Mahendrakar 76*103e46e4SHarish Mahendrakar // The ending (exclusive) of the sequence of IDs in kIds that defines the 77*103e46e4SHarish Mahendrakar // ancestory. 78*103e46e4SHarish Mahendrakar const Id* end_ = nullptr; 79*103e46e4SHarish Mahendrakar }; 80*103e46e4SHarish Mahendrakar 81*103e46e4SHarish Mahendrakar } // namespace webm 82*103e46e4SHarish Mahendrakar 83*103e46e4SHarish Mahendrakar #endif // SRC_ANCESTORY_H_ 84