LMMS
Loading...
Searching...
No Matches
Flags.h
Go to the documentation of this file.
1/*
2 * Flags.h - class to make flags from enums
3 *
4 * Copyright (c) 2023 Dominic Clark
5 *
6 * This file is part of LMMS - https://lmms.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
22 *
23 */
24
25#ifndef LMMS_FLAGS_H
26#define LMMS_FLAGS_H
27
28#include <type_traits>
29
30namespace lmms {
31
32template<typename T>
33class Flags
34{
35 static_assert(std::is_enum_v<T>, "lmms::Flags can only be used with enum types");
36
37public:
38 using EnumType = T;
39 using UnderlyingType = std::underlying_type_t<T>;
40
41 constexpr Flags() = default;
42
43 constexpr Flags(T value) : // Intentionally not explicit
44 m_value{static_cast<UnderlyingType>(value)}
45 {}
46
47 constexpr explicit Flags(UnderlyingType value) :
49 {}
50
51 constexpr auto testAll(Flags flags) const -> bool { return (*this & flags) == flags; }
52 constexpr auto testAny(Flags flags) const -> bool { return (*this & flags) != Flags{}; }
53 constexpr auto testFlag(EnumType flag) const -> bool { return static_cast<bool>(*this & flag); }
54
55 constexpr auto operator~() const -> Flags { return Flags{~m_value}; }
56 friend constexpr auto operator&(Flags l, Flags r) -> Flags { return Flags{l.m_value & r.m_value}; }
57 friend constexpr auto operator|(Flags l, Flags r) -> Flags { return Flags{l.m_value | r.m_value}; }
58 friend constexpr auto operator^(Flags l, Flags r) -> Flags { return Flags{l.m_value ^ r.m_value}; }
59 friend constexpr auto operator+(Flags l, Flags r) -> Flags { return Flags{l.m_value | r.m_value}; }
60 friend constexpr auto operator-(Flags l, Flags r) -> Flags { return Flags{l.m_value & ~r.m_value}; }
61
62 constexpr auto operator&=(Flags f) -> Flags& { m_value &= f.m_value; return *this; }
63 constexpr auto operator|=(Flags f) -> Flags& { m_value |= f.m_value; return *this; }
64 constexpr auto operator^=(Flags f) -> Flags& { m_value ^= f.m_value; return *this; }
65 constexpr auto operator+=(Flags f) -> Flags& { m_value |= f.m_value; return *this; }
66 constexpr auto operator-=(Flags f) -> Flags& { m_value &= ~f.m_value; return *this; }
67
68 constexpr explicit operator UnderlyingType() const { return m_value; } // TODO C++23: explicit(std::is_scoped_enum<T>)
69 constexpr explicit operator bool() const { return m_value != 0; }
70
71 friend constexpr auto operator==(Flags l, Flags r) -> bool = default;
72
73private:
75};
76
77#define LMMS_DECLARE_OPERATORS_FOR_FLAGS(type) \
78constexpr inline auto operator|(type l, type r) -> ::lmms::Flags<type> { return ::lmms::Flags{l} | ::lmms::Flags{r}; }
79
80} // namespace lmms
81
82#endif // LMMS_FLAGS_H
friend constexpr auto operator-(Flags l, Flags r) -> Flags
Definition Flags.h:60
friend constexpr auto operator&(Flags l, Flags r) -> Flags
Definition Flags.h:56
constexpr auto operator+=(Flags f) -> Flags &
Definition Flags.h:65
std::underlying_type_t< T > UnderlyingType
Definition Flags.h:39
constexpr auto testAll(Flags flags) const -> bool
Definition Flags.h:51
T EnumType
Definition Flags.h:38
friend constexpr auto operator^(Flags l, Flags r) -> Flags
Definition Flags.h:58
constexpr auto operator^=(Flags f) -> Flags &
Definition Flags.h:64
constexpr auto testAny(Flags flags) const -> bool
Definition Flags.h:52
constexpr Flags()=default
constexpr Flags(UnderlyingType value)
Definition Flags.h:47
friend constexpr auto operator==(Flags l, Flags r) -> bool=default
UnderlyingType m_value
Definition Flags.h:74
constexpr auto testFlag(EnumType flag) const -> bool
Definition Flags.h:53
friend constexpr auto operator|(Flags l, Flags r) -> Flags
Definition Flags.h:57
constexpr auto operator&=(Flags f) -> Flags &
Definition Flags.h:62
constexpr auto operator|=(Flags f) -> Flags &
Definition Flags.h:63
constexpr auto operator-=(Flags f) -> Flags &
Definition Flags.h:66
constexpr auto operator~() const -> Flags
Definition Flags.h:55
friend constexpr auto operator+(Flags l, Flags r) -> Flags
Definition Flags.h:59
constexpr Flags(T value)
Definition Flags.h:43
int * l
Definition inflate.c:1579
unsigned f
Definition inflate.c:1572
static PuglViewHint int value
Definition pugl.h:1708
Definition AudioAlsa.cpp:35
int r
Definition crypt.c:458
int flag
Definition unix.c:754
#define const
Definition zconf.h:137