Movatterモバイル変換


[0]ホーム

URL:


D Logo
Menu
Search

Library Reference

version 2.111.0

overview

Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.Requires a signed-in GitHub account. This works well for small changes.If you'd like to make larger changes you may want to consider usinga local clone.

std.typecons

This module implements a variety of type constructors, i.e., templatesthat allow construction of new, useful general-purpose types.
CategorySymbols
TupleisTupleTupletuplereverse
FlagsBitFlagsisBitFlagEnumFlagNoYes
Memory allocationSafeRefCountedsafeRefCountedRefCountedAutoInitializescopedUnique
Code generationAutoImplementBlackHolegenerateAssertTrapgenerateEmptyFunctionWhiteHole
NullableNullablenullableNullableRefnullableRef
ProxiesProxyrebindableRebindableReplaceTypeunwrapwrap
TypesalignForSizeTernaryTypedefTypedefTypeUnqualRef
License:
Boost License 1.0.

Sourcestd/typecons.d

Authors:
Andrei Alexandrescu,Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara
Examples:
Value tuples
alias Coord = Tuple!(int,"x",int,"y",int,"z");Coord c;c[1] = 1;// access by indexc.z = 1;// access by given namewriteln(c);// Coord(0, 1, 1)// names can be omitted, types can be mixedalias DictEntry = Tuple!(string,int);auto dict = DictEntry("seven", 7);// element types can be inferredwriteln(tuple(2, 3, 4)[1]);// 3// type inference works with names tooauto tup = tuple!("x","y","z")(2, 3, 4);writeln(tup.y);// 3
Examples:
Rebindable references to const and immutable objects
class Widget{void foo()const @safe {}}const w1 =new Widget, w2 =new Widget;w1.foo();// w1 = w2 would not work; can't rebind const objectauto r = Rebindable!(const Widget)(w1);// invoke method as if r were a Widget objectr.foo();// rebind r to refer to another objectr = w2;
structUnique(T);
Encapsulates unique ownership of a resource.
When aUnique!T goes out of scope it will calldestroyon the resourceT that it manages, unless it is transferred.One important consequence ofdestroy is that it will call thedestructor of the resourceT. GC-managed references are notguaranteed to be valid during a destructor call, but other members ofT, such as file handles or pointers tomalloc memory, willstill be valid during the destructor call. This allows the resourceT to deallocate or clean up any non-GC resources.
If it is desirable to persist aUnique!T outside of its originalscope, then it can be transferred. The transfer can be explicit, bycallingrelease, or implicit, when returning Unique from afunction. The resourceT can be a polymorphic class object orinstance of an interface, in which case Unique behaves polymorphicallytoo.
IfT is a value type, thenUnique!T will be implementedas a reference to aT.
Examples:
struct S{int i;this(int i){this.i = i;}}Unique!S produce(){// Construct a unique instance of S on the heapUnique!S ut =new S(5);// Implicit transfer of ownershipreturn ut;}// Borrow a unique resource by refvoid increment(refUnique!S ur){    ur.i++;}void consume(Unique!S u2){    writeln(u2.i);// 6// Resource automatically deleted here}Unique!S u1;assert(u1.isEmpty);u1 = produce();writeln(u1.i);// 5increment(u1);writeln(u1.i);// 6//consume(u1); // Error: u1 is not copyable// Transfer ownership of the resourceconsume(u1.release);assert(u1.isEmpty);
aliasRefT = T;
Represents a reference toT. Resolves toT* ifT is a value type.
Unique!Tcreate(A...)(auto ref Aargs)
if (__traits(compiles, new T(args)));
Allows safe construction ofUnique. It creates the resource and guarantees unique ownership of it (unlessT publishes aliases ofthis).

NoteNested structs/classes cannot be created.

Parameters:
AargsArguments to pass toT's constructor.
staticclass C {}auto u = Unique!(C).create();
this(RefTp);
Constructor that takes an rvalue. It will ensure uniqueness, as long as the rvalue isn't just a view on an lvalue (e.g., a cast). Typical usage:
Unique!Foo f =new Foo;
this(ref RefTp);
Constructor that takes an lvalue. It nulls its source. The nulling will ensure uniqueness as long as there are no previous aliases to the source.
this(U)(Unique!Uu)
if (is(u.RefT : RefT));
Constructor that takes aUnique of a type that is convertible to our type.
Typically used to transfer aUnique rvalue of derived type to aUnique of base type.

Example

class C : Object {}Unique!C uc =new C;Unique!Object uo = uc.release;

voidopAssign(U)(Unique!Uu)
if (is(u.RefT : RefT));
Transfer ownership from aUnique of a type that is convertible to our type.
@property boolisEmpty() const;
Returns whether the resource exists.
Uniquerelease();
Transfer ownership to aUnique rvalue. Nullifies the current contents. Same as calling std.algorithm.move on it.
structTuple(Specs...) if (distinctFieldNames!Specs);
Tuple of values, for exampleTuple!(int, string) is a record thatstores anint and astring.Tuple can be used to bundlevalues together, notably when returning multiple values from afunction. Ifobj is aTuple, the individual members areaccessible with the syntaxobj[0] for the first field,obj[1]for the second, and so on.
See Also:
Parameters:
SpecsA list of types (and optionally, member names) that theTuple contains.
Examples:
Tuple!(int,int) point;// assign coordinatespoint[0] = 5;point[1] = 6;// read coordinatesauto x = point[0];auto y = point[1];
Examples:
Tuple members can be named. It is legal to mix named and unnamed members. The method above is still applicable to all fields.
alias Entry =Tuple!(int,"index", string,"value");Entry e;e.index = 4;e.value ="Hello";writeln(e[1]);// "Hello"writeln(e[0]);// 4
Examples:
ATuple with named fields is a distinct type from aTuple with unnamed fields, i.e. each naming imparts a separate type for theTuple. TwoTuples differing in naming only are still distinct, even though they might have the same structure.
Tuple!(int,"x",int,"y") point1;Tuple!(int,int) point2;assert(!is(typeof(point1) ==typeof(point2)));
Examples:
Use tuples as ranges
import std.algorithm.iteration : sum;import std.range : only;auto t = tuple(1, 2);writeln(t.expand.only.sum);// 3
Examples:
Concatenate tuples
import std.meta : AliasSeq;auto t = tuple(1,"2") ~ tuple(ushort(42),true);staticassert(is(t.Types == AliasSeq!(int, string,ushort,bool)));writeln(t[1]);// "2"writeln(t[2]);// 42writeln(t[3]);// true
aliasTypes = staticMap!(extractType, fieldSpecs);
The types of theTuple's components.
aliasfieldNames = staticMap!(extractName, fieldSpecs);
The names of theTuple's components. Unnamed fields have empty names.
Examples:
import std.meta : AliasSeq;alias Fields = Tuple!(int,"id", string,float);staticassert(Fields.fieldNames == AliasSeq!("id","",""));
Typesexpand;
Uset.expand for aTuplet to expand it into its components. The result ofexpand acts as if theTuple's components were listed as a list of values. (Ordinarily, aTuple acts as a single value.)
Examples:
auto t1 = tuple(1," hello ", 'a');writeln(t1.toString());// `Tuple!(int, string, char)(1, " hello ", 'a')`void takeSeveralTypes(int n, string s,bool b){assert(n == 4 && s =="test" && b ==false);}auto t2 = tuple(4,"test",false);//t.expand acting as a list of valuestakeSeveralTypes(t2.expand);
this(Typesvalues);
Constructor taking one value for each field.
Parameters:
TypesvaluesA list of values that are either the same types as those given by theTypes field of thisTuple, or can implicitly convert to those types. They must be in the same order as they appear inTypes.
Examples:
alias ISD = Tuple!(int, string,double);auto tup = ISD(1,"test", 3.2);writeln(tup.toString());// `Tuple!(int, string, double)(1, "test", 3.2)`
this(U, size_t n)(U[n]values)
if (n == Types.length && allSatisfy!(isBuildableFrom!U, Types));
Constructor taking a compatible array.
Parameters:
U[n]valuesA compatible static array to build theTuple from. Array slices are not supported.
Examples:
int[2] ints;Tuple!(int,int) t = ints;
this(U)(Uanother)
if (areBuildCompatibleTuples!(typeof(this), U) && (noMemberHasCopyCtor!(typeof(this)) || !is(Unqual!U == Unqual!(typeof(this)))));
Constructor taking a compatibleTuple. TwoTuples are compatibleiff they are both of the same length, and, for each typeT on the left-hand side, the corresponding typeU on the right-hand side can implicitly convert toT.
Parameters:
UanotherA compatibleTuple to build from. Its type must be compatible with the targetTuple's type.
Examples:
alias IntVec = Tuple!(int,int,int);alias DubVec = Tuple!(double,double,double);IntVec iv = tuple(1, 1, 1);//Ok, int can implicitly convert to doubleDubVec dv = iv;//Error: double cannot implicitly convert to int//IntVec iv2 = dv;
boolopEquals(R)(Rrhs)
if (areCompatibleTuples!(typeof(this), R, "=="));

boolopEquals(R)(Rrhs) const
if (areCompatibleTuples!(typeof(this), R, "=="));

boolopEquals(R...)(auto ref Rrhs)
if (R.length > 1 && areCompatibleTuples!(typeof(this), Tuple!R, "=="));
Comparison for equality. TwoTuples are considered equaliff they fulfill the following criteria:
  • EachTuple is the same length.
  • For each typeT on the left-hand side and each typeU on the right-hand side, values of typeT can be compared with values of typeU.
  • For each valuev1 on the left-hand side and each valuev2 on the right-hand side, the expressionv1 == v2 is true.
Parameters:
RrhsTheTuple to compare against. It must meeting the criteria for comparison betweenTuples.
Returns:
true if bothTuples are equal, otherwise false.
Examples:
Tuple!(int, string) t1 = tuple(1,"test");Tuple!(double, string) t2 =  tuple(1.0,"test");//Ok, int can be compared with double and//both have a value of 1writeln(t1);// t2
autoopCmp(R)(Rrhs)
if (areCompatibleTuples!(typeof(this), R, "<"));

autoopCmp(R)(Rrhs) const
if (areCompatibleTuples!(typeof(this), R, "<"));
Comparison for ordering.
Parameters:
RrhsTheTuple to compare against. It must meet the criteria for comparison betweenTuples.
Returns:
For any valuesv1 contained by the left-hand side tuple and any valuesv2 contained by the right-hand side:
0 ifv1 == v2 for all members or the following value for the first position were the mentioned criteria is not satisfied:
  • NaN, in case one of the operands is a NaN.
  • A negative number if the expressionv1 < v2 is true.
  • A positive number if the expressionv1 > v2 is true.
Examples:
The firstv1 for whichv1 > v2 is true determines the result. This could lead to unexpected behaviour.
auto tup1 = tuple(1, 1, 1);auto tup2 = tuple(1, 100, 100);assert(tup1 < tup2);//Only the first result matters for comparisontup1[0] = 2;assert(tup1 > tup2);
autoopBinary(string op, T)(auto ref Tt)
if (op == "~" && !(is(T : U[], U) && isTuple!U));

autoopBinaryRight(string op, T)(auto ref Tt)
if (op == "~" && !(is(T : U[], U) && isTuple!U));
Concatenate Tuples. Tuple concatenation is only allowed if all named fields are distinct (no named field of this tuple occurs int and no named field oft occurs in this tuple).
Parameters:
TtTheTuple to concatenate with
Returns:
A concatenation of this tuple andt
ref TupleopAssign(R)(auto ref Rrhs)
if (areCompatibleTuples!(typeof(this), R, "="));
Assignment from anotherTuple.
Parameters:
RrhsThe sourceTuple to assign from. Each element of the sourceTuple must be implicitly assignable to each respective element of the targetTuple.
ref autorename(names...)() inout return
if (names.length == 0 || allSatisfy!(isSomeString, typeof(names)));
Renames the elements of aTuple.
rename uses the passednames and returns a newTuple using these names, with the content unchanged. If fewer names are passed than there are members of theTuple then those trailing members are unchanged. An empty string will remove the name for that member. It is an compile-time error to pass more names than there are members of theTuple.
Examples:
auto t0 = tuple(4,"hello");auto t0Named = t0.rename!("val","tag");writeln(t0Named.val);// 4writeln(t0Named.tag);// "hello"Tuple!(float,"dat", size_t[2],"pos") t1;t1.pos = [2, 1];auto t1Named = t1.rename!"height";t1Named.height = 3.4f;writeln(t1Named.height);// 3.4fwriteln(t1Named.pos);// [2, 1]t1Named.rename!"altitude".altitude = 5;writeln(t1Named.height);// 5Tuple!(int,"a",int,int,"c") t2;t2 = tuple(3,4,5);auto t2Named = t2.rename!("","b");// "a" no longer has a namestaticassert(!__traits(hasMember,typeof(t2Named),"a"));writeln(t2Named[0]);// 3writeln(t2Named.b);// 4writeln(t2Named.c);// 5// not allowed to specify more names than the tuple has membersstaticassert(!__traits(compiles, t2.rename!("a","b","c","d")));// use it in a range pipelineimport std.range : iota, zip;import std.algorithm.iteration : map, sum;auto res = zip(iota(1, 4), iota(10, 13))    .map!(t => t.rename!("a","b"))    .map!(t => t.a * t.b)    .sum;writeln(res);// 68const tup = Tuple!(int,"a",int,"b")(2, 3);const renamed = tup.rename!("c","d");writeln(renamed.c + renamed.d);// 5
ref autorename(alias translate)() inout
if (is(typeof(translate) : V[K], V, K) && isSomeString!V && (isSomeString!K || is(K : size_t)));
Overload ofrename that takes an associative arraytranslate as a template parameter, where the keys are either the names or indices of the members to be changed and the new names are the corresponding values. Every key intranslate must be the name of a member of thetuple. The same rules for empty strings apply as for the variadic template overload ofrename.
Examples:
//replacing names by their current nameTuple!(float,"dat", size_t[2],"pos") t1;t1.pos = [2, 1];auto t1Named = t1.rename!(["dat":"height"]);t1Named.height = 3.4;writeln(t1Named.pos);// [2, 1]t1Named.rename!(["height":"altitude"]).altitude = 5;writeln(t1Named.height);// 5Tuple!(int,"a",int,"b") t2;t2 = tuple(3, 4);auto t2Named = t2.rename!(["a":"b","b":"c"]);writeln(t2Named.b);// 3writeln(t2Named.c);// 4const t3 = Tuple!(int,"a",int,"b")(3, 4);const t3Named = t3.rename!(["a":"b","b":"c"]);writeln(t3Named.b);// 3writeln(t3Named.c);// 4
Examples:
//replace names by their positionTuple!(float,"dat", size_t[2],"pos") t1;t1.pos = [2, 1];auto t1Named = t1.rename!([0:"height"]);t1Named.height = 3.4;writeln(t1Named.pos);// [2, 1]t1Named.rename!([0:"altitude"]).altitude = 5;writeln(t1Named.height);// 5Tuple!(int,"a",int,"b",int,"c") t2;t2 = tuple(3, 4, 5);auto t2Named = t2.rename!([0:"c", 2:"a"]);writeln(t2Named.a);// 5writeln(t2Named.b);// 4writeln(t2Named.c);// 3
@property ref @trusted inout(Tuple!(sliceSpecs!(from, to)))slice(size_t from, size_t to)() inout
if (from <= to && (to <= Types.length));
Takes a slice by-reference of thisTuple.
Parameters:
fromAsize_t designating the starting position of the slice.
toAsize_t designating the ending position (exclusive) of the slice.
Returns:
A newTuple that is a slice from[from, to) of the original. It has the same types and values as the range[from, to) in the original.
Examples:
Tuple!(int, string,float,double) a;a[1] ="abc";a[2] = 4.5;auto s = a.slice!(1, 3);staticassert(is(typeof(s) == Tuple!(string,float)));assert(s[0] =="abc" && s[1] == 4.5);// https://issues.dlang.org/show_bug.cgi?id=15645Tuple!(int,short,bool,double) b;staticassert(!__traits(compiles, b.slice!(2, 4)));
nothrow @safe size_ttoHash() const;
Creates a hash of thisTuple.
Returns:
Asize_t representing the hash of thisTuple.
stringtoString()();
Converts to string.
Returns:
The string representation of thisTuple.
voidtoString(DG)(scope DGsink);

voidtoString(DG, Char)(scope DGsink, ref scope const FormatSpec!Charfmt);
FormatsTuple with either%s,%(inner%) or%(inner%|sep%).
Formats supported by Tuple
FormatDescription

%s

Format likeTuple!(types)(elements formatted with %s each).

%(inner%)

The formatinner is applied the expandedTuple, so it may contain as many formats as theTuple has fields.

%(inner%|sep%)

The formatinner is one format, that is applied on all fields of theTuple. The inner format must be compatible to all of them.

Parameters:
DGsinkAchar accepting delegate
FormatSpec!CharfmtAstd.format.FormatSpec
Examples:
import std.format : format;Tuple!(int,double)[3] tupList = [ tuple(1, 1.0), tuple(2, 4.0), tuple(3, 9.0) ];// Default formatwriteln(format("%s", tuple("a", 1)));// `Tuple!(string, int)("a", 1)`// One Format for each individual componentwriteln(format("%(%#x v %.4f w %#x%)", tuple(1, 1.0, 10)));// `0x1 v 1.0000 w 0xa`writeln(format("%#x v %.4f w %#x", tuple(1, 1.0, 10).expand));// `0x1 v 1.0000 w 0xa`// One Format for all components// `>abc< & >1< & >2.3< & >[4, 5]<`writeln(format("%(>%s<%| & %)", tuple("abc", 1, 2.3, [4, 5])));// Array of Tupleswriteln(format("%(%(f(%d) = %.1f%);  %)", tupList));// `f(1) = 1.0;  f(2) = 4.0;  f(3) = 9.0`
Examples:
import std.exception : assertThrown;import std.format : format, FormatException;// Error: %( %) missing.assertThrown!FormatException(    format("%d, %f", tuple(1, 2.0)) ==`1, 2.0`);// Error: %( %| %) missing.assertThrown!FormatException(    format("%d", tuple(1, 2)) ==`1, 2`);// Error: %d inadequate for doubleassertThrown!FormatException(    format("%(%d%|, %)", tuple(1, 2.0)) ==`1, 2.0`);
autoreverse(T)(Tt)
if (isTuple!T);
Creates a copy of aTuple with its fields in reverse order.
Parameters:
TtTheTuple to copy.
Returns:
A newTuple.
Examples:
auto tup = tuple(1,"2");writeln(tup.reverse);// tuple("2", 1)
templatetuple(Names...)
Constructs aTuple object instantiated and initialized according to the given arguments.
Parameters:
NamesAn optional list of strings naming each successive field of theTuple or a list of types that the elements are being casted to. For a list of names, each name matches up with the corresponding field given byArgs. A name does not have to be provided for every field, but as the names must proceed in order, it is not possible to skip one field and name the next after it. For a list of types, there must be exactly as many types as parameters.
Examples:
auto value =tuple(5, 6.7,"hello");writeln(value[0]);// 5writeln(value[1]);// 6.7writeln(value[2]);// "hello"// Field names can be provided.auto entry =tuple!("index","value")(4,"Hello");writeln(entry.index);// 4writeln(entry.value);// "Hello"
autotuple(Args...)(Argsargs);
Parameters:
ArgsargsValues to initialize theTuple with. TheTuple's type will be inferred from the types of the values given.
Returns:
A newTuple with its type inferred from the arguments given.
enum autoisTuple(T);
Returnstrue if and only ifT is an instance ofstd.typecons.Tuple.
Parameters:
TThe type to check.
Returns:
true ifT is aTuple type, false otherwise.
Examples:
staticassert(isTuple!(Tuple!()));staticassert(isTuple!(Tuple!(int)));staticassert(isTuple!(Tuple!(int,real, string)));staticassert(isTuple!(Tuple!(int,"x",real,"y")));staticassert(isTuple!(Tuple!(int, Tuple!(real), string)));
templateRebindable(T) if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)

