mirror of
https://github.com/dlang/phobos.git
synced 2025-05-08 20:19:43 +03:00
Replaced std.contracts with std.exception throughout
This commit is contained in:
parent
2f98916995
commit
432e3fdfc8
20 changed files with 347 additions and 348 deletions
|
@ -46,7 +46,7 @@ Authors: $(WEB erdani.com, Andrei Alexandrescu)
|
|||
module std.algorithm;
|
||||
|
||||
import std.c.string;
|
||||
import std.array, std.container, std.contracts, std.conv, std.date,
|
||||
import std.array, std.container, std.conv, std.date, std.exception,
|
||||
std.functional, std.math, std.metastrings, std.range, std.string,
|
||||
std.traits, std.typecons, std.typetuple;
|
||||
|
||||
|
@ -776,7 +776,7 @@ unittest
|
|||
|
||||
// swap
|
||||
/**
|
||||
Swaps $(D lhs) and $(D rhs). See also $(XREF contracts, pointsTo).
|
||||
Swaps $(D lhs) and $(D rhs). See also $(XREF exception, pointsTo).
|
||||
|
||||
Preconditions:
|
||||
|
||||
|
@ -1646,7 +1646,7 @@ log(haystack.length)) steps are needed to position $(D haystack) at
|
|||
the beginning of the search. Also, once positioned, the search will
|
||||
continue only as long as haystack and the needle start with equal
|
||||
elements. To inform $(D find) that you want to perform a binary
|
||||
search, wrap $(D haystack) with a call to $(XREF contracts,
|
||||
search, wrap $(D haystack) with a call to $(XREF exception,
|
||||
assumeSorted). Then $(D find) will assume that $(D pred) and $(D less)
|
||||
are in the right relation and also that $(D haystack) is already
|
||||
sorted by $(D less).
|
||||
|
|
|
@ -14,7 +14,7 @@ module std.array;
|
|||
|
||||
import std.c.stdio;
|
||||
import core.memory;
|
||||
import std.algorithm, std.contracts, std.conv, std.encoding, std.range,
|
||||
import std.algorithm, std.conv, std.encoding, std.exception, std.range,
|
||||
std.string, std.traits, std.typecons, std.utf;
|
||||
version(unittest) private import std.stdio;
|
||||
|
||||
|
|
212
std/boxer.d
212
std/boxer.d
|
@ -4,13 +4,13 @@
|
|||
* This module is a set of types and functions for converting any object (value
|
||||
* or heap) into a generic box type, allowing the user to pass that object
|
||||
* around without knowing what's in the box, and then allowing him to recover
|
||||
* the value afterwards.
|
||||
* the value afterwards.
|
||||
*
|
||||
* WARNING:
|
||||
*
|
||||
* This module is being phased out. You may want to use $(LINK2
|
||||
* std_variant.html,std.variant) for new code.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
---
|
||||
// Convert the integer 45 into a box.
|
||||
|
@ -25,15 +25,15 @@ real r = unbox!(real)(b);
|
|||
* UnboxException. As demonstrated, it uses implicit casts to behave in the exact
|
||||
* same way that static types behave. So for example, you can unbox from int to
|
||||
* real, but you cannot unbox from real to int: that would require an explicit
|
||||
* cast.
|
||||
* cast.
|
||||
*
|
||||
* This therefore means that attempting to unbox an int as a string will throw
|
||||
* an error instead of formatting it. In general, you can call the toString method
|
||||
* on the box and receive a good result, depending upon whether std.string.format
|
||||
* accepts it.
|
||||
* accepts it.
|
||||
*
|
||||
* Boxes can be compared to one another and they can be used as keys for
|
||||
* associative arrays.
|
||||
* associative arrays.
|
||||
*
|
||||
* There are also functions for converting to and from arrays of boxes.
|
||||
*
|
||||
|
@ -78,13 +78,13 @@ module std.boxer;
|
|||
private import std.format;
|
||||
private import std.string;
|
||||
private import std.utf;
|
||||
import std.contracts;
|
||||
import std.exception;
|
||||
|
||||
/* These functions and types allow packing objects into generic containers
|
||||
* and recovering them later. This comes into play in a wide spectrum of
|
||||
* utilities, such as with a scripting language, or as additional user data
|
||||
* for an object.
|
||||
*
|
||||
*
|
||||
* Box an object by calling the box function:
|
||||
*
|
||||
* Box x = box(4);
|
||||
|
@ -105,7 +105,7 @@ import std.contracts;
|
|||
* throw an error and not format it. In general, you can call the toString
|
||||
* method on the box and receive a good result, depending upon whether
|
||||
* std.string.format accepts it.
|
||||
*
|
||||
*
|
||||
* Boxes can be compared to one another and they can be used as keys for
|
||||
* associative arrays. Boxes of different types can be compared to one
|
||||
* another, using the same casting rules as the main type system.
|
||||
|
@ -127,7 +127,7 @@ import std.contracts;
|
|||
* bool unboxable!(T) (Box value);
|
||||
* bool Box.unboxable(TypeInfo T);
|
||||
*/
|
||||
|
||||
|
||||
/** Return the next type in an array typeinfo, or null if there is none. */
|
||||
private bool isArrayTypeInfo(TypeInfo type)
|
||||
{
|
||||
|
@ -161,13 +161,13 @@ private enum TypeClass
|
|||
struct Box
|
||||
{
|
||||
private TypeInfo p_type; /**< The type of the contained object. */
|
||||
|
||||
|
||||
private union
|
||||
{
|
||||
void* p_longData; /**< An array of the contained object. */
|
||||
void[8] p_shortData; /**< Data used when the object is small. */
|
||||
}
|
||||
|
||||
|
||||
private static TypeClass findTypeClass(TypeInfo type)
|
||||
{
|
||||
if (cast(TypeInfo_Class) type)
|
||||
|
@ -206,36 +206,36 @@ struct Box
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Return whether this value could be unboxed as the given type without throwing. */
|
||||
bool unboxable(TypeInfo test) const
|
||||
{
|
||||
if (type is test)
|
||||
return true;
|
||||
|
||||
|
||||
TypeInfo_Class ca = cast(TypeInfo_Class) type, cb = cast(TypeInfo_Class) test;
|
||||
|
||||
|
||||
if (ca !is null && cb !is null)
|
||||
{
|
||||
ClassInfo ia = (*cast(Object *) data).classinfo, ib = cb.info;
|
||||
|
||||
|
||||
for ( ; ia !is null; ia = ia.base)
|
||||
if (ia is ib)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TypeClass ta = findTypeClass(type), tb = findTypeClass(test);
|
||||
|
||||
|
||||
if (type is typeid(void*) && *cast(void**) data is null)
|
||||
return (tb == TypeClass.Class || tb == TypeClass.Pointer || tb == TypeClass.Array);
|
||||
|
||||
|
||||
if (test is typeid(void*))
|
||||
return (tb == TypeClass.Class || tb == TypeClass.Pointer || tb == TypeClass.Array);
|
||||
|
||||
|
||||
if (ta == TypeClass.Pointer && tb == TypeClass.Pointer)
|
||||
return (cast(TypeInfo_Pointer)type).next is (cast(TypeInfo_Pointer)test).next;
|
||||
|
||||
|
||||
if ((ta == tb && ta != TypeClass.Other)
|
||||
|| (ta == TypeClass.Bool && tb == TypeClass.Integer)
|
||||
|| (ta <= TypeClass.Integer && tb == TypeClass.Float)
|
||||
|
@ -243,7 +243,7 @@ struct Box
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Property for the type contained by the box.
|
||||
* This is initially null and cannot be assigned directly.
|
||||
|
@ -253,7 +253,7 @@ struct Box
|
|||
{
|
||||
return cast(TypeInfo)p_type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Property for the data pointer to the value of the box.
|
||||
* This is initially null and cannot be assigned directly.
|
||||
|
@ -262,41 +262,41 @@ struct Box
|
|||
const(void)[] data() const
|
||||
{
|
||||
size_t size = type.tsize();
|
||||
|
||||
|
||||
return size <= p_shortData.length ? p_shortData[0..size] : p_longData[0..size];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to convert the boxed value into a string using std.string.format;
|
||||
* this will throw if that function cannot handle it. If the box is
|
||||
* uninitialized then this returns "".
|
||||
* uninitialized then this returns "".
|
||||
*/
|
||||
string toString()
|
||||
{
|
||||
if (type is null)
|
||||
return "<empty box>";
|
||||
|
||||
|
||||
TypeInfo[2] arguments;
|
||||
char[] str;
|
||||
void[] args = new void[(string).sizeof + data.length];
|
||||
string format = "%s";
|
||||
|
||||
|
||||
arguments[0] = typeid(char[]);
|
||||
arguments[1] = type;
|
||||
|
||||
|
||||
void putc(dchar ch)
|
||||
{
|
||||
std.utf.encode(str, ch);
|
||||
}
|
||||
|
||||
|
||||
args[0..(char[]).sizeof] = (cast(void*) &format)[0..(char[]).sizeof];
|
||||
args[(char[]).sizeof..$] = data;
|
||||
std.format.doFormat(&putc, arguments, args.ptr);
|
||||
delete args;
|
||||
|
||||
|
||||
return assumeUnique(str);
|
||||
}
|
||||
|
||||
|
||||
private bool opEqualsInternal(Box other, bool inverted)
|
||||
{
|
||||
if (type != other.type)
|
||||
|
@ -307,13 +307,13 @@ struct Box
|
|||
return false;
|
||||
return other.opEqualsInternal(this, true);
|
||||
}
|
||||
|
||||
|
||||
TypeClass ta = findTypeClass(type), tb = findTypeClass(other.type);
|
||||
|
||||
|
||||
if (ta <= TypeClass.Integer && tb <= TypeClass.Integer)
|
||||
{
|
||||
string na = type.toString, nb = other.type.toString;
|
||||
|
||||
|
||||
if (na == "ulong" || nb == "ulong")
|
||||
return unbox!(ulong)(this) == unbox!(ulong)(other);
|
||||
return unbox!(long)(this) == unbox!(long)(other);
|
||||
|
@ -324,27 +324,27 @@ struct Box
|
|||
return unbox!(creal)(this) == unbox!(creal)(other);
|
||||
else if (tb == TypeClass.Imaginary)
|
||||
return unbox!(ireal)(this) == unbox!(ireal)(other);
|
||||
|
||||
|
||||
assert (0);
|
||||
}
|
||||
|
||||
|
||||
return cast(bool)type.equals(data.ptr, other.data.ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this box's value with another box. This implicitly casts if the
|
||||
* types are different, identical to the regular type system.
|
||||
* types are different, identical to the regular type system.
|
||||
*/
|
||||
const bool opEquals(const ref Box other)
|
||||
{
|
||||
return (cast(Box)this).opEqualsInternal(cast(Box)other, false);
|
||||
}
|
||||
|
||||
|
||||
const bool opEquals(Box other)
|
||||
{
|
||||
return (cast(Box)this).opEqualsInternal(other, false);
|
||||
}
|
||||
|
||||
|
||||
private float opCmpInternal(Box other, bool inverted)
|
||||
{
|
||||
if (type != other.type)
|
||||
|
@ -355,9 +355,9 @@ struct Box
|
|||
return 0;
|
||||
return other.opCmpInternal(this, true);
|
||||
}
|
||||
|
||||
|
||||
TypeClass ta = findTypeClass(type), tb = findTypeClass(other.type);
|
||||
|
||||
|
||||
if (ta <= TypeClass.Integer && tb == TypeClass.Integer)
|
||||
{
|
||||
if (type == typeid(ulong) || other.type == typeid(ulong))
|
||||
|
@ -365,7 +365,7 @@ struct Box
|
|||
ulong va = unbox!(ulong)(this), vb = unbox!(ulong)(other);
|
||||
return va > vb ? 1 : va < vb ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
long va = unbox!(long)(this), vb = unbox!(long)(other);
|
||||
return va > vb ? 1 : va < vb ? -1 : 0;
|
||||
}
|
||||
|
@ -384,10 +384,10 @@ struct Box
|
|||
ireal va = unbox!(ireal)(this), vb = unbox!(ireal)(other);
|
||||
return va > vb ? 1 : va < vb ? -1 : va == vb ? 0 : float.nan;
|
||||
}
|
||||
|
||||
|
||||
assert (0);
|
||||
}
|
||||
|
||||
|
||||
return type.compare(data.ptr, other.data.ptr);
|
||||
}
|
||||
|
||||
|
@ -411,8 +411,8 @@ struct Box
|
|||
|
||||
/**
|
||||
* Box the single argument passed to the function. If more or fewer than one
|
||||
* argument is passed, this will assert.
|
||||
*/
|
||||
* argument is passed, this will assert.
|
||||
*/
|
||||
Box box(...)
|
||||
in
|
||||
{
|
||||
|
@ -427,7 +427,7 @@ body
|
|||
* Box the explicitly-defined object. type must not be null; data must not be
|
||||
* null if the type's size is greater than zero.
|
||||
* The data is copied.
|
||||
*/
|
||||
*/
|
||||
Box box(TypeInfo type, void* data)
|
||||
in
|
||||
{
|
||||
|
@ -437,13 +437,13 @@ body
|
|||
{
|
||||
Box result;
|
||||
size_t size = type.tsize();
|
||||
|
||||
|
||||
result.p_type = type;
|
||||
if (size <= result.p_shortData.length)
|
||||
result.p_shortData[0..size] = data[0..size];
|
||||
else
|
||||
result.p_longData = data[0..size].dup.ptr;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -455,23 +455,23 @@ private size_t argumentLength(size_t baseLength)
|
|||
|
||||
/**
|
||||
* Convert a list of arguments into a list of boxes.
|
||||
*/
|
||||
*/
|
||||
Box[] boxArray(TypeInfo[] types, void* data)
|
||||
{
|
||||
Box[] array = new Box[types.length];
|
||||
|
||||
|
||||
foreach(size_t index, TypeInfo type; types)
|
||||
{
|
||||
array[index] = box(type, data);
|
||||
data += argumentLength(type.tsize());
|
||||
}
|
||||
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Box each argument passed to the function, returning an array of boxes.
|
||||
*/
|
||||
*/
|
||||
Box[] boxArray(...)
|
||||
{
|
||||
return boxArray(_arguments, _argptr);
|
||||
|
@ -479,16 +479,16 @@ Box[] boxArray(...)
|
|||
|
||||
/**
|
||||
* Convert an array of boxes into an array of arguments.
|
||||
*/
|
||||
*/
|
||||
void boxArrayToArguments(Box[] arguments, out TypeInfo[] types, out void* data)
|
||||
{
|
||||
size_t dataLength;
|
||||
void* pointer;
|
||||
|
||||
|
||||
/* Determine the number of bytes of data to allocate by summing the arguments. */
|
||||
foreach (Box item; arguments)
|
||||
dataLength += argumentLength(item.data.length);
|
||||
|
||||
|
||||
types = new TypeInfo[arguments.length];
|
||||
pointer = data = (new void[dataLength]).ptr;
|
||||
|
||||
|
@ -498,13 +498,13 @@ void boxArrayToArguments(Box[] arguments, out TypeInfo[] types, out void* data)
|
|||
types[index] = item.type;
|
||||
pointer[0..item.data.length] = item.data;
|
||||
pointer += argumentLength(item.data.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is thrown if unbox is unable to cast the value into the desired
|
||||
* result.
|
||||
*/
|
||||
*/
|
||||
class UnboxException : Exception
|
||||
{
|
||||
Box object; /// This is the box that the user attempted to unbox.
|
||||
|
@ -529,7 +529,7 @@ private template unboxCastReal(T)
|
|||
T unboxCastReal(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (value.type is typeid(float))
|
||||
return cast(T) *cast(float*) value.data;
|
||||
if (value.type is typeid(double))
|
||||
|
@ -546,7 +546,7 @@ private template unboxCastInteger(T)
|
|||
T unboxCastInteger(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (value.type is typeid(int))
|
||||
return cast(T) *cast(int*) value.data;
|
||||
if (value.type is typeid(uint))
|
||||
|
@ -575,7 +575,7 @@ private template unboxCastComplex(T)
|
|||
T unboxCastComplex(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (value.type is typeid(cfloat))
|
||||
return cast(T) *cast(cfloat*) value.data;
|
||||
if (value.type is typeid(cdouble))
|
||||
|
@ -598,7 +598,7 @@ private template unboxCastImaginary(T)
|
|||
T unboxCastImaginary(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (value.type is typeid(ifloat))
|
||||
return cast(T) *cast(ifloat*) value.data;
|
||||
if (value.type is typeid(idouble))
|
||||
|
@ -614,7 +614,7 @@ private template unboxCastImaginary(T)
|
|||
* takes a box object and returns the specified type.
|
||||
*
|
||||
* To use it, instantiate the template with the desired result type, and then
|
||||
* call the function with the box to convert.
|
||||
* call the function with the box to convert.
|
||||
* This will implicitly cast base types as necessary and in a way consistent
|
||||
* with static types - for example, it will cast a boxed byte into int, but it
|
||||
* won't cast a boxed float into short.
|
||||
|
@ -630,13 +630,13 @@ private template unboxCastImaginary(T)
|
|||
* Box y = box(4);
|
||||
* int x = unbox!(int) (y);
|
||||
* ---
|
||||
*/
|
||||
*/
|
||||
template unbox(T)
|
||||
{
|
||||
T unbox(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (typeid(T) is value.type)
|
||||
return *cast(T*) value.data;
|
||||
throw new UnboxException(value, typeid(T));
|
||||
|
@ -666,19 +666,19 @@ template unbox(T : Object)
|
|||
T unbox(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (typeid(T) == value.type || cast(TypeInfo_Class) value.type)
|
||||
{
|
||||
Object object = *cast(Object*)value.data;
|
||||
T result = cast(T)object;
|
||||
|
||||
|
||||
if (object is null)
|
||||
return null;
|
||||
if (result is null)
|
||||
throw new UnboxException(value, typeid(T));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
if (typeid(void*) is value.type && *cast(void**) value.data is null)
|
||||
return null;
|
||||
throw new UnboxException(value, typeid(T));
|
||||
|
@ -690,7 +690,7 @@ template unbox(T : T[])
|
|||
T[] unbox(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (typeid(T[]) is value.type)
|
||||
return *cast(T[]*) value.data;
|
||||
if (typeid(void*) is value.type && *cast(void**) value.data is null)
|
||||
|
@ -704,14 +704,14 @@ template unbox(T : T*)
|
|||
T* unbox(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (typeid(T*) is value.type)
|
||||
return *cast(T**) value.data;
|
||||
if (typeid(void*) is value.type && *cast(void**) value.data is null)
|
||||
return null;
|
||||
if (typeid(T[]) is value.type)
|
||||
return (*cast(T[]*) value.data).ptr;
|
||||
|
||||
|
||||
throw new UnboxException(value, typeid(T*));
|
||||
}
|
||||
}
|
||||
|
@ -721,14 +721,14 @@ template unbox(T : void*)
|
|||
T unbox(Box value)
|
||||
{
|
||||
assert (value.type !is null);
|
||||
|
||||
|
||||
if (cast(TypeInfo_Pointer) value.type)
|
||||
return *cast(void**) value.data;
|
||||
if (isArrayTypeInfo(value.type))
|
||||
return (*cast(void[]*) value.data).ptr;
|
||||
if (cast(TypeInfo_Class) value.type)
|
||||
return cast(T)(*cast(Object*) value.data);
|
||||
|
||||
|
||||
throw new UnboxException(value, typeid(T));
|
||||
}
|
||||
}
|
||||
|
@ -736,7 +736,7 @@ template unbox(T : void*)
|
|||
/**
|
||||
* Return whether the value can be unboxed as the given type; if this returns
|
||||
* false, attempting to do so will throw UnboxException.
|
||||
*/
|
||||
*/
|
||||
template unboxable(T)
|
||||
{
|
||||
bool unboxable(Box value)
|
||||
|
@ -752,7 +752,7 @@ private template unboxTest(T)
|
|||
{
|
||||
T result;
|
||||
bool unboxable = value.unboxable(typeid(T));
|
||||
|
||||
|
||||
try result = unbox!(T) (value);
|
||||
catch (UnboxException error)
|
||||
{
|
||||
|
@ -765,7 +765,7 @@ private template unboxTest(T)
|
|||
assert (!unboxable);
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
||||
if (!unboxable)
|
||||
throw new Error(cast(string)
|
||||
("Unboxed " ~ value.type.toString ~ " as "
|
||||
|
@ -781,9 +781,9 @@ unittest
|
|||
class B : A { }
|
||||
struct SA { }
|
||||
struct SB { }
|
||||
|
||||
|
||||
Box a, b;
|
||||
|
||||
|
||||
/* Call the function, catch UnboxException, return that it threw correctly. */
|
||||
bool fails(void delegate()func)
|
||||
{
|
||||
|
@ -792,107 +792,107 @@ unittest
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Check that equals and comparison work properly. */
|
||||
a = box(0);
|
||||
b = box(32);
|
||||
assert (a != b);
|
||||
assert (a == a);
|
||||
assert (a < b);
|
||||
|
||||
|
||||
/* Check that toString works properly. */
|
||||
assert (b.toString == "32");
|
||||
|
||||
|
||||
/* Assert that unboxable works. */
|
||||
assert (unboxable!(string)(box("foobar")));
|
||||
|
||||
|
||||
/* Assert that we can cast from int to byte. */
|
||||
assert (unboxTest!(byte)(b) == 32);
|
||||
|
||||
|
||||
/* Assert that we can cast from int to real. */
|
||||
assert (unboxTest!(real)(b) == 32.0L);
|
||||
|
||||
|
||||
/* Check that real works properly. */
|
||||
assert (unboxTest!(real)(box(32.45L)) == 32.45L);
|
||||
|
||||
|
||||
/* Assert that we cannot implicitly cast from real to int. */
|
||||
assert(fails(delegate void() { unboxTest!(int)(box(1.3)); }));
|
||||
|
||||
|
||||
/* Check that the unspecialized unbox template works. */
|
||||
assert(unboxTest!(string)(box("foobar")) == "foobar");
|
||||
|
||||
|
||||
/* Assert that complex works correctly. */
|
||||
assert(unboxTest!(cdouble)(box(1 + 2i)) == 1 + 2i);
|
||||
|
||||
|
||||
/* Assert that imaginary works correctly. */
|
||||
assert(unboxTest!(ireal)(box(45i)) == 45i);
|
||||
|
||||
|
||||
/* Create an array of boxes from arguments. */
|
||||
Box[] array = boxArray(16, "foobar", new Object);
|
||||
|
||||
|
||||
assert(array.length == 3);
|
||||
assert(unboxTest!(int)(array[0]) == 16);
|
||||
assert(unboxTest!(string)(array[1]) == "foobar");
|
||||
assert(unboxTest!(Object)(array[2]) !is null);
|
||||
|
||||
|
||||
/* Convert the box array back into arguments. */
|
||||
TypeInfo[] array_types;
|
||||
void* array_data;
|
||||
|
||||
|
||||
boxArrayToArguments(array, array_types, array_data);
|
||||
assert (array_types.length == 3);
|
||||
|
||||
|
||||
/* Confirm the symmetry. */
|
||||
assert (boxArray(array_types, array_data) == array);
|
||||
|
||||
|
||||
/* Assert that we can cast from int to creal. */
|
||||
assert (unboxTest!(creal)(box(45)) == 45+0i);
|
||||
|
||||
|
||||
/* Assert that we can cast from idouble to creal. */
|
||||
assert (unboxTest!(creal)(box(45i)) == 0+45i);
|
||||
|
||||
|
||||
/* Assert that equality testing casts properly. */
|
||||
assert (box(1) == box(cast(byte)1));
|
||||
assert (box(cast(real)4) == box(4));
|
||||
assert (box(5) == box(5+0i));
|
||||
assert (box(0+4i) == box(4i));
|
||||
assert (box(8i) == box(0+8i));
|
||||
|
||||
|
||||
/* Assert that comparisons cast properly. */
|
||||
assert (box(450) < box(451));
|
||||
assert (box(4) > box(3.0));
|
||||
assert (box(0+3i) < box(0+4i));
|
||||
|
||||
|
||||
/* Assert that casting from bool to int works. */
|
||||
assert (1 == unboxTest!(int)(box(true)));
|
||||
assert (box(1) == box(true));
|
||||
|
||||
|
||||
/* Assert that unboxing to an object works properly. */
|
||||
assert (unboxTest!(B)(box(cast(A)new B)) !is null);
|
||||
|
||||
/* Assert that illegal object casting fails properly. */
|
||||
|
||||
/* Assert that illegal object casting fails properly. */
|
||||
assert (fails(delegate void() { unboxTest!(B)(box(new A)); }));
|
||||
|
||||
|
||||
/* Assert that we can unbox a null. */
|
||||
assert (unboxTest!(A)(box(cast(A)null)) is null);
|
||||
assert (unboxTest!(A)(box(null)) is null);
|
||||
|
||||
|
||||
/* Unboxing null in various contexts. */
|
||||
assert (unboxTest!(string)(box(null)) is null);
|
||||
assert (unboxTest!(int*)(box(null)) is null);
|
||||
|
||||
|
||||
/* Assert that unboxing between pointer types fails. */
|
||||
int [1] p;
|
||||
assert (fails(delegate void() { unboxTest!(char*)(box(p.ptr)); }));
|
||||
|
||||
|
||||
/* Assert that unboxing various types as void* does work. */
|
||||
assert (unboxTest!(void*)(box(p.ptr))); // int*
|
||||
assert (unboxTest!(void*)(box(p))); // int[]
|
||||
assert (unboxTest!(void*)(box(new A))); // Object
|
||||
|
||||
|
||||
/* Assert that we can't unbox an integer as bool. */
|
||||
assert (!unboxable!(bool) (box(4)));
|
||||
|
||||
|
||||
/* Assert that we can't unbox a struct as another struct. */
|
||||
SA sa;
|
||||
assert (!unboxable!(SB)(box(sa)));
|
||||
|
|
|
@ -39,21 +39,21 @@ private
|
|||
//import core.sync.condition;
|
||||
//import core.sync.mutex;
|
||||
import std.algorithm;
|
||||
import std.contracts;
|
||||
import std.exception;
|
||||
import std.range;
|
||||
import std.stdio;
|
||||
import std.range;
|
||||
import std.traits;
|
||||
import std.typecons;
|
||||
import std.typetuple;
|
||||
|
||||
|
||||
template isTuple(T)
|
||||
{
|
||||
enum isTuple = __traits(compiles,
|
||||
{ void f(X...)(Tuple!(X) t) {};
|
||||
f(T.init); });
|
||||
}
|
||||
|
||||
|
||||
template hasLocalAliasing(T...)
|
||||
{
|
||||
static if( !T.length )
|
||||
|
@ -69,12 +69,12 @@ private
|
|||
priority,
|
||||
linkDead,
|
||||
}
|
||||
|
||||
|
||||
struct Message
|
||||
{
|
||||
MsgType type;
|
||||
Variant data;
|
||||
|
||||
|
||||
this(T...)( MsgType t, T vals )
|
||||
{
|
||||
type = t;
|
||||
|
@ -87,7 +87,7 @@ private
|
|||
data = vals;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Priority
|
||||
{
|
||||
Variant data;
|
||||
|
@ -157,7 +157,7 @@ class OwnerTerminated : Exception
|
|||
super( msg );
|
||||
tid = t;
|
||||
}
|
||||
|
||||
|
||||
Tid tid;
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ class LinkTerminated : Exception
|
|||
super( msg );
|
||||
tid = t;
|
||||
}
|
||||
|
||||
|
||||
Tid tid;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ class PriorityMessageException(T...) : Exception
|
|||
message = vals;
|
||||
else message.field = vals;
|
||||
}
|
||||
|
||||
|
||||
static if( T.length == 1 )
|
||||
T message;
|
||||
else Tuple!(T) message;
|
||||
|
@ -206,7 +206,7 @@ class MailboxFull : Exception
|
|||
super( msg );
|
||||
tid = t;
|
||||
}
|
||||
|
||||
|
||||
Tid tid;
|
||||
}
|
||||
|
||||
|
@ -364,7 +364,7 @@ private void _send(T...)( Tid tid, T vals )
|
|||
* both Tid.send() and .send().
|
||||
*/
|
||||
private void _send(T...)( MsgType type, Tid tid, T vals )
|
||||
{
|
||||
{
|
||||
tid.mbox.put( Message( type, vals ) );
|
||||
}
|
||||
|
||||
|
@ -441,14 +441,14 @@ private
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool onCrowdingThrow( Tid tid )
|
||||
{
|
||||
throw new MailboxFull( tid );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool onCrowdingIgnore( Tid tid )
|
||||
{
|
||||
return false;
|
||||
|
@ -522,8 +522,8 @@ private
|
|||
m_notFull = new Condition( m_lock );
|
||||
m_closed = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Sets a limit on the maximum number of user messages allowed in the
|
||||
* mailbox. If this limit is reached, the caller attempting to add
|
||||
|
@ -543,8 +543,8 @@ private
|
|||
m_onMaxMsgs = call;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* If maxMsgs is not set, the message is added to the queue and the
|
||||
* owner is notified. If the queue is full, the message will still be
|
||||
|
@ -591,8 +591,8 @@ private
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Matches ops against each message in turn until a match is found.
|
||||
*
|
||||
|
@ -603,7 +603,7 @@ private
|
|||
* Returns:
|
||||
* true if a message was retrieved and false if not (such as if a
|
||||
* timeout occurred).
|
||||
*
|
||||
*
|
||||
* Throws:
|
||||
* LinkTerminated if a linked thread terminated, or OwnerTerminated
|
||||
* if the owner thread terminates and no existing messages match the
|
||||
|
@ -627,7 +627,7 @@ private
|
|||
alias vals[0 .. $] ops;
|
||||
enum timedWait = false;
|
||||
}
|
||||
|
||||
|
||||
bool onStandardMsg( Message msg )
|
||||
{
|
||||
Variant data = msg.data;
|
||||
|
@ -680,9 +680,9 @@ private
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ownerDead = false;
|
||||
|
||||
|
||||
bool onLinkDeadMsg( Variant data )
|
||||
{
|
||||
alias Tuple!(Tid) Wrap;
|
||||
|
@ -715,7 +715,7 @@ private
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool onControlMsg( Message msg )
|
||||
{
|
||||
switch( msg.type )
|
||||
|
@ -726,7 +726,7 @@ private
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool scan( ref ListT list )
|
||||
{
|
||||
for( auto range = list[]; !range.empty; )
|
||||
|
@ -749,8 +749,8 @@ private
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool pty( ref ListT list )
|
||||
{
|
||||
alias Tuple!(Priority) Wrap;
|
||||
|
@ -762,7 +762,7 @@ private
|
|||
assert( data.convertsTo!(Wrap) );
|
||||
auto p = data.get!(Wrap).field[0];
|
||||
Message msg;
|
||||
|
||||
|
||||
msg.data = p.data;
|
||||
if( onStandardMsg( msg ) )
|
||||
{
|
||||
|
@ -773,7 +773,7 @@ private
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while( true )
|
||||
{
|
||||
ListT arrived;
|
||||
|
@ -823,8 +823,8 @@ private
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Called on thread termination. This routine processes any remaining
|
||||
* control messages, clears out message queues, and sets a flag to
|
||||
|
@ -850,7 +850,7 @@ private
|
|||
if( wrap.field[0] == owner )
|
||||
owner = Tid.init;
|
||||
}
|
||||
|
||||
|
||||
void sweep( ref ListT list )
|
||||
{
|
||||
for( auto range = list[]; !range.empty; range.popFront() )
|
||||
|
@ -859,7 +859,7 @@ private
|
|||
onLinkDeadMsg( range.front.data );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ListT arrived;
|
||||
|
||||
sweep( m_localBox );
|
||||
|
@ -868,35 +868,35 @@ private
|
|||
arrived.put( m_sharedBox );
|
||||
m_closed = true;
|
||||
}
|
||||
m_localBox.clear();
|
||||
sweep( arrived );
|
||||
m_localBox.clear();
|
||||
sweep( arrived );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Routines involving shared data, m_lock must be held.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
bool mboxFull()
|
||||
{
|
||||
return m_maxMsgs &&
|
||||
m_maxMsgs <= m_localMsgs + m_sharedBox.length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void updateMsgCount()
|
||||
{
|
||||
m_localMsgs = m_localBox.length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Routines for specific message types, no lock necessary.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
void onOwnerDead()
|
||||
{
|
||||
|
@ -927,52 +927,52 @@ private
|
|||
scope(failure) owner = Tid.init;
|
||||
throw new OwnerTerminated( owner );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Routines involving local data only, no lock needed.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
pure final bool isControlMsg( Message msg )
|
||||
{
|
||||
return msg.type != MsgType.standard &&
|
||||
msg.type != MsgType.priority;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pure final bool isPriorityMsg( Message msg )
|
||||
{
|
||||
return msg.type == MsgType.priority;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Type declarations.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
alias bool function(Tid) OnMaxFn;
|
||||
alias List!(Message) ListT;
|
||||
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Local data, no lock needed.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
ListT m_localBox;
|
||||
ListT m_localPty;
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Shared data, m_lock must be held on access.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
Mutex m_lock;
|
||||
Condition m_putMsg;
|
||||
Condition m_notFull;
|
||||
|
@ -1000,7 +1000,7 @@ private
|
|||
|
||||
@property T front()
|
||||
{
|
||||
enforce( m_prev.next );
|
||||
enforce( m_prev.next );
|
||||
return m_prev.next.val;
|
||||
}
|
||||
|
||||
|
@ -1087,8 +1087,8 @@ private
|
|||
//delete todelete;
|
||||
m_count--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -1096,8 +1096,8 @@ private
|
|||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -1106,7 +1106,7 @@ private
|
|||
m_first = m_last = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
|
10
std/date.d
10
std/date.d
|
@ -24,7 +24,7 @@ module std.date;
|
|||
|
||||
private import std.stdio;
|
||||
private import std.dateparse;
|
||||
import std.c.stdlib, std.contracts, std.conv;
|
||||
import std.c.stdlib, std.conv, std.exception;
|
||||
|
||||
/**
|
||||
* $(D d_time) is a signed arithmetic type giving the time elapsed
|
||||
|
@ -615,7 +615,7 @@ string toString(d_time time)
|
|||
hourFromTime(t), minFromTime(t), secFromTime(t),
|
||||
sign, hr, mn,
|
||||
cast(long)yearFromTime(t));
|
||||
|
||||
|
||||
// Ensure no buggy buffer overflows
|
||||
//printf("len = %d, buffer.length = %d\n", len, buffer.length);
|
||||
assert(len < buffer.length);
|
||||
|
@ -642,10 +642,10 @@ string toUTCString(d_time t)
|
|||
&monstr[monthFromTime(t) * 3],
|
||||
yearFromTime(t),
|
||||
hourFromTime(t), minFromTime(t), secFromTime(t));
|
||||
|
||||
|
||||
// Ensure no buggy buffer overflows
|
||||
assert(len < buffer.length);
|
||||
|
||||
|
||||
return cast(string) buffer[0 .. len];
|
||||
}
|
||||
|
||||
|
@ -929,7 +929,7 @@ version (Posix)
|
|||
d_time getLocalTZA()
|
||||
{
|
||||
time_t t;
|
||||
|
||||
|
||||
time(&t);
|
||||
version (OSX)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ private import std.ctype;
|
|||
private import std.string;
|
||||
import std.conv;
|
||||
private import std.utf;
|
||||
import std.contracts;
|
||||
import std.exception;
|
||||
|
||||
private import std.stdio;
|
||||
|
||||
|
|
140
std/file.d
140
std/file.d
|
@ -20,8 +20,8 @@ module std.file;
|
|||
|
||||
import core.memory;
|
||||
import core.stdc.stdio, core.stdc.stdlib, core.stdc.string,
|
||||
core.stdc.errno, std.algorithm, std.array,
|
||||
std.contracts, std.conv, std.date, std.format, std.path, std.process,
|
||||
core.stdc.errno, std.algorithm, std.array,
|
||||
std.conv, std.date, std.exception, std.format, std.path, std.process,
|
||||
std.range, std.regexp, std.stdio, std.string, std.traits, std.typecons,
|
||||
std.typetuple, std.utf;
|
||||
version (Win32)
|
||||
|
@ -128,13 +128,13 @@ class FileException : Exception
|
|||
{
|
||||
/**
|
||||
OS error code.
|
||||
*/
|
||||
*/
|
||||
immutable uint errno;
|
||||
|
||||
|
||||
/**
|
||||
Constructor taking the name of the file where error happened and a
|
||||
message describing the error.
|
||||
*/
|
||||
*/
|
||||
this(in char[] name, in char[] message)
|
||||
{
|
||||
super(text(name, ": ", message));
|
||||
|
@ -151,7 +151,7 @@ message describing the error.
|
|||
Constructor taking the name of the file where error happened and the
|
||||
error number ($(LUCKY GetLastError) in Windows, $(D getErrno) in
|
||||
Posix).
|
||||
*/
|
||||
*/
|
||||
version(Windows) this(in char[] name, uint errno = GetLastError)
|
||||
{
|
||||
this(name, sysErrorString(errno));
|
||||
|
@ -213,7 +213,7 @@ version(Windows) void[] read(in char[] name, size_t upTo = size_t.max)
|
|||
auto h = useWfuncs
|
||||
? CreateFileW(std.utf.toUTF16z(name), defaults)
|
||||
: CreateFileA(toMBSz(name), defaults);
|
||||
|
||||
|
||||
cenforce(h != INVALID_HANDLE_VALUE, name);
|
||||
scope(exit) cenforce(CloseHandle(h), name);
|
||||
auto size = GetFileSize(h, null);
|
||||
|
@ -221,7 +221,7 @@ version(Windows) void[] read(in char[] name, size_t upTo = size_t.max)
|
|||
size = min(upTo, size);
|
||||
auto buf = GC.malloc(size, GC.BlkAttr.NO_SCAN)[0 .. size];
|
||||
scope(failure) delete buf;
|
||||
|
||||
|
||||
DWORD numread = void;
|
||||
cenforce(ReadFile(h,buf.ptr, size, &numread, null) == 1
|
||||
&& numread == size, name);
|
||||
|
@ -237,16 +237,16 @@ version(Posix) void[] read(in char[] name, in size_t upTo = size_t.max)
|
|||
sizeIncrement = 1024 * 16,
|
||||
maxSlackMemoryAllowed = 1024;
|
||||
// }
|
||||
|
||||
|
||||
immutable fd = core.sys.posix.fcntl.open(toStringz(name),
|
||||
core.sys.posix.fcntl.O_RDONLY);
|
||||
cenforce(fd != -1, name);
|
||||
scope(exit) core.sys.posix.unistd.close(fd);
|
||||
|
||||
|
||||
struct_stat64 statbuf = void;
|
||||
cenforce(fstat64(fd, &statbuf) == 0, name);
|
||||
//cenforce(core.sys.posix.sys.stat.fstat(fd, &statbuf) == 0, name);
|
||||
|
||||
|
||||
immutable initialAlloc = to!size_t(statbuf.st_size
|
||||
? min(statbuf.st_size + 1, maxInitialAlloc)
|
||||
: minInitialAlloc);
|
||||
|
@ -254,7 +254,7 @@ version(Posix) void[] read(in char[] name, in size_t upTo = size_t.max)
|
|||
[0 .. initialAlloc];
|
||||
scope(failure) delete result;
|
||||
size_t size = 0;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
immutable actual = core.sys.posix.unistd.read(fd, result.ptr + size,
|
||||
|
@ -267,7 +267,7 @@ version(Posix) void[] read(in char[] name, in size_t upTo = size_t.max)
|
|||
result = GC.realloc(result.ptr, newAlloc, GC.BlkAttr.NO_SCAN)
|
||||
[0 .. newAlloc];
|
||||
}
|
||||
|
||||
|
||||
return result.length - size >= maxSlackMemoryAllowed
|
||||
? GC.realloc(result.ptr, size, GC.BlkAttr.NO_SCAN)[0 .. size]
|
||||
: result[0 .. size];
|
||||
|
@ -280,7 +280,7 @@ unittest
|
|||
}
|
||||
|
||||
version (linux) unittest
|
||||
{
|
||||
{
|
||||
// A file with "zero" length that doesn't have 0 length at all
|
||||
auto s = std.file.readText("/proc/sys/kernel/osrelease");
|
||||
assert(s.length > 0);
|
||||
|
@ -336,7 +336,7 @@ version(Windows) void write(in char[] name, const void[] buffer)
|
|||
auto h = useWfuncs
|
||||
? CreateFileW(std.utf.toUTF16z(name), defaults)
|
||||
: CreateFileA(toMBSz(name), defaults);
|
||||
|
||||
|
||||
cenforce(h != INVALID_HANDLE_VALUE, name);
|
||||
scope(exit) cenforce(CloseHandle(h), name);
|
||||
DWORD numwritten;
|
||||
|
@ -360,11 +360,11 @@ version(Windows) void append(in char[] name, in void[] buffer)
|
|||
alias TypeTuple!(GENERIC_WRITE,0,null,OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,HANDLE.init)
|
||||
defaults;
|
||||
|
||||
|
||||
auto h = useWfuncs
|
||||
? CreateFileW(std.utf.toUTF16z(name), defaults)
|
||||
: CreateFileA(toMBSz(name), defaults);
|
||||
|
||||
|
||||
cenforce(h != INVALID_HANDLE_VALUE, name);
|
||||
scope(exit) cenforce(CloseHandle(h), name);
|
||||
DWORD numwritten;
|
||||
|
@ -446,11 +446,11 @@ version(Windows) ulong getSize(in char[] name)
|
|||
HANDLE findhndl = void;
|
||||
uint resulth = void;
|
||||
uint resultl = void;
|
||||
|
||||
|
||||
if (useWfuncs)
|
||||
{
|
||||
WIN32_FIND_DATAW filefindbuf;
|
||||
|
||||
|
||||
findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf);
|
||||
resulth = filefindbuf.nFileSizeHigh;
|
||||
resultl = filefindbuf.nFileSizeLow;
|
||||
|
@ -458,12 +458,12 @@ version(Windows) ulong getSize(in char[] name)
|
|||
else
|
||||
{
|
||||
WIN32_FIND_DATA filefindbuf;
|
||||
|
||||
|
||||
findhndl = FindFirstFileA(toMBSz(name), &filefindbuf);
|
||||
resulth = filefindbuf.nFileSizeHigh;
|
||||
resultl = filefindbuf.nFileSizeLow;
|
||||
}
|
||||
|
||||
|
||||
cenforce(findhndl != cast(HANDLE)-1 && FindClose(findhndl), name);
|
||||
return (cast(ulong) resulth << 32) + resultl;
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ version(Posix) ulong getSize(in char[] name)
|
|||
cenforce(stat64(toStringz(name), &statbuf) == 0, name);
|
||||
return statbuf.st_size;
|
||||
}
|
||||
|
||||
|
||||
unittest
|
||||
{
|
||||
version(Windows)
|
||||
|
@ -489,7 +489,7 @@ unittest
|
|||
write(deleteme, "abc");
|
||||
assert(getSize(deleteme) == 3);
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
* Get creation/access/modified times of file $(D name).
|
||||
* Throws: $(D FileException) on error.
|
||||
|
@ -499,11 +499,11 @@ version(Windows) void getTimes(in char[] name,
|
|||
out d_time ftc, out d_time fta, out d_time ftm)
|
||||
{
|
||||
HANDLE findhndl = void;
|
||||
|
||||
|
||||
if (useWfuncs)
|
||||
{
|
||||
WIN32_FIND_DATAW filefindbuf;
|
||||
|
||||
|
||||
findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf);
|
||||
ftc = std.date.FILETIME2d_time(&filefindbuf.ftCreationTime);
|
||||
fta = std.date.FILETIME2d_time(&filefindbuf.ftLastAccessTime);
|
||||
|
@ -512,13 +512,13 @@ version(Windows) void getTimes(in char[] name,
|
|||
else
|
||||
{
|
||||
WIN32_FIND_DATA filefindbuf;
|
||||
|
||||
|
||||
findhndl = FindFirstFileA(toMBSz(name), &filefindbuf);
|
||||
ftc = std.date.FILETIME2d_time(&filefindbuf.ftCreationTime);
|
||||
fta = std.date.FILETIME2d_time(&filefindbuf.ftLastAccessTime);
|
||||
ftm = std.date.FILETIME2d_time(&filefindbuf.ftLastWriteTime);
|
||||
}
|
||||
|
||||
|
||||
if (findhndl == cast(HANDLE)-1)
|
||||
{
|
||||
throw new FileException(name.idup);
|
||||
|
@ -572,11 +572,11 @@ version(Posix) d_time lastModified(in char[] name)
|
|||
cenforce(stat64(toStringz(name), &statbuf) == 0, name);
|
||||
return cast(d_time) statbuf.st_mtime * std.date.ticksPerSecond;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns the time of the last modification of file $(D name). If the
|
||||
file does not exist, returns $(D returnIfMissing).
|
||||
|
||||
|
||||
A frequent usage pattern occurs in build automation tools such as
|
||||
$(WEB gnu.org/software/make, make) or $(WEB
|
||||
en.wikipedia.org/wiki/Apache_Ant, ant). To check whether file $(D
|
||||
|
@ -642,7 +642,7 @@ version(Posix) bool exists(in char[] name)
|
|||
{
|
||||
return access(toStringz(name), 0) == 0;
|
||||
}
|
||||
|
||||
|
||||
unittest
|
||||
{
|
||||
assert(exists("."));
|
||||
|
@ -704,7 +704,7 @@ version(Posix) bool isfile(in char[] name)
|
|||
{
|
||||
return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Change directory to $(D pathname).
|
||||
* Throws: $(D FileException) on error.
|
||||
|
@ -723,7 +723,7 @@ version(Posix) void chdir(in char[] pathname)
|
|||
cenforce(core.sys.posix.unistd.chdir(toStringz(pathname)) == 0,
|
||||
pathname);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
Make directory $(D pathname).
|
||||
|
||||
|
@ -839,11 +839,11 @@ version(Windows) struct DirEntry
|
|||
d_time lastAccessTime = d_time_nan; /// time file was last accessed
|
||||
d_time lastWriteTime = d_time_nan; /// time file was last written to
|
||||
uint attributes; // Windows file attributes OR'd together
|
||||
|
||||
|
||||
void init(in char[] path, in WIN32_FIND_DATA *fd)
|
||||
{
|
||||
auto clength = std.c.string.strlen(fd.cFileName.ptr);
|
||||
|
||||
|
||||
// Convert cFileName[] to unicode
|
||||
const wlength = MultiByteToWideChar(0, 0, fd.cFileName.ptr,
|
||||
clength, null,0);
|
||||
|
@ -853,14 +853,14 @@ version(Windows) struct DirEntry
|
|||
assert(n == wlength);
|
||||
// toUTF8() returns a new buffer
|
||||
name = std.path.join(path, std.utf.toUTF8(wbuf[0 .. wlength]));
|
||||
|
||||
|
||||
size = (cast(ulong)fd.nFileSizeHigh << 32) | fd.nFileSizeLow;
|
||||
creationTime = std.date.FILETIME2d_time(&fd.ftCreationTime);
|
||||
lastAccessTime = std.date.FILETIME2d_time(&fd.ftLastAccessTime);
|
||||
lastWriteTime = std.date.FILETIME2d_time(&fd.ftLastWriteTime);
|
||||
attributes = fd.dwFileAttributes;
|
||||
}
|
||||
|
||||
|
||||
void init(in char[] path, in WIN32_FIND_DATAW *fd)
|
||||
{
|
||||
size_t clength = std.string.wcslen(fd.cFileName.ptr);
|
||||
|
@ -872,7 +872,7 @@ version(Windows) struct DirEntry
|
|||
lastWriteTime = std.date.FILETIME2d_time(&fd.ftLastWriteTime);
|
||||
attributes = fd.dwFileAttributes;
|
||||
}
|
||||
|
||||
|
||||
/****
|
||||
* Return $(D true) if DirEntry is a directory.
|
||||
*/
|
||||
|
@ -880,7 +880,7 @@ version(Windows) struct DirEntry
|
|||
{
|
||||
return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
|
||||
/****
|
||||
* Return !=0 if DirEntry is a file.
|
||||
*/
|
||||
|
@ -900,7 +900,7 @@ version(Posix) struct DirEntry
|
|||
ubyte d_type;
|
||||
struct_stat64 statbuf;
|
||||
bool didstat; // done lazy evaluation of stat()
|
||||
|
||||
|
||||
void init(in char[] path, core.sys.posix.dirent.dirent *fd)
|
||||
{
|
||||
immutable len = std.c.string.strlen(fd.d_name.ptr);
|
||||
|
@ -908,45 +908,45 @@ version(Posix) struct DirEntry
|
|||
d_type = fd.d_type;
|
||||
didstat = false;
|
||||
}
|
||||
|
||||
|
||||
bool isdir() const
|
||||
{
|
||||
return (d_type & DT_DIR) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool isfile() const
|
||||
{
|
||||
return (d_type & DT_REG) != 0;
|
||||
}
|
||||
|
||||
|
||||
ulong size()
|
||||
{
|
||||
ensureStatDone;
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
d_time creationTime()
|
||||
{
|
||||
ensureStatDone;
|
||||
return _creationTime;
|
||||
}
|
||||
|
||||
|
||||
d_time lastAccessTime()
|
||||
{
|
||||
ensureStatDone;
|
||||
return _lastAccessTime;
|
||||
}
|
||||
|
||||
|
||||
d_time lastWriteTime()
|
||||
{
|
||||
ensureStatDone;
|
||||
return _lastWriteTime;
|
||||
}
|
||||
|
||||
|
||||
/* This is to support lazy evaluation, because doing stat's is
|
||||
* expensive and not always needed.
|
||||
*/
|
||||
|
||||
|
||||
void ensureStatDone()
|
||||
{
|
||||
if (didstat) return;
|
||||
|
@ -1007,7 +1007,7 @@ version(Windows) void listdir(in char[] pathname,
|
|||
if (useWfuncs)
|
||||
{
|
||||
WIN32_FIND_DATAW fileinfo;
|
||||
|
||||
|
||||
auto h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
@ -1018,7 +1018,7 @@ version(Windows) void listdir(in char[] pathname,
|
|||
if (std.string.wcscmp(fileinfo.cFileName.ptr, ".") == 0 ||
|
||||
std.string.wcscmp(fileinfo.cFileName.ptr, "..") == 0)
|
||||
continue;
|
||||
|
||||
|
||||
de.init(pathname, &fileinfo);
|
||||
if (!callback(&de))
|
||||
break;
|
||||
|
@ -1027,11 +1027,11 @@ version(Windows) void listdir(in char[] pathname,
|
|||
else
|
||||
{
|
||||
WIN32_FIND_DATA fileinfo;
|
||||
|
||||
|
||||
auto h = FindFirstFileA(toMBSz(c), &fileinfo);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
|
||||
scope(exit) FindClose(h);
|
||||
do
|
||||
{
|
||||
|
@ -1039,7 +1039,7 @@ version(Windows) void listdir(in char[] pathname,
|
|||
if (std.c.string.strcmp(fileinfo.cFileName.ptr, ".") == 0 ||
|
||||
std.c.string.strcmp(fileinfo.cFileName.ptr, "..") == 0)
|
||||
continue;
|
||||
|
||||
|
||||
de.init(pathname, &fileinfo);
|
||||
if (!callback(&de))
|
||||
break;
|
||||
|
@ -1083,11 +1083,11 @@ version(Posix) void copy(in char[] from, in char[] to)
|
|||
immutable fd = core.sys.posix.fcntl.open(toStringz(from), O_RDONLY);
|
||||
cenforce(fd != -1, from);
|
||||
scope(exit) core.sys.posix.unistd.close(fd);
|
||||
|
||||
|
||||
struct_stat64 statbuf = void;
|
||||
cenforce(fstat64(fd, &statbuf) == 0, from);
|
||||
//cenforce(core.sys.posix.sys.stat.fstat(fd, &statbuf) == 0, from);
|
||||
|
||||
|
||||
auto toz = toStringz(to);
|
||||
immutable fdw = core.sys.posix.fcntl.open(toz,
|
||||
O_CREAT | O_WRONLY | O_TRUNC, octal!666);
|
||||
|
@ -1104,7 +1104,7 @@ version(Posix) void copy(in char[] from, in char[] to)
|
|||
buf || assert(false, "Out of memory in std.file.copy");
|
||||
}
|
||||
scope(exit) std.c.stdlib.free(buf);
|
||||
|
||||
|
||||
for (auto size = statbuf.st_size; size; )
|
||||
{
|
||||
immutable toxfer = (size > BUFSIZ) ? BUFSIZ : cast(size_t) size;
|
||||
|
@ -1116,13 +1116,13 @@ version(Posix) void copy(in char[] from, in char[] to)
|
|||
size -= toxfer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cenforce(core.sys.posix.unistd.close(fdw) != -1, from);
|
||||
|
||||
|
||||
utimbuf utim = void;
|
||||
utim.actime = cast(time_t)statbuf.st_atime;
|
||||
utim.modtime = cast(time_t)statbuf.st_mtime;
|
||||
|
||||
|
||||
cenforce(utime(toz, &utim) != -1, from);
|
||||
}
|
||||
|
||||
|
@ -1175,7 +1175,7 @@ unittest
|
|||
assert(ftm1 + 1000 == ftm2);
|
||||
}
|
||||
+/
|
||||
|
||||
|
||||
/****************************************************
|
||||
Remove directory and all of its content and subdirectories,
|
||||
recursively.
|
||||
|
@ -1287,7 +1287,7 @@ struct DirIterator
|
|||
{
|
||||
int result = 0;
|
||||
// worklist used only in breadth-first traversal
|
||||
string[] worklist = [ pathname ];
|
||||
string[] worklist = [ pathname ];
|
||||
|
||||
bool callback(DirEntry* de)
|
||||
{
|
||||
|
@ -1457,13 +1457,13 @@ unittest
|
|||
string[] listdir(in char[] pathname)
|
||||
{
|
||||
Appender!(string[]) result;
|
||||
|
||||
|
||||
bool listing(string filename)
|
||||
{
|
||||
result.put(filename);
|
||||
return true; // continue
|
||||
}
|
||||
|
||||
|
||||
listdir(pathname, &listing);
|
||||
return result.data;
|
||||
}
|
||||
|
@ -1517,7 +1517,7 @@ unittest
|
|||
string[] listdir(in char[] pathname, in char[] pattern)
|
||||
{
|
||||
Appender!(string[]) result;
|
||||
|
||||
|
||||
bool callback(DirEntry* de)
|
||||
{
|
||||
if (de.isdir)
|
||||
|
@ -1529,17 +1529,17 @@ string[] listdir(in char[] pathname, in char[] pattern)
|
|||
}
|
||||
return true; // continue
|
||||
}
|
||||
|
||||
|
||||
listdir(pathname, &callback);
|
||||
return result.data;
|
||||
}
|
||||
|
||||
|
||||
/** Ditto */
|
||||
|
||||
|
||||
string[] listdir(in char[] pathname, RegExp r)
|
||||
{
|
||||
Appender!(string[]) result;
|
||||
|
||||
|
||||
bool callback(DirEntry* de)
|
||||
{
|
||||
if (de.isdir)
|
||||
|
@ -1551,11 +1551,11 @@ string[] listdir(in char[] pathname, RegExp r)
|
|||
}
|
||||
return true; // continue
|
||||
}
|
||||
|
||||
|
||||
listdir(pathname, &callback);
|
||||
return result.data;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* For each file and directory name in pathname[],
|
||||
* pass it to the callback delegate.
|
||||
|
@ -1602,6 +1602,6 @@ void listdir(in char[] pathname, bool delegate(string filename) callback)
|
|||
{
|
||||
return callback(std.path.getBaseName(de.name));
|
||||
}
|
||||
|
||||
|
||||
listdir(pathname, &listing);
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ module std.format;
|
|||
//debug=format; // uncomment to turn on debugging printf's
|
||||
|
||||
import core.stdc.stdio, core.stdc.stdlib, core.stdc.string;
|
||||
import std.algorithm, std.array, std.bitmanip, std.contracts, std.conv,
|
||||
std.ctype, std.functional, std.range, std.stdarg, std.string, std.system,
|
||||
std.traits, std.typetuple, std.utf;
|
||||
import std.algorithm, std.array, std.bitmanip, std.conv,
|
||||
std.ctype, std.exception, std.functional, std.range, std.stdarg,
|
||||
std.string, std.system, std.traits, std.typetuple, std.utf;
|
||||
version(unittest) {
|
||||
import std.stdio, std.typecons;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ module std.functional;
|
|||
|
||||
import std.metastrings, std.stdio, std.traits, std.typecons, std.typetuple;
|
||||
// for making various functions visible in *naryFun
|
||||
import std.algorithm, std.contracts, std.conv, std.math, std.range, std.string;
|
||||
import std.algorithm, std.conv, std.exception, std.math, std.range, std.string;
|
||||
|
||||
/**
|
||||
Transforms a string representing an expression into a unary
|
||||
|
@ -48,7 +48,7 @@ template unaryFunImpl(alias fun, bool byRef, string parmName = "a")
|
|||
// enum testAsExpression = "{"~ElementType.stringof
|
||||
// ~" "~parmName~"; return ("~fun~");}()";
|
||||
enum testAsExpression = "{ ElementType "~parmName
|
||||
~"; return ("~fun~");}()";
|
||||
~"; return ("~fun~");}()";
|
||||
enum testAsStmts = "{"~ElementType.stringof
|
||||
~" "~parmName~"; "~fun~"}()";
|
||||
// pragma(msg, "Expr: "~testAsExpression);
|
||||
|
@ -162,7 +162,7 @@ template binaryFunImpl(alias fun,
|
|||
else
|
||||
{
|
||||
// Credit for this idea goes to Don Clugston
|
||||
enum string msg =
|
||||
enum string msg =
|
||||
"Bad binary function q{" ~ fun ~ "}."
|
||||
~" You need to use a valid D expression using symbols "
|
||||
~parm1Name~" of type "~ElementType1.stringof~" and "
|
||||
|
@ -413,7 +413,7 @@ unittest
|
|||
// }
|
||||
|
||||
// /**
|
||||
// naryFun
|
||||
// naryFun
|
||||
// */
|
||||
// template naryFun(string fun)
|
||||
// {
|
||||
|
@ -451,7 +451,7 @@ template compose(fun...) { alias composeImpl!(fun).doIt compose; }
|
|||
// Implementation of compose
|
||||
template composeImpl(fun...)
|
||||
{
|
||||
static if (fun.length == 1)
|
||||
static if (fun.length == 1)
|
||||
{
|
||||
static if (is(typeof(fun[0]) : string))
|
||||
alias unaryFun!(fun[0]) doIt;
|
||||
|
@ -489,7 +489,7 @@ template composeImpl(fun...)
|
|||
execution is the same as lexical order.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
----
|
||||
// Read an entire text file, split the resulting string in
|
||||
// whitespace-separated tokens, and then convert each token into an
|
||||
|
@ -510,10 +510,10 @@ unittest
|
|||
// double baz(int a) { return a + 0.5; }
|
||||
// assert(compose!(baz, bar, foo)(1) == 2.5);
|
||||
// assert(pipe!(foo, bar, baz)(1) == 2.5);
|
||||
|
||||
|
||||
// assert(compose!(baz, `to!(int)(a) + 1`, foo)(1) == 2.5);
|
||||
// assert(compose!(baz, bar)("1"[]) == 2.5);
|
||||
|
||||
|
||||
// @@@BUG@@@
|
||||
//assert(compose!(baz, bar)("1") == 2.5);
|
||||
|
||||
|
@ -643,24 +643,24 @@ unittest {
|
|||
static assert(is(typeof(incMyNumDel) == int delegate(ref uint)));
|
||||
auto returnVal = incMyNumDel(myNum);
|
||||
assert(myNum == 1);
|
||||
|
||||
|
||||
interface I { int opCall(); }
|
||||
class C: I { int opCall() { inc(myNum); return myNum;} }
|
||||
auto c = new C;
|
||||
auto i = cast(I) c;
|
||||
|
||||
|
||||
auto getvalc = toDelegate(c);
|
||||
assert(getvalc() == 2);
|
||||
|
||||
|
||||
auto getvali = toDelegate(i);
|
||||
assert(getvali() == 3);
|
||||
|
||||
|
||||
struct S1 { int opCall() { inc(myNum); return myNum; } }
|
||||
static assert(!is(typeof(&s1.opCall) == delegate));
|
||||
S1 s1;
|
||||
auto getvals1 = toDelegate(s1);
|
||||
assert(getvals1() == 4);
|
||||
|
||||
|
||||
struct S2 { static int opCall() { return 123456; } }
|
||||
static assert(!is(typeof(&S2.opCall) == delegate));
|
||||
S2 s2;
|
||||
|
|
50
std/getopt.d
50
std/getopt.d
|
@ -2,14 +2,14 @@
|
|||
|
||||
/**
|
||||
Processing of command line options.
|
||||
|
||||
|
||||
The getopt module implements a $(D getopt) function, which adheres to
|
||||
the POSIX syntax for command line options. GNU extensions are
|
||||
supported in the form of long options introduced by a double dash
|
||||
("--"). Support for bundling of command line options, as was the case
|
||||
with the more traditional single-letter approach, is provided but not
|
||||
enabled by default.
|
||||
|
||||
|
||||
Macros:
|
||||
|
||||
WIKI = Phobos/StdGetopt
|
||||
|
@ -30,8 +30,8 @@ Distributed under the Boost Software License, Version 1.0.
|
|||
*/
|
||||
module std.getopt;
|
||||
|
||||
private import std.string, std.conv, std.traits, std.contracts, std.bitmanip,
|
||||
std.algorithm, std.ctype;
|
||||
private import std.string, std.conv, std.traits, std.bitmanip,
|
||||
std.algorithm, std.ctype, std.exception;
|
||||
|
||||
//version (unittest)
|
||||
//{
|
||||
|
@ -90,7 +90,7 @@ void main(string[] args)
|
|||
$(LI $(I Numeric options.) If an option is bound to a numeric type, a
|
||||
number is expected as the next option, or right within the option
|
||||
separated with an "=" sign:
|
||||
|
||||
|
||||
---------
|
||||
uint timeout;
|
||||
getopt(args, "timeout", &timeout);
|
||||
|
@ -98,7 +98,7 @@ void main(string[] args)
|
|||
|
||||
Invoking the program with "--timeout=5" or "--timeout 5" will set
|
||||
$(D timeout) to 5.)
|
||||
|
||||
|
||||
$(UL $(LI $(I Incremental options.) If an option name has a "+" suffix and
|
||||
is bound to a numeric type, then the option's value tracks the number
|
||||
of times the option occurred on the command line:
|
||||
|
@ -114,11 +114,11 @@ void main(string[] args)
|
|||
--paranoid", the "42" does not set $(D paranoid) to 42;
|
||||
instead, $(D paranoid) is set to 2 and "42" is not considered
|
||||
as part of the program options.))
|
||||
|
||||
|
||||
$(LI $(I String options.) If an option is bound to a string, a string
|
||||
is expected as the next option, or right within the option separated
|
||||
with an "=" sign:
|
||||
|
||||
|
||||
---------
|
||||
string outputFile;
|
||||
getopt(args, "output", &outputFile);
|
||||
|
@ -127,11 +127,11 @@ getopt(args, "output", &outputFile);
|
|||
Invoking the program with "--output=myfile.txt" or "--output
|
||||
myfile.txt" will set $(D outputFile) to "myfile.txt".) If you want to
|
||||
pass a string containing spaces, you need to use the quoting that is
|
||||
appropriate to your shell, e.g. --output='my file.txt'.
|
||||
|
||||
appropriate to your shell, e.g. --output='my file.txt'.
|
||||
|
||||
$(LI $(I Array options.) If an option is bound to an array, a new
|
||||
element is appended to the array each time the option occurs:
|
||||
|
||||
|
||||
---------
|
||||
string[] outputFiles;
|
||||
getopt(args, "output", &outputFiles);
|
||||
|
@ -140,11 +140,11 @@ getopt(args, "output", &outputFiles);
|
|||
Invoking the program with "--output=myfile.txt --output=yourfile.txt"
|
||||
or "--output myfile.txt --output yourfile.txt" will set $(D
|
||||
outputFiles) to [ "myfile.txt", "yourfile.txt" ] .)
|
||||
|
||||
|
||||
$(LI $(I Hash options.) If an option is bound to an associative
|
||||
array, a string of the form "name=value" is expected as the next
|
||||
option, or right within the option separated with an "=" sign:
|
||||
|
||||
|
||||
---------
|
||||
double[string] tuningParms;
|
||||
getopt(args, "tune", &tuningParms);
|
||||
|
@ -153,7 +153,7 @@ getopt(args, "tune", &tuningParms);
|
|||
Invoking the program with e.g. "--tune=alpha=0.5 --tune beta=0.6" will
|
||||
set $(D tuningParms) to [ "alpha" : 0.5, "beta" : 0.6 ].) In general,
|
||||
keys and values can be of any parsable types.
|
||||
|
||||
|
||||
$(LI $(I Delegate options.) An option can be bound to a delegate with
|
||||
the signature $(D void delegate()), $(D void delegate(string option))
|
||||
or $(D void delegate(string option, string value)).
|
||||
|
@ -163,7 +163,7 @@ whenever the option is seen.) $(LI In the $(D void delegate(string
|
|||
option)) case, the option string (without the leading dash(es)) is
|
||||
passed to the delegate. After that, the option string is considered
|
||||
handled and removed from the options array.)
|
||||
|
||||
|
||||
---------
|
||||
void main(string[] args)
|
||||
{
|
||||
|
@ -189,7 +189,7 @@ option string is handled as an option with one argument, and parsed
|
|||
accordingly. The option and its value are passed to the
|
||||
delegate. After that, whatever was passed to the delegate is
|
||||
considered handled and removed from the list.)
|
||||
|
||||
|
||||
---------
|
||||
void main(string[] args)
|
||||
{
|
||||
|
@ -291,7 +291,7 @@ A lonesome double-dash terminates $(D getopt) gathering. It is used to separate
|
|||
|
||||
void getopt(T...)(ref string[] args, T opts) {
|
||||
enforce(args.length,
|
||||
"Invalid arguments string passed: program name missing");
|
||||
"Invalid arguments string passed: program name missing");
|
||||
configuration cfg;
|
||||
return getoptImpl(args, cfg, opts);
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ private void getoptImpl(T...)(ref string[] args,
|
|||
{
|
||||
// not an option
|
||||
if (cfg.stopOnFirstNonOption) break;
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
if (endOfOptions.length && a == endOfOptions) break;
|
||||
if (!cfg.passThrough)
|
||||
|
@ -386,7 +386,7 @@ void handleOption(R)(string option, R receiver, ref string[] args,
|
|||
// found it; from here on, commit to eat args[i]
|
||||
// (and potentially args[i + 1] too)
|
||||
args = args[0 .. i] ~ args[i + 1 .. $];
|
||||
|
||||
|
||||
static if (is(typeof(*receiver) == bool)) {
|
||||
*receiver = true;
|
||||
break;
|
||||
|
@ -414,12 +414,12 @@ void handleOption(R)(string option, R receiver, ref string[] args,
|
|||
}
|
||||
else static if (is(typeof(receiver) == delegate))
|
||||
{
|
||||
static if (is(typeof(receiver("", "")) : void))
|
||||
static if (is(typeof(receiver("", "")) : void))
|
||||
{
|
||||
// option with argument
|
||||
receiver(option, val);
|
||||
}
|
||||
else static if (is(typeof(receiver("")) : void))
|
||||
else static if (is(typeof(receiver("")) : void))
|
||||
{
|
||||
static assert(is(typeof(receiver("")) : void));
|
||||
// boolean-style receiver
|
||||
|
@ -553,7 +553,7 @@ unittest
|
|||
"--paranoid", "--paranoid", "--paranoid"]).dup;
|
||||
getopt(args, "paranoid+", ¶noid);
|
||||
assert(paranoid == 5, to!(string)(paranoid));
|
||||
|
||||
|
||||
string data = "file.dat";
|
||||
int length = 24;
|
||||
bool verbose = false;
|
||||
|
@ -562,7 +562,7 @@ unittest
|
|||
getopt(
|
||||
args,
|
||||
"length", &length,
|
||||
"file", &data,
|
||||
"file", &data,
|
||||
"verbose", &verbose);
|
||||
assert(args.length == 1);
|
||||
assert(data == "dat.file");
|
||||
|
@ -638,7 +638,7 @@ unittest
|
|||
|
||||
args = (["program.name", "--foo", "nonoption", "--bar"]).dup;
|
||||
foo = bar = false;
|
||||
getopt(args,
|
||||
getopt(args,
|
||||
std.getopt.config.stopOnFirstNonOption,
|
||||
"foo", &foo,
|
||||
"bar", &bar);
|
||||
|
@ -646,7 +646,7 @@ unittest
|
|||
|
||||
args = (["program.name", "--foo", "nonoption", "--zab"]).dup;
|
||||
foo = bar = false;
|
||||
getopt(args,
|
||||
getopt(args,
|
||||
std.getopt.config.stopOnFirstNonOption,
|
||||
"foo", &foo,
|
||||
"bar", &bar);
|
||||
|
|
10
std/md5.d
10
std/md5.d
|
@ -5,10 +5,10 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Computes MD5 digests of arbitrary data. MD5 digests are 16 byte quantities that are like a checksum or crc, but are more robust.
|
||||
* Computes MD5 digests of arbitrary data. MD5 digests are 16 byte quantities that are like a checksum or crc, but are more robust.
|
||||
*
|
||||
* There are two ways to do this. The first does it all in one function call to
|
||||
* sum(). The second is for when the data is buffered.
|
||||
* sum(). The second is for when the data is buffered.
|
||||
*
|
||||
* Bugs:
|
||||
* MD5 digests have been demonstrated to not be unique.
|
||||
|
@ -87,7 +87,7 @@ module std.md5;
|
|||
//debug=md5; // uncomment to turn on debugging printf's
|
||||
|
||||
import std.string;
|
||||
import std.contracts;
|
||||
import std.exception;
|
||||
import std.c.stdio : printf;
|
||||
|
||||
/***************************************
|
||||
|
@ -122,7 +122,7 @@ string digestToString(in ubyte[16] digest)
|
|||
{
|
||||
auto result = new char[32];
|
||||
int i;
|
||||
|
||||
|
||||
foreach (ubyte u; digest)
|
||||
{
|
||||
result[i] = std.string.hexdigits[u >> 4];
|
||||
|
@ -141,7 +141,7 @@ Example:
|
|||
string a = "Mary has ", b = "a little lamb";
|
||||
int[] c = [ 1, 2, 3, 4, 5 ];
|
||||
string d = getDigestString(a, b, c);
|
||||
----
|
||||
----
|
||||
*/
|
||||
string getDigestString(in void[][] data...)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ private import std.conv;
|
|||
private import std.string;
|
||||
private import std.c.process;
|
||||
private import core.stdc.errno;
|
||||
private import std.contracts;
|
||||
private import std.exception;
|
||||
version (Windows)
|
||||
{
|
||||
import std.array, std.format, std.random, std.file;
|
||||
|
|
18
std/random.d
18
std/random.d
|
@ -54,7 +54,7 @@ Distributed under the Boost Software License, Version 1.0.
|
|||
*/
|
||||
module std.random;
|
||||
|
||||
import std.algorithm, std.c.time, std.contracts, std.conv, std.date, std.math,
|
||||
import std.algorithm, std.c.time, std.conv, std.date, std.exception, std.math,
|
||||
std.numeric, std.process, std.range, std.stdio, std.traits, core.thread;
|
||||
|
||||
// Segments of the code in this file Copyright (c) 1997 by Rick Booth
|
||||
|
@ -271,7 +271,7 @@ $(D x0).
|
|||
{
|
||||
return _x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Always $(D false) (random generators are infinite ranges).
|
||||
*/
|
||||
|
@ -636,18 +636,18 @@ if (is(CommonType!(T1, UniformRandomNumberGenerator) == void) &&
|
|||
{
|
||||
alias Unqual!(CommonType!(T1, T2)) NumberType;
|
||||
NumberType _a, _b;
|
||||
static if (boundaries[0] == '(')
|
||||
static if (boundaries[0] == '(')
|
||||
{
|
||||
static if (isIntegral!(NumberType) || is(Unqual!NumberType : dchar))
|
||||
static if (isIntegral!(NumberType) || is(Unqual!NumberType : dchar))
|
||||
{
|
||||
_a = a;
|
||||
_a++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_a = nextafter(a, a.infinity);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
_a = a;
|
||||
}
|
||||
|
@ -734,13 +734,13 @@ unittest
|
|||
assert('a' <= x && x <= 'z');
|
||||
//writeln(x);
|
||||
}
|
||||
|
||||
|
||||
foreach (i; 0 .. 20)
|
||||
{
|
||||
auto x = uniform('a', 'z', gen);
|
||||
assert('a' <= x && x < 'z');
|
||||
}
|
||||
|
||||
|
||||
foreach(i; 0 .. 20) {
|
||||
immutable ubyte a = 0;
|
||||
immutable ubyte b = 15;
|
||||
|
|
|
@ -16,7 +16,7 @@ Authors: $(WEB erdani.org, Andrei Alexandrescu)
|
|||
module std.range;
|
||||
|
||||
public import std.array;
|
||||
import std.contracts;
|
||||
import std.exception;
|
||||
import std.traits;
|
||||
import std.typecons;
|
||||
import std.typetuple;
|
||||
|
|
|
@ -18,7 +18,7 @@ public import core.stdc.stdio;
|
|||
import std.stdiobase;
|
||||
import core.memory, core.stdc.errno, core.stdc.stddef, core.stdc.stdlib,
|
||||
core.stdc.string, core.stdc.wchar_;
|
||||
import std.algorithm, std.array, std.contracts, std.conv, std.file, std.format,
|
||||
import std.algorithm, std.array, std.conv, std.exception, std.file, std.format,
|
||||
std.range, std.string, std.traits, std.typecons,
|
||||
std.typetuple, std.utf;
|
||||
|
||||
|
|
60
std/string.d
60
std/string.d
|
@ -27,8 +27,8 @@ module std.string;
|
|||
|
||||
private import core.exception : onRangeError;
|
||||
import core.stdc.stdio, core.stdc.stdlib,
|
||||
core.stdc.string, std.algorithm, std.array,
|
||||
std.contracts, std.conv, std.ctype, std.encoding, std.format,
|
||||
core.stdc.string, std.algorithm, std.array,
|
||||
std.conv, std.ctype, std.encoding, std.exception, std.format,
|
||||
std.metastrings, std.range, std.regex, std.stdarg, std.stdio, std.traits,
|
||||
std.typetuple, std.uni, std.utf;
|
||||
|
||||
|
@ -225,12 +225,12 @@ out (result)
|
|||
body
|
||||
{
|
||||
char[] copy;
|
||||
|
||||
|
||||
/+ Unfortunately, this isn't reliable.
|
||||
We could make this work if string literals are put
|
||||
in read-only memory and we test if s[] is pointing into
|
||||
that.
|
||||
|
||||
|
||||
/* Peek past end of s[], if it's 0, no conversion necessary.
|
||||
* Note that the compiler will put a 0 past the end of static
|
||||
* strings, and the storage allocator will put a 0 past the end
|
||||
|
@ -313,7 +313,7 @@ if (isSomeString!(Char[]))
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// c is a universal character
|
||||
foreach (int i, dchar c2; s)
|
||||
{
|
||||
|
@ -326,7 +326,7 @@ if (isSomeString!(Char[]))
|
|||
if (c <= 0x7F)
|
||||
{ // Plain old ASCII
|
||||
auto c1 = cast(char) std.ctype.tolower(c);
|
||||
|
||||
|
||||
foreach (int i, Char c2; s)
|
||||
{
|
||||
auto c3 = cast(Char)std.ctype.tolower(c2);
|
||||
|
@ -337,7 +337,7 @@ if (isSomeString!(Char[]))
|
|||
else
|
||||
{ // c is a universal character
|
||||
auto c1 = std.uni.toUniLower(c);
|
||||
|
||||
|
||||
foreach (int i, dchar c2; s)
|
||||
{
|
||||
auto c3 = std.uni.toUniLower(c2);
|
||||
|
@ -394,12 +394,12 @@ unittest
|
|||
assert(i == 0);
|
||||
i = indexOf("def", cast(dchar)'F', CaseSensitive.no);
|
||||
assert(i == 2);
|
||||
|
||||
|
||||
string sPlts = "Mars: the fourth Rock (Planet) from the Sun.";
|
||||
|
||||
|
||||
i = indexOf("def", cast(char)'f', CaseSensitive.no);
|
||||
assert(i == 2);
|
||||
|
||||
|
||||
i = indexOf(sPlts, cast(char)'P', CaseSensitive.no);
|
||||
assert(i == 23);
|
||||
i = indexOf(sPlts, cast(char)'R', CaseSensitive.no);
|
||||
|
@ -429,7 +429,7 @@ int lastIndexOf(in char[] s, dchar c, CaseSensitive cs = CaseSensitive.yes)
|
|||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
// c is a universal character
|
||||
char[4] buf;
|
||||
auto t = std.utf.toUTF8(buf, c);
|
||||
|
@ -473,13 +473,13 @@ int lastIndexOf(in char[] s, dchar c, CaseSensitive cs = CaseSensitive.yes)
|
|||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unittest
|
||||
{
|
||||
debug(string) printf("string.rfind.unittest\n");
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
i = lastIndexOf(null, cast(dchar)'a');
|
||||
assert(i == -1);
|
||||
i = lastIndexOf("def", cast(dchar)'a');
|
||||
|
@ -519,12 +519,12 @@ unittest
|
|||
/**
|
||||
$(D indexOf) find first occurrence of $(D sub[]) in string $(D s[]).
|
||||
lastIndexOf find last occurrence of $(D sub[]) in string $(D s[]).
|
||||
|
||||
|
||||
$(D CaseSensitive cs) controls whether the comparisons are case
|
||||
sensitive or not.
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
|
||||
Index in $(D s) where $(D sub) is found, $(D -1) if not found.
|
||||
*/
|
||||
|
||||
|
@ -619,7 +619,7 @@ unittest
|
|||
i = indexOf("dfeffgfff", "fff", CaseSensitive.no);
|
||||
assert(i == 6);
|
||||
}
|
||||
|
||||
|
||||
string sPlts = "Mars: the fourth Rock (Planet) from the Sun.";
|
||||
string sMars = "Who\'s \'My Favorite Maritian?\'";
|
||||
|
||||
|
@ -654,7 +654,7 @@ int lastIndexOf(in char[] s, in char[] sub, CaseSensitive cs = CaseSensitive.yes
|
|||
if (cs == CaseSensitive.yes)
|
||||
{
|
||||
char c;
|
||||
|
||||
|
||||
if (sub.length == 0)
|
||||
return s.length;
|
||||
c = sub[0];
|
||||
|
@ -1196,12 +1196,12 @@ string join(in string[] words, string sep)
|
|||
if (!words.length) return null;
|
||||
immutable seplen = sep.length;
|
||||
size_t len = (words.length - 1) * seplen;
|
||||
|
||||
|
||||
foreach (i; 0 .. words.length)
|
||||
len += words[i].length;
|
||||
|
||||
|
||||
auto result = new char[len];
|
||||
|
||||
|
||||
size_t j;
|
||||
foreach (i; 0 .. words.length)
|
||||
{
|
||||
|
@ -1288,7 +1288,7 @@ unittest
|
|||
S s = " peter paul\tjerry ";
|
||||
S[] words;
|
||||
int i;
|
||||
|
||||
|
||||
words = split(s);
|
||||
assert(words.length == 3);
|
||||
i = cmp(words[0], "peter");
|
||||
|
@ -1411,7 +1411,7 @@ S[] splitlines(S)(S s)
|
|||
auto result = Appender!(S[])();
|
||||
|
||||
foreach (i; 0 .. s.length)
|
||||
{
|
||||
{
|
||||
immutable c = s[i];
|
||||
if (c == '\r' || c == '\n')
|
||||
{
|
||||
|
@ -1550,7 +1550,7 @@ debug unittest
|
|||
{
|
||||
// fails to compile with: Error: array equality comparison type
|
||||
// mismatch, immutable(char)[] vs ubyte[]
|
||||
version(none)
|
||||
version(none)
|
||||
{
|
||||
alias TypeTuple!(string, wstring, dstring, char[], wchar[], dchar[])
|
||||
StringTypes;
|
||||
|
@ -1783,7 +1783,7 @@ string chop(string s)
|
|||
if (!len) return s;
|
||||
if (len >= 2 && s[len - 1] == '\n' && s[len - 2] == '\r')
|
||||
return s[0 .. len - 2];
|
||||
|
||||
|
||||
// If we're in a tail of a UTF-8 sequence, back up
|
||||
while ((s[len - 1] & 0xC0) == 0x80)
|
||||
{
|
||||
|
@ -1791,7 +1791,7 @@ string chop(string s)
|
|||
if (len == 0)
|
||||
throw new std.utf.UtfException("invalid UTF sequence", 0);
|
||||
}
|
||||
|
||||
|
||||
return s[0 .. len - 1];
|
||||
}
|
||||
|
||||
|
@ -3999,7 +3999,7 @@ public:
|
|||
_input = input;
|
||||
if (!input.empty) popFront;
|
||||
}
|
||||
|
||||
|
||||
/// Range primitives
|
||||
bool empty()
|
||||
{
|
||||
|
@ -4048,8 +4048,8 @@ public:
|
|||
assert(!empty);
|
||||
if (!_input.empty)
|
||||
std.utf.decodeBack(_input);
|
||||
else
|
||||
_front = _front.init;
|
||||
else
|
||||
_front = _front.init;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,8 +51,8 @@ Authors: $(WEB erdani.org, Andrei Alexandrescu),
|
|||
Shin Fujishiro
|
||||
*/
|
||||
module std.typecons;
|
||||
import core.stdc.stdlib, std.algorithm, std.array, std.contracts, std.conv,
|
||||
std.metastrings, std.traits, std.typetuple, core.memory;
|
||||
import core.stdc.stdlib, std.algorithm, std.array, std.conv,
|
||||
std.exception, std.metastrings, std.traits, std.typetuple, core.memory;
|
||||
version(unittest) import std.stdio;
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@ private import std.ctype;
|
|||
private import std.c.stdlib;
|
||||
private import std.utf;
|
||||
private import std.stdio;
|
||||
import std.contracts;
|
||||
import std.exception;
|
||||
|
||||
class URIerror : Error
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
*/
|
||||
module std.utf;
|
||||
|
||||
import std.contracts, std.conv, std.range, std.traits, std.typecons;
|
||||
import std.conv, std.exception, std.range, std.traits, std.typecons;
|
||||
|
||||
//debug=utf; // uncomment to turn on debugging printf's
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
* Copyright: Copyright Andrei Alexandrescu 2007 - 2009.
|
||||
* License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
|
||||
* Authors: $(WEB erdani.org, Andrei Alexandrescu)
|
||||
* Credits: Brad Roberts came up with the name $(D_PARAM contracts).
|
||||
*
|
||||
* Copyright Andrei Alexandrescu 2007 - 2009.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
|
@ -68,7 +67,7 @@ module std.variant;
|
|||
import std.traits, std.c.string, std.typetuple, std.conv;
|
||||
version(unittest)
|
||||
{
|
||||
import std.contracts, std.stdio;
|
||||
import std.exception, std.stdio;
|
||||
}
|
||||
|
||||
private template maxSize(T...)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue