Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | /* |
| 2 | * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>. |
||
| 3 | * It is copyright by its individual contributors, as recorded in the |
||
| 4 | * project's Git history. See COPYING.txt at the top level for license |
||
| 5 | * terms and a link to the Git history. |
||
| 6 | */ |
||
| 7 | |||
| 8 | #pragma once |
||
| 9 | #include "dxxsconf.h" |
||
| 10 | #include <array> |
||
| 11 | #include <cstddef> |
||
| 12 | |||
| 13 | namespace dcx { |
||
| 14 | |||
| 15 | /* Wrap a std::array and override the normal indexing operations to take |
||
| 16 | * an instance of type `E`. This is intended for use where `E` is an |
||
| 17 | * instance of `enum class`. When `E` is an `enum class`, instances of |
||
| 18 | * `E` cannot implicitly convert to `std::array::size_type`, and so |
||
| 19 | * would require a cast in the caller if this wrapper were not used. |
||
| 20 | * Using this wrapper moves the casts into the wrapper, after the |
||
| 21 | * compiler has checked that the argument is the right type of `enum |
||
| 22 | * class`. This prevents accidentally using an incorrect `enum class`. |
||
| 23 | * |
||
| 24 | * Other types for E are not likely to be useful, but are not blocked. |
||
| 25 | */ |
||
| 26 | template <typename T, std::size_t N, typename E> |
||
| 27 | struct enumerated_array : std::array<T, N> |
||
| 28 | { |
||
| 29 | using base_type = std::array<T, N>; |
||
| 30 | using typename base_type::reference; |
||
| 31 | using typename base_type::const_reference; |
||
| 32 | constexpr reference at(E position) |
||
| 33 | { |
||
| 34 | return this->base_type::at(static_cast<std::size_t>(position)); |
||
| 35 | } |
||
| 36 | constexpr const_reference at(E position) const |
||
| 37 | { |
||
| 38 | return this->base_type::at(static_cast<std::size_t>(position)); |
||
| 39 | } |
||
| 40 | constexpr reference operator[](E position) |
||
| 41 | { |
||
| 42 | return this->base_type::operator[](static_cast<std::size_t>(position)); |
||
| 43 | } |
||
| 44 | constexpr const_reference operator[](E position) const |
||
| 45 | { |
||
| 46 | return this->base_type::operator[](static_cast<std::size_t>(position)); |
||
| 47 | } |
||
| 48 | __attribute_warn_unused_result |
||
| 49 | static constexpr bool valid_index(std::size_t s) |
||
| 50 | { |
||
| 51 | return s < N; |
||
| 52 | } |
||
| 53 | __attribute_warn_unused_result |
||
| 54 | static constexpr bool valid_index(E e) |
||
| 55 | { |
||
| 56 | return valid_index(static_cast<std::size_t>(e)); |
||
| 57 | } |
||
| 58 | }; |
||
| 59 | |||
| 60 | } |