std.conv - D Programming Language (original) (raw)

A one-stop shop for converting values from one type to another.

class ConvException: object.Exception;

Thrown on conversion errors.

Examples:

import std.exception : assertThrown; assertThrown!ConvException(to!int("abc"));

class ConvOverflowException: std.conv.ConvException;

Thrown on conversion overflow errors.

Examples:

import std.exception : assertThrown; assertThrown!ConvOverflowException(to!ubyte(1_000_000));

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to!int(42.0) converts the number 42 fromdouble to int. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw theConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalentsatoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is:

Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is:

UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples:

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42; int b = to!int(a); double c = to!double(3.14);

Examples:

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420; writeln(to!long(a)); assertThrown!ConvOverflowException(to!byte(a));

writeln(to!int(4.2e6)); assertThrown!ConvOverflowException(to!uint(-3.14)); writeln(to!uint(3.14)); writeln(to!uint(3.99)); writeln(to!int(-3.99));

Examples:

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16); writeln(str); auto i = to!int(str, 16); writeln(i);

Examples:

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 forfloat, 2^53-1 for double, and 2^64-1 for real (whenreal is 80-bit, e.g. on Intel machines).

int a = 16_777_215; writeln(to!int(to!float(a))); writeln(to!int(to!float(-a)));

Examples:

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

writeln(to!char("a")); assertThrown(to!char("ñ")); writeln(to!wchar("ñ")); assertThrown(to!wchar("😃")); writeln(to!dchar("😃")); writeln(to!char("a"w)); writeln(to!char("a"d)); assertThrown(to!char("ab"));

Examples:

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3]; auto b = to!(float[])(a); writeln(b); string str = "1 2 3 4 5 6"; auto numbers = to!(double[])(split(str)); writeln(numbers); int[string] c; c["a"] = 1; c["b"] = 2; auto d = to!(double[wstring])(c); assert(d["a"w] == 1 && d["b"w] == 2);

Examples:

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to!short applies to an int, to!wstring applies to a string, to!string applies to a double, andto!(double[]) applies to an int[]. The conversion might throw an exception because to!short might fail the range check.

int[string][double[int[]]] a; auto b = to!(short[wstring][string[double[]]])(a);

Examples:

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown; class 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));

Examples:

Stringize conversion from all types is supported.

See std.format.formatValue on how toString should be defined.

long[] a = [ 1, 3, 5 ]; writeln(to!string(a)); int[string] associativeArray = ["0":1, "1":2]; assert(to!string(associativeArray) == ["0":1, "1":2] || to!string(associativeArray) == ["1":2, "0":1]);

writeln(to!string(cast(char*)null)); writeln(to!string("foo\0".ptr)); auto w = "abcx"w; const(void)[] b = w; writeln(b.length); auto c = to!(wchar[])(b); writeln(c);

Examples:

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c } writeln(to!E("a")); writeln(to!E("b")); assertThrown!ConvException(to!E("A"));

Rounded conversion from floating point to integral.

Rounded conversions do not work with non-integral target types.

Examples:

writeln(roundTo!int(3.14)); writeln(roundTo!int(3.49)); writeln(roundTo!int(3.5)); writeln(roundTo!int(3.999)); writeln(roundTo!int(-3.14)); writeln(roundTo!int(-3.49)); writeln(roundTo!int(-3.5)); writeln(roundTo!int(-3.999)); writeln(roundTo!(const int)(to!(const double)(-3.999)));

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source)
if (is(immutable(Target) == immutable(bool)) && isInputRange!Source && isSomeChar!(ElementType!Source));

The parse family of functions works quite like the tofamily, except that:

  1. It only works with character ranges as input.
  2. It takes the input by reference. This means that rvalues (such as string literals) are not accepted: use to instead.
  3. It advances the input to the position following the conversion.
  4. It does not throw if it could not convert the entire input.

This overload parses a bool from a character input range.

Parameters:

Target the boolean type to convert to
Source source the lvalue of an input range
doCount the flag for deciding to report the number of consumed characters

Returns:

Throws:

A ConvException if the range does not represent a bool.

