mirror of
https://github.com/dlang/phobos.git
synced 2025-05-03 16:40:48 +03:00
Merge pull request #8360 from WebFreak001/is-some-finite-char-input-range
add isSomeFiniteCharInputRange as simplification Signed-off-by: Nicholas Wilson <thewilsonator@users.noreply.github.com> Merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
This commit is contained in:
commit
263652cee6
8 changed files with 110 additions and 96 deletions
|
@ -50,7 +50,7 @@ module std.conv;
|
|||
public import std.ascii : LetterCase;
|
||||
|
||||
import std.meta;
|
||||
import std.range.primitives;
|
||||
import std.range;
|
||||
import std.traits;
|
||||
import std.typecons : Flag, Yes, No, tuple, isTuple;
|
||||
|
||||
|
@ -1996,7 +1996,7 @@ if (isInputRange!S && isSomeChar!(ElementEncodingType!S) &&
|
|||
|
||||
/// ditto
|
||||
private T toImpl(T, S)(S value, uint radix)
|
||||
if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S) &&
|
||||
if (isSomeFiniteCharInputRange!S &&
|
||||
isIntegral!T && is(typeof(parse!T(value, radix))))
|
||||
{
|
||||
scope(success)
|
||||
|
|
100
std/file.d
100
std/file.d
|
@ -89,7 +89,7 @@ import std.datetime.date : DateTime;
|
|||
import std.datetime.systime : Clock, SysTime, unixTimeToStdTime;
|
||||
import std.internal.cstring;
|
||||
import std.meta;
|
||||
import std.range.primitives;
|
||||
import std.range;
|
||||
import std.traits;
|
||||
import std.typecons;
|
||||
|
||||
|
@ -313,8 +313,7 @@ Throws: $(LREF FileException) on error.
|
|||
*/
|
||||
|
||||
void[] read(R)(R name, size_t upTo = size_t.max)
|
||||
if (isInputRange!R && isSomeChar!(ElementEncodingType!R) && !isInfinite!R &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
|
||||
return readImpl(name, name.tempCString!FSChar(), upTo);
|
||||
|
@ -500,7 +499,7 @@ version (linux) @safe unittest
|
|||
$(REF UTFException, std, utf) on UTF decoding error.
|
||||
+/
|
||||
S readText(S = string, R)(auto ref R name)
|
||||
if (isSomeString!S && (isInputRange!R && !isInfinite!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R)))
|
||||
if (isSomeString!S && (isSomeFiniteCharInputRange!R || is(StringTypeOf!R)))
|
||||
{
|
||||
import std.algorithm.searching : startsWith;
|
||||
import std.encoding : getBOM, BOM;
|
||||
|
@ -736,8 +735,7 @@ Throws: $(LREF FileException) on error.
|
|||
See_also: $(REF toFile, std,stdio)
|
||||
*/
|
||||
void write(R)(R name, const void[] buffer)
|
||||
if ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if ((isSomeFiniteCharInputRange!R || isSomeString!R) && !isConvertibleToString!R)
|
||||
{
|
||||
static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
|
||||
writeImpl(name, name.tempCString!FSChar(), buffer, false);
|
||||
|
@ -785,8 +783,7 @@ Params:
|
|||
Throws: $(LREF FileException) on error.
|
||||
*/
|
||||
void append(R)(R name, const void[] buffer)
|
||||
if ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if ((isSomeFiniteCharInputRange!R || isSomeString!R) && !isConvertibleToString!R)
|
||||
{
|
||||
static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
|
||||
writeImpl(name, name.tempCString!FSChar(), buffer, true);
|
||||
|
@ -915,10 +912,8 @@ version (Windows) private void writeImpl(scope const(char)[] name, scope const(F
|
|||
* Throws: $(LREF FileException) on error.
|
||||
*/
|
||||
void rename(RF, RT)(RF from, RT to)
|
||||
if ((isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) || isSomeString!RF)
|
||||
&& !isConvertibleToString!RF &&
|
||||
(isInputRange!RT && !isInfinite!RT && isSomeChar!(ElementEncodingType!RT) || isSomeString!RT)
|
||||
&& !isConvertibleToString!RT)
|
||||
if ((isSomeFiniteCharInputRange!RF || isSomeString!RF) && !isConvertibleToString!RF &&
|
||||
(isSomeFiniteCharInputRange!RT || isSomeString!RT) && !isConvertibleToString!RT)
|
||||
{
|
||||
// Place outside of @trusted block
|
||||
auto fromz = from.tempCString!FSChar();
|
||||
|
@ -1027,8 +1022,7 @@ Params:
|
|||
Throws: $(LREF FileException) on error.
|
||||
*/
|
||||
void remove(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
|
||||
removeImpl(name, name.tempCString!FSChar());
|
||||
|
@ -1082,7 +1076,7 @@ private void removeImpl(scope const(char)[] name, scope const(FSChar)* namez) @t
|
|||
}
|
||||
|
||||
version (Windows) private WIN32_FILE_ATTRIBUTE_DATA getFileAttributesWin(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R))
|
||||
if (isSomeFiniteCharInputRange!R)
|
||||
{
|
||||
auto namez = name.tempCString!FSChar();
|
||||
|
||||
|
@ -1137,8 +1131,7 @@ Throws:
|
|||
$(LREF FileException) on error (e.g., file not found).
|
||||
*/
|
||||
ulong getSize(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -1233,8 +1226,7 @@ private SysTime statTimeToStdTime(char which)(ref const stat_t statbuf)
|
|||
void getTimes(R)(R name,
|
||||
out SysTime accessTime,
|
||||
out SysTime modificationTime)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -1378,8 +1370,9 @@ version (StdDdoc)
|
|||
out SysTime fileCreationTime,
|
||||
out SysTime fileAccessTime,
|
||||
out SysTime fileModificationTime)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R);
|
||||
if (isSomeFiniteCharInputRange!R || isConvertibleToString!R);
|
||||
// above line contains both constraints for docs
|
||||
// (so users know how it can be called)
|
||||
}
|
||||
else version (Windows)
|
||||
{
|
||||
|
@ -1387,8 +1380,7 @@ else version (Windows)
|
|||
out SysTime fileCreationTime,
|
||||
out SysTime fileAccessTime,
|
||||
out SysTime fileModificationTime)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
import std.datetime.systime : FILETIMEToSysTime;
|
||||
|
||||
|
@ -1509,8 +1501,7 @@ private
|
|||
void setTimes(R)(R name,
|
||||
SysTime accessTime,
|
||||
SysTime modificationTime)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
auto namez = name.tempCString!FSChar();
|
||||
static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
|
||||
|
@ -1657,8 +1648,7 @@ private void setTimesImpl(scope const(char)[] names, scope const(FSChar)* namez,
|
|||
$(LREF FileException) if the given file does not exist.
|
||||
+/
|
||||
SysTime timeLastModified(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -1742,7 +1732,7 @@ else
|
|||
--------------------
|
||||
+/
|
||||
SysTime timeLastModified(R)(R name, SysTime returnIfMissing)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R))
|
||||
if (isSomeFiniteCharInputRange!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -1902,8 +1892,7 @@ version (OSX) {} else
|
|||
* true if the file _name specified as input _exists
|
||||
*/
|
||||
bool exists(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
return existsImpl(name.tempCString!FSChar());
|
||||
}
|
||||
|
@ -2004,8 +1993,7 @@ private bool existsImpl(scope const(FSChar)* namez) @trusted nothrow @nogc
|
|||
Throws: $(LREF FileException) on error.
|
||||
+/
|
||||
uint getAttributes(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -2105,8 +2093,7 @@ if (isConvertibleToString!R)
|
|||
$(LREF FileException) on error.
|
||||
+/
|
||||
uint getLinkAttributes(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -2214,8 +2201,7 @@ if (isConvertibleToString!R)
|
|||
$(LREF FileException) if the given file does not exist.
|
||||
+/
|
||||
void setAttributes(R)(R name, uint attributes)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -2323,8 +2309,7 @@ if (isConvertibleToString!R)
|
|||
$(LREF FileException) if the given file does not exist.
|
||||
+/
|
||||
@property bool isDir(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
{
|
||||
|
@ -2503,8 +2488,7 @@ bool attrIsDir(uint attributes) @safe pure nothrow @nogc
|
|||
$(LREF FileException) if the given file does not exist.
|
||||
+/
|
||||
@property bool isFile(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
return !name.isDir;
|
||||
|
@ -2679,8 +2663,7 @@ bool attrIsFile(uint attributes) @safe pure nothrow @nogc
|
|||
$(LREF FileException) if the given file does not exist.
|
||||
+/
|
||||
@property bool isSymlink(R)(R name)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
version (Windows)
|
||||
return (getAttributes(name) & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
|
||||
|
@ -2860,8 +2843,7 @@ Params:
|
|||
Throws: $(LREF FileException) on error.
|
||||
*/
|
||||
void chdir(R)(R pathname)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
// Place outside of @trusted block
|
||||
auto pathz = pathname.tempCString!FSChar();
|
||||
|
@ -2931,8 +2913,7 @@ Throws:
|
|||
if an error occured.
|
||||
*/
|
||||
void mkdir(R)(R pathname)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
// Place outside of @trusted block
|
||||
const pathz = pathname.tempCString!FSChar();
|
||||
|
@ -3135,8 +3116,7 @@ Params:
|
|||
Throws: $(LREF FileException) on error.
|
||||
*/
|
||||
void rmdir(R)(R pathname)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
|
||||
!isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
|
||||
{
|
||||
// Place outside of @trusted block
|
||||
auto pathz = pathname.tempCString!FSChar();
|
||||
|
@ -3202,15 +3182,11 @@ if (isConvertibleToString!R)
|
|||
exists).
|
||||
+/
|
||||
version (StdDdoc) void symlink(RO, RL)(RO original, RL link)
|
||||
if ((isInputRange!RO && !isInfinite!RO && isSomeChar!(ElementEncodingType!RO) ||
|
||||
isConvertibleToString!RO) &&
|
||||
(isInputRange!RL && !isInfinite!RL && isSomeChar!(ElementEncodingType!RL) ||
|
||||
isConvertibleToString!RL));
|
||||
if ((isSomeFiniteCharInputRange!RO || isConvertibleToString!RO) &&
|
||||
(isSomeFiniteCharInputRange!RL || isConvertibleToString!RL));
|
||||
else version (Posix) void symlink(RO, RL)(RO original, RL link)
|
||||
if ((isInputRange!RO && !isInfinite!RO && isSomeChar!(ElementEncodingType!RO) ||
|
||||
isConvertibleToString!RO) &&
|
||||
(isInputRange!RL && !isInfinite!RL && isSomeChar!(ElementEncodingType!RL) ||
|
||||
isConvertibleToString!RL))
|
||||
if ((isSomeFiniteCharInputRange!RO || isConvertibleToString!RO) &&
|
||||
(isSomeFiniteCharInputRange!RL || isConvertibleToString!RL))
|
||||
{
|
||||
static if (isConvertibleToString!RO || isConvertibleToString!RL)
|
||||
{
|
||||
|
@ -3291,11 +3267,9 @@ version (Posix) @safe unittest
|
|||
$(LREF FileException) on error.
|
||||
+/
|
||||
version (StdDdoc) string readLink(R)(R link)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) ||
|
||||
isConvertibleToString!R);
|
||||
if (isSomeFiniteCharInputRange!R || isConvertibleToString!R);
|
||||
else version (Posix) string readLink(R)(R link)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) ||
|
||||
isConvertibleToString!R)
|
||||
if (isSomeFiniteCharInputRange!R || isConvertibleToString!R)
|
||||
{
|
||||
static if (isConvertibleToString!R)
|
||||
{
|
||||
|
@ -4216,8 +4190,8 @@ Params:
|
|||
Throws: $(LREF FileException) on error.
|
||||
*/
|
||||
void copy(RF, RT)(RF from, RT to, PreserveAttributes preserve = preserveAttributesDefault)
|
||||
if (isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) && !isConvertibleToString!RF &&
|
||||
isInputRange!RT && !isInfinite!RT && isSomeChar!(ElementEncodingType!RT) && !isConvertibleToString!RT)
|
||||
if (isSomeFiniteCharInputRange!RF && !isConvertibleToString!RF &&
|
||||
isSomeFiniteCharInputRange!RT && !isConvertibleToString!RT)
|
||||
{
|
||||
// Place outside of @trusted block
|
||||
auto fromz = from.tempCString!FSChar();
|
||||
|
@ -4781,7 +4755,7 @@ private struct DirIteratorImpl
|
|||
}
|
||||
|
||||
this(R)(R pathname, SpanMode mode, bool followSymlink)
|
||||
if (isInputRange!R && isSomeChar!(ElementEncodingType!R))
|
||||
if (isSomeFiniteCharInputRange!R)
|
||||
{
|
||||
_mode = mode;
|
||||
_followSymlink = followSymlink;
|
||||
|
|
|
@ -19,7 +19,7 @@ module std.json;
|
|||
|
||||
import std.array;
|
||||
import std.conv;
|
||||
import std.range.primitives;
|
||||
import std.range;
|
||||
import std.traits;
|
||||
|
||||
///
|
||||
|
@ -929,7 +929,7 @@ Params:
|
|||
options = enable decoding string representations of NaN/Inf as float values
|
||||
*/
|
||||
JSONValue parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none)
|
||||
if (isInputRange!T && !isInfinite!T && isSomeChar!(ElementEncodingType!T))
|
||||
if (isSomeFiniteCharInputRange!T)
|
||||
{
|
||||
import std.ascii : isDigit, isHexDigit, toUpper, toLower;
|
||||
import std.typecons : Nullable, Yes;
|
||||
|
@ -1437,7 +1437,7 @@ Params:
|
|||
options = enable decoding string representations of NaN/Inf as float values
|
||||
*/
|
||||
JSONValue parseJSON(T)(T json, JSONOptions options)
|
||||
if (isInputRange!T && !isInfinite!T && isSomeChar!(ElementEncodingType!T))
|
||||
if (isSomeFiniteCharInputRange!T)
|
||||
{
|
||||
return parseJSON!T(json, -1, options);
|
||||
}
|
||||
|
|
13
std/path.d
13
std/path.d
|
@ -98,7 +98,7 @@ module std.path;
|
|||
|
||||
import std.file : getcwd;
|
||||
static import std.meta;
|
||||
import std.range.primitives;
|
||||
import std.range;
|
||||
import std.traits;
|
||||
|
||||
version (OSX)
|
||||
|
@ -262,8 +262,7 @@ version (Windows)
|
|||
from a path.
|
||||
*/
|
||||
private auto ltrimDirSeparators(R)(R path)
|
||||
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementType!R) ||
|
||||
isNarrowString!R)
|
||||
if (isSomeFiniteCharInputRange!R || isNarrowString!R)
|
||||
{
|
||||
static if (isRandomAccessRange!R && hasSlicing!R || isNarrowString!R)
|
||||
{
|
||||
|
@ -3213,12 +3212,8 @@ int filenameCharCmp(CaseSensitive cs = CaseSensitive.osDefault)(dchar a, dchar b
|
|||
*/
|
||||
int filenameCmp(CaseSensitive cs = CaseSensitive.osDefault, Range1, Range2)
|
||||
(Range1 filename1, Range2 filename2)
|
||||
if (isInputRange!Range1 && !isInfinite!Range1 &&
|
||||
isSomeChar!(ElementEncodingType!Range1) &&
|
||||
!isConvertibleToString!Range1 &&
|
||||
isInputRange!Range2 && !isInfinite!Range2 &&
|
||||
isSomeChar!(ElementEncodingType!Range2) &&
|
||||
!isConvertibleToString!Range2)
|
||||
if (isSomeFiniteCharInputRange!Range1 && !isConvertibleToString!Range1 &&
|
||||
isSomeFiniteCharInputRange!Range2 && !isConvertibleToString!Range2)
|
||||
{
|
||||
alias C1 = Unqual!(ElementEncodingType!Range1);
|
||||
alias C2 = Unqual!(ElementEncodingType!Range2);
|
||||
|
|
|
@ -106,9 +106,8 @@ version (Windows)
|
|||
}
|
||||
|
||||
import std.internal.cstring;
|
||||
import std.range.primitives;
|
||||
import std.range;
|
||||
import std.stdio;
|
||||
import std.traits : isSomeChar;
|
||||
|
||||
version (OSX)
|
||||
version = Darwin;
|
||||
|
@ -1527,7 +1526,7 @@ package(std) string searchPathFor(scope const(char)[] executable)
|
|||
// current user.
|
||||
version (Posix)
|
||||
private bool isExecutable(R)(R path) @trusted nothrow @nogc
|
||||
if (isInputRange!R && isSomeChar!(ElementEncodingType!R))
|
||||
if (isSomeFiniteCharInputRange!R)
|
||||
{
|
||||
return (access(path.tempCString(), X_OK) == 0);
|
||||
}
|
||||
|
|
|
@ -13521,3 +13521,49 @@ pure @safe unittest
|
|||
|
||||
assert([1, 2, 3, 4].padRight(0, 10)[7 .. 9].equal([0, 0]));
|
||||
}
|
||||
|
||||
/**
|
||||
This simplifies a commonly used idiom in phobos for accepting any kind of string
|
||||
parameter. The type `R` can for example be a simple string, chained string using
|
||||
$(REF chain, std,range), $(REF chainPath, std,path) or any other input range of
|
||||
characters.
|
||||
|
||||
Only finite length character ranges are allowed with this constraint.
|
||||
|
||||
This template is equivalent to:
|
||||
---
|
||||
isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R)
|
||||
---
|
||||
|
||||
See_Also:
|
||||
$(REF isInputRange, std,range,primitives),
|
||||
$(REF isInfinite, std,range,primitives),
|
||||
$(LREF isSomeChar),
|
||||
$(REF ElementEncodingType, std,range,primitives)
|
||||
*/
|
||||
template isSomeFiniteCharInputRange(R)
|
||||
{
|
||||
import std.traits : isSomeChar;
|
||||
|
||||
enum isSomeFiniteCharInputRange = isInputRange!R && !isInfinite!R
|
||||
&& isSomeChar!(ElementEncodingType!R);
|
||||
}
|
||||
|
||||
///
|
||||
@safe unittest
|
||||
{
|
||||
import std.path : chainPath;
|
||||
import std.range : chain;
|
||||
|
||||
void someLibraryMethod(R)(R argument)
|
||||
if (isSomeFiniteCharInputRange!R)
|
||||
{
|
||||
// implementation detail, would iterate over each character of argument
|
||||
}
|
||||
|
||||
someLibraryMethod("simple strings work");
|
||||
someLibraryMethod(chain("chained", " ", "strings", " ", "work"));
|
||||
someLibraryMethod(chainPath("chained", "paths", "work"));
|
||||
// you can also use custom structs implementing a char range
|
||||
}
|
||||
|
||||
|
|
18
std/stdio.d
18
std/stdio.d
|
@ -50,8 +50,8 @@ import core.stdc.stddef : wchar_t;
|
|||
public import core.stdc.stdio;
|
||||
import std.algorithm.mutation : copy;
|
||||
import std.meta : allSatisfy;
|
||||
import std.range.primitives : ElementEncodingType, empty, front,
|
||||
isBidirectionalRange, isInputRange, put;
|
||||
import std.range : ElementEncodingType, empty, front, isBidirectionalRange,
|
||||
isInputRange, isSomeFiniteCharInputRange, put;
|
||||
import std.traits : isSomeChar, isSomeString, Unqual, isPointer;
|
||||
import std.typecons : Flag, No, Yes;
|
||||
|
||||
|
@ -555,7 +555,7 @@ Throws: `ErrnoException` if the file could not be opened.
|
|||
|
||||
/// ditto
|
||||
this(R1, R2)(R1 name)
|
||||
if (isInputRange!R1 && isSomeChar!(ElementEncodingType!R1))
|
||||
if (isSomeFiniteCharInputRange!R1)
|
||||
{
|
||||
import std.conv : to;
|
||||
this(name.to!string, "rb");
|
||||
|
@ -563,8 +563,8 @@ Throws: `ErrnoException` if the file could not be opened.
|
|||
|
||||
/// ditto
|
||||
this(R1, R2)(R1 name, R2 mode)
|
||||
if (isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) &&
|
||||
isInputRange!R2 && isSomeChar!(ElementEncodingType!R2))
|
||||
if (isSomeFiniteCharInputRange!R1 &&
|
||||
isSomeFiniteCharInputRange!R2)
|
||||
{
|
||||
import std.conv : to;
|
||||
this(name.to!string, mode.to!string);
|
||||
|
@ -4642,8 +4642,8 @@ if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&
|
|||
* with appropriately-constructed C-style strings.
|
||||
*/
|
||||
private FILE* _fopen(R1, R2)(R1 name, R2 mode = "r")
|
||||
if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1) &&
|
||||
(isInputRange!R2 && isSomeChar!(ElementEncodingType!R2) || isSomeString!R2))
|
||||
if ((isSomeFiniteCharInputRange!R1 || isSomeString!R1) &&
|
||||
(isSomeFiniteCharInputRange!R2 || isSomeString!R2))
|
||||
{
|
||||
import std.internal.cstring : tempCString;
|
||||
|
||||
|
@ -4684,8 +4684,8 @@ version (Posix)
|
|||
* with appropriately-constructed C-style strings.
|
||||
*/
|
||||
FILE* _popen(R1, R2)(R1 name, R2 mode = "r") @trusted nothrow @nogc
|
||||
if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1) &&
|
||||
(isInputRange!R2 && isSomeChar!(ElementEncodingType!R2) || isSomeString!R2))
|
||||
if ((isSomeFiniteCharInputRange!R1 || isSomeString!R1) &&
|
||||
(isSomeFiniteCharInputRange!R2 || isSomeString!R2))
|
||||
{
|
||||
import std.internal.cstring : tempCString;
|
||||
|
||||
|
|
14
std/utf.d
14
std/utf.d
|
@ -65,9 +65,9 @@ module std.utf;
|
|||
import std.exception : basicExceptionCtors;
|
||||
import core.exception : UnicodeException;
|
||||
import std.meta : AliasSeq;
|
||||
import std.range.primitives;
|
||||
import std.traits : isAutodecodableString, isPointer, isSomeChar,
|
||||
isSomeString, isStaticArray, Unqual, isConvertibleToString;
|
||||
import std.range;
|
||||
import std.traits : isAutodecodableString, isConvertibleToString, isPointer,
|
||||
isSomeChar, isSomeString, isStaticArray, Unqual;
|
||||
import std.typecons : Flag, Yes, No;
|
||||
|
||||
|
||||
|
@ -2809,7 +2809,7 @@ if (isSomeChar!C)
|
|||
The number of code units in `input` when encoded to `C`
|
||||
+/
|
||||
size_t codeLength(C, InputRange)(InputRange input)
|
||||
if (isInputRange!InputRange && !isInfinite!InputRange && isSomeChar!(ElementType!InputRange))
|
||||
if (isSomeFiniteCharInputRange!InputRange)
|
||||
{
|
||||
alias EncType = Unqual!(ElementEncodingType!InputRange);
|
||||
static if (isSomeString!InputRange && is(EncType == C) && is(typeof(input.length)))
|
||||
|
@ -2961,7 +2961,7 @@ if (isSomeString!S)
|
|||
* For a lazy, non-allocating version of these functions, see $(LREF byUTF).
|
||||
*/
|
||||
string toUTF8(S)(S s)
|
||||
if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))
|
||||
if (isSomeFiniteCharInputRange!S)
|
||||
{
|
||||
return toUTFImpl!string(s);
|
||||
}
|
||||
|
@ -3003,7 +3003,7 @@ if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))
|
|||
* For a lazy, non-allocating version of these functions, see $(LREF byUTF).
|
||||
*/
|
||||
wstring toUTF16(S)(S s)
|
||||
if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))
|
||||
if (isSomeFiniteCharInputRange!S)
|
||||
{
|
||||
return toUTFImpl!wstring(s);
|
||||
}
|
||||
|
@ -3047,7 +3047,7 @@ if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))
|
|||
* For a lazy, non-allocating version of these functions, see $(LREF byUTF).
|
||||
*/
|
||||
dstring toUTF32(S)(scope S s)
|
||||
if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S))
|
||||
if (isSomeFiniteCharInputRange!S)
|
||||
{
|
||||
return toUTFImpl!dstring(s);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue