Skip to content

Commit

Permalink
Make the enum mapper enumeratable
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianFeldmann committed Jul 25, 2024
1 parent 6e5cef7 commit 483c73a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 19 deletions.
73 changes: 62 additions & 11 deletions YUViewLib/src/common/EnumMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

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

Expand All @@ -44,7 +44,56 @@ using namespace std::string_view_literals;

template <class T, std::size_t N> struct EnumMapper
{
using VALUE_AND_NAME = std::pair<T, std::string_view>;
public:
using ValueNamePair = std::pair<T, std::string_view>;
using ItemArray = std::array<T, 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)
{
Expand All @@ -66,12 +115,14 @@ template <class T, std::size_t N> struct EnumMapper

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

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

constexpr std::optional<T> getValueCaseInsensitive(const std::string_view name) const
Expand Down Expand Up @@ -123,16 +174,16 @@ template <class T, std::size_t N> struct EnumMapper
return this->items.at(index);
}

constexpr const std::array<T, N> &getItems() const { return this->items; }
constexpr const std::array<std::string_view, N> &getNames() const { return this->names; }
constexpr const ItemArray &getItems() const { return this->items; }
constexpr const NameArray &getNames() const { return this->names; }

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

template <typename TArg, typename... Args>
constexpr void addElementsRecursively(const std::size_t index, TArg first, Args... args)
{
static_assert(std::is_same<VALUE_AND_NAME, TArg>());
static_assert(std::is_same<ValueNamePair, TArg>());

const auto [value, name] = first;
this->items[index] = value;
Expand All @@ -141,6 +192,6 @@ template <class T, std::size_t N> struct EnumMapper
addElementsRecursively(index + 1, args...);
}

std::array<T, N> items{};
std::array<std::string_view, N> names{};
ItemArray items{};
NameArray names{};
};
9 changes: 4 additions & 5 deletions YUViewLib/src/video/rgb/PixelFormatRGBGuess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ std::optional<PixelFormatRGB> findPixelFormatIndicatorInName(const std::string &
std::string matcher = "(?:_|\\.|-)(";

std::map<std::string, PixelFormatRGB> stringToMatchingFormat;
for (const auto channelOrder : ChannelOrderMapper.getItems())
for (const auto [channelOrder, channelOrderName] : ChannelOrderMapper)
{
for (auto alphaMode : {AlphaMode::None, AlphaMode::First, AlphaMode::Last})
{
Expand All @@ -68,7 +68,7 @@ std::optional<PixelFormatRGB> findPixelFormatIndicatorInName(const std::string &
std::string name;
if (alphaMode == AlphaMode::First)
name += "a";
name += functions::toLower(ChannelOrderMapper.getName(channelOrder));
name += functions::toLower(channelOrderName);
if (alphaMode == AlphaMode::Last)
name += "a";
name += bitDepthString + endiannessName;
Expand All @@ -95,12 +95,11 @@ std::optional<PixelFormatRGB> findPixelFormatIndicatorInName(const std::string &

std::optional<PixelFormatRGB> findPixelFormatFromFileExtension(const std::string &ext)
{
for (auto channelOrder : ChannelOrderMapper.getItems())
for (const auto [channelOrder, name] : ChannelOrderMapper)
{
if (functions::toLower(ext) == functions::toLower(ChannelOrderMapper.getName(channelOrder)))
if (functions::toLower(ext) == functions::toLower(name))
return PixelFormatRGB(8, DataLayout::Packed, channelOrder);
}

return {};
}

Expand Down
4 changes: 2 additions & 2 deletions YUViewLib/src/video/rgb/videoHandlerRGB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@

#include "videoHandlerRGB.h"

#include <common/EnumMapper.h>
#include <common/FileInfo.h>
#include <common/Formatting.h>
#include <common/Functions.h>
#include <common/FunctionsGui.h>
#include <common/EnumMapper.h>
#include <video/rgb/ConversionRGB.h>
#include <video/rgb/PixelFormatRGBGuess.h>
#include <video/rgb/videoHandlerRGBCustomFormatDialog.h>
Expand Down Expand Up @@ -303,7 +303,7 @@ void videoHandlerRGB::slotDisplayOptionsChanged()
{
{
const auto index = ui.colorComponentsComboBox->currentIndex();
if (index >= 0 && static_cast<std::size_t>(index) < ComponentShowMapper.size())
if (index >= 0)
if (const auto mode = ComponentShowMapper.at(static_cast<std::size_t>(index)))
this->componentDisplayMode = *mode;
}
Expand Down
1 change: 0 additions & 1 deletion YUViewUnitTest/video/rgb/ConversionRGBTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

#include "gtest/gtest.h"

#include <common/EnumMapper.h>
#include <video/rgb/ConversionRGB.h>

using ::testing::Combine;
Expand Down

0 comments on commit 483c73a

Please sign in to comment.