NoteAll character input range conversions using to are forwarded to parse and do not require lvalues.

Examples:

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

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref scope Source s)
if (isIntegral!Target && !is(Target == enum) && isSomeChar!(ElementType!Source));

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source, uint radix)
if (isIntegral!Target && !is(Target == enum) && isSomeChar!(ElementType!Source));

Parses an integer from a character input range.

Parameters:

Target the integral type to convert to
Source s the lvalue of an input range
doCount the flag for deciding to report the number of consumed characters

Returns:

Throws:

A ConvException If an overflow occurred during conversion or if no character of the input was meaningfully converted.

Examples:

import std.typecons : Flag, Yes, No; string s = "123"; auto a = parse!int(s); writeln(a); string s1 = "123"; auto a1 = parse!(int, string, Yes.doCount)(s1); assert(a1.data == 123 && a1.count == 3);

Examples:

import std.string : tr; import std.typecons : Flag, Yes, No; string test = "123 \t 76.14"; auto a = parse!uint(test); writeln(a); assert(test == " \t 76.14"); test = tr(test, " \t\n\r", "", "d"); writeln(test); auto b = parse!double(test); writeln(b); writeln(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");test2 = tr(test2, " \t\n\r", "", "d"); writeln(test2); auto b2 = parse!(double, string, Yes.doCount)(test2); assert(b2.data == 76.14 && b2.count == 5); writeln(test2);

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (is(Target == enum) && isSomeString!Source && !is(Source == enum));

Parses an enum type from a string representing an enum member name.

Parameters:

Target the enum type to convert to
Source s the lvalue of the range to parse
doCount the flag for deciding to report the number of consumed characters

Returns:

Throws:

A ConvException if type Target does not have a member represented by s.

Examples:

import std.typecons : Flag, Yes, No, tuple; enum EnumType : bool { a = true, b = false, c = a }

auto str = "a"; writeln(parse!EnumType(str)); auto str2 = "a"; writeln(parse!(EnumType, string, No.doCount)(str2)); auto str3 = "a"; writeln(parse!(EnumType, string, Yes.doCount)(str3));

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source)
if (isFloatingPoint!Target && !is(Target == enum) && isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum));

Parses a floating point number from a character range.

Parameters:

Target a floating point type
Source source the lvalue of the range to parse
doCount the flag for deciding to report the number of consumed characters

Returns:

Throws:

A ConvException if source is empty, if no number could be parsed, or if an overflow occurred.

Examples:

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); auto str4 = "-123.456"; r = parse!(double, string, Yes.doCount)(str4); assert(r.data.isClose(-123.456)); writeln(r.count); auto str5 = "+123.456"; r = parse!(double, string, Yes.doCount)(str5); assert(r.data.isClose(123.456)); writeln(r.count); auto 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);

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (staticIndexOf!(immutable(Target), immutable(dchar), immutable(ElementEncodingType!Source)) >= 0 && isSomeString!Source && !is(Source == enum));

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (isSomeChar!Target && (Target.sizeof >= ElementType!Source.sizeof) && !is(Target == enum) && !isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source));

Parses one character from a character range.

Parameters:

Target the type to convert to
Source s the lvalue of an input range
doCount the flag for deciding to report the number of consumed characters

Returns:

Throws:

A ConvException if the range is empty.

Examples:

import std.typecons : Flag, Yes, No; auto s = "Hello, World!"; char first = parse!char(s); writeln(first); writeln(s); char second = parse!(char, string, No.doCount)(s); writeln(second); writeln(s); auto third = parse!(char, string, Yes.doCount)(s); assert(third.data == 'l' && third.count == 1); writeln(s);

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (is(immutable(Target) == immutable(typeof(null))) && isInputRange!Source && isSomeChar!(ElementType!Source));

Parses typeof(null) from a character range if the range spells "null". This function is case insensitive.

Parameters:

Target the type to convert to
Source s the lvalue of an input range
doCount the flag for deciding to report the number of consumed characters

Returns:

Throws:

A ConvException if the range doesn't represent null.

Examples:

import std.exception : assertThrown; import std.typecons : Flag, Yes, No;

