1 /** Computer Science Units. 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.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 { 39 alias _value this; 40 41 inout(T) value() @property inout @safe pure nothrow { return _value; } 42 43 /** 44 See_Also: http://searchstorage.techtarget.com/definition/Kilo-mega-giga-tera-peta-and-all-that 45 See_Also: https://en.wikipedia.org/wiki/Exabyte 46 */ 47 string toString(bool inBits = false) const @property @trusted /* pure nothrow */ 48 { 49 // import core.internal.traits : Unqual; 50 51 string name = void; 52 T val = void; 53 if (inBits) 54 { 55 name = "Bits"; // Unqual!(typeof(this)).stringof; // Unqual: "const(Bytes)" => "Bytes" 56 val = 8*_value; 57 } 58 else 59 { 60 name = "Bytes"; // Unqual!(typeof(this)).stringof; // Unqual: "const(Bytes)" => "Bytes" 61 val = _value; 62 } 63 64 import std.conv : to; 65 if (val < 1024^^1) { return to!string(val) ~ " " ~ name; } 66 else if (val < 1024^^2) { return to!string(cast(real)val / 1024^^1) ~ " kilo" ~ name; } 67 else if (val < 1024^^3) { return to!string(cast(real)val / 1024^^2) ~ " Mega" ~ name; } 68 else if (val < 1024^^4) { return to!string(cast(real)val / 1024^^3) ~ " Giga" ~ name; } 69 else if (val < 1024^^5) { return to!string(cast(real)val / 1024^^4) ~ " Tera" ~ name; } 70 else if (val < 1024^^6) { return to!string(cast(real)val / 1024^^5) ~ " Peta" ~ name; } 71 else if (val < 1024^^7) { return to!string(cast(real)val / 1024^^6) ~ " Exa" ~ name; } 72 else if (val < 1024^^8) { return to!string(cast(real)val / 1024^^7) ~ " Zetta" ~ name; } 73 else /* if (val < 1024^^9) */ { return to!string(cast(real)val / 1024^^8) ~ " Yotta" ~ name; 74 /* } else { */ 75 /* return to!string(val) ~ " " ~ name; */ 76 } 77 } 78 79 T opUnary(string op, string file = __FILE__, int line = __LINE__)() 80 { 81 T tmp = void; mixin("tmp = " ~ op ~ " _value;"); return tmp; 82 } 83 84 T opBinary(string op, string file = __FILE__, int line = __LINE__)(T rhs) 85 { 86 T tmp = void; mixin("tmp = _value " ~ op ~ "rhs;"); return tmp; 87 } 88 89 T opOpAssign(string op, string file = __FILE__, int line = __LINE__)(T rhs) 90 { 91 mixin("_value = _value " ~ op ~ "rhs;"); return _value; 92 } 93 94 T opAssign(T rhs, string file = __FILE__, int line = __LINE__) 95 { 96 return _value = rhs; 97 } 98 99 /* private: */ 100 T _value; 101 } 102 103 /** $(D Bytes) Instantiator. */ 104 auto bytes(T)(T value) { return Bytes!T(value); } 105 106 @safe pure nothrow @nogc unittest 107 { 108 immutable a = bytes(1); 109 immutable b = bytes(1); 110 immutable c = a + b; 111 assert(c == 2); 112 assert(1.bytes == 1); 113 } 114 115 auto inPercent (T)(T a) { return to!string(a * 1e2) ~ " \u0025"; } 116 auto inPerMille (T)(T a) { return to!string(a * 1e3) ~ " \u2030"; } 117 auto inPerTenThousand(T)(T a) { return to!string(a * 1e4) ~ " \u2031"; } 118 auto inDegrees (T)(T a) { return to!string(a ) ~ " \u00B0"; }