www.digitalmars.com

D Programming Language 2.0

Last update Thu Mar 6 15:45:46 2008

std.typecons

This module implements a variety of type constructors, i.e., templates that allow construction of new, useful general-purpose types.

Synopsis:
// value tuples
alias Tuple!(float, "x", float, "y", float, "z") Coord;
Coord c;
c._0 = 1;         // access by index-based name
c.field!(1) = 1;  // access by index
c.z = 1;          // access by given name
alias Tuple!(string, string) DicEntry; // names can be omitted

// enumerated values with conversions to and from strings
mixin(defineEnum!("Openmode", "READ", "WRITE", "READWRITE", "APPEND"));
void foo()
{
    Openmode m = Openmode.READ;
    string s = toString(m);
    assert(s == "READ");
    Openmode m1;
    assert(fromString(s, m1) && m1 == m);
}


Author:
Andrei Alexandrescu

struct Tuple(T...);
Tuple of values, for example Tuple!(int, string) is a record that stores an int and a string. Tuple can be used to bundle values together, notably when returning multiple values from a function. If obj is a tuple, the individual members are accessible with the syntax obj.field!(0) for the first field, obj.field!(1) for the second, and so on. A shortcut notation is obj._0, obj._1 etc.

The choice of zero-based indexing instead of one-base indexing was motivated by the ability to use value tuples with various compile-time loop constructs (e.g. type tuple iteration), all of which use zero-based indexing.

Example:
Tuple!(int, int) point;
// assign coordinates
point._0 = 5;
point.field!(1) = 6;
// read coordinates
auto x = point.field!(0);
auto y = point._1;
Tuple members can be named. It is legal to mix named and unnamed members. The method above is still applicable to all fields.

Example:
alias Tuple!(int, "index", string, "value") Entry;
Entry e;
e.index = 4;
e.value = "Hello";
assert(e._1 == "Hello");
assert(e.field!(0) == 4);
Tuples with named fields are distinct types from tuples with unnamed fields, i.e. each naming imparts a separate type for the tuple. Two tuple differing in naming only are still distinct, even though they might have the same structure.

Example:
Tuple!(int, "x", int, "y") point1;
Tuple!(int, int) point2;
assert(!is(typeof(point1) == typeof(point2))); // passes


Tuple!(T) tuple(T...)(T args);
Returns a Tuple object instantiated and initialized according to the arguments.

Example:
auto value = tuple(5, 6.7, "hello");
assert(value._0 == 5);
assert(value._1 == 6.7);
assert(value._2 == "hello");


template defineEnum(string name,T...)
Defines truly named enumerated values with parsing and stringizing primitives.

Example:
mixin(defineEnum!("Abc", "A", "B", 5, "C"));
is equivalent to the following code:

enum Abc { A, B = 5, C }
string toString(Abc v) { ... }
Abc fromString(string s) { ... }
The toString function generates the unqualified names of the enumerated values, i.e. "A", "B", and "C". The fromString function expects one of "A", "B", and "C", and throws an exception in any other case.

A base type can be specified for the enumeration like this:

mixin(defineEnum!("Abc", ubyte, "A", "B", "C", 255));
In this case the generated enum will have a ubyte representation.

template Rebindable(T : Object)