commit
2d9f9c537f
67
README.md
67
README.md
|
@ -3,4 +3,69 @@ 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](https://travis-ci.org/s-ludwig/taggedalgebraic.svg?branch=master)](https://travis-ci.org/s-ludwig/taggedalgebraic) [![Coverage Status](https://coveralls.io/repos/s-ludwig/taggedalgebraic/badge.png?branch=master)](https://coveralls.io/r/s-ludwig/taggedalgebraic?branch=master)
|
||||
[![Build Status](https://travis-ci.org/s-ludwig/taggedalgebraic.svg?branch=master)](https://travis-ci.org/s-ludwig/taggedalgebraic) [![Coverage Status](https://coveralls.io/repos/s-ludwig/taggedalgebraic/badge.png?branch=master)](https://coveralls.io/r/s-ludwig/taggedalgebraic?branch=master)
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
```d
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
|
|
@ -195,6 +195,70 @@ struct TaggedAlgebraic(U) if (is(U == union) || is(U == struct))
|
|||
private @trusted @property ref inout(T) trustedGet(T)() inout { return *cast(inout(T)*)m_data.ptr; }
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/** Operators and methods of the contained type can be used transparently.
|
||||
*/
|
||||
@safe unittest {
|
||||
|
|
Loading…
Reference in a new issue