#ifndef UNITS_H // -*- c++ -*- #define UNITS_H /// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include #include #include class unknown_unit_error: public std::runtime_error { public: unknown_unit_error(std::string msg) : std::runtime_error(msg) {} }; template class Units { public: Units(const identifier &_base_unit) : base_unit(_base_unit) { add_unit(base_unit, 1); } const identifier &get_base_unit() const { return base_unit; } void add_unit(identifier unit, number conv_factor) { units[unit] = conv_factor; } bool has_unit(const identifier &unit) const { return find(unit) != units.end(); } number get_factor(const identifier &unit) const { typename _Units::const_iterator i = find(unit); if(i == units.end()) throw unknown_unit_error("Unit \"" + std::string(unit) + "\" is unknown"); return i->second; } number to_base(number value, const identifier &unit) const { return value * get_factor(unit); } number from_base(number value, const identifier &unit) const { return value / get_factor(unit); } typedef std::vector UnitList; UnitList list_units() const { UnitList list; for(typename _Units::const_iterator i = units.begin(); i != units.end(); i++) list.push_back(i->first); return list; } private: identifier base_unit; typedef std::map _Units; _Units units; /// map::find doesn't work with ustrings containing non-ascii chars /// for some reason typename _Units::const_iterator find(const identifier &unit) const { typename _Units::const_iterator i = units.begin(); for(;i != units.end(); i++) if(i->first == unit) break; return i; } }; #endif