Skip to content

Commit

Permalink
Merge pull request #1 from FeepingCreature/xml
Browse files Browse the repository at this point in the history
pull up to origin, add some xml functionality
  • Loading branch information
belka-ew authored Jan 11, 2018
2 parents 846e4e2 + f588924 commit faeaafa
Show file tree
Hide file tree
Showing 15 changed files with 552 additions and 69 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
*.so
*.dll

# dub
.dub
dub.selections.json
/ae-test-library

# demos - rdmd binaries
/demo/http/httpserve
Expand All @@ -32,3 +34,7 @@ dub.selections.json
/demo/sqlite/ae-demo-sqlite
/demo/turtle/ae-demo-turtle
/demo/ui/ae-demo-ui

# generated by makejson.sh
/ae.json
/all.d
9 changes: 5 additions & 4 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
install:
# cinst dmd --version=2.071.0
- ps: Start-FileDownload 'http://downloads.dlang.org/releases/2.x/2.071.0/dmd.2.071.0.windows.7z' -FileName 'dmd2.7z'
- ps: Start-FileDownload 'http://downloads.dlang.org/releases/2.x/2.073.1/dmd.2.073.1.windows.7z' -FileName 'dmd2.7z'
- 7z x dmd2.7z > nul
- set PATH=%CD%\dmd2\windows\bin;%CD%\dmd2\windows\bin64;%PATH%
- dmd.exe --version
# Dub
- cinst dub
- dub.exe --version
build_script:
- dub test --arch=x86
- call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64
- dub test --arch=x86_64
- call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
- set DFLAGS=-m32mscoff
- dub test --arch=x86
16 changes: 16 additions & 0 deletions dist.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
set -e

