Move enum class operators from replay_enums.h into main header

This commit is contained in:
baldurk
2017-09-01 15:08:07 +01:00
parent 276783b948
commit 2d219018cd
2 changed files with 138 additions and 138 deletions
+138
View File
@@ -206,6 +206,144 @@ typedef void(RENDERDOC_CC *pRENDERDOC_FreeArrayMem)(const void *mem);
extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_AllocArrayMem(uint64_t sz);
typedef void *(RENDERDOC_CC *pRENDERDOC_AllocArrayMem)(uint64_t sz);
#ifdef NO_ENUM_CLASS_OPERATORS
#define BITMASK_OPERATORS(a)
#define ITERABLE_OPERATORS(a)
#else
#include <type_traits>
// helper template that allows the result of & to be cast back to the enum or explicitly cast to
// bool for use in if() or ?: or so on or compared against 0.
//
// If you get an error about missing operator then you're probably doing something like
// (bitfield & value) == 0 or (bitfield & value) != 0 or similar. Instead prefer:
// !(bitfield & value) or (bitfield & value) to make use of the bool cast directly
template <typename enum_name>
struct EnumCastHelper
{
public:
constexpr EnumCastHelper(enum_name v) : val(v) {}
constexpr operator enum_name() const { return val; }
constexpr explicit operator bool() const
{
typedef typename std::underlying_type<enum_name>::type etype;
return etype(val) != 0;
}
private:
const enum_name val;
};
// helper templates for iterating over all values in an enum that has sequential values and is
// to be used for array indices or something like that.
template <typename enum_name>
struct ValueIterContainer
{
struct ValueIter
{
ValueIter(enum_name v) : val(v) {}
enum_name val;
enum_name operator*() const { return val; }
bool operator!=(const ValueIter &it) const { return !(val == *it); }
const inline enum_name operator++()
{
++val;
return val;
}
};
ValueIter begin() { return ValueIter(enum_name::First); }
ValueIter end() { return ValueIter(enum_name::Count); }
};
template <typename enum_name>
struct IndexIterContainer
{
typedef typename std::underlying_type<enum_name>::type etype;
struct IndexIter
{
IndexIter(enum_name v) : val(v) {}
enum_name val;
etype operator*() const { return etype(val); }
bool operator!=(const IndexIter &it) const { return !(val == it.val); }
const inline enum_name operator++()
{
++val;
return val;
}
};
IndexIter begin() { return IndexIter(enum_name::First); }
IndexIter end() { return IndexIter(enum_name::Count); }
};
template <typename enum_name>
constexpr inline ValueIterContainer<enum_name> values()
{
return ValueIterContainer<enum_name>();
};
template <typename enum_name>
constexpr inline IndexIterContainer<enum_name> indices()
{
return IndexIterContainer<enum_name>();
};
template <typename enum_name>
constexpr inline size_t arraydim()
{
typedef typename std::underlying_type<enum_name>::type etype;
return (size_t)etype(enum_name::Count);
};
// clang-format makes a even more of a mess of this multi-line macro than it usually does, for some
// reason. So we just disable it since it's still readable and this isn't really the intended case
// we are using clang-format for.
// clang-format off
#define BITMASK_OPERATORS(enum_name) \
\
constexpr inline enum_name operator|(enum_name a, enum_name b) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return enum_name(etype(a) | etype(b)); \
} \
\
constexpr inline EnumCastHelper<enum_name> operator&(enum_name a, enum_name b) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return EnumCastHelper<enum_name>(enum_name(etype(a) & etype(b))); \
} \
\
constexpr inline enum_name operator~(enum_name a) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return enum_name(~etype(a)); \
} \
\
inline enum_name &operator|=(enum_name &a, enum_name b) \
{ return a = a | b; } \
\
inline enum_name &operator&=(enum_name &a, enum_name b) \
{ return a = a & b; }
#define ITERABLE_OPERATORS(enum_name) \
\
inline enum_name operator++(enum_name &a) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return a = enum_name(etype(a)+1); \
}
// clang-format on
#endif
#define ENUM_ARRAY_SIZE(enum_name) size_t(enum_name::Count)
#include "basic_types.h"
#ifdef RENDERDOC_EXPORTS
-138
View File
@@ -25,144 +25,6 @@
#pragma once
#ifdef NO_ENUM_CLASS_OPERATORS
#define BITMASK_OPERATORS(a)
#define ITERABLE_OPERATORS(a)
#else
#include <type_traits>
// helper template that allows the result of & to be cast back to the enum or explicitly cast to
// bool for use in if() or ?: or so on or compared against 0.
//
// If you get an error about missing operator then you're probably doing something like
// (bitfield & value) == 0 or (bitfield & value) != 0 or similar. Instead prefer:
// !(bitfield & value) or (bitfield & value) to make use of the bool cast directly
template <typename enum_name>
struct EnumCastHelper
{
public:
constexpr EnumCastHelper(enum_name v) : val(v) {}
constexpr operator enum_name() const { return val; }
constexpr explicit operator bool() const
{
typedef typename std::underlying_type<enum_name>::type etype;
return etype(val) != 0;
}
private:
const enum_name val;
};
// helper templates for iterating over all values in an enum that has sequential values and is
// to be used for array indices or something like that.
template <typename enum_name>
struct ValueIterContainer
{
struct ValueIter
{
ValueIter(enum_name v) : val(v) {}
enum_name val;
enum_name operator*() const { return val; }
bool operator!=(const ValueIter &it) const { return !(val == *it); }
const inline enum_name operator++()
{
++val;
return val;
}
};
ValueIter begin() { return ValueIter(enum_name::First); }
ValueIter end() { return ValueIter(enum_name::Count); }
};
template <typename enum_name>
struct IndexIterContainer
{
typedef typename std::underlying_type<enum_name>::type etype;
struct IndexIter
{
IndexIter(enum_name v) : val(v) {}
enum_name val;
etype operator*() const { return etype(val); }
bool operator!=(const IndexIter &it) const { return !(val == it.val); }
const inline enum_name operator++()
{
++val;
return val;
}
};
IndexIter begin() { return IndexIter(enum_name::First); }
IndexIter end() { return IndexIter(enum_name::Count); }
};
template <typename enum_name>
constexpr inline ValueIterContainer<enum_name> values()
{
return ValueIterContainer<enum_name>();
};
template <typename enum_name>
constexpr inline IndexIterContainer<enum_name> indices()
{
return IndexIterContainer<enum_name>();
};
template <typename enum_name>
constexpr inline size_t arraydim()
{
typedef typename std::underlying_type<enum_name>::type etype;
return (size_t)etype(enum_name::Count);
};
// clang-format makes a even more of a mess of this multi-line macro than it usually does, for some
// reason. So we just disable it since it's still readable and this isn't really the intended case
// we are using clang-format for.
// clang-format off
#define BITMASK_OPERATORS(enum_name) \
\
constexpr inline enum_name operator|(enum_name a, enum_name b) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return enum_name(etype(a) | etype(b)); \
} \
\
constexpr inline EnumCastHelper<enum_name> operator&(enum_name a, enum_name b) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return EnumCastHelper<enum_name>(enum_name(etype(a) & etype(b))); \
} \
\
constexpr inline enum_name operator~(enum_name a) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return enum_name(~etype(a)); \
} \
\
inline enum_name &operator|=(enum_name &a, enum_name b) \
{ return a = a | b; } \
\
inline enum_name &operator&=(enum_name &a, enum_name b) \
{ return a = a & b; }
#define ITERABLE_OPERATORS(enum_name) \
\
inline enum_name operator++(enum_name &a) \
{ \
typedef typename std::underlying_type<enum_name>::type etype; \
return a = enum_name(etype(a)+1); \
}
// clang-format on
#endif
#define ENUM_ARRAY_SIZE(enum_name) size_t(enum_name::Count)
DOCUMENT(R"(A set of flags describing the properties of a path on a remote filesystem.
.. data:: NoFlags