Not efficient, but did the job. It can handle unlimited enum values.
For example
DEFINE_ENUM(Fruit, int32_t, PEAR = -100, APPLE, BANANA, ORANGE = 100, MANGO, STRAWBERRY = 75, WATERMELON = 100)
It generates
enum class Fruit : int32_t {
    PEAR = -100, APPLE, BANANA, ORANGE = 100, MANGO, STRAWBERRY = 75, WATERMELON = 100
};
[[nodiscard]] static inline std::string EnumFruitToString(const Fruit& value, bool includeEnumName = false) {
    using underlying = typename std::underlying_type<Fruit>::type;
    std::string values = "PEAR = -100, APPLE, BANANA, ORANGE = 100, MANGO, STRAWBERRY = 75, WATERMELON = 100";
    underlying integralValue = 0;
    std::vector<std::string> valuePairs = StringExtensions::Split(values, ", ");
    std::map<underlying, std::string> dictionary{};
    for (std::string str : valuePairs) {
        std::vector<std::string> keyAndValue = StringExtensions::Split(StringExtensions::Remove((includeEnumName ? "Fruit"s + "::"s : ""s) + str, " "), "=");
        if (keyAndValue.size() == 1) {
            dictionary.emplace(integralValue, keyAndValue[0]);
            integralValue += 1;
        } else {
            dictionary.emplace(StringExtensions::ToNumber<underlying>(keyAndValue[1]), keyAndValue[0]);
            integralValue = StringExtensions::ToNumber<underlying>(keyAndValue[1]) + 1;
        }
    }
    return StringExtensions::Trim(dictionary.at(static_cast<underlying>(value)));
}
Another example.
DEFINE_DEFAULT_ENUM(Animal, Dog, Cat, Monkey = 50, Fish, Human = 100, Duck, __COUNT)
It generates
enum class Animal : int {
    Dog, 
    Cat, 
    Monkey = 50, 
    Fish, 
    Human = 100, 
    Duck, 
    __COUNT
};
[[nodiscard]] static inline std::string EnumAnimalToString(const Animal& value, bool includeEnumName = false) {
    using underlying = typename std::underlying_type<Animal>::type;
    std::string values = "Dog, Cat, Monkey = 50, Fish, Human = 100, Duck, __COUNT";
    underlying integralValue = 0;
    std::vector<std::string> valuePairs = StringExtensions::Split(values, ", ");
    std::map<underlying, std::string> dictionary{};
    for (std::string str : valuePairs) {
        std::vector<std::string> keyAndValue = StringExtensions::Split(StringExtensions::Remove((includeEnumName ? "Animal"s + "::"s : ""s) + str, " "), "=");
        if (keyAndValue.size() == 1) {
            dictionary.emplace(integralValue, keyAndValue[0]);
            integralValue += 1;
        } else {
            dictionary.emplace(StringExtensions::ToNumber<underlying>(keyAndValue[1]), keyAndValue[0]);
            integralValue = StringExtensions::ToNumber<underlying>(keyAndValue[1]) + 1;
        }
    }
    return StringExtensions::Trim(dictionary.at(static_cast<underlying>(value)));
}
C++ Code
You can test/run in https://godbolt.org/z/PzMqfGoae
#include <iostream>
#include <string>
#include <iostream>
#include <type_traits>
#include <vector>
#include <map>
#include <sstream>
#define SPACE_STRING (" "s)
#define EQUAL_SIGN_STRING ("="s)
#define ARGUMENT_SEPARATOR_STRING (", "s)
#define NAMESPACE_SEPARATOR_STRING ("::"s)
#define EMPTY_STRING (""s)
using namespace std::string_literals;
#define TOSTR(value) std::to_string(value)
class StringExtensions
{
public:
    static std::string Remove(const std::string& data, const std::string& toRemove)
    {
        std::string result = data;
        size_t pos = 0;
        while ((pos = result.find(toRemove, pos)) != std::string::npos)
        {
            result.erase(pos, toRemove.length());
        }
        return result;
    }
    [[nodiscard]] static std::vector<std::string> Split(const std::string& data, const std::string& toFind)
    {
        std::vector<std::string> v;
        if (data.empty() || toFind.empty())
        {
            v.push_back(data);
            return v;
        }
        size_t ini = 0;
        size_t pos;
        while ((pos = data.find(toFind, ini)) != std::string::npos)
        {
            std::string s = data.substr(ini, pos - ini);
            if (!s.empty())
            {
                v.push_back(s);
            }
            ini = pos + toFind.length();
        }
        if (ini < data.length())
        {
            v.push_back(data.substr(ini));
        }
        return v;
    }
    [[nodiscard]] static std::string TrimStart(const std::string& data)
    {
        std::string s = data;
        s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch)
            { return !std::isspace(ch); }));
        return s;
    }
    [[nodiscard]] static std::string TrimEnd(const std::string& data)
    {
        std::string s = data;
        s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch)
            { return !std::isspace(ch); })
            .base(),
            s.end());
        return s;
    }
    [[nodiscard]] static std::string Trim(const std::string& data)
    {
        return TrimEnd(TrimStart(data));
    }
    template <typename T>
    [[nodiscard]]  static T ToNumber(const std::string& str) requires std::is_integral_v<T> {
        std::stringstream ss(str);
        T result;
        ss >> result;
        return result;
    }
