blob: 8208c3ce97c0f7ba00ffd2154151477bf478a98c [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_MAGIC_H_
#define SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_MAGIC_H_
#include <stdint.h>
#include <zircon/assert.h>
namespace amlogic_decoder {
// Once we're on C++20 we can make MagicNumber a class with a uint64_t in it and avoid the strange
// enum without any declared values. Also we could keep the file and line around if we wanted
// without breaking ergonomics, if we want.
enum class MagicNumberValue : uint64_t {};
constexpr MagicNumberValue MagicNumber(const char* file, int line) {
struct impl {
static constexpr uint32_t FileMagic(const char* file) {
return file[0] ? FileMagic(file + 1) * 13 + static_cast<uint32_t>(file[0]) : 0;
}
};
return static_cast<MagicNumberValue>(impl::FileMagic(file) + line);
}
template <MagicNumberValue magic_number>
class Magic {
public:
Magic() = default;
Magic(const Magic& to_copy) {
ZX_ASSERT_MSG(to_copy.magic_ == kMagic,
"Magic::Magic(const Magic&) copy source invalid - value: 0x%lx expected 0x%lx",
to_copy.magic_, kMagic);
magic_ = to_copy.magic_;
}
Magic& operator=(const Magic& to_copy) {
ZX_ASSERT_MSG(
to_copy.magic_ == kMagic,
"Magic::operator=(const Magic&) copy source invalid - value: 0x%lx expected 0x%lx",
to_copy.magic_, kMagic);
magic_ = to_copy.magic_;
return *this;
}
Magic(Magic<magic_number>&& to_move) noexcept {
ZX_ASSERT_MSG(to_move.magic_ == kMagic,
"Magic::Magic(Magic&&) move source invalid - value: 0x%lx expected: 0x%lx",
to_move.magic_, kMagic);
magic_ = to_move.magic_;
to_move.magic_ = kMovedOut;
}
~Magic() {
ZX_ASSERT_MSG(magic_ == kMagic || magic_ == kMovedOut,
"Magic::~Magic() found corrupted magic - value: 0x%lx expected 0x%lx or 0x%lx",
magic_, kMagic, kMovedOut);
magic_ = kGone;
}
void AssertOk() {
ZX_ASSERT_MSG(magic_ == kMagic, "Magic::AssertOk() failing - value: 0x%lx expected: 0x%lx",
magic_, kMagic);
}
private:
using MagicType = uint64_t;
static constexpr MagicType kMagic = static_cast<MagicType>(magic_number);
static constexpr MagicType kGone = 0xBADC0DEBADC0DE;
static constexpr MagicType kMovedOut = 0xDEAD1DEAD1DEAD1;
MagicType magic_ = kMagic;
};
} // namespace amlogic_decoder
#endif // SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_MAGIC_H_