1 module universal.meta;
2 private { /* imports */
3   import std.string;
4   import std.algorithm;
5   import std.range;
6   import std.conv;
7   import std.format;
8 	import std.traits;
9 	import std.typetuple;
10 	import std.typecons;
11 
12   alias splitter = std.algorithm.splitter;
13 }
14 
15 string toPascalCase(string name)
16 {
17 	string nName;
18 
19 	if(name == name.map!toUpper.text)
20 		nName = name.map!toLower.text;
21 	else
22 		nName = name;
23 
24     string capitalizeFirst(string str) 
25     {
26         if(str.length > 0) 
27             return str[0].toUpper.text ~ str[1..$];
28         else 
29             return str;
30     }
31 
32 	if(name.canFind("_"))
33 		return nName.splitter('_').map!capitalizeFirst.join.text;
34 	else 
35 		return capitalizeFirst(nName);
36 }
37 string toCamelCase(string name)
38 {
39   auto pc = name.toPascalCase;
40 
41   if(name == "")
42     return "";
43   else
44     return pc[0].toLower.text ~ pc[1..$];
45 }
46 string indent(string range)
47 {
48   return "\t" ~ range.replace("\n", "\n\t");
49 }
50 
51 enum simpleName(A...) = simpleName!(__traits(identifier, A));
52 enum simpleName(string name) = name.retro.until('.').text.retro.text;
53 
54 enum isString(A...) = is(typeof(A[0]) == string);
55 enum isType  (A...) = is(A[0]);
56 
57 enum isParameterized(A...) 
58 = isCallable!A || __traits(isTemplate, A);
59 
60 alias Instantiate(alias symbol, Args...) = symbol!Args;
61 
62 template Interleave(Symbols...) if(Symbols.length % 2 == 0)
63 {
64 	alias A = Symbols[0..$/2];
65 	alias B = Symbols[$/2..$];
66 
67 	alias Pair(uint i) = TypeTuple!(A[i], B[i]);
68 
69 	alias Interleave = staticMap!(Pair, aliasSeqOf!(A.length.iota));
70 }
71 
72 template DeclSpecs(specs...)
73 {
74   alias names = Filter!(isString, specs);
75   alias Types = Filter!(isType, specs);
76 
77   static if(isString!(specs[0]))
78     alias DeclSpecs = Interleave!(names, Types);
79   else static if(names.length > 0)
80     alias DeclSpecs = Interleave!(Types, names);
81   else
82     alias DeclSpecs = Types;
83 }
84 alias DeclSpecs() = TypeTuple!();
85 
86 auto WIP(string f = __FUNCTION__)() 
87 { return format(q{ assert(0, "unimplemented \"%s\""); }, simpleName!f); }