1 #!/usr/bin/env rdmd-unittest-module
2 
3 /** Memory Usage.
4     Copyright: Per Nordlöw 2018-.
5     License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
6     Authors: $(WEB Per Nordlöw)
7 */
8 module nxt.memuse;
9 
10 import nxt.csunits;
11 
12 /** Linear One-Dimensional Growth on index of type $(D D) with $(D ElementSize). */
13 struct Linear1D(D, size_t ElementSize) {}
14 
15 /** Quadratic One-Dimensional Growth on index of type $(D D) with $(D ElementSize). */
16 struct Quadratic1D(D, size_t ElementSize) {}
17 
18 /** Get Asymptotic Memory Usage of $(D x) in Bytes.
19  */
20 template UsageOf(T)
21 {
22     import std.range: ElementType;
23     import std.traits: isDynamicArray, hasIndirections, isScalarType;
24     import std.typecons: Nullable;
25 
26     static if (!hasIndirections!T)
27     {
28         enum UsageOf = T.sizeof;
29     }
30     else static if (isDynamicArray!T &&
31                     isScalarType!(ElementType!T))
32     {
33         alias UsageOf = Linear1D!(size_t, ElementType!T.sizeof);
34     }
35     else static if (isDynamicArray!T &&
36                     isDynamicArray!(ElementType!T) &&
37                     isScalarType!(ElementType!(ElementType!T)))
38     {
39         alias UsageOf = Quadratic1D!(size_t, ElementType!T.sizeof);
40     }
41     else
42     {
43         static assert(0, "Type " ~ T.stringof ~ "unsupported.");
44     }
45 
46     /** Maybe Minimum Usage in bytes. */
47     /* size_t min() { return 0; } */
48 
49     /** Maybe Maximum Usage in bytes. */
50     /* Nullable!size_t max() { return 0; } */
51 }
52 
53 @safe pure nothrow @nogc unittest
54 {
55     import std.meta: AliasSeq;
56 
57     foreach (T; AliasSeq!(byte, short, int, long,
58                           ubyte, ushort, uint, ulong, char, wchar, dchar))
59     {
60         static assert(UsageOf!T == T.sizeof);
61     }
62 
63     struct S { int x, y; }
64     static assert(UsageOf!S == S.sizeof);
65 
66     foreach (T; AliasSeq!(byte, short, int, long))
67     {
68         static assert(is(UsageOf!(T[]) ==
69                          Linear1D!(size_t, T.sizeof)));
70     }
71 }