mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Move enum class operators from replay_enums.h into main header
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user