ezEngine  Release 25.03
ezVariant Class Reference

ezVariant is a class that can store different types of variables, which is useful in situations where it is not clear up front, which type of data will be passed around. More...

#include <Variant.h>

Classes

struct  StringWrapper
 helper struct to wrap a string pointer More...
 

Public Types

using Type = ezVariantType
 
template<typename T >
using TypeDeduction = ezVariantTypeDeduction< T >
 

Public Member Functions

 ezVariant ()
 Initializes the variant to be 'Invalid'.
 
 ezVariant (const ezVariant &other)
 Copies the data from the other variant. More...
 
 ezVariant (ezVariant &&other) noexcept
 Moves the data from the other variant.
 
 ezVariant (const bool &value)
 
 ezVariant (const ezInt8 &value)
 
 ezVariant (const ezUInt8 &value)
 
 ezVariant (const ezInt16 &value)
 
 ezVariant (const ezUInt16 &value)
 
 ezVariant (const ezInt32 &value)
 
 ezVariant (const ezUInt32 &value)
 
 ezVariant (const ezInt64 &value)
 
 ezVariant (const ezUInt64 &value)
 
 ezVariant (const float &value)
 
 ezVariant (const double &value)
 
 ezVariant (const ezColor &value)
 
 ezVariant (const ezVec2 &value)
 
 ezVariant (const ezVec3 &value)
 
 ezVariant (const ezVec4 &value)
 
 ezVariant (const ezVec2I32 &value)
 
 ezVariant (const ezVec3I32 &value)
 
 ezVariant (const ezVec4I32 &value)
 
 ezVariant (const ezVec2U32 &value)
 
 ezVariant (const ezVec3U32 &value)
 
 ezVariant (const ezVec4U32 &value)
 
 ezVariant (const ezQuat &value)
 
 ezVariant (const ezMat3 &value)
 constructors
 
 ezVariant (const ezMat4 &value)
 
 ezVariant (const ezTransform &value)
 
 ezVariant (const char *value)
 
 ezVariant (const ezString &value)
 
 ezVariant (const ezUntrackedString &value)
 
 ezVariant (const ezStringView &value, bool bCopyString=true)
 
 ezVariant (const ezDataBuffer &value)
 
 ezVariant (const ezTime &value)
 
 ezVariant (const ezUuid &value)
 
 ezVariant (const ezAngle &value)
 
 ezVariant (const ezColorGammaUB &value)
 
 ezVariant (const ezHashedString &value)
 
 ezVariant (const ezTempHashedString &value)
 
 ezVariant (const ezVariantArray &value)
 
 ezVariant (const ezVariantDictionary &value)
 
 ezVariant (const ezTypedPointer &value)
 
 ezVariant (const ezTypedObject &value)
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::CustomTypeCast, int > = 0>
 ezVariant (const T &value)
 
template<typename T >
 ezVariant (const T *value)
 
 ezVariant (void *value, const ezRTTI *pType)
 Initializes to a TypedPointer of the given object and type.
 
void CopyTypedObject (const void *value, const ezRTTI *pType)
 Initializes to a TypedObject by cloning the given object and type.
 
void MoveTypedObject (void *value, const ezRTTI *pType)
 Initializes to a TypedObject by taking ownership of the given object and type.
 
 ~ezVariant ()
 If necessary, this will deallocate any heap memory that is not in use any more.
 
void operator= (const ezVariant &other)
 Copies the data from the other variant into this one.
 
void operator= (ezVariant &&other) noexcept
 Moves the data from the other variant into this one.
 
template<typename T >
void operator= (const T &value)
 Deduces the type of T and stores value. More...
 
bool operator== (const ezVariant &other) const
 Will compare the value of this variant to that of other. More...
 
 EZ_ADD_DEFAULT_OPERATOR_NOTEQUAL (const ezVariant &)
 
template<typename T >
bool operator== (const T &other) const
 See non-templated operator==.
 
bool IsValid () const
 Returns whether this variant stores any other type than 'Invalid'.
 
bool IsNumber () const
 Returns whether the stored type is numerical type either integer or floating point. More...
 
bool IsFloatingPoint () const
 Returns whether the stored type is floating point (float or double).
 
bool IsString () const
 Returns whether the stored type is a string (ezString or ezStringView).
 
