EnumeratedArray.h (3316B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* EnumeratedArray is like Array, but indexed by a typed enum. */ 8 9 #ifndef mozilla_EnumeratedArray_h 10 #define mozilla_EnumeratedArray_h 11 12 #include <utility> 13 14 #include "mozilla/Array.h" 15 #include "EnumTypeTraits.h" 16 17 namespace mozilla { 18 19 /** 20 * EnumeratedArray is a fixed-size array container for use when an 21 * array is indexed by a specific enum class. 22 * 23 * This provides type safety by guarding at compile time against accidentally 24 * indexing such arrays with unrelated values. This also removes the need 25 * for manual casting when using a typed enum value to index arrays. 26 * 27 * Aside from the typing of indices, EnumeratedArray is similar to Array. 28 * 29 * Example: 30 * 31 * enum class AnimalSpecies { 32 * Cow, 33 * Sheep, 34 * Count 35 * }; 36 * 37 * EnumeratedArray<AnimalSpecies, int, AnimalSpecies::Count> headCount; 38 * 39 * headCount[AnimalSpecies::Cow] = 17; 40 * headCount[AnimalSpecies::Sheep] = 30; 41 * 42 * If the enum class has contiguous values and provides a specialization of 43 * mozilla::MaxContiguousEnumValue then the size will be calculated as the max 44 * value + 1. 45 */ 46 template <typename Enum, typename ValueType, 47 size_t Size = ContiguousEnumSize<Enum>::value> 48 class EnumeratedArray { 49 private: 50 static_assert(UnderlyingValue(MinContiguousEnumValue<Enum>::value) == 0, 51 "All indexes would need to be corrected if min != 0"); 52 53 using ArrayType = Array<ValueType, Size>; 54 55 ArrayType mArray; 56 57 public: 58 constexpr EnumeratedArray() = default; 59 60 template <typename... Args> 61 MOZ_IMPLICIT constexpr EnumeratedArray(Args&&... aArgs) 62 : mArray{std::forward<Args>(aArgs)...} {} 63 64 constexpr ValueType& operator[](Enum aIndex) { 65 return mArray[size_t(aIndex)]; 66 } 67 68 constexpr const ValueType& operator[](Enum aIndex) const { 69 return mArray[size_t(aIndex)]; 70 } 71 72 using iterator = typename ArrayType::iterator; 73 using const_iterator = typename ArrayType::const_iterator; 74 using reverse_iterator = typename ArrayType::reverse_iterator; 75 using const_reverse_iterator = typename ArrayType::const_reverse_iterator; 76 77 // Methods for range-based for loops. 78 iterator begin() { return mArray.begin(); } 79 const_iterator begin() const { return mArray.begin(); } 80 const_iterator cbegin() const { return mArray.cbegin(); } 81 iterator end() { return mArray.end(); } 82 const_iterator end() const { return mArray.end(); } 83 const_iterator cend() const { return mArray.cend(); } 84 85 // Method for std::size. 86 constexpr size_t size() const { return mArray.size(); } 87 88 // Methods for reverse iterating. 89 reverse_iterator rbegin() { return mArray.rbegin(); } 90 const_reverse_iterator rbegin() const { return mArray.rbegin(); } 91 const_reverse_iterator crbegin() const { return mArray.crbegin(); } 92 reverse_iterator rend() { return mArray.rend(); } 93 const_reverse_iterator rend() const { return mArray.rend(); } 94 const_reverse_iterator crend() const { return mArray.crend(); } 95 }; 96 97 } // namespace mozilla 98 99 #endif // mozilla_EnumeratedArray_h