• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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