if [ $# -eq 0 ]
then
echo "Please specify the ae folder name."
exit
fi

rm ae.zip || true
rm -rf "$1"|| true
mkdir -p "$1"/src/ae
cp .travis.yml appveyor.yml dub.json README.md "$1"
cp -r utils "$1"/src/ae/
zip -r "$1".zip "$1"
rm -rf "$1"
11 changes: 11 additions & 0 deletions utils/aa.d
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,17 @@ struct OrderedMap(K, V)
V[] values;
size_t[K] index;

/// Convert from regular AA
this(V[K] aa)
{
foreach (ref k, ref v; aa)
{
index[k] = values.length;
keys ~= k;
values ~= v;
}
}

ref inout(V) opIndex()(auto ref K k) inout
{
return values[index[k]];
Expand Down
61 changes: 55 additions & 6 deletions utils/array.d
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,16 @@ T[] toArray(T)(ref T v)

/// Return the value represented as an array of bytes.
@property inout(ubyte)[] bytes(T)(ref inout(T) value)
if (!(is(T == class) || isDynamicArray!T))
if (!hasIndirections!T)
{
return value.toArray().bytes;
}

/// ditto
@property inout(ubyte)[] bytes(T)(inout(T) value)
if ( (is(T == class) || isDynamicArray!T))
if (is(T U : U[]) && !hasIndirections!U)
{
static if (is(T U : U[]))
return cast(inout(ubyte)[])value;
else
return (cast(inout(ubyte)*)value)[0..__traits(classInstanceSize, T)];
return cast(inout(ubyte)[])value;
}

unittest
Expand All @@ -63,6 +60,37 @@ unittest
assert(sa.bytes == [5]);
}

/// Reverse of bytes()
ref inout(T) fromBytes(T)(inout(ubyte)[] bytes)
if (!hasIndirections!T)
{
assert(bytes.length == T.sizeof, "Data length mismatch for %s".format(T.stringof));
return *cast(inout(T)*)bytes.ptr;
}

/// ditto
inout(T) fromBytes(T)(inout(ubyte)[] bytes)
if (is(T U : U[]) && !hasIndirections!U)
{
return cast(inout(T))bytes;
}

unittest
{
{ ubyte b = 5; assert(b.bytes.fromBytes!ubyte == 5); }
{ const ubyte b = 5; assert(b.bytes.fromBytes!ubyte == 5); }
struct S { ubyte b; }
{ ubyte b = 5; assert(b.bytes.fromBytes!S == S(5)); }
}

unittest
{
struct S { ubyte a, b; }
ubyte[] arr = [1, 2];
assert(arr.fromBytes!S == S(1, 2));
assert(arr.fromBytes!(S[]) == [S(1, 2)]);
}

int memcmp(in ubyte[] a, in ubyte[] b)
{
assert(a.length == b.length);
Expand Down Expand Up @@ -324,7 +352,28 @@ T queuePop(T)(ref T[] arr)
}

T shift(T)(ref T[] arr) { T result = arr[0]; arr = arr[1..$]; return result; }
T[] shift(T)(ref T[] arr, size_t n) { T[] result = arr[0..n]; arr = arr[n..$]; return result; }
T[N] shift(size_t N, T)(ref T[] arr) { T[N] result = cast(T[N])(arr[0..N]); arr = arr[N..$]; return result; }
void unshift(T)(ref T[] arr, T value) { arr.insertInPlace(0, value); }
void unshift(T)(ref T[] arr, T[] value) { arr.insertInPlace(0, value); }

unittest
{
int[] arr = [1, 2, 3];
assert(arr.shift == 1);
assert(arr == [2, 3]);
assert(arr.shift(2) == [2, 3]);
assert(arr == []);

arr = [3];
arr.unshift([1, 2]);
assert(arr == [1, 2, 3]);
arr.unshift(0);
assert(arr == [0, 1, 2, 3]);

assert(arr.shift!2 == [0, 1]);
assert(arr == [2, 3]);
}

/// If arr starts with prefix, slice it off and return true.
/// Otherwise leave arr unchaned and return false.
Expand Down
143 changes: 134 additions & 9 deletions utils/meta/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ public import ae.utils.meta.binding;

// ************************************************************************

import std.algorithm;
import std.range;
import std.string;
import std.traits;
import std.typetuple;

/**
* Same as TypeTuple, but meant to be used with values.
Expand Down Expand Up @@ -79,6 +75,8 @@ unittest
template expand(alias arr, size_t offset = 0)
if (isStaticArray!(typeof(arr)))
{
import std.typetuple : AliasSeq;

static if (arr.length == offset)
alias expand = AliasSeq!();
else
Expand Down Expand Up @@ -206,10 +204,15 @@ template enumLength(T)
deprecated alias EnumLength = enumLength;

/// A range that iterates over all members of an enum.
@property auto enumIota(T)() { return iota(T.init, enumLength!T); }
@property auto enumIota(T)()
{
import std.range : iota;
return iota(T.init, enumLength!T);
}

unittest
{
import std.algorithm.comparison : equal;
enum E { a, b, c }
static assert(equal(enumIota!E, [E.a, E.b, E.c]));
}
Expand All @@ -233,24 +236,44 @@ static template stringofArray(Args...)
/// "names" can contain multiple names separated by slashes.
static size_t findParameter(alias fun, string names)()
{
import std.array : split;

foreach (name; names.split("/"))
foreach (i, param; ParameterIdentifierTuple!fun)
if (param == name)
return i;
assert(false, "Function " ~ __traits(identifier, fun) ~ " doesn't have a parameter called " ~ name);
assert(false, "Function " ~ __traits(identifier, fun) ~ " doesn't have a parameter called " ~ names);
}

/// ditto
// Workaround for no "static alias" template parameters
static size_t findParameter()(string[] searchedNames, string soughtNames, string funName)
{
import std.array : split;

foreach (soughtName; soughtNames.split("/"))
{
import std.algorithm.searching : countUntil;

auto targetIndex = searchedNames.countUntil(soughtName);
if (targetIndex >= 0)
return targetIndex;
}
assert(false, "No argument %s in %s's parameters (%s)".format(soughtNames, funName, searchedNames).idup);

{
import std.format : format;

assert(false, "No argument %s in %s's parameters (%s)"
.format(soughtNames, funName, searchedNames).idup);
}
}

unittest
{
static void fun(int a, int b, int c) {}

static assert(findParameter!(fun, "x/c") == 2);
assert(findParameter(["a", "b", "c"], "x/c", "fun") == 2);
}

/// Generates a function which passes its arguments to a struct, which is
Expand All @@ -259,6 +282,12 @@ template structFun(S)
{
string gen()
{
import std.algorithm.iteration : map;
import std.array : join;
import std.format : format;
import std.meta : staticMap;
import std.range : iota;

enum identifierAt(int n) = __traits(identifier, S.tupleof[n]);
enum names = [staticMap!(identifierAt, RangeTuple!(S.tupleof.length))];

Expand Down Expand Up @@ -286,6 +315,52 @@ unittest
assert(test.b == 42);
}

/// Evaluate all arguments and return the last argument.
/// Can be used instead of the comma operator.
/// Inspired by http://clhs.lisp.se/Body/s_progn.htm
Args[$-1] progn(Args...)(lazy Args args)
{
foreach (n; RangeTuple!(Args.length-1))
cast(void)args[n];
return args[$-1];
}

unittest
{
// Test that expressions are correctly evaluated exactly once.
int a, b, c, d;
d = progn(a++, b++, c++);
assert(a==1 && b==1 && c == 1 && d == 0);
d = progn(a++, b++, ++c);
assert(a==2 && b==2 && c == 2 && d == 2);
}

unittest
{
// Test void expressions.
int a, b;
void incA() { a++; }
void incB() { b++; }
progn(incA(), incB());
assert(a == 1 && b == 1);
}

/// Like progn, but return the first argument instead.
Args[0] prog1(Args...)(lazy Args args)
{
auto result = args[0];
foreach (n; RangeTuple!(Args.length-1))
cast(void)args[1+n];
return result;
}

unittest
{
int a = 10, b = 20, c = 30;
int d = prog1(a++, b++, c++);
assert(a==11 && b==21 && c == 31 && d == 10);
}

// ************************************************************************

// Using a compiler with UDA support?
Expand Down Expand Up @@ -371,7 +446,7 @@ else

/// Generate constructors that simply call the parent class constructors.
/// Based on http://forum.dlang.org/post/[email protected]
mixin template GenerateContructorProxies()
mixin template GenerateConstructorProxies()
{
mixin(() {
import std.conv : text;
Expand All @@ -397,6 +472,8 @@ mixin template GenerateContructorProxies()
} ());
}

deprecated alias GenerateContructorProxies = GenerateConstructorProxies;

unittest
{
class A
Expand All @@ -409,7 +486,7 @@ unittest

class B : A
{
mixin GenerateContructorProxies;
mixin GenerateConstructorProxies;
}

A a;
Expand Down Expand Up @@ -552,6 +629,26 @@ static assert(is(ResizeNumericType!(float, double.mant_dig) == double));
alias ExpandNumericType(T, uint additionalBits) =
ResizeNumericType!(T, valueBits!T + additionalBits);

/// Like ExpandNumericType, but do not error if the resulting type is
/// too large to fit any native D type - just expand to the largest
/// type of the same kind instead.
template TryExpandNumericType(T, uint additionalBits)
{
static if (is(typeof(ExpandNumericType!(T, additionalBits))))
alias TryExpandNumericType = ExpandNumericType!(T, additionalBits);
else
static if (is(T : ulong))
static if (isSigned!T)
alias TryExpandNumericType = long;
else
alias TryExpandNumericType = ulong;
else
static if (is(T : real))
alias TryExpandNumericType = real;
else
static assert(false, "Don't know how to expand type: " ~ T.stringof);
}

/// Unsigned integer type big enough to fit N bits of precision.
template UnsignedBitsType(uint bits)
{
Expand Down Expand Up @@ -590,3 +687,31 @@ template SignedBitsType(uint bits)
}
return fields;
}

/// Create a functor value type (bound struct) from an alias.
template functor(alias fun)
{
struct Functor
{
//alias opCall = fun;
auto opCall(T...)(auto ref T args) { return fun(args); }
}

Functor functor()
{
Functor f;
return f;
}
}

unittest
{
static void caller(F)(F fun)
{
fun(42);
}

int result;
caller(functor!((int i) => result = i));
assert(result == 42);
}
Loading

0 comments on commit faeaafa

Please sign in to comment.