bool IsHashedString () const
 Returns whether the stored type is a hashed string (ezHashedString or ezTempHashedString).
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > = 0>
bool IsA () const
 Returns whether the stored type is exactly the given type. More...
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::PointerCast, int > = 0>
bool IsA () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::TypedObject, int > = 0>
bool IsA () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::CustomTypeCast, int > = 0>
bool IsA () const
 
Type::Enum GetType () const
 Returns the exact ezVariant::Type value.
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > = 0>
const T & Get () const
 Returns the variants value as the provided type. More...
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::PointerCast, int > = 0>
Get () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::TypedObject, int > = 0>
const T Get () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::CustomTypeCast, int > = 0>
const T & Get () const
 
ezTypedPointer GetWriteAccess ()
 Returns an writable ezTypedPointer to the internal data. If the data is currently shared a clone will be made to ensure we hold the only reference.
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > = 0>
T & GetWritable ()
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::PointerCast, int > = 0>
GetWritable ()
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::CustomTypeCast, int > = 0>
T & GetWritable ()
 
const void * GetData () const
 Returns a const void* to the internal data. For TypedPointer and TypedObject this will return a pointer to the target object.
 
const ezRTTIGetReflectedType () const
 Returns the ezRTTI type of the held value. For TypedPointer and TypedObject this will return the type of the target object.
 
const ezVariant operator[] (ezUInt32 uiIndex) const
 Returns the sub value at iIndex. This could be an element in an array or a member property inside a reflected type. More...
 
const ezVariant operator[] (StringWrapper key) const
 Returns the sub value with szKey. This could be a value in a dictionary or a member property inside a reflected type. More...
 
template<typename T >
bool CanConvertTo () const
 Returns whether the stored type can generally be converted to the desired type. More...
 
bool CanConvertTo (Type::Enum type) const
 Same as the templated CanConvertTo function.
 
template<typename T >
ConvertTo (ezResult *out_pConversionStatus=nullptr) const
 Tries to convert the stored value to the given type. The optional status parameter can be used to check whether the conversion succeeded. More...
 
ezVariant ConvertTo (Type::Enum type, ezResult *out_pConversionStatus=nullptr) const
 Same as the templated function.
 
ezUInt64 ComputeHash (ezUInt64 uiSeed=0) const
 Computes the hash value of the stored data. Returns uiSeed (unchanged) for an invalid Variant.
 
template<typename T >
EZ_ALWAYS_INLINE void InitShared (const T &value)
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::CustomTypeCast, int > >
EZ_ALWAYS_INLINE ezVariant (const T &value)
 
template<typename T >
EZ_ALWAYS_INLINE ezVariant (const T *value)
 
template<typename T >
EZ_ALWAYS_INLINE void operator= (const T &value)
 
template<typename T >
EZ_FORCE_INLINE bool operator== (const T &other) const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > >
EZ_ALWAYS_INLINE bool IsA () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > >
const EZ_ALWAYS_INLINE T & Get () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::PointerCast, int > >
EZ_ALWAYS_INLINE T Get () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::TypedObject, int > >
const EZ_ALWAYS_INLINE T Get () const
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > >
EZ_ALWAYS_INLINE T & GetWritable ()
 
template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::PointerCast, int > >
EZ_ALWAYS_INLINE T GetWritable ()
 
template<typename T >
EZ_ALWAYS_INLINE bool CanConvertTo () const
 
template<typename T >
EZ_FORCE_INLINE void InitInplace (const T &value)
 private methods
 
template<typename T >
EZ_FORCE_INLINE void InitTypedObject (const T &value, ezTraitInt< 0 >)
 
template<typename T >
EZ_FORCE_INLINE void InitTypedObject (const T &value, ezTraitInt< 1 >)
 

Static Public Member Functions

template<typename Functor , class... Args>
static auto DispatchTo (Functor &ref_functor, Type::Enum type, Args &&... args)
 This will call the overloaded operator() (function call operator) of the provided functor. More...
 

Friends

class ezVariantHelper
 
struct CompareFunc
 
struct GetTypeFromVariantFunc
 

Detailed Description

ezVariant is a class that can store different types of variables, which is useful in situations where it is not clear up front, which type of data will be passed around.

The variant supports a fixed list of types that it can store (

See also
ezVariant::Type). All types of 16 bytes or less in size can be stored without requiring a heap allocation. For larger types memory is allocated on the heap. In general variants should be used for code that needs to be flexible. Although ezVariant is implemented very efficiently, it should be avoided to use ezVariant in code that needs to be fast.

