Компилятор не сворачивает константу для класса маскирования

Для встроенного проекта я использую вспомогательные классы для флагов и масок. По неизвестным причинам код класса маски некорректно сложен, как ожидалось.

Минимальная реализация маски показана ниже:

template<typename Enum, typename MaskValue>
class EnumMask
{
public:
constexpr inline EnumMask() noexcept : _mask(0) {}
constexpr inline EnumMask(Enum enumValue) noexcept : _mask(maskFromEnum(enumValue)) {}
constexpr inline EnumMask(const std::initializer_list<Enum> enumValues) noexcept : _mask(maskFromEnum(enumValues.begin(), enumValues.end())) {}
constexpr inline operator MaskValue() const noexcept { return _mask; }
private:
constexpr static inline MaskValue maskFromEnum(const Enum enumValue) noexcept {
return (static_cast<MaskValue>(1)<<static_cast<uint8_t>(enumValue));
}
constexpr static inline MaskValue maskFromEnum(
typename std::initializer_list<Enum>::const_iterator it,
typename std::initializer_list<Enum>::const_iterator end) noexcept
{
return (it == end ? static_cast<MaskValue>(0) : (maskFromEnum(*it)|maskFromEnum(it+1, end)));
}
private:
const MaskValue _mask;
};

Класс используется, как показано в следующем примере:

class Driver
{
public:
enum Pin : uint8_t {
GPA0 = 0x00,
GPA1 = 0x01,
GPA2 = 0x02,
};
typedef EnumMask<Pin, uint16_t> PinMask;
void setPinDirection(const uint16_t mask, bool direction);
inline void setPinDirection(const PinMask &mask, bool direction) {
setPinDirection(static_cast<uint16_t>(mask), direction);
}
};

void main()
{
Driver d;
d.setPinDirection({Driver::GPA0, Driver::GPA1}, true);
}

Код компилируется с использованием GCC 4.8.3 с опцией -Os, Я ожидаю, что компилятор преобразует этот код в одно значение, но на самом деле он создает функцию для вычисления маски по значениям.

Есть ли конкретная причина в моем коде, которая препятствует правильному свертыванию констант?

3

Решение

Объяснение на самом деле очень просто:

begin() а также end() Члены std::initializer_list являются constexpr только с C ++ 14.

Увидеть ссылка

2

Другие решения

Других решений пока нет …