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, version 3 of the License ONLY.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // various "metaprogramming" utilities
17 // some of 'em duplicates functionality of `std.traits` and other such
18 // modules, to avoid importing the whole phobos. sorry.
19 module iv
.meta
is aliced
;
22 // ////////////////////////////////////////////////////////////////////////// //
23 /** this is character buffer that can be used to build strings in CTFE.
25 * doing naive string concatenation in CTFE leads to excessive memory
26 * consuming and slowdowns ('cause compiler allocates a new string each
27 * time, and old one stays in memory forever). by using this simple
28 * buffer, we can cut CTFE code generation times and memory consumption
29 * by magnitutes (no, really!).
31 * it is better to create non-resizeable buffers. the easiest (albeit
32 * stupid ;-) way to do that is to increase initial buffer size until
33 * compilation succeeds. sorry, there is no `ctfeWrite()` in Aliced
34 * yet. i'm working on it.
36 public struct CTFECharBuffer(bool allowResize
) {
37 // i see no reason to hide this
41 /// create buffer with the given size
42 this (uint maxsize
) { buf
.length
= maxsize
; }
44 static if (allowResize
) {
45 /// put something into the buffer
46 void put (const(char)[] s
...) nothrow @trusted {
47 if (s
.length
== 0) return;
48 if (buf
.length
-bufpos
< s
.length
) {
50 uint newsz
= cast(uint)(s
.length
-(buf
.length
-bufpos
));
51 if (buf
.length
< 65536) newsz
+= cast(uint)buf
.length
*2; else newsz
+= 65536;
54 assert(buf
.length
-bufpos
>= s
.length
);
55 buf
[bufpos
..bufpos
+s
.length
] = s
[];
56 bufpos
+= cast(uint)s
.length
;
59 /// put something into the buffer
60 void put (const(char)[] s
...) nothrow @trusted @nogc {
61 if (s
.length
== 0) return;
62 if (buf
.length
-bufpos
< s
.length
) assert(0, "out of buffer");
63 buf
[bufpos
..bufpos
+s
.length
] = s
[];
64 bufpos
+= cast(uint)s
.length
;
68 /// put lo-cased ASCII char into the buffer
69 void putLoCased() (char ch
) nothrow @trusted {
70 if (ch
>= 'A' && ch
<= 'Z') ch
+= 32;
74 /// put string with lo-cased first char into the buffer
75 void putStrLoCasedFirst() (const(char)[] s
...) nothrow @trusted {
76 if (s
.length
== 0) return;
81 /// put string into the buffer with all chars lo-cased
82 void putStrLoCased() (const(char)[] s
...) nothrow @trusted {
83 if (s
.length
== 0) return;
84 foreach (char ch
; s
) {
85 if (ch
>= 'A' && ch
<= 'Z') ch
+= 32;
90 /// get buffer as string.
91 /// WARNING! don't modify buffer after this! i won't put any guards here.
92 @property string
asString () const nothrow @trusted @nogc => cast(string
)buf
[0..bufpos
];
96 // ////////////////////////////////////////////////////////////////////////// //
97 /// removes all qualifiers, if any, from type `T`
99 static if (is(T U
== immutable U
)) alias Unqual
= U
;
100 else static if (is(T U
== shared inout const U
)) alias Unqual
= U
;
101 else static if (is(T U
== shared inout U
)) alias Unqual
= U
;
102 else static if (is(T U
== shared const U
)) alias Unqual
= U
;
103 else static if (is(T U
== shared U
)) alias Unqual
= U
;
104 else static if (is(T U
== inout const U
)) alias Unqual
= U
;
105 else static if (is(T U
== inout U
)) alias Unqual
= U
;
106 else static if (is(T U
== const U
)) alias Unqual
= U
;
107 else alias Unqual
= T
;
111 // ////////////////////////////////////////////////////////////////////////// //
112 /// is `T` char, wchar, or dchar? can ignore qualifiers if `unqual` is `true`.
113 template isAnyCharType(T
, bool unqual
=false) {
114 static if (unqual
) private alias UT
= Unqual
!T
; else private alias UT
= T
;
115 enum isAnyCharType
= is(UT
== char) ||
is(UT
== wchar) ||
is(UT
== dchar);
119 // ////////////////////////////////////////////////////////////////////////// //
120 /// is `T` wchar, or dchar? can ignore qualifiers if `unqual` is `true`.
121 template isWideCharType(T
, bool unqual
=false) {
122 static if (unqual
) private alias UT
= Unqual
!T
; else private alias UT
= T
;
123 enum isWideCharType
= is(UT
== wchar) ||
is(UT
== dchar);