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 | } |