// Written in the D programming language. /**A one-stop shop for converting values from one type to another. $(SCRIPT inhibitQuickIndex = 1;)$(DIVC quickindex,$(BOOKTABLE,$(TR $(TH Category) $(TH Functions))$(TR $(TD Generic) $(TD $(LREF asOriginalType) $(LREF castFrom) $(LREF parse) $(LREF to) $(LREF toChars) $(LREF bitCast)))$(TR $(TD Strings) $(TD $(LREF text) $(LREF wtext) $(LREF dtext) $(LREF writeText) $(LREF writeWText) $(LREF writeDText) $(LREF hexString)))$(TR $(TD Numeric) $(TD $(LREF octal) $(LREF roundTo) $(LREF signed) $(LREF unsigned)))$(TR $(TD Exceptions) $(TD $(LREF ConvException) $(LREF ConvOverflowException))))) Copyright: Copyright The D Language Foundation 2007-. License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: $(HTTP digitalmars.com, Walter Bright), $(HTTP erdani.org, Andrei Alexandrescu), Shin Fujishiro, Adam D. Ruppe, Kenji Hara Source: $(PHOBOSSRC std/conv.d) */module std.conv; public import std.ascii : LetterCase; import std.meta;import std.range;import std.traits;import std.typecons : Flag, Yes, No, tuple, isTuple; // Same as std.string.format, but "self-importing".// Helps reduce code and imports, particularly in static asserts.// Also helps with missing imports errors.package template convFormat(){ import std.format : format; alias convFormat = format;} /* ************* Exceptions *************** */ /** * Thrown on conversion errors. */class ConvException : Exception{ import std.exception : basicExceptionCtors; /// mixin basicExceptionCtors;} ///@safe unittest{ import std.exception : assertThrown; assertThrown!ConvException(to!int("abc"));} private auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE__){ string msg; if (source.empty) msg = "Unexpected end of input when converting from type " ~ S.stringof ~ " to type " ~ T.stringof; else { ElementType!S el = source.front; if (el == '\n') msg = text("Unexpected '\\n' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof); else msg = text("Unexpected '", el, "' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof); } return new ConvException(msg, fn, ln);} @safe pure/* nothrow*/ // lazy parameter bugprivate auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__){ return new ConvException(text("Can't parse string: ", msg), fn, ln);} private void parseCheck(alias source)(dchar c, string fn = __FILE__, size_t ln = __LINE__){ if (source.empty) throw parseError(text("unexpected end of input when expecting \"", c, "\"")); if (source.front != c) throw parseError(text("\"", c, "\" is missing"), fn, ln); source.popFront();} private{ T toStr(T, S)(S src) if (isSomeString!T) { // workaround for https://issues.dlang.org/show_bug.cgi?id=14198 static if (is(S == bool) && is(typeof({ T s = "string"; }))) { return src ? "true" : "false"; } else { import std.array : appender; import std.format.spec : FormatSpec; import std.format.write : formatValue; auto w = appender!T(); FormatSpec!(ElementEncodingType!T) f; formatValue(w, src, f); return w.data; } } template isExactSomeString(T) { enum isExactSomeString = isSomeString!T && !is(T == enum); } template isEnumStrToStr(S, T) { enum isEnumStrToStr = is(S : T) && is(S == enum) && isExactSomeString!T; } template isNullToStr(S, T) { enum isNullToStr = is(S : T) && (is(immutable S == immutable typeof(null))) && isExactSomeString!T; }} /** * Thrown on conversion overflow errors. */class ConvOverflowException : ConvException{ @safe pure nothrow this(string s, string fn = __FILE__, size_t ln = __LINE__) { super(s, fn, ln); }} ///@safe unittest{ 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 theexpression `to!int(42.0)` converts the number 42 from`double` _to `int`. The conversion is "safe", i.e.,it checks for overflow; `to!int(4.2e10)` would throw the`ConvOverflowException` exception. Overflow checks are onlyinserted when necessary, e.g., `to!double(42)` does not doany checking because any `int` fits in a `double`. Conversions from string _to numeric types differ from the C equivalents`atoi()` and `atol()` by checking for overflow and not allowing whitespace. For conversion of strings _to signed types, the grammar recognized is:$(PRE $(I Integer): $(I Sign UnsignedInteger) $(I UnsignedInteger)$(I Sign): $(B +) $(B -)) For conversion _to unsigned types, the grammar recognized is:$(PRE $(I UnsignedInteger): $(I DecimalDigit) $(I DecimalDigit) $(I UnsignedInteger)) */template to(T){ T to(A...)(A args) if (A.length > 0) { return toImpl!T(args); } // Fix https://issues.dlang.org/show_bug.cgi?id=6175 T to(S)(ref S arg) if (isStaticArray!S) { return toImpl!T(arg); } // Fix https://issues.dlang.org/show_bug.cgi?id=16108 T to(S)(ref S arg) if (isAggregateType!S && !isCopyable!S) { return toImpl!T(arg); }} /** * Converting a value _to its own type (useful mostly for generic code) * simply returns its argument. */@safe pure unittest{ int a = 42; int b = to!int(a); double c = to!double(3.14); // c is double with value 3.14} /** * 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`.) */@safe pure unittest{ import std.exception : assertThrown; int a = 420; assert(to!long(a) == a); assertThrown!ConvOverflowException(to!byte(a)); assert(to!int(4.2e6) == 4200000); assertThrown!ConvOverflowException(to!uint(-3.14)); assert(to!uint(3.14) == 3); assert(to!uint(3.99) == 3); assert(to!int(-3.99) == -3);} /** * 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. */@safe pure unittest{ auto str = to!string(42, 16); assert(str == "2A"); auto i = to!int(str, 16); assert(i == 42);} /** * 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` for * `float`, `2^53-1` for `double`, and `2^64-1` for `real` (when * `real` is 80-bit, e.g. on Intel machines). */@safe pure unittest{ // 2^24 - 1, largest proper integer representable as float int a = 16_777_215; assert(to!int(to!float(a)) == a); assert(to!int(to!float(-a)) == -a);} /** 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, $(LREF ConvException) is thrown. */@safe pure unittest{ import std.exception : assertThrown; assert(to!char("a") == 'a'); assertThrown(to!char("ñ")); // 'ñ' does not fit into a char assert(to!wchar("ñ") == 'ñ'); assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar assert(to!dchar("😃") == '😃'); // Using wstring or dstring as source type does not affect the result assert(to!char("a"w) == 'a'); assert(to!char("a"d) == 'a'); // Two code points cannot be converted to a single one assertThrown(to!char("ab"));} /** * 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. */@safe pure unittest{ import std.string : split; int[] a = [1, 2, 3]; auto b = to!(float[])(a); assert(b == [1.0f, 2, 3]); string str = "1 2 3 4 5 6"; auto numbers = to!(double[])(split(str)); assert(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);} /** * 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`, and * `to!(double[])` applies _to an `int[]`. The conversion might throw an * exception because `to!short` might fail the range check. */@safe unittest{ int[string][double[int[]]] a; auto b = to!(short[wstring][string[double[]]])(a);} /** * Object-to-object conversions by dynamic casting throw exception when * the source is non-null and the target is null. */@safe pure unittest{ import std.exception : assertThrown; // Testing object conversions 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));} /** * Stringize conversion from all types is supported. * $(UL * $(LI String _to string conversion works for any two string types having * (`char`, `wchar`, `dchar`) character widths and any * combination of qualifiers (mutable, `const`, or `immutable`).) * $(LI Converts array (other than strings) _to string. * Each element is converted by calling `to!T`.) * $(LI Associative array _to string conversion. * Each element is converted by calling `to!T`.) * $(LI Object _to string conversion calls `toString` against the object or * returns `"null"` if the object is null.) * $(LI Struct _to string conversion calls `toString` against the struct if * it is defined.) * $(LI For structs that do not define `toString`, the conversion _to string * produces the list of fields.) * $(LI Enumerated types are converted _to strings as their symbolic names.) * $(LI Boolean values are converted to `"true"` or `"false"`.) * $(LI `char`, `wchar`, `dchar` _to a string type.) * $(LI Unsigned or signed integers _to strings. * $(DL $(DT [special case]) * $(DD Convert integral value _to string in $(D_PARAM radix) radix. * radix must be a value from 2 to 36. * value is treated as a signed value only if radix is 10. * The characters A through Z are used to represent values 10 through 36 * and their case is determined by the $(D_PARAM letterCase) parameter.))) * $(LI All floating point types _to all string types.) * $(LI Pointer to string conversions convert the pointer to a `size_t` value. * If pointer is `char*`, treat it as C-style strings. * In that case, this function is `@system`.)) * See $(REF formatValue, std,format) on how `toString` should be defined. */@system pure unittest // @system due to cast and ptr{ // Conversion representing dynamic/static array with string long[] a = [ 1, 3, 5 ]; assert(to!string(a) == "[1, 3, 5]"); // Conversion representing associative array with string int[string] associativeArray = ["0":1, "1":2]; assert(to!string(associativeArray) == `["0":1, "1":2]` || to!string(associativeArray) == `["1":2, "0":1]`); // char* to string conversion assert(to!string(cast(char*) null) == ""); assert(to!string("foo\0".ptr) == "foo"); // Conversion reinterpreting void array to string auto w = "abcx"w; const(void)[] b = w; assert(b.length == 8); auto c = to!(wchar[])(b); assert(c == "abcx");} /** * 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 $(LREF ConvException) is thrown if the enum does not have the specified member. */@safe pure unittest{ import std.exception : assertThrown; enum E { a, b, c } assert(to!E("a") == E.a); assert(to!E("b") == E.b); assertThrown!ConvException(to!E("A"));} // Tests for https://issues.dlang.org/show_bug.cgi?id=6175@safe pure nothrow unittest{ char[9] sarr = "blablabla"; auto darr = to!(char[])(sarr); assert(sarr.ptr == darr.ptr); assert(sarr.length == darr.length);} // Tests for https://issues.dlang.org/show_bug.cgi?id=7348@safe pure /+nothrow+/ unittest{ assert(to!string(null) == "null"); assert(text(null) == "null");} // Test `scope` inference of parameters of `text`@safe unittest{ static struct S { int* x; // make S a type with pointers string toString() const scope { return "S"; } } scope S s; assert(text("a", s) == "aS");} // Tests for https://issues.dlang.org/show_bug.cgi?id=11390@safe pure /+nothrow+/ unittest{ const(typeof(null)) ctn; immutable(typeof(null)) itn; assert(to!string(ctn) == "null"); assert(to!string(itn) == "null");} // Tests for https://issues.dlang.org/show_bug.cgi?id=8729: do NOT skip leading WS@safe pure unittest{ import std.exception; static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong)) { assertThrown!ConvException(to!T(" 0")); assertThrown!ConvException(to!T(" 0", 8)); } static foreach (T; AliasSeq!(float, double, real)) { assertThrown!ConvException(to!T(" 0")); } Lines 1–500 of 6420. Load more
// Written in the D programming language. /** A one-stop shop for converting values from one type to another. $(SCRIPT inhibitQuickIndex = 1;) $(DIVC quickindex, $(BOOKTABLE, $(TR $(TH Category) $(TH Functions)) $(TR $(TD Generic) $(TD $(LREF asOriginalType) $(LREF castFrom) $(LREF parse) $(LREF to) $(LREF toChars) $(LREF bitCast) )) $(TR $(TD Strings) $(TD $(LREF text) $(LREF wtext) $(LREF dtext) $(LREF writeText) $(LREF writeWText) $(LREF writeDText) $(LREF hexString) )) $(TR $(TD Numeric) $(TD $(LREF octal) $(LREF roundTo) $(LREF signed) $(LREF unsigned) )) $(TR $(TD Exceptions) $(TD $(LREF ConvException) $(LREF ConvOverflowException) )) )) Copyright: Copyright The D Language Foundation 2007-. License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: $(HTTP digitalmars.com, Walter Bright), $(HTTP erdani.org, Andrei Alexandrescu), Shin Fujishiro, Adam D. Ruppe, Kenji Hara Source: $(PHOBOSSRC std/conv.d) */ module std.conv; public import std.ascii : LetterCase; import std.meta; import std.range; import std.traits; import std.typecons : Flag, Yes, No, tuple, isTuple; // Same as std.string.format, but "self-importing". // Helps reduce code and imports, particularly in static asserts. // Also helps with missing imports errors. package template convFormat() { import std.format : format; alias convFormat = format; } /* ************* Exceptions *************** */ /** * Thrown on conversion errors. */ class ConvException : Exception { import std.exception : basicExceptionCtors; /// mixin basicExceptionCtors; } /// @safe unittest { import std.exception : assertThrown; assertThrown!ConvException(to!int("abc")); } private auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE__) { string msg; if (source.empty) msg = "Unexpected end of input when converting from type " ~ S.stringof ~ " to type " ~ T.stringof; else { ElementType!S el = source.front; if (el == '\n') msg = text("Unexpected '\\n' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof); else msg = text("Unexpected '", el, "' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof); } return new ConvException(msg, fn, ln); } @safe pure/* nothrow*/ // lazy parameter bug private auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__) { return new ConvException(text("Can't parse string: ", msg), fn, ln); } private void parseCheck(alias source)(dchar c, string fn = __FILE__, size_t ln = __LINE__) { if (source.empty) throw parseError(text("unexpected end of input when expecting \"", c, "\"")); if (source.front != c) throw parseError(text("\"", c, "\" is missing"), fn, ln); source.popFront(); } private { T toStr(T, S)(S src) if (isSomeString!T) { // workaround for https://issues.dlang.org/show_bug.cgi?id=14198 static if (is(S == bool) && is(typeof({ T s = "string"; }))) { return src ? "true" : "false"; } else { import std.array : appender; import std.format.spec : FormatSpec; import std.format.write : formatValue; auto w = appender!T(); FormatSpec!(ElementEncodingType!T) f; formatValue(w, src, f); return w.data; } } template isExactSomeString(T) { enum isExactSomeString = isSomeString!T && !is(T == enum); } template isEnumStrToStr(S, T) { enum isEnumStrToStr = is(S : T) && is(S == enum) && isExactSomeString!T; } template isNullToStr(S, T) { enum isNullToStr = is(S : T) && (is(immutable S == immutable typeof(null))) && isExactSomeString!T; } } /** * Thrown on conversion overflow errors. */ class ConvOverflowException : ConvException { @safe pure nothrow this(string s, string fn = __FILE__, size_t ln = __LINE__) { super(s, fn, ln); } } /// @safe unittest { 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 from `double` _to `int`. The conversion is "safe", i.e., it checks for overflow; `to!int(4.2e10)` would throw the `ConvOverflowException` 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 equivalents `atoi()` and `atol()` by checking for overflow and not allowing whitespace. For conversion of strings _to signed types, the grammar recognized is: $(PRE $(I Integer): $(I Sign UnsignedInteger) $(I UnsignedInteger) $(I Sign): $(B +) $(B -)) For conversion _to unsigned types, the grammar recognized is: $(PRE $(I UnsignedInteger): $(I DecimalDigit) $(I DecimalDigit) $(I UnsignedInteger)) */ template to(T) { T to(A...)(A args) if (A.length > 0) { return toImpl!T(args); } // Fix https://issues.dlang.org/show_bug.cgi?id=6175 T to(S)(ref S arg) if (isStaticArray!S) { return toImpl!T(arg); } // Fix https://issues.dlang.org/show_bug.cgi?id=16108 T to(S)(ref S arg) if (isAggregateType!S && !isCopyable!S) { return toImpl!T(arg); } } /** * Converting a value _to its own type (useful mostly for generic code) * simply returns its argument. */ @safe pure unittest { int a = 42; int b = to!int(a); double c = to!double(3.14); // c is double with value 3.14 } /** * 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`.) */ @safe pure unittest { import std.exception : assertThrown; int a = 420; assert(to!long(a) == a); assertThrown!ConvOverflowException(to!byte(a)); assert(to!int(4.2e6) == 4200000); assertThrown!ConvOverflowException(to!uint(-3.14)); assert(to!uint(3.14) == 3); assert(to!uint(3.99) == 3); assert(to!int(-3.99) == -3); } /** * 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. */ @safe pure unittest { auto str = to!string(42, 16); assert(str == "2A"); auto i = to!int(str, 16); assert(i == 42); } /** * 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` for * `float`, `2^53-1` for `double`, and `2^64-1` for `real` (when * `real` is 80-bit, e.g. on Intel machines). */ @safe pure unittest { // 2^24 - 1, largest proper integer representable as float int a = 16_777_215; assert(to!int(to!float(a)) == a); assert(to!int(to!float(-a)) == -a); } /** 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, $(LREF ConvException) is thrown. */ @safe pure unittest { import std.exception : assertThrown; assert(to!char("a") == 'a'); assertThrown(to!char("ñ")); // 'ñ' does not fit into a char assert(to!wchar("ñ") == 'ñ'); assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar assert(to!dchar("😃") == '😃'); // Using wstring or dstring as source type does not affect the result assert(to!char("a"w) == 'a'); assert(to!char("a"d) == 'a'); // Two code points cannot be converted to a single one assertThrown(to!char("ab")); } /** * 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. */ @safe pure unittest { import std.string : split; int[] a = [1, 2, 3]; auto b = to!(float[])(a); assert(b == [1.0f, 2, 3]); string str = "1 2 3 4 5 6"; auto numbers = to!(double[])(split(str)); assert(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); } /** * 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`, and * `to!(double[])` applies _to an `int[]`. The conversion might throw an * exception because `to!short` might fail the range check. */ @safe unittest { int[string][double[int[]]] a; auto b = to!(short[wstring][string[double[]]])(a); } /** * Object-to-object conversions by dynamic casting throw exception when * the source is non-null and the target is null. */ @safe pure unittest { import std.exception : assertThrown; // Testing object conversions 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)); } /** * Stringize conversion from all types is supported. * $(UL * $(LI String _to string conversion works for any two string types having * (`char`, `wchar`, `dchar`) character widths and any * combination of qualifiers (mutable, `const`, or `immutable`).) * $(LI Converts array (other than strings) _to string. * Each element is converted by calling `to!T`.) * $(LI Associative array _to string conversion. * Each element is converted by calling `to!T`.) * $(LI Object _to string conversion calls `toString` against the object or * returns `"null"` if the object is null.) * $(LI Struct _to string conversion calls `toString` against the struct if * it is defined.) * $(LI For structs that do not define `toString`, the conversion _to string * produces the list of fields.) * $(LI Enumerated types are converted _to strings as their symbolic names.) * $(LI Boolean values are converted to `"true"` or `"false"`.) * $(LI `char`, `wchar`, `dchar` _to a string type.) * $(LI Unsigned or signed integers _to strings. * $(DL $(DT [special case]) * $(DD Convert integral value _to string in $(D_PARAM radix) radix. * radix must be a value from 2 to 36. * value is treated as a signed value only if radix is 10. * The characters A through Z are used to represent values 10 through 36 * and their case is determined by the $(D_PARAM letterCase) parameter.))) * $(LI All floating point types _to all string types.) * $(LI Pointer to string conversions convert the pointer to a `size_t` value. * If pointer is `char*`, treat it as C-style strings. * In that case, this function is `@system`.)) * See $(REF formatValue, std,format) on how `toString` should be defined. */ @system pure unittest // @system due to cast and ptr { // Conversion representing dynamic/static array with string long[] a = [ 1, 3, 5 ]; assert(to!string(a) == "[1, 3, 5]"); // Conversion representing associative array with string int[string] associativeArray = ["0":1, "1":2]; assert(to!string(associativeArray) == `["0":1, "1":2]` || to!string(associativeArray) == `["1":2, "0":1]`); // char* to string conversion assert(to!string(cast(char*) null) == ""); assert(to!string("foo\0".ptr) == "foo"); // Conversion reinterpreting void array to string auto w = "abcx"w; const(void)[] b = w; assert(b.length == 8); auto c = to!(wchar[])(b); assert(c == "abcx"); } /** * 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 $(LREF ConvException) is thrown if the enum does not have the specified member. */ @safe pure unittest { import std.exception : assertThrown; enum E { a, b, c } assert(to!E("a") == E.a); assert(to!E("b") == E.b); assertThrown!ConvException(to!E("A")); } // Tests for https://issues.dlang.org/show_bug.cgi?id=6175 @safe pure nothrow unittest { char[9] sarr = "blablabla"; auto darr = to!(char[])(sarr); assert(sarr.ptr == darr.ptr); assert(sarr.length == darr.length); } // Tests for https://issues.dlang.org/show_bug.cgi?id=7348 @safe pure /+nothrow+/ unittest { assert(to!string(null) == "null"); assert(text(null) == "null"); } // Test `scope` inference of parameters of `text` @safe unittest { static struct S { int* x; // make S a type with pointers string toString() const scope { return "S"; } } scope S s; assert(text("a", s) == "aS"); } // Tests for https://issues.dlang.org/show_bug.cgi?id=11390 @safe pure /+nothrow+/ unittest { const(typeof(null)) ctn; immutable(typeof(null)) itn; assert(to!string(ctn) == "null"); assert(to!string(itn) == "null"); } // Tests for https://issues.dlang.org/show_bug.cgi?id=8729: do NOT skip leading WS @safe pure unittest { import std.exception; static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong)) { assertThrown!ConvException(to!T(" 0")); assertThrown!ConvException(to!T(" 0", 8)); } static foreach (T; AliasSeq!(float, double, real)) { assertThrown!ConvException(to!T(" 0")); }