From 830a7ee003069cc998277edb2c5e93a31f74829f Mon Sep 17 00:00:00 2001 From: Teemu Piippo Date: Sat, 4 Apr 2015 19:19:17 +0300 Subject: [PATCH] - added TFlags --- src/farchive.h | 7 ++++ src/tflags.h | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/tflags.h diff --git a/src/farchive.h b/src/farchive.h index 329b448db..87ebf999b 100644 --- a/src/farchive.h +++ b/src/farchive.h @@ -37,6 +37,7 @@ #include #include "dobject.h" #include "r_state.h" +#include "tflags.h" class FFile { @@ -333,4 +334,10 @@ FArchive &operator<< (FArchive &arc, side_t *&side); +template +FArchive& operator<< (FArchive& arc, TFlags& flag) +{ + return flag.Serialize (arc); +} + #endif //__FARCHIVE_H__ diff --git a/src/tflags.h b/src/tflags.h new file mode 100644 index 000000000..20caba227 --- /dev/null +++ b/src/tflags.h @@ -0,0 +1,110 @@ +/* +** 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 +#include "doomtype.h" + +/* + * 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 DWORD) + */ +template +class TFlags +{ + struct ZeroDummy {}; + +public: + typedef TFlags Self; + typedef T EnumType; + typedef TT IntType; + + TFlags(){} + TFlags (const Self& other) : Value (other.GetValue()) {} + TFlags (T value) : Value (static_cast (value)) {} + + // This allows initializing the flagset with 0, as 0 implicitly converts into a null pointer. + TFlags (ZeroDummy*) : Value (0) {} + + // Relation operators + Self operator| (Self other) const { return Self::FromInt (Value | other.GetValue()); } + Self operator& (Self other) const { return Self::FromInt (Value & other.GetValue()); } + Self operator^ (Self other) const { return Self::FromInt (Value ^ other.GetValue()); } + Self operator| (T value) const { return Self::FromInt (Value | value); } + Self operator& (T value) const { return Self::FromInt (Value & value); } + Self operator^ (T value) const { return Self::FromInt (Value ^ value); } + Self operator~() const { return Self::FromInt (~Value); } + + // Assignment operators + Self& operator= (Self other) { Value = other.GetValue(); return *this; } + Self& operator|= (Self other) { Value |= other.GetValue(); return *this; } + Self& operator&= (Self other) { Value &= other.GetValue(); return *this; } + Self& operator^= (Self other) { Value ^= other.GetValue(); return *this; } + Self& operator= (T value) { Value = value; return *this; } + Self& operator|= (T value) { Value |= value; return *this; } + Self& operator&= (T value) { Value &= value; return *this; } + Self& operator^= (T value) { Value ^= value; return *this; } + + // Access the value of the flagset + TT GetValue() const { return Value; } + operator TT() const { return Value; } + + // Serialize to FArchive + FArchive& Serialize (FArchive& arc) + { + arc << Value; + return arc; + } + + // Set the value of the flagset manually with an integer. + // Please think twice before using this. + static Self FromInt (TT value) { return Self (static_cast (value)); } + +private: + TT Value; +}; + +/* + * Additional operators for TFlags types. + */ +#define DEFINE_TFLAGS_OPERATORS(T) \ +inline T operator| (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \ +inline T operator& (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \ +inline T operator^ (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \ +inline T operator| (T::EnumType a, T b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \ +inline T operator& (T::EnumType a, T b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \ +inline T operator^ (T::EnumType a, T b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \ +inline T operator~ (T::EnumType a) { return T::FromInt (~T::IntType (a)); } \ No newline at end of file