[FR] Add support for enum and enum class in juce::var

With a very small change, it is possible to support enum and enum class types in a juce::var.

In juce_Variant.h

template <typename Type>
struct VariantConverter
{
    static Type fromVar (const var& v)             { return static_cast<Type> (v); }
    static var toVar (const Type& t)               { return t; }
};

can be changed to (note the extra defaulted template parameter):

template <typename Type, typename = void>
struct VariantConverter
{
    static Type fromVar (const var& v)             { return static_cast<Type> (v); }
    static var toVar (const Type& t)               { return t; }
};

This would then allow - either built into juce (as in the case of juce::String) or added by the user/developer like any other custom variant converter:

template<typename EnumType>
struct juce::VariantConverter<EnumType, typename std::enable_if_t<std::is_enum_v<EnumType>>>
{
    static EnumType fromVar(const juce::var& v)
    {
        return static_cast<EnumType>(static_cast<int>(v));
    }

    static juce::var toVar (const EnumType& e)
    {
        return static_cast<int>(e);
    }
};

At which point you can then use any enum and enum class in a juce::var without writing specific converters, e.g:

enum class EnumClassType { zero, one, two, three };
enum EnumType { four = 4, five };

auto enumClassValue = EnumClassType::two;
auto enumValue = EnumType::five;

auto enumClassVar = juce::VariantConverter<EnumClassType>::toVar (enumClassValue);

auto enumVar = juce::VariantConverter<EnumType>::toVar (enumValue);

I thought I’d share this as it may be something we’d like to get added to juce.

static_cast<int>(v)

That wouldn’t work if the enum class is of type int64. Either you store everything as int64 to give yourself the max headroom, or you’d have to figure out if the underlying type is int32 or int64 (using std::underlying_type and some other trickery).

1 Like