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