Line data Source code
1 : /** @file basis_unit_abbrev.hpp 2 : * 3 : * Author: Roland Conybeare 4 : **/ 5 : 6 : #pragma once 7 : 8 : #include "native_unit.hpp" 9 : #include "xo/ratio/ratio.hpp" 10 : //#include <cstdint> 11 : 12 : namespace xo { 13 : namespace qty { 14 : using basis_unit2_abbrev_type = flatstring<16>; 15 : using scalefactor_ratio_type = xo::ratio::ratio<std::int64_t>; 16 : 17 : namespace abbrev { 18 : static 19 : constexpr basis_unit2_abbrev_type 20 0 : fallback_unit_abbrev(const scalefactor_ratio_type & scalefactor, 21 : dim native_dim) 22 : { 23 : /* e.g. unit of '1000 grams' will have abbrev '1000g' in absence 24 : * of a specialization for scaled_native_unit_abbrev 25 : */ 26 0 : return (basis_unit2_abbrev_type::from_flatstring 27 0 : (flatstring_concat 28 0 : (scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(), 29 0 : native_unit2_v[static_cast<std::uint32_t>(native_dim)].abbrev_str()))); 30 : } 31 : 32 : // ----- units for dim::mass ----- 33 : 34 : static 35 : constexpr basis_unit2_abbrev_type 36 28 : mass_unit2_abbrev(const scalefactor_ratio_type & scalefactor) 37 : { 38 28 : if (scalefactor.num() == 1) { 39 10 : switch (scalefactor.den()) { 40 2 : case 1: 41 2 : return basis_unit2_abbrev_type::from_chars("g"); 42 3 : case 1000: 43 3 : return basis_unit2_abbrev_type::from_chars("mg"); 44 2 : case 1000000: 45 2 : return basis_unit2_abbrev_type::from_chars("ug"); 46 2 : case 1000000000: 47 2 : return basis_unit2_abbrev_type::from_chars("ng"); 48 1 : case 1000000000000: 49 1 : return basis_unit2_abbrev_type::from_chars("pg"); 50 : } 51 : } 52 : 53 18 : if (scalefactor.den() == 1) { 54 18 : switch (scalefactor.num()) { 55 13 : case 1000: 56 13 : return basis_unit2_abbrev_type::from_chars("kg"); 57 2 : case 1000000: 58 2 : return basis_unit2_abbrev_type::from_chars("t"); 59 2 : case 1000000000: 60 2 : return basis_unit2_abbrev_type::from_chars("kt"); 61 1 : case 1000000000000: 62 1 : return basis_unit2_abbrev_type::from_chars("Mt"); 63 : } 64 : } 65 : 66 0 : return fallback_unit_abbrev(scalefactor, dim::mass); 67 : } 68 : 69 : // ----- units for dim::distance ----- 70 : 71 : static 72 : constexpr basis_unit2_abbrev_type 73 26 : distance_unit2_abbrev(const scalefactor_ratio_type & scalefactor) 74 : { 75 26 : if (scalefactor.num() == 1) { 76 19 : switch (scalefactor.den()) { 77 11 : case 1: 78 11 : return basis_unit2_abbrev_type::from_chars("m"); 79 3 : case 1000: 80 3 : return basis_unit2_abbrev_type::from_chars("mm"); 81 2 : case 1000000: 82 2 : return basis_unit2_abbrev_type::from_chars("um"); 83 2 : case 1000000000: 84 2 : return basis_unit2_abbrev_type::from_chars("nm"); 85 1 : case 1000000000000: 86 1 : return basis_unit2_abbrev_type::from_chars("pm"); 87 : } 88 : } 89 : 90 7 : if (scalefactor.den() == 1) { 91 7 : switch (scalefactor.num()) { 92 3 : case 1000: 93 3 : return basis_unit2_abbrev_type::from_chars("km"); 94 1 : case 1000000: 95 1 : return basis_unit2_abbrev_type::from_chars("Mm"); 96 1 : case 299792458: 97 1 : return basis_unit2_abbrev_type::from_chars("lsec"); 98 1 : case 1000000000: 99 1 : return basis_unit2_abbrev_type::from_chars("Gm"); 100 1 : case 149597870700: 101 1 : return basis_unit2_abbrev_type::from_chars("AU"); 102 : } 103 : } 104 : 105 0 : return fallback_unit_abbrev(scalefactor, dim::distance); 106 : } 107 : 108 : // ----- units for dim::time ----- 109 : 110 : static 111 : constexpr basis_unit2_abbrev_type 112 31 : time_unit2_abbrev(const scalefactor_ratio_type & scalefactor) 113 : { 114 31 : if (scalefactor.num() == 1) { 115 16 : switch (scalefactor.den()) { 116 9 : case 1: 117 9 : return basis_unit2_abbrev_type::from_chars("s"); 118 2 : case 1000: 119 2 : return basis_unit2_abbrev_type::from_chars("ms"); 120 2 : case 1000000: 121 2 : return basis_unit2_abbrev_type::from_chars("us"); 122 2 : case 1000000000: 123 2 : return basis_unit2_abbrev_type::from_chars("ns"); 124 1 : case 1000000000000: 125 1 : return basis_unit2_abbrev_type::from_chars("ps"); 126 : } 127 : } 128 : 129 15 : if (scalefactor.den() == 1) { 130 15 : switch (scalefactor.num()) { 131 2 : case 60: 132 2 : return basis_unit2_abbrev_type::from_chars("min"); 133 2 : case 3600: 134 2 : return basis_unit2_abbrev_type::from_chars("hr"); 135 2 : case 24*3600: 136 2 : return basis_unit2_abbrev_type::from_chars("dy"); 137 1 : case 7*24*3600: 138 1 : return basis_unit2_abbrev_type::from_chars("wk"); 139 1 : case 30*24*3600: 140 1 : return basis_unit2_abbrev_type::from_chars("mo"); 141 2 : case 250*24*3600: 142 2 : return basis_unit2_abbrev_type::from_chars("yr250"); 143 2 : case 360*24*3600: 144 2 : return basis_unit2_abbrev_type::from_chars("yr360"); 145 2 : case 365*24*3600: 146 2 : return basis_unit2_abbrev_type::from_chars("yr365"); 147 1 : case 365*24*3600+6*3600: 148 1 : return basis_unit2_abbrev_type::from_chars("yr"); 149 : } 150 : } 151 : 152 0 : return fallback_unit_abbrev(scalefactor, dim::time); 153 : } 154 : 155 : // ----- units for dim::currency ----- 156 : 157 : static constexpr basis_unit2_abbrev_type 158 3 : currency_unit2_abbrev(const scalefactor_ratio_type & scalefactor) 159 : { 160 3 : if (scalefactor.num() == 1) { 161 3 : switch(scalefactor.den()) { 162 3 : case 1: 163 3 : return basis_unit2_abbrev_type::from_chars("ccy"); 164 : } 165 : } 166 : 167 0 : return fallback_unit_abbrev(scalefactor, dim::currency); 168 : } 169 : 170 : // ----- units for dim::price ----- 171 : 172 : static constexpr basis_unit2_abbrev_type 173 3 : price_unit2_abbrev(const scalefactor_ratio_type & scalefactor) 174 : { 175 3 : if (scalefactor.num() == 1) { 176 3 : switch(scalefactor.den()) { 177 3 : case 1: 178 3 : return basis_unit2_abbrev_type::from_chars("px"); 179 : } 180 : } 181 : 182 0 : return fallback_unit_abbrev(scalefactor, dim::price); 183 : } 184 : 185 : // ----- basis_unit2_abbrev ----- 186 : 187 : static 188 : constexpr basis_unit2_abbrev_type 189 91 : basis_unit2_abbrev(dim native_dim, 190 : const scalefactor_ratio_type & scalefactor) 191 : { 192 62 : switch(native_dim) { 193 28 : case dim::mass: 194 28 : return mass_unit2_abbrev(scalefactor); 195 26 : case dim::distance: 196 26 : return distance_unit2_abbrev(scalefactor); 197 31 : case dim::time: 198 31 : return time_unit2_abbrev(scalefactor); 199 3 : case dim::currency: 200 3 : return currency_unit2_abbrev(scalefactor); 201 3 : case dim::price: 202 3 : return price_unit2_abbrev(scalefactor); 203 0 : case dim::invalid: 204 0 : case dim::n_dim: 205 0 : return basis_unit2_abbrev_type(); 206 0 : break; 207 : } 208 : 209 : /* unreachable (for well-constructed dim instances) */ 210 : 211 0 : return basis_unit2_abbrev_type(); 212 : } 213 : } /*namespace abbrev*/ 214 : } /*namespace qty*/ 215 : } /*namespace xo*/ 216 : 217 : 218 : /** end basis_unit_abbrev.hpp **/