structRebindable(T) if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T);
Rebindable!(T) is a simple, efficient wrapper that behaves justlike an object of typeT, except that you can reassign it torefer to another object. For completeness,Rebindable!(T) aliasesitself away toT ifT is a non-const object type.
You may want to useRebindable when you want to have mutablestorage referring toconst objects, for example an array ofreferences that must be sorted in place.Rebindable does notbreak the soundness of D's type system and does not incur any of therisks usually associated withcast.
Parameters:
TAny type.
Examples:
Regularconst object references cannot be reassigned.
class Widget {int x;int y() @safeconst {return x; } }const a =new Widget;// Finea.y();// error! can't modify const a// a.x = 5;// error! can't modify const a// a = new Widget;
Examples:
However,Rebindable!(Widget) does allow reassignment, while otherwise behaving exactly like aconst Widget.
class Widget {int x;int y()const @safe {return x; } }auto a =Rebindable!(const Widget)(new Widget);// Finea.y();// error! can't modify const a// a.x = 5;// Finea =new Widget;
Examples:
Using Rebindable in a generic algorithm:
import std.range.primitives : front, popFront;// simple version of std.algorithm.searching.maxElementtypeof(R.init.front) maxElement(R)(R r){auto max = rebindable(r.front);    r.popFront;foreach (e; r)if (e > max)            max = e;// Rebindable allows const-correct reassignmentreturn max;}struct S{char[] arr;alias arrthis;// for comparison}// can't convert to mutableconst S cs;staticassert(!__traits(compiles, { S s = cs; }));alias CS =const S;CS[] arr = [CS("harp"), CS("apple"), CS("pot")];CS ms = maxElement(arr);writeln(ms.arr);// "pot"
Examples:
staticstruct S{int* ptr;}S s = S(newint);const cs = s;// Can't assign s.ptr to cs.ptrstaticassert(!__traits(compiles, {s = cs;}));Rebindable!(const S) rs = s;assert(rs.ptris s.ptr);// rs.ptr is conststaticassert(!__traits(compiles, {rs.ptr =null;}));// Can't assign s.ptr to rs.ptrstaticassert(!__traits(compiles, {s = rs;}));const S cs2 = rs;// Rebind rsrs = cs2;rs = S();assert(rs.ptrisnull);
Rebindable!Trebindable(T)(Tobj)
if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T);

