1 /** Memory Usage.
2 	Copyright: Per Nordlöw 2022-.
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 pure nothrow @safe @nogc unittest {
52 	import std.meta: AliasSeq;
53 
54 	foreach (T; AliasSeq!(byte, short, int, long,
55 						  ubyte, ushort, uint, ulong, char, wchar, dchar))
56 	{
57 		static assert(UsageOf!T == T.sizeof);
58 	}
59 
60 	struct S { int x, y; }
61 	static assert(UsageOf!S == S.sizeof);
62 
63 	foreach (T; AliasSeq!(byte, short, int, long))
64 	{
65 		static assert(is(UsageOf!(T[]) ==
66 						 Linear1D!(size_t, T.sizeof)));
67 	}
68 }