1 // Copyright 2020 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef COMMON_ITYP_ARRAY_H_ 16 #define COMMON_ITYP_ARRAY_H_ 17 18 #include "common/TypedInteger.h" 19 #include "common/UnderlyingType.h" 20 21 #include <array> 22 #include <cstddef> 23 #include <type_traits> 24 25 namespace ityp { 26 27 // ityp::array is a helper class that wraps std::array with the restriction that 28 // indices must be a particular type |Index|. Dawn uses multiple flat maps of 29 // index-->data, and this class helps ensure an indices cannot be passed interchangably 30 // to a flat map of a different type. 31 template <typename Index, typename Value, size_t Size> 32 class array : private std::array<Value, Size> { 33 using I = UnderlyingType<Index>; 34 using Base = std::array<Value, Size>; 35 36 static_assert(Size <= std::numeric_limits<I>::max(), ""); 37 38 public: 39 constexpr array() = default; 40 41 template <typename... Values> array(Values &&...values)42 constexpr array(Values&&... values) : Base{std::forward<Values>(values)...} { 43 } 44 45 Value& operator[](Index i) { 46 I index = static_cast<I>(i); 47 ASSERT(index >= 0 && index < I(Size)); 48 return Base::operator[](index); 49 } 50 51 constexpr const Value& operator[](Index i) const { 52 I index = static_cast<I>(i); 53 ASSERT(index >= 0 && index < I(Size)); 54 return Base::operator[](index); 55 } 56 at(Index i)57 Value& at(Index i) { 58 I index = static_cast<I>(i); 59 ASSERT(index >= 0 && index < I(Size)); 60 return Base::at(index); 61 } 62 at(Index i)63 constexpr const Value& at(Index i) const { 64 I index = static_cast<I>(i); 65 ASSERT(index >= 0 && index < I(Size)); 66 return Base::at(index); 67 } 68 begin()69 typename Base::iterator begin() noexcept { 70 return Base::begin(); 71 } 72 begin()73 typename Base::const_iterator begin() const noexcept { 74 return Base::begin(); 75 } 76 end()77 typename Base::iterator end() noexcept { 78 return Base::end(); 79 } 80 end()81 typename Base::const_iterator end() const noexcept { 82 return Base::end(); 83 } 84 size()85 constexpr Index size() const { 86 return Index(I(Size)); 87 } 88 89 using Base::back; 90 using Base::data; 91 using Base::empty; 92 using Base::fill; 93 using Base::front; 94 }; 95 96 } // namespace ityp 97 98 #endif // COMMON_ITYP_ARRAY_H_ 99