boost::units を少し使いやすくする
boost::unitsを使う場合、下記のようになる。
#include <boost/untis/systems/si.hpp> #include <boost/units/systems/prefixes.hpp> using namespace boost::units; quantity<si::time> x(1.0*si::second); // 1 s quantity<si::time> y(1.0*si::milli*si::meter); // 0.001 s
この書き方にはいくつか気になる点がある。
まず、quantityで使ってる単位が分かりづらい。
この例だと、SI 単位系における時間の単位は秒だから、分かるといえば分かるけど、
もっと、単位が秒だということを主張してほしい。
さらに、秒以外の単位(ミリ秒、マイクロ秒、…)でも扱いたい。
浮動小数点の誤差などを考えると特に。
いちいち接頭辞を掛けるのがめんどくさい。
millisecond、microsecond、nanosecond、millimeter、centimeter、kilometer くらいは
デフォルトで用意しておいてくれてもいいはず。
というわけで、これらの不満を無理やり解決してみた。
#include <boost/units/systems/si.hpp> #include <boost/units/make_scaled_unit.hpp> // 実際は適当な名前空間に放り込んだ方がいいのかもしれない typedef boost::units::si::time second; using boost::units::si::seconds; typedef boost::units::make_scaled_unit< second, boost::units::scale<10, boost::units::static_rational<-3> > >::type millisecond; BOOST_UNITS_STATIC_CONSTANT(milliseconds, millisecond); typedef boost::units::make_scaled_unit< second, boost::units::scale<10, boost::units::static_rational<-6> > >::type microsecond; BOOST_UNITS_STATIC_CONSTANT(microseconds, microsecond); typedef boost::units::make_scaled_unit< second, boost::units::scale<10, boost::units::static_rational<-9> > >::type nanosecond; BOOST_UNITS_STATIC_CONSTANT(nanoseconds, nanosecond); typedef boost::units::si::length meter; using boost::units::si::meters; typedef boost::units::make_scaled_unit< meter, boost::units::scale<10, boost::units::static_rational<-3> > >::type millimeter; BOOST_UNITS_STATIC_CONSTANT(millimeters, millimeter); typedef boost::units::make_scaled_unit< meter, boost::units::scale<10, boost::units::static_rational<-2> > >::type centimeter; BOOST_UNITS_STATIC_CONSTANT(centimeters, centimeter); typedef boost::units::make_scaled_unit< meter, boost::units::scale<10, boost::units::static_rational<3> > >::type kilometer; BOOST_UNITS_STATIC_CONSTANT(kilometers, kilometer);
とりあえず秒とメートルだけ定義してみた。
#include <iostream> int main() { using boost::units::quantity; std::cout << quantity<second>(1*seconds) << std::endl; // 1 s std::cout << quantity<millisecond>(1*seconds) << std::endl; // 1000 ms std::cout << quantity<microsecond>(1*seconds) << std::endl; // 1e+006 us std::cout << quantity<nanosecond>(1*seconds) << std::endl; // 1e+009 ns std::cout << std::endl; std::cout << quantity<second>(1*seconds) << std::endl; // 1 s std::cout << quantity<second>(1*milliseconds) << std::endl; // 0.001 s std::cout << quantity<second>(1*microseconds) << std::endl; // 1e-006 s std::cout << quantity<second>(1*nanoseconds) << std::endl; // 1e-009 s std::cout << std::endl; std::cout << quantity<kilometer>(1*meters) << std::endl; // 0.001 km std::cout << quantity<meter>(1*meters) << std::endl; // 1 m std::cout << quantity<centimeter>(1*meters) << std::endl; // 100 cm std::cout << quantity<millimeter>(1*meters) << std::endl; // 1000 mm std::cout << std::endl; std::cout << quantity<meter>(1*kilometers) << std::endl; // 1000 m std::cout << quantity<meter>(1*meters) << std::endl; // 1 m std::cout << quantity<meter>(1*centimeters) << std::endl; // 0.01 m std::cout << quantity<meter>(1*millimeters) << std::endl; // 0.001 m return 0; }
コンセプトとしては、quantityには単数形の、値を作るためには複数形の単位を使用するという方向で。
1 seconds なんて、ネイティブには気持ち悪いんだろうけど、日本人なのでキニシナイ。