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 yocto = -24, // y 13 zepto = -21, // z 14 atto = -18, // a 15 femto = -15, // f 16 pico = -12, // p 17 nano = -9, // n 18 micro = -6, // m 19 milli = -3, // m 20 centi = -2, // c 21 deci = -1, // d 22 none = 0, 23 deka = 1, // D 24 hecto = 2, // h 25 kilo = 3, // k 26 mega = 6, // M 27 giga = 9, // G 28 tera = 12, // T 29 peta = 15, // P 30 exa = 18, // E 31 zetta = 21, // Z 32 yotta = 24, // Y 33 } 34 35 /** Bytes (Count) Unit. */ 36 struct Bytes { 37 alias T = size_t; 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 } else { 56 name = "Bytes"; // Unqual!(typeof(this)).stringof; // Unqual: "const(Bytes)" => "Bytes" 57 val = _value; 58 } 59 60 import std.conv : to; 61 if (val < 1024^^1) { return to!string(val) ~ " " ~ name; } 62 else if (val < 1024^^2) { return to!string(cast(real)val / 1024^^1) ~ " kilo" ~ name; } 63 else if (val < 1024^^3) { return to!string(cast(real)val / 1024^^2) ~ " Mega" ~ name; } 64 else if (val < 1024^^4) { return to!string(cast(real)val / 1024^^3) ~ " Giga" ~ name; } 65 else if (val < 1024^^5) { return to!string(cast(real)val / 1024^^4) ~ " Tera" ~ name; } 66 else if (val < 1024^^6) { return to!string(cast(real)val / 1024^^5) ~ " Peta" ~ name; } 67 else if (val < 1024^^7) { return to!string(cast(real)val / 1024^^6) ~ " Exa" ~ name; } 68 else if (val < 1024^^8) { return to!string(cast(real)val / 1024^^7) ~ " Zetta" ~ name; } 69 else /* if (val < 1024^^9) */ { return to!string(cast(real)val / 1024^^8) ~ " Yotta" ~ name; 70 /* } else { */ 71 /* return to!string(val) ~ " " ~ name; */ 72 } 73 } 74 75 T opUnary(string op, string file = __FILE__, int line = __LINE__)() { 76 T tmp = void; mixin("tmp = " ~ op ~ " _value;"); return tmp; 77 } 78 79 T opBinary(string op, string file = __FILE__, int line = __LINE__)(T rhs) { 80 T tmp = void; mixin("tmp = _value " ~ op ~ "rhs;"); return tmp; 81 } 82 83 T opOpAssign(string op, string file = __FILE__, int line = __LINE__)(T rhs) { 84 mixin("_value = _value " ~ op ~ "rhs;"); return _value; 85 } 86 87 T opAssign(T rhs) { 88 return _value = rhs; 89 } 90 91 private T _value; 92 } 93 94 /** $(D Bytes) Instantiator. */ 95 auto bytes(size_t value) => Bytes(value); 96 97 /// 98 pure nothrow @safe @nogc unittest { 99 immutable a = bytes(1); 100 immutable b = bytes(1); 101 immutable c = a + b; 102 assert(c == 2); 103 assert(1.bytes == 1); 104 } 105 106 auto inPercent (T)(T a) => to!string(a * 1e2) ~ " \u0025"; 107 auto inPerMille (T)(T a) => to!string(a * 1e3) ~ " \u2030"; 108 auto inPerTenThousand(T)(T a) => to!string(a * 1e4) ~ " \u2031"; 109 auto inDegrees (T)(T a) => to!string(a ) ~ " \u00B0";