EnumeratedArray.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. /* EnumeratedArray is like Array, but indexed by a typed enum. */
  7. #ifndef mozilla_EnumeratedArray_h
  8. #define mozilla_EnumeratedArray_h
  9. #include "mozilla/Array.h"
  10. #include "mozilla/Move.h"
  11. namespace mozilla {
  12. /**
  13. * EnumeratedArray is a fixed-size array container for use when an
  14. * array is indexed by a specific enum class.
  15. *
  16. * This provides type safety by guarding at compile time against accidentally
  17. * indexing such arrays with unrelated values. This also removes the need
  18. * for manual casting when using a typed enum value to index arrays.
  19. *
  20. * Aside from the typing of indices, EnumeratedArray is similar to Array.
  21. *
  22. * Example:
  23. *
  24. * enum class AnimalSpecies {
  25. * Cow,
  26. * Sheep,
  27. * Count
  28. * };
  29. *
  30. * EnumeratedArray<AnimalSpecies, AnimalSpecies::Count, int> headCount;
  31. *
  32. * headCount[AnimalSpecies::Cow] = 17;
  33. * headCount[AnimalSpecies::Sheep] = 30;
  34. *
  35. */
  36. template<typename IndexType,
  37. IndexType SizeAsEnumValue,
  38. typename ValueType>
  39. class EnumeratedArray
  40. {
  41. public:
  42. static const size_t kSize = size_t(SizeAsEnumValue);
  43. private:
  44. typedef Array<ValueType, kSize> ArrayType;
  45. ArrayType mArray;
  46. public:
  47. EnumeratedArray() {}
  48. template <typename... Args>
  49. MOZ_IMPLICIT EnumeratedArray(Args&&... aArgs)
  50. : mArray{mozilla::Forward<Args>(aArgs)...}
  51. {}
  52. explicit EnumeratedArray(const EnumeratedArray& aOther)
  53. {
  54. for (size_t i = 0; i < kSize; i++) {
  55. mArray[i] = aOther.mArray[i];
  56. }
  57. }
  58. EnumeratedArray(EnumeratedArray&& aOther)
  59. {
  60. for (size_t i = 0; i < kSize; i++) {
  61. mArray[i] = Move(aOther.mArray[i]);
  62. }
  63. }
  64. ValueType& operator[](IndexType aIndex)
  65. {
  66. return mArray[size_t(aIndex)];
  67. }
  68. const ValueType& operator[](IndexType aIndex) const
  69. {
  70. return mArray[size_t(aIndex)];
  71. }
  72. typedef typename ArrayType::iterator iterator;
  73. typedef typename ArrayType::const_iterator const_iterator;
  74. typedef typename ArrayType::reverse_iterator reverse_iterator;
  75. typedef typename ArrayType::const_reverse_iterator const_reverse_iterator;
  76. // Methods for range-based for loops.
  77. iterator begin() { return mArray.begin(); }
  78. const_iterator begin() const { return mArray.begin(); }
  79. const_iterator cbegin() const { return mArray.cbegin(); }
  80. iterator end() { return mArray.end(); }
  81. const_iterator end() const { return mArray.end(); }
  82. const_iterator cend() const { return mArray.cend(); }
  83. // Methods for reverse iterating.
  84. reverse_iterator rbegin() { return mArray.rbegin(); }
  85. const_reverse_iterator rbegin() const { return mArray.rbegin(); }
  86. const_reverse_iterator crbegin() const { return mArray.crbegin(); }
  87. reverse_iterator rend() { return mArray.rend(); }
  88. const_reverse_iterator rend() const { return mArray.rend(); }
  89. const_reverse_iterator crend() const { return mArray.crend(); }
  90. };
  91. } // namespace mozilla
  92. #endif // mozilla_EnumeratedArray_h