Subversion Repositories Games.Descent

Rev

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
}