Sourcestd/conv.d
ConvException:object.Exception;import std.exception : assertThrown;assertThrown!ConvException(to!int("abc"));
ConvOverflowException:std.conv.ConvException;import std.exception : assertThrown;assertThrown!ConvOverflowException(to!ubyte(1_000_000));
to(T)to template converts a value from one type to another.The source type is deduced and the target type must be specified, for example theexpressionto!int(42.0) converts the number 42 fromdouble toint. The conversion is "safe", i.e.,it checks for overflow;to!int(4.2e10) would throw theConvOverflowException exception. Overflow checks are onlyinserted when necessary, e.g.,to!double(42) does not doany checking because anyint fits in adouble.Integer:Sign UnsignedIntegerUnsignedIntegerSign:+-For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:DecimalDigitDecimalDigitUnsignedInteger
int a = 42;int b =to!int(a);double c =to!double(3.14);// c is double with value 3.14
import std.exception : assertThrown;int a = 420;writeln(to!long(a));// aassertThrown!ConvOverflowException(to!byte(a));writeln(to!int(4.2e6));// 4200000assertThrown!ConvOverflowException(to!uint(-3.14));writeln(to!uint(3.14));// 3writeln(to!uint(3.99));// 3writeln(to!int(-3.99));// -3
auto str =to!string(42, 16);writeln(str);// "2A"auto i =to!int(str, 16);writeln(i);// 42
// 2^24 - 1, largest proper integer representable as floatint a = 16_777_215;writeln(to!int(to!float(a)));// awriteln(to!int(to!float(-a)));// -a
import std.exception : assertThrown;writeln(to!char("a"));// 'a'assertThrown(to!char("ñ"));// 'ñ' does not fit into a charwriteln(to!wchar("ñ"));// 'ñ'assertThrown(to!wchar("😃"));// '😃' does not fit into a wcharwriteln(to!dchar("😃"));// '😃'// Using wstring or dstring as source type does not affect the resultwriteln(to!char("a"w));// 'a'writeln(to!char("a"d));// 'a'// Two code points cannot be converted to a single oneassertThrown(to!char("ab"));
import std.string : split;int[] a = [1, 2, 3];auto b =to!(float[])(a);writeln(b);// [1.0f, 2, 3]string str ="1 2 3 4 5 6";auto numbers =to!(double[])(split(str));writeln(numbers);// [1.0, 2, 3, 4, 5, 6]int[string] c;c["a"] = 1;c["b"] = 2;auto d =to!(double[wstring])(c);assert(d["a"w] == 1 && d["b"w] == 2);
to!short applies to anint,to!wstring applies to astring,to!string applies to adouble, andto!(double[]) applies to anint[]. The conversion might throw an exception becauseto!short might fail the range check.int[string][double[int[]]] a;auto b =to!(short[wstring][string[double[]]])(a);
import std.exception : assertThrown;// Testing object conversionsclass A {}class B : A {}class C : A {}A a1 =new A, a2 =new B, a3 =new C;assert(to!B(a2)is a2);assert(to!C(a3)is a3);assertThrown!ConvException(to!B(a3));
to!T.to!T.// Conversion representing dynamic/static array with stringlong[] a = [ 1, 3, 5 ];writeln(to!string(a));// "[1, 3, 5]"// Conversion representing associative array with stringint[string] associativeArray = ["0":1,"1":2];assert(to!string(associativeArray) ==`["0":1, "1":2]` ||to!string(associativeArray) ==`["1":2, "0":1]`);// char* to string conversionwriteln(to!string(cast(char*)null));// ""writeln(to!string("foo\0".ptr));// "foo"// Conversion reinterpreting void array to stringauto w ="abcx"w;const(void)[] b = w;writeln(b.length);// 8auto c =to!(wchar[])(b);writeln(c);// "abcx"
import std.exception : assertThrown;enum E { a, b, c }writeln(to!E("a"));// E.awriteln(to!E("b"));// E.bassertThrown!ConvException(to!E("A"));
roundTo(Target)writeln(roundTo!int(3.14));// 3writeln(roundTo!int(3.49));// 3writeln(roundTo!int(3.5));// 4writeln(roundTo!int(3.999));// 4writeln(roundTo!int(-3.14));// -3writeln(roundTo!int(-3.49));// -3writeln(roundTo!int(-3.5));// -4writeln(roundTo!int(-3.999));// -4writeln(roundTo!(constint)(to!(constdouble)(-3.999)));// -4
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sourcesource)parse family of functions works quite like thetofamily, except that:| Target | the boolean type to convert to |
Sourcesource | the lvalue of aninput range |
| doCount | the flag for deciding to report the number of consumed characters |
NoteAll character input range conversions usingto are forwarded toparse and do not require lvalues.
import std.typecons : Flag, Yes, No;auto s ="true";bool b =parse!bool(s);assert(b);auto s2 ="true";bool b2 =parse!(bool, string, No.doCount)(s2);assert(b2);auto s3 ="true";auto b3 =parse!(bool, string, Yes.doCount)(s3);assert(b3.data && b3.count == 4);auto s4 ="falSE";auto b4 =parse!(bool, string, Yes.doCount)(s4);assert(!b4.data && b4.count == 5);
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref scope Sources)parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sourcesource, uintradix)| Target | the integral type to convert to |
Sources | the lvalue of an input range |
| doCount | the flag for deciding to report the number of consumed characters |
import std.typecons : Flag, Yes, No;strings ="123";auto a =parse!int(s);writeln(a);// 123string s1 ="123";auto a1 =parse!(int, string, Yes.doCount)(s1);assert(a1.data == 123 && a1.count == 3);
import std.string : tr;import std.typecons : Flag, Yes, No;string test ="123 \t 76.14";auto a =parse!uint(test);writeln(a);// 123assert(test ==" \t 76.14");// parse bumps stringtest = tr(test," \t\n\r","","d");// skip wswriteln(test);// "76.14"auto b =parse!double(test);writeln(b);// 76.14writeln(test);// ""string test2 ="123 \t 76.14";auto a2 =parse!(uint, string, Yes.doCount)(test2);assert(a2.data == 123 && a2.count == 3);assert(test2 ==" \t 76.14");// parse bumps stringtest2 = tr(test2," \t\n\r","","d");// skip wswriteln(test2);// "76.14"auto b2 =parse!(double, string, Yes.doCount)(test2);assert(b2.data == 76.14 && b2.count == 5);writeln(test2);// ""
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sources)| Target | theenum type to convert to |
Sources | the lvalue of the range to parse |
| doCount | the flag for deciding to report the number of consumed characters |
import std.typecons : Flag, Yes, No, tuple;enum EnumType :bool { a =true, b =false, c = a }auto str ="a";writeln(parse!EnumType(str));// EnumType.aauto str2 ="a";writeln(parse!(EnumType, string, No.doCount)(str2));// EnumType.aauto str3 ="a";writeln(parse!(EnumType, string, Yes.doCount)(str3));// tuple(EnumType.a, 1)
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sourcesource)| Target | a floating point type |
Sourcesource | the lvalue of the range to parse |
| doCount | the flag for deciding to report the number of consumed characters |
source is empty, if no number could be parsed, or if an overflow occurred.import std.math.operations : isClose;import std.math.traits : isNaN, isInfinity;import std.typecons : Flag, Yes, No;auto str ="123.456";assert(parse!double(str).isClose(123.456));auto str2 ="123.456";assert(parse!(double, string, No.doCount)(str2).isClose(123.456));auto str3 ="123.456";auto r =parse!(double, string, Yes.doCount)(str3);assert(r.data.isClose(123.456));writeln(r.count);// 7auto str4 ="-123.456";r =parse!(double, string, Yes.doCount)(str4);assert(r.data.isClose(-123.456));writeln(r.count);// 8auto str5 ="+123.456";r =parse!(double, string, Yes.doCount)(str5);assert(r.data.isClose(123.456));writeln(r.count);// 8auto str6 ="inf0";r =parse!(double, string, Yes.doCount)(str6);assert(isInfinity(r.data) && r.count == 3 && str6 =="0");auto str7 ="-0";auto r2 =parse!(float, string, Yes.doCount)(str7);assert(r2.data.isClose(0.0) && r2.count == 2);auto str8 ="nan";auto r3 =parse!(real, string, Yes.doCount)(str8);assert(isNaN(r3.data) && r3.count == 3);
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sources)parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sources)| Target | the type to convert to |
Sources | the lvalue of aninput range |
| doCount | the flag for deciding to report the number of consumed characters |
import std.typecons : Flag, Yes, No;autos ="Hello, World!";char first =parse!char(s);writeln(first);// 'H'writeln(s);// "ello, World!"char second =parse!(char, string, No.doCount)(s);writeln(second);// 'e'writeln(s);// "llo, World!"auto third =parse!(char, string, Yes.doCount)(s);assert(third.data == 'l' && third.count == 1);writeln(s);// "lo, World!"
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sources)| Target | the type to convert to |
Sources | the lvalue of aninput range |
| doCount | the flag for deciding to report the number of consumed characters |
import std.exception : assertThrown;import std.typecons : Flag, Yes, No;alias NullType =typeof(null);auto s1 ="null";assert(parse!NullType(s1)isnull);writeln(s1);// ""auto s2 ="NUll"d;assert(parse!NullType(s2)isnull);writeln(s2);// ""auto s3 ="nuLlNULl";assert(parse!(NullType, string, No.doCount)(s3)isnull);auto r =parse!(NullType, string, Yes.doCount)(s3);assert(r.dataisnull && r.count == 4);auto m ="maybe";assertThrown!ConvException(parse!NullType(m));assertThrown!ConvException(parse!(NullType, string, Yes.doCount)(m));assert(m =="maybe");// m shouldn't change on failureautos ="NULL";assert(parse!(const NullType)(s)isnull);
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sources, dcharlbracket = '[', dcharrbracket = ']', dcharcomma = ',')parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sources, dcharlbracket = '[', dcharrbracket = ']', dcharcomma = ',')Sources | The string to parse |
dcharlbracket | the character that starts the array |
dcharrbracket | the character that ends the array |
dcharcomma | the character that separates the elements of the array |
| doCount | the flag for deciding to report the number of consumed characters |
import std.typecons : Flag, Yes, No;auto s1 =`[['h', 'e', 'l', 'l', 'o'], "world"]`;auto a1 =parse!(string[])(s1);writeln(a1);// ["hello", "world"]auto s2 =`["aaa", "bbb", "ccc"]`;auto a2 =parse!(string[])(s2);writeln(a2);// ["aaa", "bbb", "ccc"]auto s3 =`[['h', 'e', 'l', 'l', 'o'], "world"]`;auto len3 = s3.length;auto a3 =parse!(string[], string, Yes.doCount)(s3);writeln(a3.data);// ["hello", "world"]writeln(a3.count);// len3
parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Sources, dcharlbracket = '[', dcharrbracket = ']', dcharkeyval = ':', dcharcomma = ',')Sources | the string to parse |
dcharlbracket | the character that starts the associative array |
dcharrbracket | the character that ends the associative array |
dcharkeyval | the character that associates the key with the value |
dcharcomma | the character that separates the elements of the associative array |
| doCount | the flag for deciding to report the number of consumed characters |
import std.typecons : Flag, Yes, No, tuple;import std.range.primitives : save;import std.array : assocArray;auto s1 ="[1:10, 2:20, 3:30]";auto copyS1 = s1.save;auto aa1 =parse!(int[int])(s1);writeln(aa1);// [1:10, 2:20, 3:30]// parse!(int[int], string, Yes.doCount)(copyS1)writeln(tuple([1:10, 2:20, 3:30], copyS1.length));auto s2 =`["aaa":10, "bbb":20, "ccc":30]`;auto copyS2 = s2.save;auto aa2 =parse!(int[string])(s2);writeln(aa2);// ["aaa":10, "bbb":20, "ccc":30]assert(tuple(["aaa":10,"bbb":20,"ccc":30], copyS2.length) ==parse!(int[string], string, Yes.doCount)(copyS2));auto s3 =`["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]]`;auto copyS3 = s3.save;auto aa3 =parse!(int[][string])(s3);writeln(aa3);// ["aaa":[1], "bbb":[2, 3], "ccc":[4, 5, 6]]assert(tuple(["aaa":[1],"bbb":[2,3],"ccc":[4,5,6]], copyS3.length) ==parse!(int[][string], string, Yes.doCount)(copyS3));auto s4 =`[]`;int[int] emptyAA;writeln(tuple(emptyAA, s4.length));// parse!(int[int], string, Yes.doCount)(s4)
text(T...)(Targs)wtext(T...)(Targs)dtext(T...)(Targs)writeln(text(42, ' ', 1.5,": xyz"));// "42 1.5: xyz"cwriteln(wtext(42, ' ', 1.5,": xyz"));// "42 1.5: xyz"wwriteln(dtext(42, ' ', 1.5,": xyz"));// "42 1.5: xyz"d
octal(string num) if (isOctalLiteral(num))octal(alias decimalInteger) if (is(typeof(decimalInteger)) && isIntegral!(typeof(decimalInteger)))octal facility provides a means to declare a number in base 8.Usingoctal!177 oroctal!"177" for 127 represented in octal(same as 0177 in C).// Same as 0177auto a =octal!177;// octal is a compile-time deviceenum b =octal!160;// Create an unsigned octalauto c =octal!"1_000_000u";// Leading zeros are allowed when converting from a stringauto d =octal!"0001_200_000";
unsigned(T)(Tx)unsigned(T)(Tx)x (e.g. ifx has typeint, it returnscast(uint) x). The advantage compared to the cast is that you do not need to rewrite the cast ifx later changes type (e.g fromint tolong).import std.traits : Unsigned;immutableint s = 42;auto u1 =unsigned(s);//not qualifiedstaticassert(is(typeof(u1) ==uint));Unsigned!(typeof(s)) u2 =unsigned(s);//same qualificationstaticassert(is(typeof(u2) ==immutableuint));immutable u3 =unsigned(s);//explicitly qualified
signed(T)(Tx)x (e.g. ifx has typeuint, it returnscast(int) x). The advantage compared to the cast is that you do not need to rewrite the cast ifx later changes type (e.g fromuint toulong).import std.traits : Signed;immutableuint u = 42;auto s1 =signed(u);//not qualifiedstaticassert(is(typeof(s1) ==int));Signed!(typeof(u)) s2 =signed(u);//same qualificationstaticassert(is(typeof(s2) ==immutableint));immutable s3 =signed(u);//explicitly qualified
asOriginalType(E)(Evalue)enum A { a = 42 }staticassert(is(typeof(A.a.asOriginalType) ==int));writeln(A.a.asOriginalType);// 42enum B :double { a = 43 }staticassert(is(typeof(B.a.asOriginalType) ==double));writeln(B.a.asOriginalType);// 43
castFrom(From)| From | The type to cast from. The programmer must ensure it is legal to make this cast. |
// Regular cast, which has been verified to be legal by the programmer:{long x;auto y =cast(int) x;}// However this will still compile if 'x' is changed to be a pointer:{long* x;auto y =cast(int) x;}// castFrom provides a more reliable alternative to casting:{long x;auto y =castFrom!long.to!int(x);}// Changing the type of 'x' will now issue a compiler error,// allowing bad casts to be caught before it's too late:{long* x;staticassert( !__traits(compiles,castFrom!long.to!int(x)) );// if cast is still needed, must be changed to:auto y =castFrom!(long*).to!int(x);}
to(To, T)(auto ref Tvalue);| To | The type to cast to. |
Tvalue | The value to cast. It must be of typeFrom, otherwise a compile-time error is emitted. |
hexString(string hexData) if (hexData.isHexLiteral)hexString(wstring hexData) if (hexData.isHexLiteral)hexString(dstring hexData) if (hexData.isHexLiteral)| hexData | string to be converted. |
// conversion at compile timeauto string1 =hexString!"304A314B";writeln(string1);// "0J1K"auto string2 =hexString!"304A314B"w;writeln(string2);// "0J1K"wauto string3 =hexString!"304A314B"d;writeln(string3);// "0J1K"d
toChars(ubyte radix = 10, Char = char, LetterCase letterCase = LetterCase.lower, T)(Tvalue)| radix | 2, 8, 10, 16 |
| Char | character type for output |
| letterCase | lower for deadbeef, upper for DEADBEEF |
Tvalue | integer to convert. Can be ubyte, ushort, uint or ulong. If radix is 10, can also be byte, short, int or long. |
import std.algorithm.comparison : equal;assert(toChars(1).equal("1"));assert(toChars(1_000_000).equal("1000000"));assert(toChars!(2)(2U).equal("10"));assert(toChars!(16)(255U).equal("ff"));assert(toChars!(16,char, LetterCase.upper)(255U).equal("FF"));
bitCast(T, S)(ref Svalue)| T | the new type. |
Svalue | the value to reinterpret. |
uint n = 0xDEADBEEF;version (LittleEndian) writeln(n.bitCast!(ubyte[4]));// [0xEF, 0xBE, 0xAD, 0xDE]version (BigEndian) writeln(n.bitCast!(ubyte[4]));// [0xDE, 0xAD, 0xBE, 0xEF]