Find a file
Sönke Ludwig 513729bf59 Enable proper default initialization.
Since @disable this() still leaves an invalid .init open, TaggedAlgebraic.init has now been changed to always contain the .init value of the first specified sub type.

Note that this change is restricted to DMD 2.072 and up, because earlier versions of DMD do not allow postblits or destructors within unions and using a union appears to be the only way to implement this.
2017-06-12 21:12:42 +02:00
source Enable proper default initialization. 2017-06-12 21:12:42 +02:00
.editorconfig Add .travis.yml and .editorconfig. See #2. 2016-01-27 23:02:37 +01:00
.travis.yml Generate coverage information for the latest DMD release. 2017-06-12 21:11:43 +02:00
dub.sdl Convert package recipe to SDLang. 2016-07-04 11:18:58 +02:00
README.md Document basic usage. 2016-09-20 00:52:02 -04:00
travis.sh Only perform coverage analysis for one compiler version. 2016-01-29 11:41:02 +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 Coverage Status

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;
}