iv.nanovega.textlayouter: more API!
[iv.d.git] / meta.d
blob4a62398f344cb7526620f58819ff6bb46e9fb6b5
1 /* coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
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 // various "metaprogramming" utilities
18 // some of 'em duplicates functionality of `std.traits` and other such
19 // modules, to avoid importing the whole phobos. sorry.
20 module iv.meta is aliced;
23 // ////////////////////////////////////////////////////////////////////////// //
24 /** this is character buffer that can be used to build strings in CTFE.
26 * doing naive string concatenation in CTFE leads to excessive memory
27 * consuming and slowdowns ('cause compiler allocates a new string each
28 * time, and old one stays in memory forever). by using this simple
29 * buffer, we can cut CTFE code generation times and memory consumption
30 * by magnitutes (no, really!).
32 * it is better to create non-resizeable buffers. the easiest (albeit
33 * stupid ;-) way to do that is to increase initial buffer size until
34 * compilation succeeds. sorry, there is no `ctfeWrite()` in Aliced
35 * yet. i'm working on it.
37 public struct CTFECharBuffer(bool allowResize) {
38 // i see no reason to hide this
39 char[] buf;
40 uint bufpos = 0;
42 /// create buffer with the given size
43 this (uint maxsize) { buf.length = maxsize; }
45 static if (allowResize) {
46 /// put something into the buffer
47 void put (const(char)[] s...) nothrow @trusted {
48 if (s.length == 0) return;
49 if (buf.length-bufpos < s.length) {
50 //FIXME: overflows
51 uint newsz = cast(uint)(s.length-(buf.length-bufpos));
52 if (buf.length < 65536) newsz += cast(uint)buf.length*2; else newsz += 65536;
53 buf.length = newsz;
55 assert(buf.length-bufpos >= s.length);
56 buf[bufpos..bufpos+s.length] = s[];
57 bufpos += cast(uint)s.length;
59 } else {
60 /// put something into the buffer
61 void put (const(char)[] s...) nothrow @trusted @nogc {
62 if (s.length == 0) return;
63 if (buf.length-bufpos < s.length) assert(0, "out of buffer");
64 buf[bufpos..bufpos+s.length] = s[];
65 bufpos += cast(uint)s.length;
69 /// put lo-cased ASCII char into the buffer
70 void putLoCased() (char ch) nothrow @trusted {
71 if (ch >= 'A' && ch <= 'Z') ch += 32;
72 put(ch);
75 /// put string with lo-cased first char into the buffer
76 void putStrLoCasedFirst() (const(char)[] s...) nothrow @trusted {
77 if (s.length == 0) return;
78 putLoCased(s[0]);
79 put(s[1..$]);
82 /// put string into the buffer with all chars lo-cased
83 void putStrLoCased() (const(char)[] s...) nothrow @trusted {
84 if (s.length == 0) return;
85 foreach (char ch; s) {
86 if (ch >= 'A' && ch <= 'Z') ch += 32;
87 put(ch);
91 /// get buffer as string.
92 /// WARNING! don't modify buffer after this! i won't put any guards here.
93 @property string asString () const nothrow @trusted @nogc => cast(string)buf[0..bufpos];
97 // ////////////////////////////////////////////////////////////////////////// //
98 /// removes all qualifiers, if any, from type `T`
99 template Unqual(T) {
100 static if (is(T U == immutable U)) alias Unqual = U;
101 else static if (is(T U == shared inout const U)) alias Unqual = U;
102 else static if (is(T U == shared inout U)) alias Unqual = U;
103 else static if (is(T U == shared const U)) alias Unqual = U;
104 else static if (is(T U == shared U)) alias Unqual = U;
105 else static if (is(T U == inout const U)) alias Unqual = U;
106 else static if (is(T U == inout U)) alias Unqual = U;
107 else static if (is(T U == const U)) alias Unqual = U;
108 else alias Unqual = T;
112 // ////////////////////////////////////////////////////////////////////////// //
113 /// is `T` char, wchar, or dchar? can ignore qualifiers if `unqual` is `true`.
114 template isAnyCharType(T, bool unqual=false) {
115 static if (unqual) private alias UT = Unqual!T; else private alias UT = T;
116 enum isAnyCharType = is(UT == char) || is(UT == wchar) || is(UT == dchar);
120 // ////////////////////////////////////////////////////////////////////////// //
121 /// is `T` wchar, or dchar? can ignore qualifiers if `unqual` is `true`.
122 template isWideCharType(T, bool unqual=false) {
123 static if (unqual) private alias UT = Unqual!T; else private alias UT = T;
124 enum isWideCharType = is(UT == wchar) || is(UT == dchar);