egra: don't use ENTER/LEAVE (because intel sux, and they are slower than the correspo...
[iv.d.git] / alice.d
blob564b93a040dbdcdd10ec7ab09c1e53e4f1243c45
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module iv.alice;
19 version(aliced) {} else {
21 // ////////////////////////////////////////////////////////////////////////// //
22 static if (!is(typeof(usize))) public alias usize = size_t;
23 static if (!is(typeof(sptrdiff))) public alias sptrdiff = ptrdiff_t;
24 static if (!is(typeof(ssizediff))) public alias ssizediff = ptrdiff_t;
26 static if (!is(typeof(ssize))) {
27 static if (usize.sizeof == 8) public alias ssize = long; //k8
28 else static if (usize.sizeof == 4) public alias ssize = int; //k8
29 else static assert(0, "invalid usize size"); //k8
33 // ////////////////////////////////////////////////////////////////////////// //
34 static if (!is(typeof(NamedExceptionBase))) {
35 mixin template ExceptionCtorMixinTpl() {
36 this (string msg, string file=__FILE__, size_t line=__LINE__, Throwable next=null) @safe pure nothrow @nogc {
37 super(msg, file, line, next);
41 // usage:
42 // mixin(NewExceptionClass!"MyEx");
43 // mixin(NewExceptionClass!("MyEx1", "MyEx"));
44 enum NewExceptionClass(string name, string base="Exception") = `class `~name~` : `~base~` { mixin ExceptionCtorMixinTpl; }`;
47 mixin(NewExceptionClass!("NamedExceptionBase", "Exception"));
48 mixin(NewExceptionClass!("NamedException(string name)", "NamedExceptionBase"));
52 // ////////////////////////////////////////////////////////////////////////// //
53 template Imp(string mod) { mixin("import Imp="~mod~";"); }
54 // usage: auto boo(T)(Imp!"std.datetime".SysTime tm) if (Imp!"std.traits".isCallable!T) { return tm; }
57 // ////////////////////////////////////////////////////////////////////////// //
62 * Named method and struct literal arguments
64 * License:
65 * This Source Code Form is subject to the terms of
66 * the Mozilla Public License, v. 2.0. If a copy of
67 * the MPL was not distributed with this file, You
68 * can obtain one at http://mozilla.org/MPL/2.0/.
70 * Authors:
71 * Vladimir Panteleev <vladimir@thecybershadow.net>
73 //module namedargs /*is aliced*/;
75 //import iv.alice;
76 //import std.traits;
78 // Inspired by
79 // http://forum.dlang.org/post/awjuoemsnmxbfgzhgkgx@forum.dlang.org
81 // Simulates named arguments for function calls.
82 // Accepts arguments as lambdas (name => value) on the template parameter list,
83 // and positional arguments on the runtime parameter list (see examples below).
84 template args(alias fun, dgs...) if (is(typeof(fun) == function)) {
85 auto args(PosArgs...) (auto ref PosArgs posArgs) {
86 import std.traits;
87 ParameterTypeTuple!fun args;
88 enum names = ParameterIdentifierTuple!fun;
90 foreach (immutable i, ref arg; posArgs) args[i] = posArgs[i];
91 foreach (immutable i, immutable arg; ParameterDefaults!fun) {
92 static if (i >= posArgs.length) args[i] = ParameterDefaults!fun[i];
95 // anything works here, but use a custom type to avoid user errors
96 static struct DummyType {}
97 foreach (immutable dg; dgs) {
98 alias fun = dg!DummyType;
99 static if (is(FunctionTypeOf!fun PT == __parameters)) {
100 enum name = __traits(identifier, PT);
101 foreach (immutable i, string argName; names) static if (name == argName) args[i] = fun(DummyType.init);
102 } else {
103 static assert(false, "Failed to extract parameter name from " ~ fun.stringof);
106 return fun(args);
111 version(iv_named_args_test) unittest {
112 static int fun (int a=1, int b=2, int c=3, int d=4, int e=5) {
113 return a+b+c+d+e;
116 assert(args!(fun) == 15);
117 assert(args!(fun, b=>3) == 16);
118 assert(args!(fun, b=>3, d=>3) == 15);
119 { import core.stdc.stdio; printf("named args test 00 complete.\n"); }
122 // Mixing named and positional arguments
123 version(iv_named_args_test) unittest {
124 static int fun(int a, int b=2, int c=3, int d=4, int e=5) {
125 return a+b+c+d+e;
128 assert(args!(fun)(1) == 15);
129 assert(args!(fun, b=>3)(1) == 16);
130 { import core.stdc.stdio; printf("named args test 01 complete.\n"); }
133 // Simulates named arguments for struct literals.
134 template args(S, dgs...) if (is(S == struct)) {
135 @property S args () {
136 import std.traits;
137 S s;
138 // anything works here, but use a custom type to avoid user errors
139 static struct DummyType {}
140 foreach (immutable dg; dgs) {
141 alias fun = dg!DummyType;
142 static if (is(FunctionTypeOf!fun PT == __parameters)) {
143 enum name = __traits(identifier, PT);
144 foreach (immutable i, immutable field; s.tupleof) static if (__traits(identifier, S.tupleof[i]) == name) s.tupleof[i] = fun(DummyType.init);
145 } else {
146 static assert(false, "Failed to extract parameter name from " ~ fun.stringof);
149 return s;
153 version(iv_named_args_test) unittest {
154 static struct S {
155 int a = 1, b = 2, c = 3, d = 4, e = 5;
156 @property int sum () { return a+b+c+d+e; }
159 assert(args!(S).sum == 15);
160 assert(args!(S, b=>3).sum == 16);
161 assert(args!(S, b=>3, d=>3).sum == 15);
163 static assert(!is(typeof(args!(S, b=>b))));
164 { import core.stdc.stdio; printf("named args test 02 complete.\n"); }