Rebindable!Trebindable(T)(Tvalue)
if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T && !is(T : Rebindable!U, U));
Convenience function for creating aRebindable using automatic typeinference.
Parameters:
TobjA reference to a value to initialize theRebindable with.
Returns:
A newly constructedRebindable initialized with the given reference.
Examples:
class C{int payload;this(int p) { payload = p; }}const c =new C(1);auto c2 = c.rebindable;writeln(c2.payload);// 1// passing Rebindable to rebindablec2 = c2.rebindable;c2 =new C(2);writeln(c2.payload);// 2const c3 = c2.get;writeln(c3.payload);// 2
Examples:
immutablestruct S{int[] array;}auto s1 = [3].idup.rebindable;s1 = [4].idup.rebindable;writeln(s1);// [4]
Rebindable!Trebindable(T)(Rebindable!Tobj);
This function simply returns theRebindable object passed in. It's usefulin generic programming cases when a given object may be either a regularclass or aRebindable.
Parameters:
Rebindable!TobjAn instance of Rebindable!T.
Returns:
obj without any modification.
Examples:
class C{int payload;this(int p) { payload = p; }}const c =new C(1);auto c2 = c.rebindable;writeln(c2.payload);// 1// passing Rebindable to rebindablec2 = c2.rebindable;writeln(c2.payload);// 1
templateUnqualRef(T) if (is(T == class) || is(T == interface))
Similar toRebindable!(T) but strips all qualifiers from the reference as opposed to just constness / immutability. Primary intended use case is with shared (having thread-local reference to shared class data)
Parameters:
TA class or interface type.
Examples:
class Data {}staticshared(Data) a;staticUnqualRef!(shared Data) b;import core.thread;auto thread =new core.thread.Thread({    a =newshared Data();    b =newshared Data();});thread.start();thread.join();assert(a !isnull);assert(bisnull);
stringalignForSize(E...)(const char[][]names...);
Order the provided members to minimize size while preserving alignment. Alignment is not always optimal for 80-bit reals, nor for structs declared as align(1).
Parameters:
EA list of the types to be aligned, representing fields of an aggregate such as astruct orclass.
char[][]namesThe names of the fields that are to be aligned.
Returns:
A string to be mixed in to an aggregate, such as astruct orclass.
Examples:
struct Banner {mixin(alignForSize!(byte[6],double)(["name","height"]));}
structNullable(T);