alias NullType = typeof(null); auto s1 = "null"; assert(parse!NullType(s1) is null); writeln(s1); auto s2 = "NUll"d; assert(parse!NullType(s2) is null); writeln(s2); auto s3 = "nuLlNULl"; assert(parse!(NullType, string, No.doCount)(s3) is null); auto r = parse!(NullType, string, Yes.doCount)(s3); assert(r.data is null && r.count == 4);

auto m = "maybe"; assertThrown!ConvException(parse!NullType(m)); assertThrown!ConvException(parse!(NullType, string, Yes.doCount)(m)); assert(m == "maybe");
auto s = "NULL"; assert(parse!(const NullType)(s) is null);

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')
if (isDynamicArray!Target && !is(Target == enum) && isSomeString!Source && !is(Source == enum));

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')
if (isStaticArray!Target && !is(Target == enum) && isExactSomeString!Source);

Parses an array from a string given the left bracket (default '['), right bracket (default ']'), and element separator (by default ','). A trailing separator is allowed.

Parameters:

Source s The string to parse
dchar lbracket the character that starts the array
dchar rbracket the character that ends the array
dchar comma the character that separates the elements of the array
doCount the flag for deciding to report the number of consumed characters

Returns:

Examples:

import std.typecons : Flag, Yes, No; auto s1 = [['h', 'e', 'l', 'l', 'o'], "world"]; auto a1 = parse!(string[])(s1); writeln(a1); auto s2 = ["aaa", "bbb", "ccc"]; auto a2 = parse!(string[])(s2); writeln(a2); auto s3 = [['h', 'e', 'l', 'l', 'o'], "world"]; auto len3 = s3.length; auto a3 = parse!(string[], string, Yes.doCount)(s3); writeln(a3.data); writeln(a3.count);

auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar keyval = ':', dchar comma = ',')
if (isAssociativeArray!Target && !is(Target == enum) && isSomeString!Source && !is(Source == enum));

Parses an associative array from a string given the left bracket (default '['), right bracket (default ']'), key-value separator (default ':'), and element seprator (by default ',').

Parameters:

Source s the string to parse
dchar lbracket the character that starts the associative array
dchar rbracket the character that ends the associative array
dchar keyval the character that associates the key with the value
dchar comma the character that separates the elements of the associative array
doCount the flag for deciding to report the number of consumed characters

Returns:

Examples:

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

string text(T...)(T args)
if (T.length > 0);

wstring wtext(T...)(T args)
if (T.length > 0);

dstring dtext(T...)(T args)
if (T.length > 0);

Convenience functions for converting one or more arguments of any type into text (the three character widths).

Examples:

writeln(text(42, ' ', 1.5, ": xyz")); writeln(wtext(42, ' ', 1.5, ": xyz")); writeln(dtext(42, ' ', 1.5, ": xyz"));

template octal(string num) if (isOctalLiteral(num))

template octal(alias decimalInteger) if (is(typeof(decimalInteger)) && isIntegral!(typeof(decimalInteger)))

The octal facility provides a means to declare a number in base 8. Using octal!177 or octal!"177" for 127 represented in octal (same as 0177 in C).

The rules for strings are the usual for literals: If it can fit in anint, it is an int. Otherwise, it is a long. But, if the user specifically asks for a long with the L suffix, always give the long. Give an unsigned iff it is asked for with the U or u suffix. Octals created from integers preserve the type of the passed-in integral.

See Also:

parse for parsing octal strings at runtime.

Examples:

auto a = octal!177; enum b = octal!160; auto c = octal!"1_000_000u"; auto d = octal!"0001_200_000";

auto unsigned(T)(T x)
if (isIntegral!T);

auto unsigned(T)(T x)
if (isSomeChar!T);

Returns the corresponding unsigned value for x (e.g. if x has typeint, it returns cast(uint) x). The advantage compared to the cast is that you do not need to rewrite the cast if x later changes type (e.g from int to long).

Note that the result is always mutable even if the original type was const or immutable. In order to retain the constness, use std.traits.Unsigned.

Examples:

