examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

dimensions.cpp (4779B)


      1 #include <iostream>
      2 
      3 namespace system_of_units {
      4 
      5 struct dimensions
      6 {
      7 	static constexpr unsigned extent = 3;
      8 	int ds[extent] = {0,0,0};
      9 
     10 	constexpr dimensions operator *(dimensions rhs) const
     11 	{
     12 		dimensions res;
     13 		for (unsigned i = 0; i < extent; ++i)
     14 			res.ds[i] = ds[i] + rhs.ds[i];
     15 		return res;
     16 	}
     17 	constexpr dimensions operator /(dimensions rhs) const
     18 	{
     19 		dimensions res;
     20 		for (unsigned i = 0; i < extent; ++i)
     21 			res.ds[i] = ds[i] - rhs.ds[i];
     22 		return res;
     23 	}
     24 	constexpr dimensions operator ()(int power) const
     25 	{
     26 		dimensions res;
     27 		for (unsigned i = 0; i < extent; ++i)
     28 			res.ds[i] = ds[i] * power;
     29 		return res;
     30 	}
     31 };
     32 
     33 template <dimensions Us>
     34 struct unit
     35 {
     36 	long double v;
     37 
     38 	unit operator +(unit rhs) { return {v + rhs.v}; }
     39 	unit operator -(unit rhs) { return {v - rhs.v}; }
     40 
     41 	template <dimensions U2>
     42 	unit<Us*U2> operator *(unit<U2> rhs) { return {v * rhs.v}; }
     43 	template <dimensions U2>
     44 	unit<Us/U2> operator /(unit<U2> rhs) { return {v / rhs.v}; }
     45 };
     46 
     47 constexpr dimensions second{1,0,0};
     48 constexpr dimensions meter{0,1,0};
     49 constexpr dimensions kilogram{0,0,1};
     50 
     51 using dimensionless = unit<dimensions{}>;
     52 using time = unit<second>;
     53 using length = unit<meter>;
     54 using mass = unit<kilogram>;
     55 using frequency = unit<second(-1)>;
     56 using velocity = unit<meter/second>;
     57 using acceleration = unit<meter/second(2)>;
     58 using energy = unit<kilogram*meter(2)/second(2)>;
     59 using power = unit<kilogram*meter(2)/second(3)>;
     60 
     61 template <dimensions Us>
     62 std::ostream& operator <<(std::ostream& out, unit<Us> u)
     63 {
     64 	using U = decltype(u);
     65 
     66 	auto scale = abs(u.v);
     67 
     68 	if constexpr (std::is_same_v<U, dimensionless>)
     69 	{
     70 		if (scale < 2)
     71 			return out << u.v*100 << '%';
     72 		else
     73 			return out << u.v;
     74 	}
     75 	if constexpr (std::is_same_v<U, time>)
     76 	{
     77 		if (scale < 1)
     78 			return out << u.v*1000 << "ms";
     79 		else if (scale < 60)
     80 			return out << u.v << "s";
     81 		else if (scale < 3600)
     82 			return out << u.v/60 << "min";
     83 		else if (scale < 86400)
     84 			return out << u.v/3600 << "hour";
     85 		else
     86 			return out << u.v/86400 << "days";
     87 	}
     88 	if constexpr (std::is_same_v<U, mass>)
     89 	{
     90 		if (scale < 1)
     91 			return out << u.v << "g";
     92 		else if (scale < 1000)
     93 			return out << u.v << "kg";
     94 		else
     95 			return out << u.v/1000 << "t";
     96 	}
     97 
     98 	if (scale < 1)
     99 		out << u.v*1000 << 'm';
    100 	else if (scale < 1000)
    101 		out << u.v;
    102 	else if (scale < 1'000'000)
    103 		out << u.v/1000 << 'k';
    104 	else
    105 		out << u.v/1'000'000 << 'M';
    106 
    107 	if constexpr (std::is_same_v<U, length>)
    108 		return out << 'm';
    109 	if constexpr (std::is_same_v<U, frequency>)
    110 		return out << "Hz";
    111 	if constexpr (std::is_same_v<U, velocity>)
    112 		return out << "m/s";
    113 	if constexpr (std::is_same_v<U, acceleration>)
    114 		return out << "m/s²";
    115 	if constexpr (std::is_same_v<U, energy>)
    116 		return out << "J";
    117 	if constexpr (std::is_same_v<U, power>)
    118 		return out << "W";
    119 
    120 	out << '[';
    121 	for (auto d : Us.ds)
    122 		out << ' ' << d;
    123 
    124 	return out << " ]?";
    125 }
    126 
    127 dimensionless operator ""_mu(long double v) { return {v}; }
    128 time operator ""_s(long double v) { return {v}; }
    129 time operator ""_min(long double v) { return {v*60}; }
    130 time operator ""_hour(long double v) { return {v*3600}; }
    131 length operator ""_m(long double v) { return {v}; }
    132 length operator ""_km(long double v) { return {v*1000}; }
    133 length operator ""_mile(long double v) { return {v*1609.344}; }
    134 mass operator ""_kg(long double v) { return {v}; }
    135 mass operator ""_t(long double v) { return {v * 1000}; }
    136 frequency operator ""_Hz(long double v) { return {v}; }
    137 frequency operator ""_kHz(long double v) { return {v*1000}; }
    138 velocity operator ""_mps(long double v) { return {v}; }
    139 velocity operator ""_kmph(long double v) { return {v/3.6}; }
    140 velocity operator ""_mph(long double v) { return {v * 1609.344 / 3600}; }
    141 acceleration operator ""_mpsps(long double v) { return {v}; }
    142 energy operator ""_J(long double v) { return {v}; }
    143 energy operator ""_kJ(long double v) { return {v*1000}; }
    144 energy operator ""_MJ(long double v) { return {v*1'000'000}; }
    145 power operator ""_W(long double v) { return {v}; }
    146 power operator ""_kW(long double v) { return {v*1000}; }
    147 
    148 } // namespace system_of_units
    149 
    150 int main()
    151 {
    152 	using namespace system_of_units;
    153 	using std::cout, std::endl;
    154 
    155 	cout << 1._mu << endl;
    156 	cout << 1._s << endl;
    157 	cout << 1._min << endl;
    158 	cout << 1._hour << endl;
    159 	cout << 1._m << endl;
    160 	cout << 1._km << endl;
    161 	cout << 1._mile << endl;
    162 	cout << 1._kg << endl;
    163 	cout << 1._t << endl;
    164 	cout << 1._Hz << endl;
    165 	cout << 1._kHz << endl;
    166 	cout << 1._mps << endl;
    167 	cout << 1._kmph << endl;
    168 	cout << 1._mph << endl;
    169 	cout << 1._mpsps << endl;
    170 	cout << 1._J << endl;
    171 	cout << 1._kJ << endl;
    172 	cout << 1._MJ << endl;
    173 	cout << 1._W << endl;
    174 	cout << 1._kW << endl;
    175 	cout << endl;
    176 
    177 	auto m = 5._m;
    178 	auto t = 2._s;
    179 	cout << m/t << endl;
    180 	cout << 3000._mph << endl;
    181 	cout << t/t << endl;
    182 	cout << 11.1_t << endl;
    183 	cout << 10._mpsps << endl;
    184 }