/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* EnumeratedArray is like Array, but indexed by a typed enum. */ #ifndef mozilla_EnumeratedArray_h #define mozilla_EnumeratedArray_h #include #include "mozilla/Array.h" #include "EnumTypeTraits.h" namespace mozilla { /** * EnumeratedArray is a fixed-size array container for use when an * array is indexed by a specific enum class. * * This provides type safety by guarding at compile time against accidentally * indexing such arrays with unrelated values. This also removes the need * for manual casting when using a typed enum value to index arrays. * * Aside from the typing of indices, EnumeratedArray is similar to Array. * * Example: * * enum class AnimalSpecies { * Cow, * Sheep, * Count * }; * * EnumeratedArray headCount; * * headCount[AnimalSpecies::Cow] = 17; * headCount[AnimalSpecies::Sheep] = 30; * * If the enum class has contiguous values and provides a specialization of * mozilla::MaxContiguousEnumValue then the size will be calculated as the max * value + 1. */ template ::value> class EnumeratedArray { private: static_assert(UnderlyingValue(MinContiguousEnumValue::value) == 0, "All indexes would need to be corrected if min != 0"); using ArrayType = Array; ArrayType mArray; public: EnumeratedArray() = default; template MOZ_IMPLICIT constexpr EnumeratedArray(Args&&... aArgs) : mArray{std::forward(aArgs)...} {} ValueType& operator[](Enum aIndex) { return mArray[size_t(aIndex)]; } const ValueType& operator[](Enum aIndex) const { return mArray[size_t(aIndex)]; } using iterator = typename ArrayType::iterator; using const_iterator = typename ArrayType::const_iterator; using reverse_iterator = typename ArrayType::reverse_iterator; using const_reverse_iterator = typename ArrayType::const_reverse_iterator; // Methods for range-based for loops. iterator begin() { return mArray.begin(); } const_iterator begin() const { return mArray.begin(); } const_iterator cbegin() const { return mArray.cbegin(); } iterator end() { return mArray.end(); } const_iterator end() const { return mArray.end(); } const_iterator cend() const { return mArray.cend(); } // Methods for reverse iterating. reverse_iterator rbegin() { return mArray.rbegin(); } const_reverse_iterator rbegin() const { return mArray.rbegin(); } const_reverse_iterator crbegin() const { return mArray.crbegin(); } reverse_iterator rend() { return mArray.rend(); } const_reverse_iterator rend() const { return mArray.rend(); } const_reverse_iterator crend() const { return mArray.crend(); } }; } // namespace mozilla #endif // mozilla_EnumeratedArray_h