Skip to content

Commit

Permalink
Enum mapper is now just a std::array with some additional functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianFeldmann committed Dec 19, 2024
1 parent d1323c5 commit 0b9f935
Show file tree
Hide file tree
Showing 32 changed files with 380 additions and 415 deletions.
144 changes: 42 additions & 102 deletions YUViewLib/src/common/EnumMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,166 +32,106 @@

#pragma once

#include <algorithm>
#include <array>
#include <iterator>
#include <optional>
#include <string_view>

#include "Functions.h"

using namespace std::string_view_literals;

template <class ValueType, std::size_t N> struct EnumMapper
template <class ValueType, std::size_t N>
struct EnumMapper : public std::array<std::pair<ValueType, std::string_view>, N>
{
public:
using ValueNamePair = std::pair<ValueType, std::string_view>;
using ItemArray = std::array<ValueType, N>;
using ItemIterator = typename ItemArray::const_iterator;
using NameArray = std::array<std::string_view, N>;
using NameIterator = typename NameArray::const_iterator;

struct Iterator
{
using iterator_category = std::forward_iterator_tag;
using difference_type = int;
using value_type = ValueNamePair;
using pointer = ValueNamePair *;
using reference = ValueNamePair &;

Iterator(const ItemIterator itItem, const NameIterator itName) : itItem(itItem), itName(itName)
{
this->valueNamePair.first = *itItem;
this->valueNamePair.second = *itName;
}

ValueNamePair const &operator*() const { return this->valueNamePair; }
ValueNamePair const *operator->() const { return &this->valueNamePair; }

Iterator &operator++()
{
++this->itItem;
++this->itName;
this->valueNamePair.first = *this->itItem;
this->valueNamePair.second = *this->itName;
return *this;
}

friend bool operator==(const Iterator &a, const Iterator &b)
{
return a.itItem == b.itItem && a.itName == b.itName;
};
friend bool operator!=(const Iterator &a, const Iterator &b)
{
return a.itItem != b.itItem || a.itName != b.itName;
};

private:
ItemIterator itItem;
NameIterator itName;
ValueNamePair valueNamePair{};
};

Iterator begin() const { return Iterator(this->items.begin(), this->names.begin()); }
Iterator end() const { return Iterator(this->items.end(), this->names.end()); }

template <typename... Args> constexpr EnumMapper(Args... args)
constexpr std::optional<ValueType> getValue(const std::string_view name) const
{
static_assert(sizeof...(Args) == N);
this->addElementsRecursively(0, args...);
}
const auto it =
std::find_if(this->begin(),
this->end(),
[&name](const ValueNamePair &pair) { return pair.second == name; });

constexpr std::size_t size() const { return N; }
if (it == this->end())
return {};

constexpr std::string_view getName(const ValueType value) const
{
const auto it = std::find(this->items.begin(), this->items.end(), value);
if (it == this->items.end())
throw std::logic_error(
"The given type T was not registered in the mapper. All possible enums must be mapped.");
const auto index = std::distance(this->items.begin(), it);
return this->names.at(index);
return it->first;
}

constexpr std::optional<ValueType> getValue(const std::string_view name) const
constexpr std::string_view getName(const ValueType &value) const
{
const auto it =
std::find_if(this->begin(),
this->end(),
[&name](const ValueNamePair &pair) { return pair.second == name; });
[&value](const ValueNamePair &pair) { return pair.first == value; });

if (it == this->end())
return {};

return it->first;
return it->second;
}

constexpr std::optional<ValueType> getValueCaseInsensitive(const std::string_view name) const
{
const auto compareToNameLowercase = [&name](const std::string_view str)
const auto compareToNameLowercase = [&name](const ValueNamePair &valueNamePair)
{
if (name.length() != str.length())
if (name.length() != valueNamePair.second.length())
return false;
for (std::size_t i = 0; i < name.length(); ++i)
{
if (std::tolower(name.at(i)) != std::tolower(str.at(i)))
if (std::tolower(name.at(i)) != std::tolower(valueNamePair.second.at(i)))
return false;
}
return true;
};

const auto it = std::find_if(this->names.begin(), this->names.end(), compareToNameLowercase);
if (it == this->names.end())
const auto it = std::find_if(this->begin(), this->end(), compareToNameLowercase);
if (it == this->end())
return {};

const auto index = std::distance(this->names.begin(), it);
return this->items.at(index);
return it->first;
}

std::optional<ValueType> getValueFromNameOrIndex(const std::string_view nameOrIndex) const
{
if (auto index = functions::toUnsigned(nameOrIndex))
if (*index < N)
return this->items.at(*index);
return this->at(*index).first;

return this->getValue(nameOrIndex);
}

