GitHub - gregorburger/variant: typesafe tagged union with "don't call us, we'll call you" feature (original) (raw)

Variant

Build Status

Basic Features:

using types_t = nonstd::variant<int, float, std::string>; types_t _int(42);

std::cout << _int.get() << "\n"; //prints 42 _int.set(100);

double d = _int.get(); //won't compile bool is_double = _int.is(); //is_double = true

types_t _empty; bool is_empty = _empty.empty(); //is_empty = true _empty.setstd::string(std::string("Hello, World!");

Advanced Features:

Select on Callback:

This is like a switch case statement

using types_t = nonstd::variant<int, float, std::string>; std::vector v = {10, 10.10f, std::string("ten")};

for (auto & t: v) { t.select<int, float, std::string>( [](int &x){x = 42;}, [](float &x){x = 42.42f;}, [](std::string &x){x = "fortytwo";} ); }

Select on member function:

This is like inheritance without inheritance

//test classes defined below

using types_t = nonstd::variant<test_class, test_class_1, test_class_2, test_class_3>; std::vector v = {test_class{}, test_class_1{}, test_class_2{}, test_class_3{}};

//call member functions for (auto & t: v) { auto args = std::make_tuple(pod_parm{}); t.select(args, &test_class::print, &test_class_1::print, &test_class_2::print); }

//visitation using perfect forwarding for (auto & t: v) { pod_parm arg; t.visit(&test_class::print, &test_class_1::print, &test_class_2::print)(arg); }

//test classes struct pod_parm { int i = 42; };

struct test_class { test_class() : x(100), z(100.0f) {} int x; float z; int print(pod_parm &_p) { called = true; _p.i = -_p.i; return -10; } bool called = false; };

struct test_class_1 { int print(pod_parm &_p) { called = true; _p.i = -_p.i; return -10; } bool called = false; };

struct test_class_2 { int print(pod_parm &_p) { called = true; _p.i = -_p.i; return -10; } bool called = false; };

struct test_class_3 { int print(pod_parm &_p) { called = true; _p.i = -_p.i; return -10; } bool called = false; };