File: enum.h

package info (click to toggle)
crawl 2%3A0.33.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 95,264 kB
  • sloc: cpp: 358,145; ansic: 27,203; javascript: 9,491; python: 8,359; perl: 3,327; java: 2,667; xml: 2,191; makefile: 1,830; sh: 611; objc: 250; cs: 15; sed: 9; lisp: 3
file content (196 lines) | stat: -rw-r--r-- 6,613 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/**
 * @file
 * @brief Global (ick) enums.
**/

#pragma once

#include "macros.h"

#include <iterator>
#include <type_traits> // underlying_type<>, enable_if<>

// Provide a last_exponent static member variable only if the LastExponent
// template parameter is nonnegative.
template<int LastExponent, bool Provided = LastExponent >= 0>
struct _enum_bitfield_exponent_base { };

template<int LastExponent>
struct _enum_bitfield_exponent_base<LastExponent, true>
{
    static constexpr int last_exponent = LastExponent;
};

// If LastExponent is nonnegative, is the last exponent that will
// be iterated over by range()
template<class E, int LastExponent = -1>
class enum_bitfield : public _enum_bitfield_exponent_base<LastExponent>
{
public:
    typedef typename std::underlying_type<E>::type underlying_type;
    typedef enum_bitfield<E, LastExponent> field_type;
    underlying_type flags;
private:
    explicit constexpr enum_bitfield(underlying_type rawflags)
        : flags(rawflags)
    {}
public:
    /// Get the flag corresponding to the given bit position (0 = LSB).
    static constexpr E exponent(int pos)
    {
        return static_cast<E>(underlying_type(1) << pos);
    }

    constexpr enum_bitfield() : flags(0) {}
    constexpr enum_bitfield(E flag) : flags(underlying_type(flag)) {}
    template<class ... Es>
    constexpr enum_bitfield(E flag, E flag2, Es... rest)
        : flags(enum_bitfield(flag2, rest...).flags | underlying_type(flag)) {}

    explicit constexpr operator underlying_type () const { return flags; }
    explicit constexpr operator bool () const { return flags; }
    constexpr bool operator==(field_type other) const
    {
        return flags == other.flags;
    }
    constexpr bool operator!=(field_type other) const
    {
        return !(*this == other);
    }

    field_type &operator|=(field_type other)
    {
        flags |= other.flags;
        return *this;
    }

    field_type &operator&=(field_type other)
    {
        flags &= other.flags;
        return *this;
    }

    field_type &operator^=(field_type other)
    {
        flags ^= other.flags;
        return *this;
    }

    constexpr field_type operator|(field_type other) const
    {
        return field_type(flags | other.flags);
    }

    constexpr field_type operator&(field_type other) const
    {
        return field_type(flags & other.flags);
    }

    constexpr field_type operator^(field_type other) const
    {
        return field_type(flags ^ other.flags);
    }

    constexpr field_type operator~() const
    {
        return field_type(~flags);
    }

    struct range
    {
        class iterator : public std::iterator<std::forward_iterator_tag, const E>
        {
        private:
            int exp_;
        public:
            constexpr iterator() : exp_(0) { }
            constexpr iterator(int exp) : exp_(exp) { }
            constexpr E operator*() const { return exponent(exp_); }
            constexpr bool operator==(const iterator &other) const
            {
                return exp_ == other.exp_;
            }
            constexpr bool operator!=(const iterator &other) const
            {
                return !(*this == other);
            }
            iterator &operator++() { ++exp_; return *this; }
            iterator operator++(int)
            {
                iterator copy = *this;
                ++(*this);
                return copy;
            }
        };

        const int final;

        constexpr range(int last_exp) : final(last_exp) {}

        // Only create the default constructor if we got a nonnegative
        // LastExponent template parameter.
        template<typename std::enable_if<LastExponent >= 0, int>::type = 0>
        constexpr range() : final(LastExponent) {}

        constexpr iterator begin() const { return iterator(); }
        constexpr iterator end() const { return final + 1; }
    };
};

#define DEF_BITFIELD_OPERATORS(fieldT, flagT, ...) \
    inline constexpr fieldT operator|(flagT a, flagT b)  { return fieldT(a) | b; } \
    inline constexpr fieldT operator|(flagT a, fieldT b) { return fieldT(a) | b; } \
    inline constexpr fieldT operator&(flagT a, flagT b)  { return fieldT(a) & b; } \
    inline constexpr fieldT operator&(flagT a, fieldT b) { return fieldT(a) & b; } \
    inline constexpr fieldT operator^(flagT a, flagT b)  { return fieldT(a) ^ b; } \
    inline constexpr fieldT operator^(flagT a, fieldT b) { return fieldT(a) ^ b; } \
    inline constexpr fieldT operator~(flagT a) { return ~fieldT(a); } \
    COMPILE_CHECK(is_enum<flagT>::value)
// The last line above is really just to eat a semicolon; template
// substitution of enum_bitfield would have already failed.

// Work around MSVC's idiosyncratic interpretation of __VA_ARGS__ as a
// single macro argument: http://stackoverflow.com/questions/5134523
#define EXPANDMACRO(x) x
/**
 * Define fieldT as a bitfield of the enum flagT, and make bitwise
 * operators on flagT yield a fieldT.
 *
 * This macro produces a typedef and several inline function definitions;
 * use it only at file/namespace scope. It requires a trailing semicolon.
 *
 * The operations ~, |, ^, and (binary) & on flags or fields yield a field.
 * Fields also support &=, |=, and ^=. Fields can be explicitly converted to
 * an integer of the enum's underlying type, or to bool. Note that in C++
 * using a bitfield expression as the condition of a control structure,
 * or as an operand of a logical operator, counts as explicit conversion
 * to bool.
 *
 * @param fieldT   An identifier naming the bitfield type to define.
 * @param flagT    An identifier naming the enum type to use as a flag.
 *                 Could theoretically be a more complex type expression, but
 *                 I wouldn't try anything trickier than scope resolution.
 * @param lastExp  The last exponent over which fieldT::range() should
 *                 iterate. If unspecified or negative, the bitfield will not
 *                 have the last_exponent static member variable, and the
 *                 bitfield's nested range class will not have a default
 *                 constructor.
 */
#define DEF_BITFIELD(fieldT, ...) \
    typedef enum_bitfield<__VA_ARGS__> fieldT; \
    EXPANDMACRO(DEF_BITFIELD_OPERATORS(fieldT, __VA_ARGS__, ))
// The trailing comma suppresses "ISO C99 requires rest arguments to be used"

// The rest of this file should probably move elsewhere
// normal tile size in px
enum
{
    TILE_X = 32,
    TILE_Y = 32,
};

// Don't change this without also modifying the data save/load routines.
enum
{
    NUM_MAX_DOLLS = 10,
};