mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-29 23:42:08 +00:00
108 lines
5 KiB
C++
108 lines
5 KiB
C++
/*
|
|
** tflags.h
|
|
**
|
|
**---------------------------------------------------------------------------
|
|
** Copyright 2015 Teemu Piippo
|
|
** All rights reserved.
|
|
**
|
|
** Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions
|
|
** are met:
|
|
**
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
** notice, this list of conditions and the following disclaimer.
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
** documentation and/or other materials provided with the distribution.
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
** derived from this software without specific prior written permission.
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
**---------------------------------------------------------------------------
|
|
**
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
/*
|
|
* TFlags
|
|
*
|
|
* A Qt-inspired type-safe flagset type.
|
|
*
|
|
* T is the enum type of individual flags,
|
|
* TT is the underlying integer type used (defaults to uint32_t)
|
|
*/
|
|
template<typename T, typename TT = uint32_t>
|
|
class TFlags
|
|
{
|
|
struct ZeroDummy {};
|
|
|
|
public:
|
|
typedef TFlags<T, TT> Self;
|
|
typedef T EnumType;
|
|
typedef TT IntType;
|
|
|
|
TFlags() = default;
|
|
TFlags(const Self& other) = default;
|
|
constexpr TFlags (T value) : Value (static_cast<TT> (value)) {}
|
|
|
|
// This allows initializing the flagset with 0, as 0 implicitly converts into a null pointer.
|
|
constexpr TFlags (ZeroDummy*) : Value (0) {}
|
|
|
|
// Relation operators
|
|
constexpr Self operator| (const Self& other) const { return Self::FromInt (Value | other.GetValue()); }
|
|
constexpr Self operator& (const Self& other) const { return Self::FromInt (Value & other.GetValue()); }
|
|
constexpr Self operator^ (const Self& other) const { return Self::FromInt (Value ^ other.GetValue()); }
|
|
constexpr Self operator| (T value) const { return Self::FromInt (Value | value); }
|
|
constexpr Self operator& (T value) const { return Self::FromInt (Value & value); }
|
|
constexpr Self operator^ (T value) const { return Self::FromInt (Value ^ value); }
|
|
constexpr Self operator~() const { return Self::FromInt (~Value); }
|
|
|
|
// Assignment operators
|
|
constexpr Self& operator= (const Self& other) = default;
|
|
constexpr Self& operator|= (const Self& other) { Value |= other.GetValue(); return *this; }
|
|
constexpr Self& operator&= (const Self& other) { Value &= other.GetValue(); return *this; }
|
|
constexpr Self& operator^= (const Self& other) { Value ^= other.GetValue(); return *this; }
|
|
constexpr Self& operator= (T value) { Value = value; return *this; }
|
|
constexpr Self& operator|= (T value) { Value |= value; return *this; }
|
|
constexpr Self& operator&= (T value) { Value &= value; return *this; }
|
|
constexpr Self& operator^= (T value) { Value ^= value; return *this; }
|
|
|
|
// Access the value of the flagset
|
|
constexpr TT GetValue() const { return Value; }
|
|
constexpr operator TT() const { return Value; }
|
|
|
|
// Set the value of the flagset manually with an integer.
|
|
// Please think twice before using this.
|
|
static constexpr Self FromInt (TT value) { return Self (static_cast<T> (value)); }
|
|
|
|
private:
|
|
template<typename X> constexpr Self operator| (X value) const { return Self::FromInt (Value | value); }
|
|
template<typename X> constexpr Self operator& (X value) const { return Self::FromInt (Value & value); }
|
|
template<typename X> constexpr Self operator^ (X value) const { return Self::FromInt (Value ^ value); }
|
|
|
|
public: // to be removed.
|
|
TT Value;
|
|
};
|
|
|
|
/*
|
|
* Additional operators for TFlags types.
|
|
*/
|
|
#define DEFINE_TFLAGS_OPERATORS(T) \
|
|
constexpr inline T operator| (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \
|
|
constexpr inline T operator& (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \
|
|
constexpr inline T operator^ (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \
|
|
constexpr inline T operator| (T::EnumType a, T b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \
|
|
constexpr inline T operator& (T::EnumType a, T b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \
|
|
constexpr inline T operator^ (T::EnumType a, T b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \
|
|
constexpr inline T operator~ (T::EnumType a) { return T::FromInt (~T::IntType (a)); }
|
|
|