blob: 70e32910fcd31bff6bae730881c81bc804b7fcc0 [file] [log] [blame]
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// PackedGLEnums_autogen.h:
// Declares ANGLE-specific enums classes for GLEnum and functions operating
// on them.
#ifndef LIBANGLE_PACKEDGLENUMS_H_
#define LIBANGLE_PACKEDGLENUMS_H_
#include "libANGLE/PackedGLEnums_autogen.h"
#include <array>
#include <cstddef>
namespace angle
{
template <typename E>
class EnumIterator final
{
private:
using UnderlyingType = typename std::underlying_type<E>::type;
public:
EnumIterator(E value) : mValue(static_cast<UnderlyingType>(value)) {}
EnumIterator &operator++()
{
mValue++;
return *this;
}
bool operator==(const EnumIterator &other) const { return mValue == other.mValue; }
bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; }
E operator*() const { return static_cast<E>(mValue); }
private:
UnderlyingType mValue;
};
template <typename E>
struct AllEnums
{
EnumIterator<E> begin() const { return {static_cast<E>(0)}; }
EnumIterator<E> end() const { return {E::InvalidEnum}; }
};
template <typename E, typename T>
class PackedEnumMap
{
private:
using UnderlyingType = typename std::underlying_type<E>::type;
static constexpr size_t kSize = static_cast<UnderlyingType>(E::EnumCount);
using Storage = std::array<T, kSize>;
Storage mData;
public:
// types:
using value_type = T;
using pointer = T *;
using const_pointer = const T *;
using reference = T &;
using const_reference = const T &;
using size_type = size_t;
using difference_type = ptrdiff_t;
using iterator = typename Storage::iterator;
using const_iterator = typename Storage::const_iterator;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
// No explicit construct/copy/destroy for aggregate type
void fill(const T &u) { mData.fill(u); }
void swap(PackedEnumMap<E, T> &a) noexcept { mData.swap(a.mData); }
// iterators:
iterator begin() noexcept { return mData.begin(); }
const_iterator begin() const noexcept { return mData.begin(); }
iterator end() noexcept { return mData.end(); }
const_iterator end() const noexcept { return mData.end(); }
reverse_iterator rbegin() noexcept { return mData.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return mData.rbegin(); }
reverse_iterator rend() noexcept { return mData.rend(); }
const_reverse_iterator rend() const noexcept { return mData.rend(); }
// capacity:
constexpr size_type size() const noexcept { return mData.size(); }
constexpr size_type max_size() const noexcept { return mData.max_size(); }
constexpr bool empty() const noexcept { return mData.empty(); }
// element access:
reference operator[](E n) { return mData[static_cast<UnderlyingType>(n)]; }
const_reference operator[](E n) const { return mData[static_cast<UnderlyingType>(n)]; }
const_reference at(E n) const { return mData.at(static_cast<UnderlyingType>(n)); }
reference at(E n) { return mData.at(static_cast<UnderlyingType>(n)); }
reference front() { return mData.front(); }
const_reference front() const { return mData.front(); }
reference back() { return mData.back(); }
const_reference back() const { return mData.back(); }
T *data() noexcept { return mData.data(); }
const T *data() const noexcept { return mData.data(); }
};
} // namespace angle
#endif // LIBANGLE_PACKEDGLENUMS_H_