Constructor & Destructor Documentation

◆ ezVariant()

EZ_ALWAYS_INLINE ezVariant::ezVariant ( const ezVariant other)

Copies the data from the other variant.

Note
If the data of the variant needed to be allocated on the heap, it will be shared among variants. Thus, once you have stored such a type inside a variant, you can copy it to other variants, without introducing additional memory allocations.

Member Function Documentation

◆ CanConvertTo()

template<typename T >
bool ezVariant::CanConvertTo ( ) const

Returns whether the stored type can generally be converted to the desired type.

This function will return true for all number conversions, as float / double / int / etc. can generally be converted into each other. It will also return true for all conversion from string to number types, and from all 'simple' types (not array or dictionary) to string.

Note
This function only returns whether a conversion between the stored TYPE and the desired TYPE is generally possible. It does NOT return whether the stored VALUE is indeed convertible to the desired type. For example, a string is generally convertible to float, if it stores a string representation of a float value. If, however, it stores anything else, the conversion can still fail.

The only way to figure out whether the stored data can be converted to some type, is to actually convert it, using ConvertTo(), and then to check the conversion status.

◆ ConvertTo()

template<typename T >
T ezVariant::ConvertTo ( ezResult out_pConversionStatus = nullptr) const

Tries to convert the stored value to the given type. The optional status parameter can be used to check whether the conversion succeeded.

When CanConvertTo() returns false, ConvertTo() will also always fail. However, when CanConvertTo() returns true, this is no guarantee that ConvertTo() will succeed. Conversion between numbers and to strings will generally succeed. However, converting from a string to another type can fail or succeed, depending on the exact string value.

◆ DispatchTo()

template<typename Functor , class... Args>
auto ezVariant::DispatchTo ( Functor &  ref_functor,
Type::Enum  type,
Args &&...  args 
)
static

This will call the overloaded operator() (function call operator) of the provided functor.

This allows to implement a functor that overloads operator() for different types and then call the proper version of that operator, depending on the provided runtime type. Note that the proper overload of operator() is selected by providing a dummy type, but it will contain no useful value. Instead, store the other necessary data inside the functor object, before calling this function. For example, store a pointer to a variant inside the functor object and then call DispatchTo to execute the function that will handle the given type of the variant.

◆ Get()

template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > = 0>
const T& ezVariant::Get ( ) const

Returns the variants value as the provided type.

Note
This function does not do ANY type of conversion from the stored type to the given type. Not even integer conversions! If the types don't match, this function will assert! So be careful to use this function only when you know exactly that the stored type matches the expected type.

Prefer to use ConvertTo() when you can instead.

◆ IsA()

template<typename T , typename std::enable_if_t< ezVariantTypeDeduction< T >::classification==ezVariantClass::DirectCast, int > = 0>
bool ezVariant::IsA ( ) const

Returns whether the stored type is exactly the given type.

Note
This explicitly also differentiates between the different integer types. So when the variant stores an Int32, IsA<Int64>() will return false, even though the types could be converted.

◆ IsNumber()

EZ_ALWAYS_INLINE bool ezVariant::IsNumber ( ) const

Returns whether the stored type is numerical type either integer or floating point.

Bool counts as number.

◆ operator=()

template<typename T >
void ezVariant::operator= ( const T &  value)

Deduces the type of T and stores value.

If the type to be stored in the variant is not supported, a compile time error will occur.

◆ operator==()

bool ezVariant::operator== ( const ezVariant other) const

Will compare the value of this variant to that of other.

public methods

If both variants store 'numbers' (float, double, int types) the comparison will work, even if the types are not identical.

Note
If the two types are not numbers and not equal, an assert will occur. So be careful to only compare variants that can either both be converted to double (
See also
CanConvertTo()) or whose types are equal.

◆ operator[]() [1/2]

const ezVariant ezVariant::operator[] ( ezUInt32  uiIndex) const

Returns the sub value at iIndex. This could be an element in an array or a member property inside a reflected type.

Out of bounds access is handled gracefully and will return an invalid variant.

◆ operator[]() [2/2]

const ezVariant ezVariant::operator[] ( StringWrapper  key) const

Returns the sub value with szKey. This could be a value in a dictionary or a member property inside a reflected type.

This function will return an invalid variant if no corresponding sub value is found.


The documentation for this class was generated from the following files: