Go to file
2018-01-18 00:02:06 +01:00
source Add the TypeOf template. 2018-01-17 23:53:57 +01:00
.codecov.yml Switch to codecov.io. 2018-01-18 00:02:06 +01:00
.editorconfig Add .travis.yml and .editorconfig. See #2. 2016-01-27 23:02:37 +01:00
.travis.yml Test on DMD 2.078.0 and LDC 1.7.0. 2018-01-17 23:55:17 +01:00
dub.sdl Convert package recipe to SDLang. 2016-07-04 11:18:58 +02:00
README.md Switch to codecov.io. 2018-01-18 00:02:06 +01:00
travis.sh Switch to codecov.io. 2018-01-18 00:02:06 +01:00

TaggedAlgebraic

Implementation of a generic algebraic data type with a tagged union storage. All operations of the contained types are available for the TaggedAlgebraic

Build Status codecov

Usage

import taggedalgebraic;

struct Foo {
	string name;
	void bar() {}
}

union Base {
	int i;
	string str;
	Foo foo;
}

alias Tagged = TaggedAlgebraic!Base;

// Instantiate
Tagged taggedInt = 5;
Tagged taggedString = "Hello";
Tagged taggedFoo = Foo();
Tagged taggedAny = taggedInt;
taggedAny = taggedString;
taggedAny = taggedFoo;

// Check type: Tagged.Kind is an enum
assert(taggedInt.kind == Tagged.Kind.i);
assert(taggedString.kind == Tagged.Kind.str);
assert(taggedFoo.kind == Tagged.Kind.foo);
assert(taggedAny.kind == Tagged.Kind.foo);

// In most cases, can simply use as-is
auto num = 4 + taggedInt;
auto msg = taggedString ~ " World!";
taggedFoo.bar();
if (taggedAny.kind == Tagged.Kind.foo) // Make sure to check type first!
	taggedAny.bar();
//taggedString.bar(); // AssertError: Not a Foo!

// Convert back by casting
auto i   = cast(int)    taggedInt;
auto str = cast(string) taggedString;
auto foo = cast(Foo)    taggedFoo;
if (taggedAny.kind == Tagged.Kind.foo) // Make sure to check type first!
	auto foo2 = cast(Foo) taggedAny;
//cast(Foo) taggedString; // AssertError!

// Kind is an enum, so final switch is supported:
final switch (taggedAny.kind) {
	case Tagged.Kind.i:
		// It's "int i"
		break;

	case Tagged.Kind.str:
		// It's "string str"
		break;

	case Tagged.Kind.foo:
		// It's "Foo foo"
		break;
}