private:
};
class EnumExtensions {
public:
    template <typename T>
    [[nodiscard]] static std::string ToEnumValueString(const T& enumValue)
        requires std::is_enum_v<T>
    {
        using UnderlyingType = typename std::underlying_type<T>::type;
        UnderlyingType integralValue = static_cast<UnderlyingType>(enumValue);
        return TOSTR(integralValue);
    }
};
#define DEFINE_ENUM(Name,UnderlyingT,...) \
    enum class Name : UnderlyingT { __VA_ARGS__ }; \
    [[nodiscard]] static inline std::string Enum##Name##ToString(const Name &value, bool includeEnumName=false) { \
        using underlying = typename std::underlying_type<Name>::type; \
        std::string values = #__VA_ARGS__; \
        underlying integralValue = 0; \
        std::vector<std::string> valuePairs = StringExtensions::Split(values, ARGUMENT_SEPARATOR_STRING); \
        std::map<underlying, std::string> dictionary{}; \
        for (std::string str : valuePairs) \
        { \
            std::vector<std::string> keyAndValue = StringExtensions::Split(StringExtensions::Remove((includeEnumName? #Name##s + NAMESPACE_SEPARATOR_STRING : EMPTY_STRING) + str, SPACE_STRING), EQUAL_SIGN_STRING); \
            if (keyAndValue.size() == 1) \
            { \
                dictionary.emplace(integralValue, keyAndValue[0]); \
                integralValue += 1; \
            } \
            else \
            { \
                dictionary.emplace(StringExtensions::ToNumber<underlying>(keyAndValue[1]), keyAndValue[0]); \
                integralValue = StringExtensions::ToNumber<underlying>(keyAndValue[1]) + 1; \
            } \
        } \
        return StringExtensions::Trim(dictionary.at(static_cast<underlying>(value))); \
    } \
#define DEFINE_DEFAULT_ENUM(Name,...) DEFINE_ENUM(Name,int,__VA_ARGS__)
namespace MyNamespace
{
    DEFINE_ENUM(Fruit, int32_t, PEAR = -100, APPLE, BANANA, ORANGE = 100, MANGO, STRAWBERRY = 75, WATERMELON = 100)
    DEFINE_DEFAULT_ENUM(Animal, Dog, Cat, Monkey = 50, Fish, Human = 100, Duck, __COUNT)
}
#define PRINT_ENUM(enumName,value,underlyingT,includeEnumName) std::cout << Enum##enumName##ToString(value, includeEnumName) << " --- " << EnumExtensions::ToEnumValueString(value) << std::endl
int main() {
    using namespace MyNamespace;
    //std::cout << EnumFruitToString(Fruit::PEAR, true) << " --- " << EnumExtensions::ToEnumValueString(Fruit::PEAR) << std::endl
    PRINT_ENUM(Fruit,Fruit::PEAR, int32_t, true);
    PRINT_ENUM(Fruit, Fruit::APPLE, int32_t, true);
    PRINT_ENUM(Fruit, Fruit::BANANA, int32_t, true);
    PRINT_ENUM(Fruit, Fruit::ORANGE, int32_t, true);
    PRINT_ENUM(Fruit, Fruit::MANGO, int32_t, true);
    PRINT_ENUM(Fruit, Fruit::STRAWBERRY, int32_t, true);
    PRINT_ENUM(Fruit, Fruit::WATERMELON, int32_t, true);
    //std::cout << EnumAnimalToString(Animal::Dog, true) << " --- " << EnumExtensions::ToEnumValueString(Animal::Dog) << std::endl
    PRINT_ENUM(Animal, Animal::Dog, int, true);
    PRINT_ENUM(Animal, Animal::Cat, int, true);
    PRINT_ENUM(Animal, Animal::Monkey, int, false);
    PRINT_ENUM(Animal, Animal::Fish, int, false);
    PRINT_ENUM(Animal, Animal::Human, int, false);
    PRINT_ENUM(Animal, Animal::Duck, int, false);
    PRINT_ENUM(Animal, Animal::__COUNT, int, false);
    
    std::cin.get();
    return 0;
}
Output
Fruit::PEAR --- -100
Fruit::APPLE --- -99
Fruit::BANANA --- -98
Fruit::ORANGE --- 100
Fruit::MANGO --- 101
Fruit::STRAWBERRY --- 75
Fruit::ORANGE --- 100
Animal::Dog --- 0
Animal::Cat --- 1
Monkey --- 50
Fish --- 51
Human --- 100
Duck --- 101
__COUNT --- 102
VisualC++

ClangX86-64 - Godbolt.org

 
New update. Alternative. This syntax is a bit ugly. But generates more efficient code.
More complete/efficient code. But can handle up to 170 enum values, if you need more than 170 feel free to modify this code. This code generates extensions methods for manipulate enum.
- ToString - returns the name of enum. If another enum has the same numeric value, the returned name is the first enum with value.
- ToIntegralString - returns the numeric value to string.
- ToIntegral - returns the numeric value of enum. The type is the underlying type of enum.
- Parse - convert the string to enum value, it can throws an exception.
- Parse - convert the numeric value to enum value, the numeric value type is the same unlying type of enum, it can throws an exception.
- GetValues - return a vector with all enun values.
Syntax
EZNUM_ENUM(EnumName,Var1,Oper1,Val1,Var2,Oper2,Val2,......,Var170,Oper170,Val170)
EZNUM_ENUM_UT(EnumName,UType,Var1,Oper1,Val1,Var2,Oper2,Val2,......,Var170,Oper170,Val170)
- EnumName - Name of enum class.
- UType - Name of underlying type.
- VarN - Name of enum value.
- OperN - Assignment operator can be EQ for equals or _ for no operator.
- ValN - Underlying type value. If OperN is _this value is ignored.
this macro needs groups of 3 - Var,Oper,Val
examples:
X,_,_ it generates X
Y,EQ,2 | it generates Y = 2
Z,_,2 | it generates Z
For example
EZNUM_ENUM(MobaGame,
        Dota2, EQ, 100,
        LeagueOfLegends, EQ, 101,
        HeroesOfTheStorm, EQ, 102,
        Smite, EQ, 103,
        Vainglory, EQ, 104,
        ArenaOfValor, EQ, 105,
        Paragon, EQ, 106,
        HeroesOfNewerth, EQ, -100)
It generates
enum class MobaGame : int
{
    Dota2 = 100,
    LeagueOfLegends = 101,
    HeroesOfTheStorm = 102,
    Smite = 103,
    Vainglory = 104,
    ArenaOfValor = 105,
    Paragon = 106,
    HeroesOfNewerth = -100,
};
class MobaGameEnumExtensions
{
public:
    [[nodiscard]] static String ToIntegralString(const MobaGame &value)
    {
        using namespace Extensions;
        return EnumExtensions::ToIntegralString(value);
    }
    [[nodiscard]] static int ToIntegral(const MobaGame &value)
    {
        using namespace Extensions;
        return EnumExtensions::ToIntegral<MobaGame>(value);
    }
    [[nodiscard]] static std::string ToString(const MobaGame &value, bool includeEnumName = false)
    {
        using namespace Extensions;
        static const std::map<MobaGame, String> values = {
            {MobaGame::Dota2, "Dota2"},
            {MobaGame::LeagueOfLegends, "LeagueOfLegends"},
            {MobaGame::HeroesOfTheStorm, "HeroesOfTheStorm"},
            {MobaGame::Smite, "Smite"},
            {MobaGame::Vainglory, "Vainglory"},
            {MobaGame::ArenaOfValor, "ArenaOfValor"},
            {MobaGame::Paragon, "Paragon"},
            {MobaGame::HeroesOfNewerth, "HeroesOfNewerth"},
        };
        return includeEnumName ? "MobaGame::"s + values.at(value) : values.at(value);
    }
    [[nodiscard]] static MobaGame Parse(const int &value)
    {
        using namespace Exceptions;
        static const std::map<int, MobaGame> values = {
            {static_cast<int>(MobaGame::Dota2), MobaGame::Dota2},
            {static_cast<int>(MobaGame::LeagueOfLegends), MobaGame::LeagueOfLegends},
            {static_cast<int>(MobaGame::HeroesOfTheStorm), MobaGame::HeroesOfTheStorm},
            {static_cast<int>(MobaGame::Smite), MobaGame::Smite},
            {static_cast<int>(MobaGame::Vainglory), MobaGame::Vainglory},
            {static_cast<int>(MobaGame::ArenaOfValor), MobaGame::ArenaOfValor},
            {static_cast<int>(MobaGame::Paragon), MobaGame::Paragon},
            {static_cast<int>(MobaGame::HeroesOfNewerth), MobaGame::HeroesOfNewerth},
        };
        try
        {
            return values.at(value);
        }
        catch (...)
        {
            throw ParseException("MobaGame::Parse"s);
        }
    }
    [[nodiscard]] static MobaGame Parse(const String &value)
    {
        using namespace Exceptions;
        using namespace Extensions;
        static const std::map<String, MobaGame> values = {
            {"Dota2", MobaGame::Dota2},
            {"LeagueOfLegends", MobaGame::LeagueOfLegends},
            {"HeroesOfTheStorm", MobaGame::HeroesOfTheStorm},
            {"Smite", MobaGame::Smite},
            {"Vainglory", MobaGame::Vainglory},
            {"ArenaOfValor", MobaGame::ArenaOfValor},
            {"Paragon", MobaGame::Paragon},
            {"HeroesOfNewerth", MobaGame::HeroesOfNewerth},
            {"MobaGame::Dota2"s, MobaGame::Dota2},
            {"MobaGame::LeagueOfLegends"s, MobaGame::LeagueOfLegends},
            {"MobaGame::HeroesOfTheStorm"s, MobaGame::HeroesOfTheStorm},
            {"MobaGame::Smite"s, MobaGame::Smite},
            {"MobaGame::Vainglory"s, MobaGame::Vainglory},
            {"MobaGame::ArenaOfValor"s, MobaGame::ArenaOfValor},
            {"MobaGame::Paragon"s, MobaGame::Paragon},
            {"MobaGame::HeroesOfNewerth"s, MobaGame::HeroesOfNewerth},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::Dota2)), MobaGame::Dota2},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::LeagueOfLegends)), MobaGame::LeagueOfLegends},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::HeroesOfTheStorm)), MobaGame::HeroesOfTheStorm},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::Smite)), MobaGame::Smite},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::Vainglory)), MobaGame::Vainglory},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::ArenaOfValor)), MobaGame::ArenaOfValor},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::Paragon)), MobaGame::Paragon},
            {IntegralExtensions::ToString(static_cast<int>(MobaGame::HeroesOfNewerth)), MobaGame::HeroesOfNewerth},
        };
        try
        {
            return values.at(value);
        }
        catch (...)
        {
            throw ParseException("MobaGame::Parse"s);
        }
    }
    [[nodiscard]] static std::vector<MobaGame> GetValues()
    {
        return {
            MobaGame::Dota2,
            MobaGame::LeagueOfLegends,
            MobaGame::HeroesOfTheStorm,
            MobaGame::Smite,
            MobaGame::Vainglory,
            MobaGame::ArenaOfValor,
            MobaGame::Paragon,
            MobaGame::HeroesOfNewerth,
        };
    }
};
std::ostream &operator<<(std::ostream &os, const MobaGame &value)
{
    os << MobaGameEnumExtensions::ToString(value);
    return os;
}
Using this
EZNUM_ENUM_UT(MobaGame,int32_t
        Dota2, EQ, 100,
        LeagueOfLegends, EQ, 101,
        HeroesOfTheStorm, EQ, 102,
        Smite, EQ, 103,
        Vainglory, EQ, 104,
        ArenaOfValor, EQ, 105,
        Paragon, _, _,
        HeroesOfNewerth, _, _)
