Listings Wilkening/Magic Enum


Listing 1: Operatoren und Funktionen des Enums myint definieren
enum class myint : int {};

myint operator+(myint lhs, myint rhs)
{
    return { static_cast<int>(lhs) + static_cast<int>(rhs) };
}

myint x1 { 20 };
myint x2 { 22 };
auto answer = x1 + x2;

-------

Listing 2: Ausgabe von Enum-Werten mithilfe eines Operators
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum::ostream_operators;    // <<<<<

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    Color color = Color::BLUE;
    cout << color << ' ' << Color::RED << '\n';
}

// Ausgabe ist BLUE RED

-------

Listing 3: Textumwandlung mit der Funktion enum_name von Magic Enum
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    Color color = Color::RED;
    auto name1 = magic_enum::enum_name(color);
    auto name2 = magic_enum::enum_name(Color::BLUE);
    cout << name1 << ' ' << name2 << '\n';
}

// Ausgabe ist RED BLUE

-------

Listing 4: String zu Enum wandeln
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    cout << boolalpha;

    string s("GREEN");
    optional<Color> color = enum_cast<Color>(s);
    cout << s << " => " << color.has_value() << " -> " << static_cast<int>(*color) << '\n';

    s = "green";
    color = enum_cast<Color>(s);
    cout << s << " => " << color.has_value() << '\n';
}

// Ausgabe ist
// GREEN => true -> 8
// green => false

-------

Listing 5: Wertüberprüfung mit der Funktion enum_cast
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;
using namespace magic_enum::ostream_operators;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    cout << boolalpha;

    int x = 4;
    optional<Color> color = enum_cast<Color>(x);
    cout << x << " => " << color.has_value() << " -> " << *color << '\n';

    x = 6;
    color = enum_cast<Color>(x);
    cout << x << " => " << color.has_value() << '\n';
}

// Ausgabe ist
// 4 => true -> BLUE
// 6 => false

-------

Listing 6: Konstanten mit enum_count ermitteln
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };
enum E { C1, C2, C3, C4, C5 };

int main()
{
    constexpr size_t count1 = enum_count<Color>();
    constexpr size_t count2 = enum_count<E>();

    cout << "Color: " << count1 << '\n';
    cout << "E: " << count2 << '\n';
}

// Ausgabe ist
// Color: 3
// E: 5

-------

Listing 7: Indexbasierter Zugriff mit der Funktion enum_value
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;
using namespace magic_enum::ostream_operators;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    for (size_t idx = 0; idx < enum_count<Color>(); ++idx)
    {
      Color color = enum_value<Color>(idx);
      cout << color << ' ';
    }
    cout << '\n';
}

// Ausgabe ist
// RED BLUE GREEN

-------

Listing 8: Die Funktion enum_integer wandelt einen Enum
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    Color color = Color::RED;
    auto value1 = enum_integer(color);
    auto value2 = enum_integer(Color::BLUE);
    cout << value1 << ' ' << value2 << ' ' << enum_integer(Color::GREEN) << '\n';
}

// Ausgabe
// 2 4 8

-------

Listing 9: Die Funktion enum_values stellt alle Enum-Konstanten bereit
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;
using namespace magic_enum::ostream_operators;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    constexpr auto colors = enum_values<Color>();
    cout << "Anzahl: " << colors.size() << '\n';
    for (Color c : colors)
    {
      cout << "- " << c << '\n';
    }
}

// Ausgabe ist
// Anzahl: 3
// - RED
// - BLUE
// - GREEN

-------

Listing 10: Enum-Namen ermitteln
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    constexpr auto names = enum_names<Color>();   
    cout << "Anzahl: " << names.size() << '\n';
    for (const string_view& name : names)
    {
      cout << "- " << name << '\n';
    }
}

// Ausgabe ist
// Anzahl: 3
// - RED
// - BLUE
// - GREEN

-------

Listing 11: Ausgabe eines Arrays
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;

enum class Color { RED = 2, BLUE = 4, GREEN = 8 };

int main()
{
    constexpr auto entries = enum_entries<Color>();
    cout << "Anzahl: " << entries.size() << '\n';
    for (auto& [color, name] : entries)
    {
      cout << "- " << enum_integer(color) << " => " << name << '\n';
    }
}

// Ausgabe ist
// Anzahl: 3
// - 2 => RED
// - 4 => BLUE
// - 8 => GREEN

-------

Listing 12: Magic Enum stellt über eine using-Anweisung die Bit-Operatoren bereit
#include <iostream>
#include <magic_enum.hpp>
using namespace std;
using namespace magic_enum;
using namespace magic_enum::bitwise_operators; 

enum class State { Null = 0, Visible = 1, Enable = 2, Checked = 4 };

int main()
{
    State s1 = State::Visible | State::Checked;
    cout << enum_integer(s1) << '\n';

    if ((s1 & State::Visible) != State::Null)
    {
      cout << "Sichtbar\n";
    }

    if ((s1 & State::Enable) != State::Null)
    {
      cout << "Aktiviert\n";
    }
    else
    {
      cout << "Deaktiviert\n";
    }
}

// Ausgabe ist
// 5
// Sichtbar
// Deaktiviert