constexpr size_t indexOf(const ValueType value) const
{
const auto it = std::find(this->items.begin(), this->items.end(), value);
if (it == this->items.end())
const auto it =
std::find_if(this->begin(),
this->end(),
[&value](const ValueNamePair &pair) { return pair.first == value; });

if (it == this->end())
throw std::logic_error(
"The given type T was not registered in the mapper. All possible enums must be mapped.");

const auto index = std::distance(this->items.begin(), it);
const auto index = std::distance(this->begin(), it);
return index;
}

constexpr std::optional<ValueType> at(const size_t index) const
constexpr std::optional<ValueType> getValueAt(const size_t index) const
{
if (index >= N)
return {};
return this->items.at(index);
return this->at(index).first;
}

constexpr const ItemArray &getValues() const { return this->items; }
constexpr const NameArray &getNames() const { return this->names; }

private:
constexpr void addElementsRecursively(const std::size_t) {};

template <typename ArgumentType, typename... Args>
constexpr void addElementsRecursively(const std::size_t index, ArgumentType first, Args... args)
constexpr std::array<ValueType, N> getValues() const
{
static_assert(std::is_same<ValueNamePair, ArgumentType>());

const auto [value, name] = first;
this->items[index] = value;
this->names[index] = name;

addElementsRecursively(index + 1, args...);
std::array<ValueType, N> values;
for (std::size_t i = 0; i < N; ++i)
values[i] = this->at(i).first;
return values;
}

ItemArray items{};
NameArray names{};
constexpr std::array<std::string_view, N> getNames() const
{
std::array<std::string_view, N> names;
for (std::size_t i = 0; i < N; ++i)
names[i] = this->at(i).second;
return names;
}
};
16 changes: 8 additions & 8 deletions YUViewLib/src/decoder/decoderBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ enum class DecoderEngine
FFMpeg // The FFMpeg decoder
};

constexpr EnumMapper<DecoderEngine, 7>
DecoderEngineMapper(std::make_pair(DecoderEngine::Invalid, "Invalid"sv),
std::make_pair(DecoderEngine::Libde265, "Libde265"sv),
std::make_pair(DecoderEngine::HM, "HM"sv),
std::make_pair(DecoderEngine::VTM, "VTM"sv),
std::make_pair(DecoderEngine::VVDec, "VVDec"sv),
std::make_pair(DecoderEngine::Dav1d, "Dav1d"sv),
std::make_pair(DecoderEngine::FFMpeg, "FFMpeg"sv));
constexpr EnumMapper<DecoderEngine, 7> DecoderEngineMapper = {
std::make_pair(DecoderEngine::Invalid, "Invalid"),
std::make_pair(DecoderEngine::Libde265, "Libde265"),
std::make_pair(DecoderEngine::HM, "HM"),
std::make_pair(DecoderEngine::VTM, "VTM"),
std::make_pair(DecoderEngine::VVDec, "VVDec"),
std::make_pair(DecoderEngine::Dav1d, "Dav1d"),
std::make_pair(DecoderEngine::FFMpeg, "FFMpeg")};

const auto DecodersHEVC =
std::vector<DecoderEngine>({DecoderEngine::Libde265, DecoderEngine::HM, DecoderEngine::FFMpeg});
Expand Down
12 changes: 6 additions & 6 deletions YUViewLib/src/filesource/FileSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ enum class InputFormat
Libav // This is some sort of container file which we will read using libavformat
};

constexpr EnumMapper<InputFormat, 5>
InputFormatMapper(std::make_pair(InputFormat::Invalid, "Invalid"sv),
std::make_pair(InputFormat::AnnexBHEVC, "AnnexBHEVC"sv),
std::make_pair(InputFormat::AnnexBAVC, "AnnexBAVC"sv),
std::make_pair(InputFormat::AnnexBVVC, "AnnexBVVC"sv),
std::make_pair(InputFormat::Libav, "Libav"sv));
constexpr EnumMapper<InputFormat, 5> InputFormatMapper = {
std::make_pair(InputFormat::Invalid, "Invalid"),
std::make_pair(InputFormat::AnnexBHEVC, "AnnexBHEVC"),
std::make_pair(InputFormat::AnnexBAVC, "AnnexBAVC"),
std::make_pair(InputFormat::AnnexBVVC, "AnnexBVVC"),
std::make_pair(InputFormat::Libav, "Libav")};