autonullable(T)(Tt);
Defines a value paired with a distinctive "null" state that denotesthe absence of a value. If default constructed, aNullable!T object starts in the null state. Assigning it renders itnon-null. Callingnullify can nullify it again.
PracticallyNullable!T stores aT and abool.
See also:apply, an alternative way to use the payload.
Examples:
struct CustomerRecord{    string name;    string address;int customerNum;}Nullable!CustomerRecord getByName(string name){//A bunch of hairy stuffreturnNullable!CustomerRecord.init;}auto queryResult = getByName("Doe, John");if (!queryResult.isNull){//Process Mr. Doe's customer recordauto address = queryResult.get.address;auto customerNum = queryResult.get.customerNum;//Do some things with this customer's info}else{//Add the customer to the database}
Examples:
import std.exception : assertThrown;auto a = 42.nullable;assert(!a.isNull);writeln(a.get);// 42a.nullify();assert(a.isNull);assertThrown!Throwable(a.get);
Examples:
import std.algorithm.iteration : each, joiner;Nullable!int a = 42;Nullable!int b;// Add each value to an arrayint[] arr;a.each!((n) => arr ~= n);writeln(arr);// [42]b.each!((n) => arr ~= n);writeln(arr);// [42]// Take first value from an array of NullablesNullable!int[] c =newNullable!int[](10);c[7] =Nullable!int(42);writeln(c.joiner.front);// 42
this(inout Tvalue) inout;
Constructor initializingthis withvalue.
Parameters:
TvalueThe value to initialize thisNullable with.
boolopEquals(this This, Rhs)(auto ref Rhsrhs)
if (!is(CommonType!(This, Rhs) == void));

boolopEquals(this This, Rhs)(auto ref Rhsrhs)
if (is(CommonType!(This, Rhs) == void) && is(typeof(this.get ==rhs)));
If they are both null, then they are equal. If one is null and the other is not, then they are not equal. If they are both non-null, then they are equal if their values are equal.
Examples:
Nullable!int empty;Nullable!int a = 42;Nullable!int b = 42;Nullable!int c = 27;writeln(empty);// emptywriteln(empty);// Nullable!int.initassert(empty != a);assert(empty != b);assert(empty != c);writeln(a);// bassert(a != c);assert(empty != 42);writeln(a);// 42assert(c != 42);
stringtoString();

stringtoString() const;

voidtoString(W)(ref Wwriter, ref scope const FormatSpec!charfmt)
if (isOutputRange!(W, char));

voidtoString(W)(ref Wwriter, ref scope const FormatSpec!charfmt) const
if (isOutputRange!(W, char));
Gives the string"Nullable.null" ifisNull istrue. Otherwise, the result is equivalent to callingstd.format.formattedWrite on the underlying value.
Parameters:
WwriterAchar acceptingoutput range
FormatSpec!charfmtAstd.format.FormatSpec which is used to represent the value if this Nullable is not null
Returns:
Astring ifwriter andfmt are not set;void otherwise.
pure nothrow @property @safe boolisNull() const;
Check ifthis is in the null state.
Returns:
trueiffthis is in the null state, otherwise false.
Examples:
Nullable!int ni;assert(ni.isNull);ni = 0;assert(!ni.isNull);
boolopCast(T : bool)() const;
Returns true ifthis has a value, otherwise false.
Allows aNullable to be used as the condition in anif statement:
if (auto result = functionReturningNullable()){    doSomethingWith(result.get);}
ref TopCast(T, this This)()
if (is(This : T) || This.sizeof == T.sizeof);
PreventsopCast from disabling built-in conversions.
voidnullify()();
Forcesthis to the null state.
Examples:
Nullable!int ni = 0;assert(!ni.isNull);ni.nullify();assert(ni.isNull);
ref NullableopAssign()(Tvalue) return;
Assignsvalue to the internally-held state. If the assignment succeeds,this becomes non-null.
Parameters:
TvalueA value of typeT to assign to thisNullable.
Examples:
If thisNullable wraps a type that already has a null value (such as a pointer), then assigning the null value to thisNullable is no different than assigning any other value of typeT, and the resulting code will look very strange. It is strongly recommended that this be avoided by instead using the version ofNullable that takes an additionalnullValue template argument.
//PassesNullable!(int*) npi;assert(npi.isNull);//Passes?!npi =null;assert(!npi.isNull);
pure nothrow @property ref @safe inout(T)get() inout;

@property inout(T)get()(inout(T)fallback) inout;

@property autoget(U)(inout(U)fallback) inout;
Gets the value if not null. Ifthis is in the null state, and the optional parameterfallback was provided, it will be returned. Withoutfallback, callingget with a null state is invalid.
When the fallback type is different from the Nullable type,get(T) returns the common type.
Parameters:
inout(T)fallbackthe value to return in case theNullable is null.
Returns:
The value held internally by thisNullable.
aliasempty = isNull;

aliaspopFront = nullify;

aliaspopBack = nullify;

pure nothrow @property ref @safe inout(T)front() inout;

aliasback = front;

@property inout(typeof(this))save() inout;

inout(typeof(this))opIndex(size_t[2]dim) inout;

size_t[2]opSlice(size_t dim : 0)(size_tfrom, size_tto) const;

pure nothrow @property @safe size_tlength() const;

templateopDollar(size_t dim : 0)

pure nothrow ref @safe inout(T)opIndex(size_tindex) inout;
Range interface functions.
autoopSlice(this This)();
ConvertsNullable to a range. Works even when the contained type isimmutable.
structNullable(T, T nullValue);

autonullable(alias nullValue, T)(Tt)
if (is(typeof(nullValue) == T));
Just likeNullable!T, except that the null state is defined as aparticular value. For example,Nullable!(uint, uint.max) is anuint that sets aside the valueuint.max to denote a nullstate.Nullable!(T, nullValue) is more storage-efficient thanNullable!T because it does not need to store an extrabool.
Parameters:
TThe wrapped type for which Nullable provides a null value.
nullValueThe null value which denotes the null state of thisNullable. Must be of typeT.
Examples:
Nullable!(size_t, size_t.max) indexOf(string[] haystack, string needle){//Find the needle, returning -1 if not foundreturnNullable!(size_t, size_t.max).init;}void sendLunchInvite(string name){}//It's safer than C...auto coworkers = ["Jane","Jim","Marry","Fred"];auto pos = indexOf(coworkers,"Bob");if (!pos.isNull){//Send Bob an invitation to lunch    sendLunchInvite(coworkers[pos]);}else{//Bob not found; report the error}//And there's no overheadstaticassert(Nullable!(size_t, size_t.max).sizeof == size_t.sizeof);
Examples:
import std.exception : assertThrown;Nullable!(int,int.min) a;assert(a.isNull);assertThrown!Throwable(a.get);a = 5;assert(!a.isNull);writeln(a);// 5staticassert(a.sizeof ==int.sizeof);
Examples:
auto a =nullable!(int.min)(8);writeln(a);// 8a.nullify();assert(a.isNull);
this(Tvalue);
Constructor initializingthis withvalue.
Parameters:
TvalueThe value to initialize thisNullable with.
@property boolisNull() const;
Check ifthis is in the null state.
Returns:
trueiffthis is in the null state, otherwise false.
Examples:
Nullable!(int, -1) ni;//Initialized to "null" stateassert(ni.isNull);ni = 0;assert(!ni.isNull);
voidnullify()();
Forcesthis to the null state.
Examples:
Nullable!(int, -1) ni = 0;assert(!ni.isNull);ni = -1;assert(ni.isNull);
voidopAssign()(Tvalue);
Assignsvalue to the internally-held state. If the assignmentsucceeds,this becomes non-null. No null checks are made. Notethat the assignment may leavethis in the null state.
Parameters:
TvalueA value of typeT to assign to thisNullable. If it isnullvalue, then the internal state of thisNullable will be set to null.
Examples:
If thisNullable wraps a type that already has a null value (such as a pointer), and that null value is not given fornullValue, then assigning the null value to thisNullable is no different than assigning any other value of typeT, and the resulting code will look very strange. It is strongly recommended that this be avoided by usingT's "built in" null value fornullValue.
//Passesenum nullVal =cast(int*) 0xCAFEBABE;Nullable!(int*, nullVal) npi;assert(npi.isNull);//Passes?!npi =null;assert(!npi.isNull);
@property ref inout(T)get() inout;
Gets the value.this must not be in the null state.This function is also called for the implicit conversion toT.

PreconditionsisNull must befalse.

Returns:
The value held internally by thisNullable.
Examples:
import std.exception : assertThrown, assertNotThrown;Nullable!(int, -1) ni;//`get` is implicitly called. Will throw//an error in non-release modeassertThrown!Throwable(ni == 0);ni = 0;assertNotThrown!Throwable(ni == 0);
templateapply(alias fun)
Unpacks the content of aNullable, performs an operation and packs it again. Does nothing if isNull.
When called on aNullable,apply will unpack the value contained in theNullable,pass it to the function you provide and wrap the result in anotherNullable (if necessary).If theNullable is null,apply will return null itself.
Parameters:
T taNullable
funa function operating on the content of the nullable
Returns:
fun(t.get).nullable if!t.isNull, elseNullable.init.
See also:TheMaybe monad
Examples:
alias toFloat = i =>cast(float) i;Nullable!int sample;// apply(null) results in a null `Nullable` of the function's return type.Nullable!float f = sample.apply!toFloat;assert(sample.isNull && f.isNull);sample = 3;// apply(non-null) calls the function and wraps the result in a `Nullable`.f = sample.apply!toFloat;assert(!sample.isNull && !f.isNull);writeln(f.get);// 3.0f
Examples:
alias greaterThree = i => (i > 3) ? i.nullable : Nullable!(typeof(i)).init;Nullable!int sample;// when the function already returns a `Nullable`, that `Nullable` is not wrapped.auto result = sample.apply!greaterThree;assert(sample.isNull && result.isNull);// The function may decide to return a null `Nullable`.sample = 3;result = sample.apply!greaterThree;assert(!sample.isNull && result.isNull);// Or it may return a value already wrapped in a `Nullable`.sample = 4;result = sample.apply!greaterThree;assert(!sample.isNull && !result.isNull);writeln(result.get);// 4
structNullableRef(T);

autonullableRef(T)(T*t);
Just likeNullable!T, except that the object refers to a valuesitting elsewhere in memory. This makes assignments overwrite theinitially assigned value. InternallyNullableRef!T only stores apointer toT (i.e.,Nullable!T.sizeof == (T*).sizeof).
Examples:
import std.exception : assertThrown;int x = 5, y = 7;auto a =nullableRef(&x);assert(!a.isNull);writeln(a);// 5writeln(x);// 5a = 42;writeln(x);// 42assert(!a.isNull);writeln(a);// 42a.nullify();writeln(x);// 42assert(a.isNull);assertThrown!Throwable(a.get);assertThrown!Throwable(a = 71);a.bind(&y);writeln(a);// 7y = 135;writeln(a);// 135
pure nothrow @safe this(T*value);
Constructor bindingthis tovalue.
Parameters:
T*valueThe value to bind to.
pure nothrow @safe voidbind(T*value);
Binds the internal state tovalue.
Parameters:
T*valueA pointer to a value of typeT to bind thisNullableRef to.
Examples:
NullableRef!int nr =newint(42);writeln(nr);// 42int* n =newint(1);nr.bind(n);writeln(nr);// 1
pure nothrow @property @safe boolisNull() const;
Returnstrue if and only ifthis is in the null state.
Returns:
true ifthis is in the null state, otherwise false.
Examples:
NullableRef!int nr;assert(nr.isNull);int* n =newint(42);nr.bind(n);assert(!nr.isNull && nr == 42);
pure nothrow @safe voidnullify();
Forcesthis to the null state.
Examples:
NullableRef!int nr =newint(42);assert(!nr.isNull);nr.nullify();assert(nr.isNull);
voidopAssign()(Tvalue)
if (isAssignable!T);
Assignsvalue to the internally-held state.
Parameters:
TvalueA value of typeT to assign to thisNullableRef. If the internal state of thisNullableRef has not been initialized, an error will be thrown in non-release mode.
Examples:
import std.exception : assertThrown, assertNotThrown;NullableRef!int nr;assert(nr.isNull);assertThrown!Throwable(nr = 42);nr.bind(newint(0));assert(!nr.isNull);assertNotThrown!Throwable(nr = 42);writeln(nr);// 42
pure nothrow @property ref @safe inout(T)get() inout;
Gets the value.this must not be in the null state.This function is also called for the implicit conversion toT.
Examples:
import std.exception : assertThrown, assertNotThrown;NullableRef!int nr;//`get` is implicitly called. Will throw//an error in non-release modeassertThrown!Throwable(nr == 0);nr.bind(newint(0));assertNotThrown!Throwable(nr == 0);
templateBlackHole(Base)
BlackHole!Base is a subclass ofBase which automatically implementsall abstract member functions inBase as do-nothing functions. Eachauto-implemented function just returns the default value of the return typewithout doing anything.
The name came fromClass::BlackHolePerl module by Sean M. Burke.
Parameters:
BaseA non-final class forBlackHole to inherit from.
See Also:
Examples:
import std.math.traits : isNaN;staticabstractclass C{int m_value;this(int v) { m_value = v; }int value() @property {return m_value; }abstractreal realValue() @property;abstractvoid doSomething();}auto c =newBlackHole!C(42);writeln(c.value);// 42// Returns real.init which is NaNassert(c.realValue.isNaN);// Abstract functions are implemented as do-nothingc.doSomething();
templateWhiteHole(Base)

classNotImplementedError:object.Error;
WhiteHole!Base is a subclass ofBase which automatically implementsall abstract member functions as functions that always fail. These functionssimply throw anError and never return.Whitehole is useful fortrapping the use of class member functions that haven't been implemented.
The name came fromClass::WhiteHolePerl module by Michael G Schwern.
Parameters:
BaseA non-final class forWhiteHole to inherit from.
See Also:
Examples:
import std.exception : assertThrown;staticclass C{abstractvoid notYetImplemented();}auto c =newWhiteHole!C;assertThrown!NotImplementedError(c.notYetImplemented());// throws an Error
Examples:
import std.exception : assertThrown;// nothrow{interface I_1    {void foo();void bar()nothrow;    }auto o =newWhiteHole!I_1;    assertThrown!NotImplementedError(o.foo());    assertThrown!NotImplementedError(o.bar());}// doc example{staticclass C    {abstractvoid notYetImplemented();    }auto c =newWhiteHole!C;try    {        c.notYetImplemented();assert(0);    }catch (Error e) {}}
classAutoImplement(Base, alias how, alias what = isAbstractFunction) if (!is(how == class)): Base;

classAutoImplement(Interface, BaseClass, alias how, alias what = isAbstractFunction) if (is(Interface == interface) && is(BaseClass == class)): BaseClass, Interface;
AutoImplement automatically implements (by default) all abstract memberfunctions in the class or interfaceBase in specified way.
The second version ofAutoImplement automatically implementsInterface, while deriving fromBaseClass.
Parameters:
howtemplate which specifies how functions will be implemented/overridden.
Two arguments are passed tohow: the typeBase and an alias to an implemented function. Thenhow must return an implemented function body as a string.
The generated function body can use these keywords:
  • a0,a1, …: arguments passed to the function;
  • args: a tuple of the arguments;
  • self: an alias to the function itself;
  • parent: an alias to the overridden function (if any).
You may want to use templated property functions (instead of Implicit Template Properties) to generate complex functions:
// Prints log messages for each call to overridden functions.string generateLogger(C,alias fun)() @property{import std.traits;enum qname = C.stringof ~"." ~__traits(identifier, fun);    string stmt;    stmt ~=q{ struct Importer { import std.stdio; } };    stmt ~=`Importer.writeln("Log: ` ~ qname ~`(", args, ")");`;staticif (!__traits(isAbstractFunction, fun))    {staticif (is(ReturnType!fun ==void))            stmt ~=q{ parent(args); };else            stmt ~=q{                auto r = parent(args);                Importer.writeln("--> ", r);                return r;            };    }return stmt;}
whattemplate which determines what functions should be implemented/overridden.
An argument is passed towhat: an alias to a non-final member function inBase. Thenwhat must return a boolean value. Returntrue to indicate that the passed function should be implemented/overridden.
// Sees if fun returns something.enumbool hasValue(alias fun) = !is(ReturnType!(fun) ==void);

NoteGenerated code is inserted in the scope ofstd.typecons module. Thus,any useful functions outsidestd.typecons cannot be used in the generatedcode. To workaround this problem, you mayimport necessary things in alocal struct, as done in thegenerateLogger() template in the aboveexample.

Bugs:
  • Variadic arguments to constructors are not forwarded to super.
  • Deep interface inheritance causes compile error with messages like "Error: function std.typecons.AutoImplement!(Foo).AutoImplement.bar does not override any function". [Bugzilla 2525]
  • Theparent keyword is actually a delegate to the super class' corresponding member function. [Bugzilla 2540]
  • Using alias template parameter inhow and/orwhat may cause strange compile error. Use template tuple parameter instead to workaround this problem. [Bugzilla 4217]
Examples:
interface PackageSupplier{int foo();int bar();}staticabstractclass AbstractFallbackPackageSupplier : PackageSupplier{protected PackageSupplier default_, fallback;this(PackageSupplier default_, PackageSupplier fallback)    {this.default_ = default_;this.fallback = fallback;    }abstractint foo();abstractint bar();}template fallback(T,alias func){import std.format : format;// for all implemented methods:// - try default first// - only on a failure run & return fallbackenum fallback =q{        try        {            return default_.%1$s(args);        }        catch (Exception)        {            return fallback.%1$s(args);        }    }.format(__traits(identifier, func));}// combines two classes and use the second one as fallbackalias FallbackPackageSupplier =AutoImplement!(AbstractFallbackPackageSupplier, fallback);class FailingPackageSupplier : PackageSupplier{int foo(){thrownew Exception("failure"); }int bar(){return 2;}}class BackupPackageSupplier : PackageSupplier{int foo(){return -1; }int bar(){return -1;}}auto registry =new FallbackPackageSupplier(new FailingPackageSupplier(),new BackupPackageSupplier());writeln(registry.foo());// -1writeln(registry.bar());// 2
templategenerateEmptyFunction(C, func...)

enum stringgenerateAssertTrap(C, func...);
Predefined how-policies forAutoImplement. These templates are also used byBlackHole andWhiteHole, respectively.
Examples:
alias BlackHole(Base) = AutoImplement!(Base,generateEmptyFunction);interface I{int foo();    string bar();}auto i =new BlackHole!I();// generateEmptyFunction returns the default value of the return type without doing anythingwriteln(i.foo);// 0assert(i.barisnull);
Examples:
import std.exception : assertThrown;alias WhiteHole(Base) = AutoImplement!(Base,generateAssertTrap);interface I{int foo();    string bar();}auto i =new WhiteHole!I();// generateAssertTrap throws an exception for every unimplemented function of the interfaceassertThrown!NotImplementedError(i.foo);assertThrown!NotImplementedError(i.bar);
templatewrap(Targets...) if (Targets.length >= 1 && allSatisfy!(isMutable, Targets))

templatewrap(Targets...) if (Targets.length >= 1 && !allSatisfy!(isMutable, Targets))

templateunwrap(Target) if (isMutable!Target)

templateunwrap(Target) if (!isMutable!Target)
Supports structural based typesafe conversion.
IfSource has structural conformance with theinterfaceTargets,wrap creates an internal wrapper class which inheritsTargets andwraps thesrc object, then returns it.
unwrap can be used to extract objects which have been wrapped bywrap.
Examples:
interface Quack{int quack();    @propertyint height();}interface Flyer{    @propertyint height();}class Duck : Quack{int quack() {return 1; }    @propertyint height() {return 10; }}class Human{int quack() {return 2; }    @propertyint height() {return 20; }}Duck d1 =new Duck();Human h1 =new Human();interface Refleshable{int reflesh();}// does not have structural conformancestaticassert(!__traits(compiles, d1.wrap!Refleshable));staticassert(!__traits(compiles, h1.wrap!Refleshable));// strict upcastQuack qd = d1.wrap!Quack;assert(qdis d1);assert(qd.quack() == 1);// calls Duck.quack// strict downcastDuck d2 = qd.unwrap!Duck;assert(d2is d1);// structural upcastQuack qh = h1.wrap!Quack;assert(qh.quack() == 2);// calls Human.quack// structural downcastHuman h2 = qh.unwrap!Human;assert(h2is h1);// structural upcast (two steps)Quack qx = h1.wrap!Quack;// Human -> QuackFlyer fx = qx.wrap!Flyer;// Quack -> Flyerassert(fx.height == 20);// calls Human.height// structural downcast (two steps)Quack qy = fx.unwrap!Quack;// Flyer -> QuackHuman hy = qy.unwrap!Human;// Quack -> Humanassert(hyis h1);// structural downcast (one step)Human hz = fx.unwrap!Human;// Flyer -> Humanassert(hzis h1);
Examples:
import std.traits : FunctionAttribute, functionAttributes;interface A {int run(); }interface B {int stop(); @propertyint status(); }class X{int run() {return 1; }int stop() {return 2; }    @propertyint status() {return 3; }}auto x =new X();auto ab = x.wrap!(A, B);A a = ab;B b = ab;writeln(a.run());// 1writeln(b.stop());// 2writeln(b.status);// 3staticassert(functionAttributes!(typeof(ab).status) & FunctionAttribute.property);
enumRefCountedAutoInitialize: int;
Options regarding auto-initialization of aSafeRefCounted object (seethe definition ofSafeRefCounted below).
Examples:
import core.exception : AssertError;import std.exception : assertThrown;struct Foo{int a = 42;}SafeRefCounted!(Foo,RefCountedAutoInitialize.yes) rcAuto;SafeRefCounted!(Foo,RefCountedAutoInitialize.no) rcNoAuto;writeln(rcAuto.refCountedPayload.a);// 42assertThrown!AssertError(rcNoAuto.refCountedPayload);rcNoAuto.refCountedStore.ensureInitialized;writeln(rcNoAuto.refCountedPayload.a);// 42
no
Do not auto-initialize the object
yes
Auto-initialize the object
structSafeRefCounted(T, RefCountedAutoInitialize autoInit = RefCountedAutoInitialize.yes) if (!is(T == class) && !is(T == interface));
Defines a reference-counted object containing aT value aspayload.
An instance ofSafeRefCounted is a reference to a structure,which is referred to as thestore, orstorage implementationstruct in this documentation. The store contains a reference countand theT payload.SafeRefCounted usesmalloc to allocatethe store. As instances ofSafeRefCounted are copied or go out ofscope, they will automatically increment or decrement the referencecount. When the reference count goes down to zero,SafeRefCountedwill calldestroy against the payload and callfree todeallocate the store. If theT payload contains any referencesto GC-allocated memory, thenSafeRefCounted will add it to the GC memorythat is scanned for pointers, and remove it from GC scanning beforefree is called on the store.
One important consequence ofdestroy is that it will call thedestructor of theT payload. GC-managed references are notguaranteed to be valid during a destructor call, but other members ofT, such as file handles or pointers tomalloc memory, willstill be valid during the destructor call. This allows theT todeallocate or clean up any non-GC resources immediately after thereference count has reached zero.
Without -preview=dip1000,SafeRefCounted is unsafe and should beused with care. No references to the payload should be escaped outsidetheSafeRefCounted object.
With -preview=dip1000,SafeRefCounted is safe if it's payload is accessed onlywith theborrow function. Scope semantics can also prevent accidentalescaping ofrefCountedPayload, but it's still up to the user to not destroythe last counted reference while the payload is in use. Due to that,refCountedPayload remains accessible only in@system code.
TheautoInit option makes the object ensure the store isautomatically initialized. LeavingautoInit ==RefCountedAutoInitialize.yes (the default option) is convenient buthas the cost of a test whenever the payload is accessed. IfautoInit == RefCountedAutoInitialize.no, user code must call eitherrefCountedStore.isInitialized orrefCountedStore.ensureInitializedbefore attempting to access the payload. Not doing so results in nullpointer dereference.
IfT.this() is annotated with@disable thenautoInit must beRefCountedAutoInitialize.no in order to compile.
See Also:
Examples:
// A pair of an `int` and a `size_t` - the latter being the// reference count - will be dynamically allocatedauto rc1 =SafeRefCounted!int(5);writeln(rc1);// 5// No more allocation, add just one extra reference countauto rc2 = rc1;// Reference semanticsrc2 = 42;writeln(rc1);// 42// the pair will be freed when rc1 and rc2 go out of scope
structRefCountedStore;
SafeRefCounted storage implementation.
pure nothrow @nogc @property @safe boolisInitialized() const;
Returnstrue if and only if the underlying store has been allocated and initialized.
pure nothrow @nogc @property @safe size_trefCount() const;
Returns underlying reference count if it is allocated and initialized (a positive integer), and0 otherwise.
pure nothrow @safe voidensureInitialized()();
Makes sure the payload was properly initialized. Such a call is typically inserted before using the payload.
This function is unavailable ifT.this() is annotated with@disable.
nothrow @property ref @safe inout(RefCountedStore)refCountedStore() inout;
Returns storage implementation struct.
this(A...)(auto ref Aargs)
if (A.length > 0);

this(return scope Tval);
Constructor that initializes the payload.

PostconditionrefCountedStore.isInitialized

voidopAssign(typeof(this)rhs);

voidopAssign(Trhs);
Assignment operators.

NoteYou may not assign a new payload to an uninitialized SafeRefCounted, ifauto initialization is off. Assigning another counted reference is still okay.

@property ref @system TrefCountedPayload() return;

pure nothrow @nogc @property ref @system inout(T)refCountedPayload() inout return;
Returns a reference to the payload. If (autoInit == RefCountedAutoInitialize.yes), calls refCountedStore.ensureInitialized. Otherwise, just issues assert(refCountedStore.isInitialized). Used withalias refCountedPayload this;, so callers can just use theSafeRefCounted object as aT.
The first overload exists only ifautoInit == RefCountedAutoInitialize.yes. So ifautoInit == RefCountedAutoInitialize.no or called for a constant or immutable object, thenrefCountedPayload will also be qualified as nothrow (but will still assert if not initialized).
templateborrow(alias fun)
Borrows the payload ofSafeRefCounted for use infun. Inferred as@safeiffun is@safe and does not escape a reference to the payload.The reference count will be incremented for the duration of the operation,so destroying the last reference will not leave dangling references infun.
Parameters:
funA callable accepting the payload either by value or by reference.
RC refCountThe counted reference to the payload.
Returns:
The return value offun, if any.ref in the return value will be forwarded.

IssuesFor yet unknown reason, code that uses this function with UFCS syntax will not be inferred as@safe. It will still compile if the code is explicitly marked@safe and nothing infun prevents that.

Examples:
This example can be marked@safe with-preview=dip1000.
auto rcInt = safeRefCounted(5);writeln(rcInt.borrow!(theInt => theInt));// 5auto sameInt = rcInt;writeln(sameInt.borrow!"a");// 5// using `ref` in the functionauto arr = [0, 1, 2, 3, 4, 5, 6];sameInt.borrow!(ref (x) => arr[x]) = 10;writeln(arr);// [0, 1, 2, 3, 4, 10, 6]// modifying the payload via an aliassameInt.borrow!"a*=2";writeln(rcInt.borrow!"a");// 10
SafeRefCounted!(T, RefCountedAutoInitialize.no)safeRefCounted(T)(Tval);
Initializes aSafeRefCounted withval. The template parameterT ofSafeRefCounted is inferred fromval. This function can be used to move non-copyable values to the heap. It also disables theautoInit option ofSafeRefCounted.
Parameters:
TvalThe value to be reference counted
Returns:
An initializedSafeRefCounted containingval.
See Also:
Examples:
staticstruct File{static size_t nDestroyed;    string name;    @disablethis(this);// not copyable    ~this() { name =null; ++nDestroyed; }}auto file = File("name");writeln(file.name);// "name"// file cannot be copied and has unique ownershipstaticassert(!__traits(compiles, {auto file2 = file;}));writeln(File.nDestroyed);// 0// make the file ref counted to share ownership// Note://   We write a compound statement (brace-delimited scope) in which all `SafeRefCounted!File` handles are created and deleted.//   This allows us to see (after the scope) what happens after all handles have been destroyed.{// We move the content of `file` to a separate (and heap-allocated) `File` object,// managed-and-accessed via one-or-multiple (initially: one) `SafeRefCounted!File` objects ("handles").// This "moving"://   (1) invokes `file`'s destructor (=> `File.nDestroyed` is incremented from 0 to 1 and `file.name` becomes `null`);//   (2) overwrites `file` with `File.init` (=> `file.name` becomes `null`).// It appears that writing `name = null;` in the destructor is redundant,// but please note that (2) is only performed if `File` defines a destructor (or post-blit operator),// and in the absence of the `nDestroyed` instrumentation there would have been no reason to define a destructor.import std.algorithm.mutation : move;auto rcFile =safeRefCounted(move(file));    writeln(rcFile.name);// "name"    writeln(File.nDestroyed);// 1    writeln(file.name);// null// We create another `SafeRefCounted!File` handle to the same separate `File` object.// While any of the handles is still alive, the `File` object is kept alive (=> `File.nDestroyed` is not modified).auto rcFile2 = rcFile;    writeln(rcFile.refCountedStore.refCount);// 2    writeln(File.nDestroyed);// 1}// The separate `File` object is deleted when the last `SafeRefCounted!File` handle is destroyed// (i.e. at the closing brace of the compound statement above, which destroys both handles: `rcFile` and `rcFile2`)// (=> `File.nDestroyed` is incremented again, from 1 to 2):writeln(File.nDestroyed);// 2
templateProxy(alias a)
Creates a proxy for the valuea that will forward all operations while disabling implicit conversions. The aliased itema must be anlvalue. This is useful for creating a new type from the "base" type (though this isnot a subtype-supertype relationship; the new type is not related to the old type in any way, by design).
The new type supports all operations that the underlying type does, including all operators such as+,--,<,[], etc.
Parameters:
aThe value to act as a proxy for all operations. It must be an lvalue.
Examples:
struct MyInt{privateint value;mixinProxy!value;this(int n){ value = n; }}MyInt n = 10;// Enable operations that original type has.++n;writeln(n);// 11writeln(n * 2);// 22void func(int n) { }// Disable implicit conversions to original type.//int x = n;//func(n);
Examples:
The proxied value must be anlvalue.
struct NewIntType{//Won't work; the literal '1'//is an rvalue, not an lvalue//mixin Proxy!1;//Okay, n is an lvalueint n;mixinProxy!n;this(int n) {this.n = n; }}NewIntType nit = 0;nit++;writeln(nit);// 1struct NewObjectType{    Object obj;//Ok, obj is an lvaluemixinProxy!obj;this (Object o) { obj = o; }}NewObjectType not =new Object();assert(__traits(compiles, not.toHash()));
Examples:
There is one exception to the fact that the new type is not related to the old type.Pseudo-member functions are usable with the new type; they will be forwarded on to the proxied value.
import std.math.traits : isInfinity;float f = 1.0;assert(!f.isInfinity);struct NewFloat{float _;mixinProxy!_;this(float f) { _ = f; }}NewFloat nf = 1.0f;assert(!nf.isInfinity);
structTypedef(T, T init = T.init, string cookie = null);
Typedef allows the creation of a unique type which isbased on an existing type. Unlike thealias feature,Typedef ensures the two types are not considered as equals.
Parameters:
initOptional initial value for the new type.
cookieOptional, used to create multiple unique types which are based on the same origin typeT

NoteIf a library routine cannot handle the Typedef type,you can use theTypedefType template to extract thetype which the Typedef wraps.

Examples:
alias MyInt =Typedef!int;MyInt foo = 10;foo++;writeln(foo);// 11
Examples:
custom initialization values
alias MyIntInit =Typedef!(int, 42);staticassert(is(TypedefType!MyIntInit ==int));staticassert(MyIntInit() == 42);
Examples:
Typedef creates a new type
alias MyInt =Typedef!int;staticvoid takeInt(int) {}staticvoid takeMyInt(MyInt) {}int i;takeInt(i);// okstaticassert(!__traits(compiles, takeMyInt(i)));MyInt myInt;staticassert(!__traits(compiles, takeInt(myInt)));takeMyInt(myInt);// ok
Examples:
Use the optionalcookie argument to create different types of the same base type
alias TypeInt1 =Typedef!int;alias TypeInt2 =Typedef!int;// The two Typedefs are the same type.staticassert(is(TypeInt1 == TypeInt2));alias MoneyEuros =Typedef!(float,float.init,"euros");alias MoneyDollars =Typedef!(float,float.init,"dollars");// The two Typedefs are _not_ the same type.staticassert(!is(MoneyEuros == MoneyDollars));
stringtoString(this T)();

voidtoString(this T, W)(ref Wwriter, ref scope const FormatSpec!charfmt)
if (isOutputRange!(W, char));
Convert wrapped value to a human readable string
Examples:
import std.conv : to;int i = 123;auto td = Typedef!int(i);writeln(i.to!string);// td.to!string
templateTypedefType(T)
Get the underlying type which aTypedef wraps.IfT is not aTypedef it will alias itself toT.
Examples:
import std.conv : to;alias MyInt = Typedef!int;staticassert(is(TypedefType!MyInt ==int));/// Instantiating with a non-Typedef will return that typestaticassert(is(TypedefType!int ==int));string num ="5";// extract the needed typeMyInt myInt = MyInt( num.to!(TypedefType!MyInt) );writeln(myInt);// 5// cast to the underlying type to get the value that's being wrappedint x =cast(TypedefType!MyInt) myInt;alias MyIntInit = Typedef!(int, 42);staticassert(is(TypedefType!MyIntInit ==int));staticassert(MyIntInit() == 42);
templatescoped(T) if (is(T == class))
Allocates aclass object right inside the current scope,therefore avoiding the overhead ofnew. This facility is unsafe;it is the responsibility of the user to not escape a reference to theobject outside the scope.
The class destructor will be called when the result ofscoped() isitself destroyed.
Scoped class instances can be embedded in a parentclass orstruct,just like a child struct instance. Scoped member variables must havetypetypeof(scoped!Class(args)), and be initialized with a call toscoped. See below for an example.

NoteIt's illegal to move a class instance even if you are sure thereare no pointers to it. As such, it is illegal to move a scoped object.

Examples:
class A{int x;this()     {x = 0;}this(int i){x = i;}    ~this()    {}}// Standard usage, constructing A on the stackauto a1 =scoped!A();a1.x = 42;// Result of `scoped` call implicitly converts to a class referenceA aRef = a1;writeln(aRef.x);// 42// Scoped destruction{auto a2 =scoped!A(1);    writeln(a2.x);// 1    aRef = a2;// a2 is destroyed here, calling A's destructor}// aRef is now an invalid reference// Here the temporary scoped A is immediately destroyed.// This means the reference is then invalid.version (Bug){// Wrong, should use `auto`    A invalid =scoped!A();}// Restrictionsversion (Bug){import std.algorithm.mutation : move;auto invalid = a1.move;// illegal, scoped objects can't be moved}staticassert(!is(typeof({auto e1 = a1;// illegal, scoped objects can't be copiedassert([a1][0].x == 42);// ditto})));staticassert(!is(typeof({alias ScopedObject =typeof(a1);auto e2 = ScopedObject();// illegal, must be built via scoped!Aauto e3 = ScopedObject(1);// ditto})));// Use with aliasalias makeScopedA =scoped!A;auto a3 = makeScopedA();auto a4 = makeScopedA(1);// Use as member variablestruct B{typeof(scoped!A()) a;// note the trailing parenthesesthis(int i)    {// construct member        a =scoped!A(i);    }}// Stack-allocateauto b1 = B(5);aRef = b1.a;writeln(aRef.x);// 5destroy(b1);// calls A's destructor for b1.a// aRef is now an invalid reference// Heap-allocateauto b2 =new B(6);writeln(b2.a.x);// 6destroy(*b2);// calls A's destructor for b2.a
@system autoscoped(Args...)(auto ref Argsargs);
Returns the scoped object.
Parameters:
ArgsargsArguments to pass toT's constructor.
templateFlag(string name)
Defines a simple, self-documenting yes/no flag. This makes it easy forAPIs to define functions accepting flags without resorting tobool, which is opaque in calls, and without needing to define anenumerated type separately. UsingFlag!"Name" instead ofbool makes the flag's meaning visible in calls. Each yes/no flag hasits own type, which makes confusions and mix-ups impossible.

ExampleCode callinggetLine (usually far away from its definition) can't beunderstood without looking at the documentation, even by users familiar withthe API:

string getLine(bool keepTerminator){    ...if (keepTerminator) ...    ...}...auto line = getLine(false);
Assuming the reverse meaning (i.e. "ignoreTerminator") and inserting the wrongcode compiles and runs with erroneous results.
After replacing the boolean parameter with an instantiation ofFlag, codecallinggetLine can be easily read and understood even by people notfluent with the API:
string getLine(Flag!"keepTerminator" keepTerminator){    ...if (keepTerminator) ...    ...}...auto line = getLine(Yes.keepTerminator);
The structsYes andNo are provided as shorthand forFlag!"Name".yes andFlag!"Name".no and are preferred for brevity andreadability. These convenience structs mean it is usually unnecessary andcounterproductive to create an alias of aFlag as a way of avoiding typingout the full type while specifying the affirmative or negative options.
Passing categorical data by means of unstructuredboolparameters is classified under "simple-data coupling" by SteveMcConnell in theCode Complete book, along with three otherkinds of coupling. The author argues citing several studies thatcoupling has a negative effect on code quality.Flag offers asimple structuring method for passing yes/no flags to APIs.

Examples:
Flag!"abc" flag;writeln(flag);// Flag!"abc".nowriteln(flag);// No.abcassert(!flag);if (flag)assert(0);
Examples:
auto flag = Yes.abc;assert(flag);writeln(flag);// Yes.abcif (!flag)assert(0);if (flag) {}elseassert(0);
enumFlag: bool;
no
When creating a value of typeFlag!"Name", use Flag!"Name".no for the negative option. When using a value of typeFlag!"Name", compare it against Flag!"Name".no or justfalse or0.
yes
When creating a value of typeFlag!"Name", use Flag!"Name".yes for the affirmative option. When using a value of typeFlag!"Name", compare it against Flag!"Name".yes.
structYes;

structNo;
Convenience names that allow using e.g.Yes.encryption instead ofFlag!"encryption".yes andNo.encryption instead ofFlag!"encryption".no.
Examples:
Flag!"abc" flag;writeln(flag);// Flag!"abc".nowriteln(flag);// No.abcassert(!flag);if (flag)assert(0);
Examples:
auto flag =Yes.abc;assert(flag);writeln(flag);// Yes.abcif (!flag)assert(0);if (flag) {}elseassert(0);
enum autoopDispatch(string name);
templateisBitFlagEnum(E)
Detect whether an enum is of integral type and has only "flag" values(i.e. values with a bit count of exactly 1).Additionally, a zero value is allowed for compatibility with enums includinga "None" value.
Examples:
enum A{    None,    A = 1 << 0,    B = 1 << 1,    C = 1 << 2,    D = 1 << 3,}staticassert(isBitFlagEnum!A);
Examples:
Test an enum with default (consecutive) values
enum B{    A,    B,    C,    D// D == 3}staticassert(!isBitFlagEnum!B);
Examples:
Test an enum with non-integral values
enum C:double{    A = 1 << 0,    B = 1 << 1}staticassert(!isBitFlagEnum!C);
structBitFlags(E, Flag!"unsafe" unsafe = No.unsafe) if (unsafe || isBitFlagEnum!E);
A typesafe structure for storing combinations of enum values.
This template defines a simple struct to represent bitwise OR combinations ofenum values. It can be used if all the enum values are integral constants witha bit count of at most 1, or if theunsafe parameter is explicitly set toYes.This is much safer than using the enum itself to storethe OR combination, which can produce surprising effects like this:
enum E{    A = 1 << 0,    B = 1 << 1}E e = E.A | E.B;// will throw SwitchErrorfinalswitch (e){case E.A:return;case E.B:return;}
Examples:
Set values with the | operator and test with &
enum Enum{    A = 1 << 0,}// A default constructed BitFlags has no value setimmutableBitFlags!Enum flags_empty;assert(!flags_empty.A);// Value can be set with the | operatorimmutable flags_A = flags_empty | Enum.A;// and tested using property accessassert(flags_A.A);// or the & operatorassert(flags_A & Enum.A);// which commutes.assert(Enum.A & flags_A);
Examples:
A default constructed BitFlags has no value set
enum Enum{    None,    A = 1 << 0,    B = 1 << 1,    C = 1 << 2}immutableBitFlags!Enum flags_empty;assert(!(flags_empty & (Enum.A | Enum.B | Enum.C)));assert(!(flags_empty & Enum.A) && !(flags_empty & Enum.B) && !(flags_empty & Enum.C));
Examples:
Binary operations: subtracting and intersecting flags
enum Enum{    A = 1 << 0,    B = 1 << 1,    C = 1 << 2,}immutableBitFlags!Enum flags_AB =BitFlags!Enum(Enum.A, Enum.B);immutableBitFlags!Enum flags_BC =BitFlags!Enum(Enum.B, Enum.C);// Use the ~ operator for subtracting flagsimmutableBitFlags!Enum flags_B = flags_AB & ~BitFlags!Enum(Enum.A);assert(!flags_B.A && flags_B.B && !flags_B.C);// use & between BitFlags for intersectionwriteln(flags_B);// (flags_BC & flags_AB)
Examples:
All the binary operators work in their assignment version
enum Enum{    A = 1 << 0,    B = 1 << 1,}BitFlags!Enum flags_empty, temp, flags_AB;flags_AB = Enum.A | Enum.B;temp |= flags_AB;writeln(temp);// (flags_empty | flags_AB)temp = flags_empty;temp |= Enum.B;writeln(temp);// (flags_empty | Enum.B)temp = flags_empty;temp &= flags_AB;writeln(temp);// (flags_empty & flags_AB)temp = flags_empty;temp &= Enum.A;writeln(temp);// (flags_empty & Enum.A)
Examples:
Conversion to bool and int
enum Enum{    A = 1 << 0,    B = 1 << 1,}BitFlags!Enum flags;// BitFlags with no value set evaluate to falseassert(!flags);// BitFlags with at least one value set evaluate to trueflags |= Enum.A;assert(flags);// This can be useful to check intersection between BitFlagsBitFlags!Enum flags_AB = Enum.A | Enum.B;assert(flags & flags_AB);assert(flags & Enum.A);// You can of course get you raw value out of flagsauto value =cast(int) flags;writeln(value);// Enum.A
Examples:
You need to specify theunsafe parameter for enums with custom values
enum UnsafeEnum{    A = 1,    B = 2,    C = 4,    BC = B|C}staticassert(!__traits(compiles, {BitFlags!UnsafeEnum flags; }));BitFlags!(UnsafeEnum, Yes.unsafe) flags;// property access tests for exact match of unsafe enumsflags.B =true;assert(!flags.BC);// only Bflags.C =true;assert(flags.BC);// both B and Cflags.B =false;assert(!flags.BC);// only C// property access sets all bits of unsafe enum groupflags = flags.init;flags.BC =true;assert(!flags.A && flags.B && flags.C);flags.A =true;flags.BC =false;assert(flags.A && !flags.B && !flags.C);
templateReplaceType(From, To, T...)
Replaces all occurrences ofFrom intoTo, in one or more typesT. Forexample,ReplaceType!(int, uint, Tuple!(int, float)[string]) yieldsTuple!(uint, float)[string]. The types in which replacement is performedmay be arbitrarily complex, including qualifiers, built-in type constructors(pointers, arrays, associative arrays, functions, and delegates), and templateinstantiations; replacement proceeds transitively through the type definition.However, member types instructs orclasses are not replaced because thereare no ways to express the types resulting after replacement.
This is an advanced type manipulation necessary e.g. for replacing theplaceholder typeThis instd.variant.Algebraic.
Returns:
ReplaceType aliases itself to the type(s) that result afterreplacement.
Examples:
staticassert(is(ReplaceType!(int, string,int[]) == string[]) &&is(ReplaceType!(int, string,int[int]) == string[string]) &&is(ReplaceType!(int, string,const(int)[]) ==const(string)[]) &&is(ReplaceType!(int, string, Tuple!(int[],float))        == Tuple!(string[],float)));
templateReplaceTypeUnless(alias pred, From, To, T...)
LikeReplaceType, but does not perform replacement in types for whichpred evaluates totrue.
Examples:
import std.traits : isArray;staticassert(is(ReplaceTypeUnless!(isArray,int, string,int*) == string*) &&is(ReplaceTypeUnless!(isArray,int, string,int[]) ==int[]) &&is(ReplaceTypeUnless!(isArray,int, string, Tuple!(int,int[]))        == Tuple!(string,int[])));
structTernary;
Ternary type with three truth values:
  • Ternary.yes fortrue
  • Ternary.no forfalse
  • Ternary.unknown as an unknown state
Also known as trinary, trivalent, or trilean.
See Also:
Examples:
Ternary a;writeln(a);// Ternary.unknownwriteln(~Ternary.yes);// Ternary.nowriteln(~Ternary.no);// Ternary.yeswriteln(~Ternary.unknown);// Ternary.unknown
enum Ternaryno;

enum Ternaryyes;

enum Ternaryunknown;
The possible states of theTernary
pure nothrow @nogc @safe this(boolb);

pure nothrow @nogc @safe voidopAssign(boolb);
Construct and assign from abool, receivingno forfalse andyes fortrue.
pure nothrow @nogc @safe this(const Ternaryb);
Construct a ternary value from another ternary value
TernaryopUnary(string s)()
if (s == "~");

TernaryopBinary(string s)(Ternaryrhs)
if (s == "|");

TernaryopBinary(string s)(Ternaryrhs)
if (s == "&");

TernaryopBinary(string s)(Ternaryrhs)
if (s == "^");

TernaryopBinary(string s)(boolrhs)
if (s == "|" || s == "&" || s == "^");
Truth table for logical operations
ab˜aa | ba & ba ^ b
nonoyesnonono
noyesyesnoyes
nounknownunknownnounknown
yesnonoyesnoyes
yesyesyesyesno
yesunknownyesunknownunknown
unknownnounknownunknownnounknown
unknownyesyesunknownunknown
unknownunknownunknownunknownunknown
structRefCounted(T, RefCountedAutoInitialize autoInit = RefCountedAutoInitialize.yes);
The old version ofSafeRefCounted, beforeborrow existed.Old code may be relying on@safety of some of the member functions whichcannot be safe in the new scheme, andcan avoid breakage by continuing to use this.SafeRefCounted should bepreferred, as this type is outdated and unrecommended for new code.
Examples:
auto rc1 =RefCounted!int(5);writeln(rc1);// 5auto rc2 = rc1;rc2 = 42;writeln(rc1);// 42
RefCounted!(T, RefCountedAutoInitialize.no)refCounted(T)(Tval);
LikesafeRefCounted but used to initializeRefCounted instead. Intended for backwards compatibility, otherwise it is preferable to usesafeRefCounted.
Examples:
staticstruct File{static size_t nDestroyed;    string name;    @disablethis(this);// not copyable    ~this() { name =null; ++nDestroyed; }}auto file = File("name");writeln(file.name);// "name"staticassert(!__traits(compiles, {auto file2 = file;}));writeln(File.nDestroyed);// 0{import std.algorithm.mutation : move;auto rcFile =refCounted(move(file));    writeln(rcFile.name);// "name"    writeln(File.nDestroyed);// 1    writeln(file.name);// nullauto rcFile2 = rcFile;    writeln(rcFile.refCountedStore.refCount);// 2    writeln(File.nDestroyed);// 1}writeln(File.nDestroyed);// 2
Copyright © 1999-2025 by theD Language Foundation | Page generated byDdoc on Fri Oct 10 22:10:18 2025

[8]ページ先頭

©2009-2025 Movatter.jp