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