`
It generates
enum class MobaGame : int32_t
{
    Dota2 = 100,
    LeagueOfLegends = 101,
    HeroesOfTheStorm = 102,
    Smite = 103,
    Vainglory = 104,
    ArenaOfValor = 105,
    Paragon,
    HeroesOfNewerth,
};
class MobaGameEnumExtensions
{
public:
    [[nodiscard]] static String ToIntegralString(const MobaGame &value)
    {
        using namespace Extensions;
        return EnumExtensions::ToIntegralString(value);
    }
    [[nodiscard]] static int32_t ToIntegral(const MobaGame &value)
    {
        using namespace Extensions;
        return EnumExtensions::ToIntegral<MobaGame>(value);
    }
    [[nodiscard]] static std::string ToString(const MobaGame &value, bool includeEnumName = false)
    {
        using namespace Extensions;
        static const std::map<MobaGame, String> values = {
            {MobaGame::Dota2, "Dota2"},
            {MobaGame::LeagueOfLegends, "LeagueOfLegends"},
            {MobaGame::HeroesOfTheStorm, "HeroesOfTheStorm"},
            {MobaGame::Smite, "Smite"},
            {MobaGame::Vainglory, "Vainglory"},
            {MobaGame::ArenaOfValor, "ArenaOfValor"},
            {MobaGame::Paragon, "Paragon"},
            {MobaGame::HeroesOfNewerth, "HeroesOfNewerth"},
        };
        return includeEnumName ? "MobaGame::"s + values.at(value) : values.at(value);
    }
    [[nodiscard]] static MobaGame Parse(const int32_t &value)
    {
        using namespace Exceptions;
        static const std::map<int32_t, MobaGame> values = {
            {static_cast<int32_t>(MobaGame::Dota2), MobaGame::Dota2},
            {static_cast<int32_t>(MobaGame::LeagueOfLegends), MobaGame::LeagueOfLegends},
            {static_cast<int32_t>(MobaGame::HeroesOfTheStorm), MobaGame::HeroesOfTheStorm},
            {static_cast<int32_t>(MobaGame::Smite), MobaGame::Smite},
            {static_cast<int32_t>(MobaGame::Vainglory), MobaGame::Vainglory},
            {static_cast<int32_t>(MobaGame::ArenaOfValor), MobaGame::ArenaOfValor},
            {static_cast<int32_t>(MobaGame::Paragon), MobaGame::Paragon},
            {static_cast<int32_t>(MobaGame::HeroesOfNewerth), MobaGame::HeroesOfNewerth},
        };
        try
        {
            return values.at(value);
        }
        catch (...)
        {
            throw ParseException("MobaGame::Parse"s);
        }
    }
    [[nodiscard]] static MobaGame Parse(const String &value)
    {
        using namespace Exceptions;
        using namespace Extensions;
        static const std::map<String, MobaGame> values = {
            {"Dota2", MobaGame::Dota2},
            {"LeagueOfLegends", MobaGame::LeagueOfLegends},
            {"HeroesOfTheStorm", MobaGame::HeroesOfTheStorm},
            {"Smite", MobaGame::Smite},
            {"Vainglory", MobaGame::Vainglory},
            {"ArenaOfValor", MobaGame::ArenaOfValor},
            {"Paragon", MobaGame::Paragon},
            {"HeroesOfNewerth", MobaGame::HeroesOfNewerth},
            {"MobaGame::Dota2"s, MobaGame::Dota2},
            {"MobaGame::LeagueOfLegends"s, MobaGame::LeagueOfLegends},
            {"MobaGame::HeroesOfTheStorm"s, MobaGame::HeroesOfTheStorm},
            {"MobaGame::Smite"s, MobaGame::Smite},
            {"MobaGame::Vainglory"s, MobaGame::Vainglory},
            {"MobaGame::ArenaOfValor"s, MobaGame::ArenaOfValor},
            {"MobaGame::Paragon"s, MobaGame::Paragon},
            {"MobaGame::HeroesOfNewerth"s, MobaGame::HeroesOfNewerth},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::Dota2)), MobaGame::Dota2},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::LeagueOfLegends)), MobaGame::LeagueOfLegends},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::HeroesOfTheStorm)), MobaGame::HeroesOfTheStorm},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::Smite)), MobaGame::Smite},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::Vainglory)), MobaGame::Vainglory},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::ArenaOfValor)), MobaGame::ArenaOfValor},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::Paragon)), MobaGame::Paragon},
            {IntegralExtensions::ToString(static_cast<int32_t>(MobaGame::HeroesOfNewerth)), MobaGame::HeroesOfNewerth},
        };
        try
        {
            return values.at(value);
        }
        catch (...)
        {
            throw ParseException("MobaGame::Parse"s);
        }
    }
    [[nodiscard]] static std::vector<MobaGame> GetValues()
    {
        return {
            MobaGame::Dota2,
            MobaGame::LeagueOfLegends,
            MobaGame::HeroesOfTheStorm,
            MobaGame::Smite,
            MobaGame::Vainglory,
            MobaGame::ArenaOfValor,
            MobaGame::Paragon,
            MobaGame::HeroesOfNewerth,
        };
    }
};
std::ostream &operator<<(std::ostream &os, const MobaGame &value)
{
    os << MobaGameEnumExtensions::ToString(value);
    return os;
}
Full code
You can test/run/any this code from https://github.com/JomaStackOverflowAnswers/EnumExtensionsCpp
https://godbolt.org/z/vx3YYTafh
https://replit.com/@JomaCorpFX/EnumExtensions
It can't be pasted here. Too long code.
Here. The main program part
namespace Enums
{
    EZNUM_ENUM_UT(Variables, int,
        X, _, _,
        Y, EQ, 25,
        Z, EQ, 75)
        EZNUM_ENUM_UT(Fruit, int32_t,
            PEAR, EQ, -100,
            APPLE, _, _,
            BANANA, _, _,
            ORANGE, EQ, 100,
            MANGO, _, _,
            STRAWBERRY, EQ, 75,
            WATERMELON, EQ, 100)
        EZNUM_ENUM(Animal,
            Dog, _, _,
            Cat, _, _,
            Monkey, EQ, 50,
            Fish, _, _,
            Human, EQ, 100,
            Duck, _, _,
            __COUNT, _, _)
        EZNUM_ENUM_UT(MathVars32, int32_t,
            X, _, _,
            Y, _, _,
            Z, EQ, 75)
        EZNUM_ENUM_UT(MathVars64, int64_t,
            X, _, _,
            Y, _, _,
            Z, EQ, 75)
        EZNUM_ENUM(Vowels,
            A, EQ, 75,
            E, _, _,
            I, EQ, 1500,
            O, EQ, -5,
            U, _, _)
        EZNUM_ENUM(MobaGame,
            Dota2, EQ, 100,
            LeagueOfLegends, EQ, 101,
            HeroesOfTheStorm, EQ, 102,
            Smite, EQ, 103,
            Vainglory, EQ, 104,
            ArenaOfValor, EQ, 105,
            Paragon, EQ, 106,
            HeroesOfNewerth, EQ, -100)
}
#define PRINT_VALUES(Name) std::cout << "EnumName: "s + #Name << std::endl; \
std::cout << StringExtensions::PadRight(EMPTY_STRING , 21 + 128, '_') << std::endl; \
for (Name element : Name##EnumExtensions::GetValues()) \
{ \
    std::cout << StringExtensions::PadRight(Name##EnumExtensions::ToString(element), 16) << " | " << \
        StringExtensions::PadRight(Name##EnumExtensions::ToString(element, true),32) << " | " << \
        StringExtensions::PadRight(Name##EnumExtensions::ToIntegralString(element),8) << " | " << \
        StringExtensions::PadRight(IntegralExtensions::ToString(Name##EnumExtensions::ToIntegral(element)),8) << " | " << \
        StringExtensions::PadRight(Name##EnumExtensions::ToString(Name##EnumExtensions::Parse(Name##EnumExtensions::ToString(element))),16) << " | " << \
        StringExtensions::PadRight(Name##EnumExtensions::ToString(Name##EnumExtensions::Parse(Name##EnumExtensions::ToString(element, true))),16) << " | " << \
        StringExtensions::PadRight(Name##EnumExtensions::ToString(Name##EnumExtensions::Parse(Name##EnumExtensions::ToIntegralString(element))),16) << " | " << \
        StringExtensions::PadRight(Name##EnumExtensions::ToString(Name##EnumExtensions::Parse(Name##EnumExtensions::ToIntegral(element))),16) << std::endl; \
} \
std::cout<< std::endl;
int main() {
    using namespace Enums;
    using namespace Extensions;
    PRINT_VALUES(Variables)
    PRINT_VALUES(Fruit)
    PRINT_VALUES(Animal)
    PRINT_VALUES(MathVars32)
    PRINT_VALUES(MathVars64)
    PRINT_VALUES(Vowels)
    PRINT_VALUES(MobaGame)
/*  std::cout << "EnumName: "s + "MobaGame" << std::endl;
    std::cout << StringExtensions::PadRight(EMPTY_STRING, 21 + 128, '_') << std::endl;
    for (MobaGame element : MobaGameEnumExtensions::GetValues())
    {
        std::cout << StringExtensions::PadRight(MobaGameEnumExtensions::ToString(element), 16) << " | " << StringExtensions::PadRight(MobaGameEnumExtensions::ToString(element, true), 32) << " | " << StringExtensions::PadRight(MobaGameEnumExtensions::ToIntegralString(element), 8) << " | " << StringExtensions::PadRight(IntegralExtensions::ToString(MobaGameEnumExtensions::ToIntegral(element)), 8) << " | " << StringExtensions::PadRight(MobaGameEnumExtensions::ToString(MobaGameEnumExtensions::Parse(MobaGameEnumExtensions::ToString(element))), 16) << " | " << StringExtensions::PadRight(MobaGameEnumExtensions::ToString(MobaGameEnumExtensions::Parse(MobaGameEnumExtensions::ToString(element, true))), 16) << " | " << StringExtensions::PadRight(MobaGameEnumExtensions::ToString(MobaGameEnumExtensions::Parse(MobaGameEnumExtensions::ToIntegralString(element))), 16) << " | " << StringExtensions::PadRight(MobaGameEnumExtensions::ToString(MobaGameEnumExtensions::Parse(MobaGameEnumExtensions::ToIntegral(element))), 16) << std::endl;
    }
    std::cout << std::endl;*/
    std::cin.get();
    return 0;
}
Output
VisualC++

Godbolt.org
