1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2022 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
// Helpers for generic enums, which underlying vals must be continuous,
// starting with 0. MaxValue here must not be real member of enum, but rather
// "position, following the last element"
#ifndef VC_UTILS_GENERAL_ENUMUTILS_H
#define VC_UTILS_GENERAL_ENUMUTILS_H
#include "Probe/Assertion.h"
#include <iterator>
#include <type_traits>
namespace vc {
template <typename Enum, Enum LastValue> class EnumIterator final {
private:
// Just an enum
static_assert(
std::is_same_v<std::remove_cv_t<std::remove_reference_t<Enum>>, Enum>);
static_assert(std::is_integral_v<std::underlying_type_t<Enum>>);
Enum CurVal;
public:
using difference_type = std::ptrdiff_t;
using value_type = Enum;
using pointer = void;
using reference = Enum const &;
using iterator_category = std::bidirectional_iterator_tag;
public:
constexpr EnumIterator()
: CurVal(static_cast<Enum>(
static_cast<std::underlying_type_t<Enum>>(LastValue) + 1)) {}
constexpr EnumIterator(Enum Value) : CurVal(Value) {
IGC_ASSERT(checkEnumValue(CurVal));
}
constexpr reference operator*() const {
IGC_ASSERT(checkEnumValue(CurVal));
return CurVal;
}
constexpr EnumIterator &operator++() {
IGC_ASSERT(checkEnumValue(CurVal));
CurVal = static_cast<Enum>(
static_cast<std::underlying_type_t<Enum>>(CurVal) + 1);
return *this;
}
constexpr EnumIterator operator++(int) {
IGC_ASSERT(checkEnumValue(CurVal));
auto RetVal = CurVal;
operator++();
return RetVal;
}
constexpr EnumIterator &operator--() {
CurVal = static_cast<Enum>(
static_cast<std::underlying_type_t<Enum>>(CurVal) - 1);
IGC_ASSERT(checkEnumValue(CurVal));
return *this;
}
constexpr EnumIterator operator--(int) {
auto RetVal = CurVal;
operator--();
IGC_ASSERT(checkEnumValue(CurVal));
return RetVal;
}
constexpr friend bool operator==(const EnumIterator &lhs,
const EnumIterator &rhs) {
return lhs.CurVal == rhs.CurVal;
}
constexpr friend bool operator!=(const EnumIterator &lhs,
const EnumIterator &rhs) {
return !(lhs == rhs);
}
private:
constexpr static bool checkEnumValue(Enum Value) {
auto IntLastVal = static_cast<std::underlying_type_t<Enum>>(LastValue);
auto IntVal = static_cast<std::underlying_type_t<Enum>>(Value);
if constexpr (std::is_signed_v<std::underlying_type_t<Enum>>) {
if (IntVal < 0)
return false;
}
if (IntVal > IntLastVal)
return false;
return true;
}
};
} // namespace vc
#endif // VC_UTILS_GENERAL_ENUMUTILS_H
|