diff --git a/NumberWithUnits.cpp b/NumberWithUnits.cpp index e64834d..b56e479 100644 --- a/NumberWithUnits.cpp +++ b/NumberWithUnits.cpp @@ -1,38 +1,136 @@ - #include #include #include #include +#include +#include #include "NumberWithUnits.hpp" -// #define BOOL true +// #define BOOL true + +using namespace std; +//m -> cm +//cm -> m +//km -> m +//m -> km +namespace ariel +{ + static map> convertor; // convertor O(3) -// using namespace std; + double convertHelp(const string &from, const string &to, double fromVal) + { + if (from == to) + { + return fromVal; + } + if (convertor.at(from).count(to) != 0) + { + return fromVal * convertor.at(from).at(to); + } + __throw_invalid_argument("Not valid convertion"); + + } -namespace ariel{ - void NumberWithUnits::read_units(const ifstream& file){} - NumberWithUnits operator+(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return NumberWithUnits();} - NumberWithUnits operator+=(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return NumberWithUnits();} - NumberWithUnits operator+(const NumberWithUnits& unit){return NumberWithUnits();} - NumberWithUnits operator-(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return NumberWithUnits();} - NumberWithUnits operator-=(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return NumberWithUnits();} - NumberWithUnits operator-(const NumberWithUnits& unit){return NumberWithUnits();} - bool operator>(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return unit1.BOOL;} - bool operator>=(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return unit1.BOOL;} - bool operator<(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return unit1.BOOL;} - bool operator<=(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return unit1.BOOL;} - bool operator==(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return unit1.BOOL;} - bool operator!=(const NumberWithUnits& unit1, const NumberWithUnits& unit2){return unit1.BOOL;} - NumberWithUnits operator++(const NumberWithUnits& unit){return NumberWithUnits();} //Prefix - NumberWithUnits operator++(const NumberWithUnits& unit, int){return NumberWithUnits();} //Postfix - NumberWithUnits operator--(const NumberWithUnits& unit){return NumberWithUnits();} //Prefix - NumberWithUnits operator--(const NumberWithUnits& unit, int){return NumberWithUnits();} //Postfix - NumberWithUnits operator*(const NumberWithUnits& unit, double num){return NumberWithUnits();} - NumberWithUnits operator*(double num, const NumberWithUnits& unit){return NumberWithUnits();} - ostream& operator<<(const ostream& os, const NumberWithUnits& unit){return cout << unit._value << "[" << unit._unit << "]" << endl;} - istream& operator>>(std::istream& in, NumberWithUnits& unit){ - string s; - in >> unit._value >> s >> unit._unit; - return in; + double convert(const string &from, const string &to, double fromVal) + { + if (from == to) + { + return fromVal; + } + if (convertor.at(from).count(to) != 0) + { + return fromVal * convertor.at(from).at(to); + } + map m = convertor.at(from); + string s; + for (map::iterator it = m.begin(); it != m.end(); ++it) + { + s = it->first; + } + return convertHelp(s, to, convert(from, s, fromVal)); + } + + void NumberWithUnits::read_units(ifstream &file) + { + double Dunit1 = 0; + double Dunit2 = 0; + string Munit1; + string Munit2; + string none; + string line; + while (getline(file, line)) + { + istringstream Sstream(line); + if (!(Sstream >> Dunit1 >> Munit1 >> none >> Dunit2 >> Munit2)) + { + break; } -} + convertor[Munit1][Munit2] = Dunit2; //from + convertor[Munit2][Munit1] = 1 / Dunit2; //to + } + } + + NumberWithUnits operator+(const NumberWithUnits &unit1, const NumberWithUnits &unit2) + { + double converted = convert(unit2._unit, unit1._unit, unit2._value); + return NumberWithUnits(unit1._value + converted, unit1._unit); + } + NumberWithUnits operator+=(NumberWithUnits &unit1, const NumberWithUnits &unit2) + { + unit1._value += convert(unit2._unit, unit1._unit, unit2._value); + return unit1; + } + NumberWithUnits operator+(const NumberWithUnits &unit, double num) + { + return NumberWithUnits(unit._value + num, unit._unit); + } + NumberWithUnits operator-(const NumberWithUnits &unit1, const NumberWithUnits &unit2) + { + double converted = convert(unit2._unit, unit1._unit, unit2._value); + return NumberWithUnits(unit1._value - converted, unit1._unit); + } + NumberWithUnits operator-=(NumberWithUnits &unit1, const NumberWithUnits &unit2) + { + unit1._value -= convert(unit2._unit, unit1._unit, unit2._value); + return unit1; + } + NumberWithUnits operator-(const NumberWithUnits &unit) + { + return NumberWithUnits(-unit._value, unit._unit); + } + int compare(const NumberWithUnits &n1, const NumberWithUnits &n2) + { + double x = n1._value - convert(n2._unit, n1._unit, n2._value); + double y = convert(n2._unit, n1._unit, n2._value) - n1._value; + const double epsilon = 0.00001; + if (x > epsilon) + { + return 1; + } + if (y > epsilon) + { + return -1; + } + return 0; + } + + bool operator>(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) > 0; } + bool operator>=(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) >= 0; } + bool operator<(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) < 0; } + bool operator<=(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) <= 0; } + bool operator==(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) == 0; } + bool operator!=(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) != 0; } + NumberWithUnits operator++(NumberWithUnits &unit) { return NumberWithUnits(++unit._value, unit._unit); } //Prefix + NumberWithUnits operator++(NumberWithUnits &unit, int) { return NumberWithUnits(unit._value++, unit._unit); } //Postfix + NumberWithUnits operator--(NumberWithUnits &unit) { return NumberWithUnits(--unit._value, unit._unit); } //Prefix + NumberWithUnits operator--(NumberWithUnits &unit, int) { return NumberWithUnits(unit._value++, unit._unit); } //Postfix + NumberWithUnits operator*(const NumberWithUnits &unit, double num) { return NumberWithUnits(num * unit._value, unit._unit); } + NumberWithUnits operator*(double num, const NumberWithUnits &unit) { return NumberWithUnits(num * unit._value, unit._unit); } + ostream &operator<<(const ostream &os, const NumberWithUnits &unit) { return cout << unit._value << "[" << unit._unit << "]" << endl; } + istream &operator>>(std::istream &in, NumberWithUnits &unit) + { + string s; + in >> unit._value >> s >> unit._unit; + return in; + } +} diff --git a/NumberWithUnits.hpp b/NumberWithUnits.hpp index f3c64e9..46acb45 100644 --- a/NumberWithUnits.hpp +++ b/NumberWithUnits.hpp @@ -16,12 +16,15 @@ namespace ariel{ } NumberWithUnits(){} ~NumberWithUnits(){} - static void read_units(const ifstream& file); + friend int compare(const NumberWithUnits& n1, const NumberWithUnits& n2); + double convert(const string &from, const string &to, double fromVal); + double convertHelp(const string &from, const string &to, double fromVal); + static void read_units(ifstream& file); friend NumberWithUnits operator+(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator+=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator+(const NumberWithUnits& unit); + friend NumberWithUnits operator+=(NumberWithUnits& unit1, const NumberWithUnits& unit2); + friend NumberWithUnits operator+(const NumberWithUnits& unit, double num); friend NumberWithUnits operator-(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator-=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); + friend NumberWithUnits operator-=(NumberWithUnits& unit1, const NumberWithUnits& unit2); friend NumberWithUnits operator-(const NumberWithUnits& unit); friend bool operator>(const NumberWithUnits& unit1, const NumberWithUnits& unit2); friend bool operator>=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); @@ -29,10 +32,10 @@ namespace ariel{ friend bool operator<=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); friend bool operator==(const NumberWithUnits& unit1, const NumberWithUnits& unit2); friend bool operator!=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator++(const NumberWithUnits& unit); //Prefix - friend NumberWithUnits operator++(const NumberWithUnits& unit, int); //Postfix - friend NumberWithUnits operator--(const NumberWithUnits& unit); //Prefix - friend NumberWithUnits operator--(const NumberWithUnits& unit, int); //Postfix + friend NumberWithUnits operator++( NumberWithUnits& unit); //Prefix + friend NumberWithUnits operator++( NumberWithUnits& unit, int); //Postfix + friend NumberWithUnits operator--( NumberWithUnits& unit); //Prefix + friend NumberWithUnits operator--( NumberWithUnits& unit, int); //Postfix friend NumberWithUnits operator*(const NumberWithUnits& unit, double num); friend NumberWithUnits operator*(double num, const NumberWithUnits& unit); friend ostream& operator<<(const ostream& os, const NumberWithUnits& unit); diff --git a/Test.cpp b/Test.cpp index 3ab40a6..3b7859a 100644 --- a/Test.cpp +++ b/Test.cpp @@ -13,6 +13,7 @@ static vector units = {"m"}; ifstream units_file{"units.txt"}; TEST_CASE("Multi operators"){ + NumberWithUnits::read_units(units_file); NumberWithUnits a{1, "m"}; NumberWithUnits b{3, "m"}; NumberWithUnits c{300, "cm"}; @@ -42,17 +43,18 @@ TEST_CASE("All bool operators"){ CHECK(d>=c); CHECK(c>=e); CHECK(e>=c); - CHECK(a