blob: 39f12cb95a4302303d601066c844d7e78ccbf47f [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro BEGIN_ENUM
///
/// BEGIN_ENUM is used to create a C++ 'struct' type around an enum, providing
/// a scope for the enum instead of being defined at the global namespace.
/// Combined with the helper macros of BEGIN_ENUM_BYTE(), ..., this enforces
/// that the enum will only be given the intended allocated storage instead of
/// the default storage of a full 4-byte 'int'.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define BEGIN_ENUM(name, storage) \
struct name \
{ \
enum _E : storage; \
\
inline name() \
{ \
_value = (storage) 0; \
} \
\
inline name(_E src) \
{ \
_value = (storage) src; \
} \
\
inline name(storage n) \
{ \
_value = n; \
} \
\
inline name(int n) \
{ \
/* */ \
/* This is needed to enable operations such as "m_value &= ~Flags::Member; */ \
/* */ \
\
_value = (storage) n; \
AssertMsg(((int) _value) == n, "Ensure no truncation"); \
} \
\
inline void operator =(_E e) \
{ \
_value = (storage) e; \
} \
\
inline void operator =(storage n) \
{ \
_value = n; \
} \
\
inline bool operator ==(_E e) const \
{ \
return ((_E) _value) == e; \
} \
\
inline bool operator !=(_E e) const \
{ \
return ((_E) _value) != e; \
} \
\
inline bool operator <(_E e) const \
{ \
return ((_E) _value) < e; \
} \
\
inline bool operator <=(_E e) const \
{ \
return ((_E) _value) <= e; \
} \
\
inline bool operator >(_E e) const \
{ \
return ((_E) _value) > e; \
} \
\
inline bool operator >=(_E e) const \
{ \
return ((_E) _value) >= e; \
} \
\
inline _E operator &(_E e) const \
{ \
return (_E) (((_E) _value) & e); \
} \
\
inline _E operator |(name e) const \
{ \
return (_E) (_value | e._value); \
} \
\
inline void operator |=(name e) \
{ \
_value = _value | e._value; \
} \
\
inline void operator &=(name e) \
{ \
_value = _value & e._value; \
} \
\
inline void operator &=(_E e) \
{ \
_value = _value & ((storage) e); \
} \
\
inline operator _E() const \
{ \
return (_E) _value; \
} \
\
enum _E : storage \
{ \
#define BEGIN_ENUM_BYTE(name) BEGIN_ENUM(name, byte)
#define BEGIN_ENUM_USHORT(name) BEGIN_ENUM(name, uint16)
#define BEGIN_ENUM_UINT(name) BEGIN_ENUM(name, uint32)
#define END_ENUM_BYTE() \
Force8BitPadding = (byte) 0xffU \
}; \
\
byte _value; \
}; \
#define END_ENUM_USHORT() \
Force16BitPadding = (uint16) 0xffffU \
}; \
\
uint16 _value; \
}; \
#define END_ENUM_UINT() \
Force32BitPadding = (uint32) 0xffffffffU \
}; \
\
uint32 _value; \
};
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro PREVENT_ASSIGN
///
/// PREVENT_ASSIGN is used within a C++ type definition to define and
/// explicitly hide the "operator =()" method, preventing it from accidentally
/// being called by the program. If these are not explicitly defined, the C++
/// compiler will implicitly define them, which usually leads to unintended
/// behavior.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define PREVENT_ASSIGN(ClassName) \
private: \
ClassName & operator =(const ClassName & rhs);
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro PREVENT_COPY
///
/// PREVENT_COPY is used within a C++ type definition to define and explicitly
/// hide the "C++ copy constructor" and "operator =()" methods, preventing them
/// from accidentally being called by the program. If these are not explicitly
/// defined, the C++ compiler will implicitly define them, which usually leads
/// to unintended behavior.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define PREVENT_COPYCONSTRUCT(ClassName) \
private: \
ClassName(const ClassName & copy);
#define PREVENT_COPY(ClassName) \
PREVENT_COPYCONSTRUCT(ClassName); \
PREVENT_ASSIGN(ClassName);
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro PREVENT_STANDALONE_HEAPINSTANCE
///
/// PREVENT_STANDALONE_HEAPINSTANCE is used within a C++ type definition to
/// define and explicitly the new operator, preventing them from accidentally
/// being instantiated in the heap by itself. This also ensures that the
/// correct destructor will always be called without using virtual destructors.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define PREVENT_STANDALONE_HEAPINSTANCE() \
private: \
static void * operator new(size_t size);
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro DECLARE_OBJECT
///
/// DECLARE_OBJECT sets up a class that derives from RcObject, RecyclableObject or
/// ZnObject:
/// - Prevent "C++ copy constructor" and "operator =()" methods.
/// - Must be allocated on heap. Because the copy constructor is hidden, this
/// requires an empty default constructor to be declared.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define DECLARE_OBJECT(ClassName) \
public: \
inline ClassName() { } \
private: \
ClassName(const ClassName & copy); \
ClassName & operator =(const ClassName & rhs);