You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.7 KiB
84 lines
2.7 KiB
// Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style license
|
|
// that can be found in the LICENSE file in the root of the source
|
|
// tree. An additional intellectual property rights grant can be found
|
|
// in the file PATENTS. All contributing project authors may
|
|
// be found in the AUTHORS file in the root of the source tree.
|
|
#ifndef SRC_ANCESTORY_H_
|
|
#define SRC_ANCESTORY_H_
|
|
|
|
#include <cassert>
|
|
#include <cstddef>
|
|
#include <iterator>
|
|
|
|
#include "webm/id.h"
|
|
|
|
namespace webm {
|
|
|
|
// Represents an element's ancestory in descending order. For example, the
|
|
// Id::kTrackNumber element has an ancestory of {Id::kSegment, Id::kTracks,
|
|
// Id::kTrackEntry}.
|
|
class Ancestory {
|
|
public:
|
|
// Constructs an empty ancestory.
|
|
Ancestory() = default;
|
|
|
|
Ancestory(const Ancestory&) = default;
|
|
Ancestory(Ancestory&&) = default;
|
|
Ancestory& operator=(const Ancestory&) = default;
|
|
Ancestory& operator=(Ancestory&&) = default;
|
|
|
|
// Returns the ancestory with the top-level parent removed. For example, if
|
|
// the current ancestory is {Id::kSegment, Id::kTracks, Id::kTrackEntry}, next
|
|
// will return {Id::kTracks, Id::kTrackEntry}. This must not be called if the
|
|
// ancestory is empty.
|
|
Ancestory next() const {
|
|
assert(begin_ < end_);
|
|
Ancestory copy = *this;
|
|
++copy.begin_;
|
|
return copy;
|
|
}
|
|
|
|
// Gets the Id of the top-level parent. For example, if the current ancestory
|
|
// is {Id::kSegment, Id::kTracks, Id::kTrackEntry}, id will return
|
|
// Id::kSegment. This must not be called if the ancestory is empty.
|
|
Id id() const {
|
|
assert(begin_ < end_);
|
|
return *begin_;
|
|
}
|
|
|
|
// Returns true if the ancestory is empty.
|
|
bool empty() const { return begin_ == end_; }
|
|
|
|
// Looks up the ancestory of the given id. Returns true and sets ancestory if
|
|
// the element's ancestory could be deduced. Global elements (i.e. Id::kVoid)
|
|
// and unknown elements can't have their ancestory deduced.
|
|
static bool ById(Id id, Ancestory* ancestory);
|
|
|
|
private:
|
|
// Constructs an Ancestory using the first count elements of ancestory.
|
|
// ancestory must have static storage duration.
|
|
template <std::size_t N>
|
|
Ancestory(const Id (&ancestory)[N], std::size_t count)
|
|
: begin_(ancestory), end_(ancestory + count) {
|
|
assert(count <= N);
|
|
}
|
|
|
|
// The following invariants apply to begin_ and end_:
|
|
// begin_ <= end_
|
|
// (begin_ == end_) || (std::begin(kIds) <= begin_ && end_ <= std::end(kIds))
|
|
|
|
// The beginning (inclusive) of the sequence of IDs in kIds that defines the
|
|
// ancestory.
|
|
const Id* begin_ = nullptr;
|
|
|
|
// The ending (exclusive) of the sequence of IDs in kIds that defines the
|
|
// ancestory.
|
|
const Id* end_ = nullptr;
|
|
};
|
|
|
|
} // namespace webm
|
|
|
|
#endif // SRC_ANCESTORY_H_
|