import std.traits : Unsigned; immutable int s = 42; auto u1 = unsigned(s); static assert(is(typeof(u1) == uint)); Unsigned!(typeof(s)) u2 = unsigned(s); static assert(is(typeof(u2) == immutable uint)); immutable u3 = unsigned(s);

auto signed(T)(T x)
if (isIntegral!T);

Returns the corresponding signed value for x (e.g. if x has typeuint, it returns cast(int) x). The advantage compared to the cast is that you do not need to rewrite the cast if x later changes type (e.g from uint to ulong).

Note that the result is always mutable even if the original type was const or immutable. In order to retain the constness, use std.traits.Signed.

Examples:

import std.traits : Signed;

immutable uint u = 42; auto s1 = signed(u); static assert(is(typeof(s1) == int)); Signed!(typeof(u)) s2 = signed(u); static assert(is(typeof(s2) == immutable int)); immutable s3 = signed(u);

OriginalType!E asOriginalType(E)(E value)
if (is(E == enum));

Returns the representation of an enumerated value, i.e. the value converted to the base type of the enumeration.

Examples:

enum A { a = 42 } static assert(is(typeof(A.a.asOriginalType) == int)); writeln(A.a.asOriginalType); enum B : double { a = 43 } static assert(is(typeof(B.a.asOriginalType) == double)); writeln(B.a.asOriginalType);

A wrapper on top of the built-in cast operator that allows one to restrict casting of the original type of the value.

A common issue with using a raw cast is that it may silently continue to compile even if the value's type has changed during refactoring, which breaks the initial assumption about the cast.

Parameters:

From The type to cast from. The programmer must ensure it is legal to make this cast.

Examples:

{ long x; auto y = cast(int) x; }

{ long* x; auto y = cast(int) x; }

{ long x; auto y = castFrom!long.to!int(x); }

{ long* x; static assert( !__traits(compiles, castFrom!long.to!int(x)) );

    auto y = castFrom!(long*).to!int(x);

}

ref @system auto to(To, T)(auto ref T value);

Parameters:

To The type to cast to.
T value The value to cast. It must be of type From, otherwise a compile-time error is emitted.

Returns:

the value after the cast, returned by reference if possible.

template hexString(string hexData) if (hexData.isHexLiteral)

template hexString(wstring hexData) if (hexData.isHexLiteral)

template hexString(dstring hexData) if (hexData.isHexLiteral)

Converts a hex literal to a string at compile time.

Takes a string made of hexadecimal digits and returns the matching string by converting each pair of digits to a character. The input string can also include white characters, which can be used to keep the literal string readable in the source code.

The function is intended to replace the hexadecimal literal strings starting with 'x', which could be removed to simplify the core language.

Parameters:

hexData string to be converted.

Returns:

a string, a wstring or a dstring, according to the type of hexData.

Examples:

auto string1 = hexString!"304A314B"; writeln(string1); auto string2 = hexString!"304A314B"w; writeln(string2); auto string3 = hexString!"304A314B"d; writeln(string3);

pure nothrow @nogc @safe auto toChars(ubyte radix = 10, Char = char, LetterCase letterCase = LetterCase.lower, T)(T value)
if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) && isIntegral!T && (radix == 10 || isUnsigned!T));

Convert integer to a range of characters. Intended to be lightweight and fast.

Parameters:

radix 2, 8, 10, 16
Char character type for output
letterCase lower for deadbeef, upper for DEADBEEF
T value integer to convert. Can be ubyte, ushort, uint or ulong. If radix is 10, can also be byte, short, int or long.

Returns:

Random access range with slicing and everything

Examples:

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"));

ref T bitCast(T, S)(ref S value)
if (T.sizeof <= S.sizeof);

Takes the raw bits of a value and reinterprets them as a different type.

Parameters:

T the new type.
S value the value to reinterpret.

Returns:

a reference to the reinterpreted value.

Examples:

uint n = 0xDEADBEEF;

version (LittleEndian) writeln(n.bitCast!(ubyte[4])); version (BigEndian) writeln(n.bitCast!(ubyte[4]));

Copyright © 1999-2025 by the D Language Foundation | Page generated byDdoc on Fri Oct 10 22:10:04 2025