cosmetix
[iv.d.git] / alice.d
blob3943ccd2f46052274fc9176c263a10be9b53c01c
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, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module iv.alice;
20 version(aliced) {} else {
22 // ////////////////////////////////////////////////////////////////////////// //
23 static if (!is(typeof(usize))) public alias usize = size_t;
24 static if (!is(typeof(sptrdiff))) public alias sptrdiff = ptrdiff_t;
25 static if (!is(typeof(ssizediff))) public alias ssizediff = ptrdiff_t;
27 static if (!is(typeof(ssize))) {
28 static if (usize.sizeof == 8) public alias ssize = long; //k8
29 else static if (usize.sizeof == 4) public alias ssize = int; //k8
30 else static assert(0, "invalid usize size"); //k8
34 // ////////////////////////////////////////////////////////////////////////// //
35 static if (!is(typeof(NamedExceptionBase))) {
36 mixin template ExceptionCtorMixinTpl() {
37 this (string msg, string file=__FILE__, size_t line=__LINE__, Throwable next=null) @safe pure nothrow @nogc {
38 super(msg, file, line, next);
42 // usage:
43 // mixin(NewExceptionClass!"MyEx");
44 // mixin(NewExceptionClass!("MyEx1", "MyEx"));
45 enum NewExceptionClass(string name, string base="Exception") = `class `~name~` : `~base~` { mixin ExceptionCtorMixinTpl; }`;
48 mixin(NewExceptionClass!("NamedExceptionBase", "Exception"));
49 mixin(NewExceptionClass!("NamedException(string name)", "NamedExceptionBase"));
53 // ////////////////////////////////////////////////////////////////////////// //
54 template Imp(string mod) { mixin("import Imp="~mod~";"); }
55 // usage: auto boo(T)(Imp!"std.datetime".SysTime tm) if (Imp!"std.traits".isCallable!T) { return tm; }
58 // ////////////////////////////////////////////////////////////////////////// //
63 * Named method and struct literal arguments
65 * License:
66 * This Source Code Form is subject to the terms of
67 * the Mozilla Public License, v. 2.0. If a copy of
68 * the MPL was not distributed with this file, You
69 * can obtain one at http://mozilla.org/MPL/2.0/.
71 * Authors:
72 * Vladimir Panteleev <vladimir@thecybershadow.net>
74 //module namedargs /*is aliced*/;
76 //import iv.alice;
77 //import std.traits;
79 // Inspired by
80 // http://forum.dlang.org/post/awjuoemsnmxbfgzhgkgx@forum.dlang.org
82 // Simulates named arguments for function calls.
83 // Accepts arguments as lambdas (name => value) on the template parameter list,
84 // and positional arguments on the runtime parameter list (see examples below).
85 template args(alias fun, dgs...) if (is(typeof(fun) == function)) {
86 auto args(PosArgs...) (auto ref PosArgs posArgs) {
87 import std.traits;
88 ParameterTypeTuple!fun args;
89 enum names = ParameterIdentifierTuple!fun;
91 foreach (immutable i, ref arg; posArgs) args[i] = posArgs[i];
92 foreach (immutable i, immutable arg; ParameterDefaults!fun) {
93 static if (i >= posArgs.length) args[i] = ParameterDefaults!fun[i];
96 // anything works here, but use a custom type to avoid user errors
97 static struct DummyType {}
98 foreach (immutable dg; dgs) {
99 alias fun = dg!DummyType;
100 static if (is(FunctionTypeOf!fun PT == __parameters)) {
101 enum name = __traits(identifier, PT);
102 foreach (immutable i, string argName; names) static if (name == argName) args[i] = fun(DummyType.init);
103 } else {
104 static assert(false, "Failed to extract parameter name from " ~ fun.stringof);
107 return fun(args);
112 version(iv_named_args_test) unittest {
113 static int fun (int a=1, int b=2, int c=3, int d=4, int e=5) {
114 return a+b+c+d+e;
117 assert(args!(fun) == 15);
118 assert(args!(fun, b=>3) == 16);
119 assert(args!(fun, b=>3, d=>3) == 15);
120 { import core.stdc.stdio; printf("named args test 00 complete.\n"); }
123 // Mixing named and positional arguments
124 version(iv_named_args_test) unittest {
125 static int fun(int a, int b=2, int c=3, int d=4, int e=5) {
126 return a+b+c+d+e;
129 assert(args!(fun)(1) == 15);
130 assert(args!(fun, b=>3)(1) == 16);
131 { import core.stdc.stdio; printf("named args test 01 complete.\n"); }
134 // Simulates named arguments for struct literals.
135 template args(S, dgs...) if (is(S == struct)) {
136 @property S args () {
137 import std.traits;
138 S s;
139 // anything works here, but use a custom type to avoid user errors
140 static struct DummyType {}
141 foreach (immutable dg; dgs) {
142 alias fun = dg!DummyType;
143 static if (is(FunctionTypeOf!fun PT == __parameters)) {
144 enum name = __traits(identifier, PT);
145 foreach (immutable i, immutable field; s.tupleof) static if (__traits(identifier, S.tupleof[i]) == name) s.tupleof[i] = fun(DummyType.init);
146 } else {
147 static assert(false, "Failed to extract parameter name from " ~ fun.stringof);
150 return s;
154 version(iv_named_args_test) unittest {
155 static struct S {
156 int a = 1, b = 2, c = 3, d = 4, e = 5;
157 @property int sum () { return a+b+c+d+e; }
160 assert(args!(S).sum == 15);
161 assert(args!(S, b=>3).sum == 16);
162 assert(args!(S, b=>3, d=>3).sum == 15);
164 static assert(!is(typeof(args!(S, b=>b))));
165 { import core.stdc.stdio; printf("named args test 02 complete.\n"); }