1 /** Computer Science Units. 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.csunits; 7 8 /** Prefix Multipliers. 9 See_Also: http://searchstorage.techtarget.com/definition/Kilo-mega-giga-tera-peta-and-all-that 10 */ 11 enum PrefixMultipliers 12 { 13 yocto = -24, // y 14 zepto = -21, // z 15 atto = -18, // a 16 femto = -15, // f 17 pico = -12, // p 18 nano = -9, // n 19 micro = -6, // m 20 milli = -3, // m 21 centi = -2, // c 22 deci = -1, // d 23 none = 0, 24 deka = 1, // D 25 hecto = 2, // h 26 kilo = 3, // k 27 mega = 6, // M 28 giga = 9, // G 29 tera = 12, // T 30 peta = 15, // P 31 exa = 18, // E 32 zetta = 21, // Z 33 yotta = 24, // Y 34 } 35 36 /** Bytes (Count) Unit. */ 37 struct Bytes(T: ulong) { 38 alias _value this; 39 40 inout(T) value() @property inout @safe pure nothrow => _value; 41 42 /** 43 See_Also: http://searchstorage.techtarget.com/definition/Kilo-mega-giga-tera-peta-and-all-that 44 See_Also: https://en.wikipedia.org/wiki/Exabyte 45 */ 46 string toString(bool inBits = false) const @property @trusted /* pure nothrow */ 47 { 48 // import core.internal.traits : Unqual; 49 50 string name = void; 51 T val = void; 52 if (inBits) { 53 name = "Bits"; // Unqual!(typeof(this)).stringof; // Unqual: "const(Bytes)" => "Bytes" 54 val = 8*_value; 55 } 56 else 57 { 58 name = "Bytes"; // Unqual!(typeof(this)).stringof; // Unqual: "const(Bytes)" => "Bytes" 59 val = _value; 60 } 61 62 import std.conv : to; 63 if (val < 1024^^1) { return to!string(val) ~ " " ~ name; } 64 else if (val < 1024^^2) { return to!string(cast(real)val / 1024^^1) ~ " kilo" ~ name; } 65 else if (val < 1024^^3) { return to!string(cast(real)val / 1024^^2) ~ " Mega" ~ name; } 66 else if (val < 1024^^4) { return to!string(cast(real)val / 1024^^3) ~ " Giga" ~ name; } 67 else if (val < 1024^^5) { return to!string(cast(real)val / 1024^^4) ~ " Tera" ~ name; } 68 else if (val < 1024^^6) { return to!string(cast(real)val / 1024^^5) ~ " Peta" ~ name; } 69 else if (val < 1024^^7) { return to!string(cast(real)val / 1024^^6) ~ " Exa" ~ name; } 70 else if (val < 1024^^8) { return to!string(cast(real)val / 1024^^7) ~ " Zetta" ~ name; } 71 else /* if (val < 1024^^9) */ { return to!string(cast(real)val / 1024^^8) ~ " Yotta" ~ name; 72 /* } else { */ 73 /* return to!string(val) ~ " " ~ name; */ 74 } 75 } 76 77 T opUnary(string op, string file = __FILE__, int line = __LINE__)() { 78 T tmp = void; mixin("tmp = " ~ op ~ " _value;"); return tmp; 79 } 80 81 T opBinary(string op, string file = __FILE__, int line = __LINE__)(T rhs) { 82 T tmp = void; mixin("tmp = _value " ~ op ~ "rhs;"); return tmp; 83 } 84 85 T opOpAssign(string op, string file = __FILE__, int line = __LINE__)(T rhs) { 86 mixin("_value = _value " ~ op ~ "rhs;"); return _value; 87 } 88 89 T opAssign(T rhs, string file = __FILE__, int line = __LINE__) { 90 return _value = rhs; 91 } 92 93 /* private: */ 94 T _value; 95 } 96 97 /** $(D Bytes) Instantiator. */ 98 auto bytes(T)(T value) => Bytes!T(value); 99 100 pure nothrow @safe @nogc unittest { 101 immutable a = bytes(1); 102 immutable b = bytes(1); 103 immutable c = a + b; 104 assert(c == 2); 105 assert(1.bytes == 1); 106 } 107 108 auto inPercent (T)(T a) => to!string(a * 1e2) ~ " \u0025"; 109 auto inPerMille (T)(T a) => to!string(a * 1e3) ~ " \u2030"; 110 auto inPerTenThousand(T)(T a) => to!string(a * 1e4) ~ " \u2031"; 111 auto inDegrees (T)(T a) => to!string(a ) ~ " \u00B0";