/* The FileSource class provides functions for accessing files. Besides the reading of
* certain blocks of the file, it also directly provides information on the file for the
Expand Down
50 changes: 25 additions & 25 deletions YUViewLib/src/parser/AVC/nal_unit_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,31 @@ enum class NalType
RESERVED_23
};

constexpr EnumMapper<NalType, 24> NalTypeMapper(
std::make_pair(NalType::UNSPECIFIED, "UNSPECIFIED"sv),
std::make_pair(NalType::CODED_SLICE_NON_IDR, "CODED_SLICE_NON_IDR"sv),
std::make_pair(NalType::CODED_SLICE_DATA_PARTITION_A, "CODED_SLICE_DATA_PARTITION_A"sv),
std::make_pair(NalType::CODED_SLICE_DATA_PARTITION_B, "CODED_SLICE_DATA_PARTITION_B"sv),
std::make_pair(NalType::CODED_SLICE_DATA_PARTITION_C, "CODED_SLICE_DATA_PARTITION_C"sv),
std::make_pair(NalType::CODED_SLICE_IDR, "CODED_SLICE_IDR"sv),
std::make_pair(NalType::SEI, "SEI"sv),
std::make_pair(NalType::SPS, "SPS"sv),
std::make_pair(NalType::PPS, "PPS"sv),
std::make_pair(NalType::AUD, "AUD"sv),
std::make_pair(NalType::END_OF_SEQUENCE, "END_OF_SEQUENCE"sv),
std::make_pair(NalType::END_OF_STREAM, "END_OF_STREAM"sv),
std::make_pair(NalType::FILLER, "FILLER"sv),
std::make_pair(NalType::SPS_EXT, "SPS_EXT"sv),
std::make_pair(NalType::PREFIX_NAL, "PREFIX_NAL"sv),
std::make_pair(NalType::SUBSET_SPS, "SUBSET_SPS"sv),
std::make_pair(NalType::DEPTH_PARAMETER_SET, "DEPTH_PARAMETER_SET"sv),
std::make_pair(NalType::RESERVED_17, "RESERVED_17"sv),
std::make_pair(NalType::RESERVED_18, "RESERVED_18"sv),
std::make_pair(NalType::CODED_SLICE_AUX, "CODED_SLICE_AUX"sv),
std::make_pair(NalType::CODED_SLICE_EXTENSION, "CODED_SLICE_EXTENSION"sv),
std::make_pair(NalType::CODED_SLICE_EXTENSION_DEPTH_MAP, "CODED_SLICE_EXTENSION_DEPTH_MAP"sv),
std::make_pair(NalType::RESERVED_22, "RESERVED_22"sv),
std::make_pair(NalType::RESERVED_23, "RESERVED_23"sv));
constexpr EnumMapper<NalType, 24> NalTypeMapper = {
std::make_pair(NalType::UNSPECIFIED, "UNSPECIFIED"),
std::make_pair(NalType::CODED_SLICE_NON_IDR, "CODED_SLICE_NON_IDR"),
std::make_pair(NalType::CODED_SLICE_DATA_PARTITION_A, "CODED_SLICE_DATA_PARTITION_A"),
std::make_pair(NalType::CODED_SLICE_DATA_PARTITION_B, "CODED_SLICE_DATA_PARTITION_B"),
std::make_pair(NalType::CODED_SLICE_DATA_PARTITION_C, "CODED_SLICE_DATA_PARTITION_C"),
std::make_pair(NalType::CODED_SLICE_IDR, "CODED_SLICE_IDR"),
std::make_pair(NalType::SEI, "SEI"),
std::make_pair(NalType::SPS, "SPS"),
std::make_pair(NalType::PPS, "PPS"),
std::make_pair(NalType::AUD, "AUD"),
std::make_pair(NalType::END_OF_SEQUENCE, "END_OF_SEQUENCE"),
std::make_pair(NalType::END_OF_STREAM, "END_OF_STREAM"),
std::make_pair(NalType::FILLER, "FILLER"),
std::make_pair(NalType::SPS_EXT, "SPS_EXT"),
std::make_pair(NalType::PREFIX_NAL, "PREFIX_NAL"),
std::make_pair(NalType::SUBSET_SPS, "SUBSET_SPS"),
std::make_pair(NalType::DEPTH_PARAMETER_SET, "DEPTH_PARAMETER_SET"),
std::make_pair(NalType::RESERVED_17, "RESERVED_17"),
std::make_pair(NalType::RESERVED_18, "RESERVED_18"),
std::make_pair(NalType::CODED_SLICE_AUX, "CODED_SLICE_AUX"),
std::make_pair(NalType::CODED_SLICE_EXTENSION, "CODED_SLICE_EXTENSION"),
std::make_pair(NalType::CODED_SLICE_EXTENSION_DEPTH_MAP, "CODED_SLICE_EXTENSION_DEPTH_MAP"),
std::make_pair(NalType::RESERVED_22, "RESERVED_22"),
std::make_pair(NalType::RESERVED_23, "RESERVED_23")};

class nal_unit_header
{
Expand Down
Loading

0 comments on commit 0b9f935

Please sign in to comment.