Biblioteka ta pozwala definiować systemy jednostek, służących do obliczeń ilościowych. Umożliwia prowadzenie obliczeń w jednostkach z różnych systemów, pod warunkiem, że prawa konwersji jednostek zostały zdefiniowane.
Obliczenia mogą być prowadzone na wartościach reprezentowanych przez zmienne, bez zwracania uwagi na jednostki, ponieważ rachunek jednostkowy będzie przeprowadzony implicite.
/** * Stanisław Nowak, I1ISI * * Ponizszy kod daje przyklad zastosowania biblioteki boost::units * * Biblioteka ta pozwala definiować systemy jednostek, umozliwiajac proste konwersje i * kalkulacje na jednostkach. Mozna rowniez wykonywac obliczenia na jednostkach roznych * systemow (np. kalkulacje angazujace jednostki metr i stopa) * * W pierwszej czesci kodu definiowany jest system jednostek. Tworzone sa 3 podstawowe * wymiary jednostek: * - length_dimension - dla jednostek dlugosci * - mass_dimension - dla jednostek masy * - time_dimension - dla jesnostek czasu * * Nastepnie tworzone sa wymiary pochodne od podstawowych, jako ich kombinacje liniowe. * Tworzone sa jednostki odpowiadajace zdefiniowanym wymiarom. Na ich podstawie powstaje * system jednostek, w ktorych prowadzone beda obliczenia. * * W dalszej czesci tworzone sa struktury wspomagajace deklarowanie, uzywanie i wypisywanie * zmiennych reprezentujacych wartosci poszczegolnych typow. * * Komentarze staralem sie umieszczac bezposrednio przed instrukcjami, do ktorego sie odnosza. * * Przykład bazuje na prostym systemie jednostek zdefiniowanym i umieszczonym na stronie * http://www.boost.org/doc/libs/1_38_0/doc/html/boost_units/Examples.html. Ponizej znajduje * sie notka licencyjna. * * Boost.Units - A C++ library for zero-overhead dimensional analysis and * unit/quantity manipulation and conversion * * Copyright (C) 2003-2008 Matthias Christian Schabel * Copyright (C) 2008 Steven Watanabe * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http:www.boost.org/LICENSE_1_0.txt) */ #include <iostream> #include <boost/mpl/list.hpp> #include <boost/mpl/vector.hpp> #include <boost/units/pow.hpp> //definiowanie jednostek skalowanych i potegowanie #include <boost/units/quantity.hpp> //uzywanie jednostek do obliczeń ilosciowych #include <boost/units/io.hpp> //obsluga base_unit_info #include <boost/units/base_dimension.hpp> //definiowanie wymiarow podstawowych jednostek #include <boost/units/derived_dimension.hpp> //tworzenie jednostek pochodnych od podstawowych #include <boost/units/static_constant.hpp> //definiowanie stalych do deklaracji zmiennych #include <boost/units/unit.hpp> //podstawowy naglowek #include <boost/units/base_unit.hpp> //tworzenie podstawowych jednostek skojarzonych z odpowiednim wymiarem #include <boost/units/make_system.hpp> //tworzenie systemu jednostek namespace boost { namespace units { /** * Podstawowe wymiary jednostek: dlugosc, masa, czas */ struct length_base_dimension : base_dimension<length_base_dimension,1> { }; struct mass_base_dimension : base_dimension<mass_base_dimension,2> { }; struct time_base_dimension : base_dimension<time_base_dimension,3> { }; typedef length_base_dimension::dimension_type length_dimension; typedef mass_base_dimension::dimension_type mass_dimension; typedef time_base_dimension::dimension_type time_dimension; /** * Wymiary pochodne: zdefiniowane na podstawie podstawowych wymiarow jednostek. * Prosze zwrocic uwage na definicje wymiaru energii. Podane zostaly wykladniki * wymiarow jednostek podstawowych skladajacych sie na dany wymiar pochodny. */ typedef derived_dimension< length_base_dimension,2>::type area_dimension; typedef derived_dimension< mass_base_dimension,1, //kilogram.. length_base_dimension,2, //metr.. time_base_dimension,-2>::type energy_dimension; //przez sekunde kwadrat namespace test { /** * Definicja jednostek podstawowych dla poszczegolnych wymiarow: metr, kilogram, sekunda. * Jednostki podstawowe posluza do stworzenia systemu jednostkowego na ich podstawie */ struct meter_base_unit : base_unit< meter_base_unit, length_dimension, 1> { }; struct kilogram_base_unit : base_unit<kilogram_base_unit, mass_dimension, 2> { }; struct second_base_unit : base_unit< second_base_unit, time_dimension, 3> { }; /** * Definicja systemu jesnostek. Jako podstawowe definiujemy metr, kilogram, sekunda. */ typedef make_system< meter_base_unit, kilogram_base_unit, second_base_unit>::type mks_system; /** * Tworzymy skrocone nazwy jednostek skojarzonych z odpowiednimi wymiarami. * Jednostki musza nalezec do uprzednio zdefiniowanego systemu jednoskowego */ typedef unit<dimensionless_type,mks_system> dimensionless; typedef unit<length_dimension,mks_system> length; typedef unit< mass_dimension,mks_system> mass; typedef unit< time_dimension,mks_system> time; typedef unit< area_dimension,mks_system> area; typedef unit<energy_dimension,mks_system> energy; /** * Tworzenie stalych dla jednostek. Ponizsze makro jest dostarczone w naglowku * boost/units/static_constant.hpp. Dzieki temu stale te sa bezpieczne w uzyciu * z watkami. Pomagaja rowniez w pozniejszej deklaracji zmiennych. * Stalych tych mozna uzywac w kodzie programu w naturalny dla czlowieka sposob, * zaraz po wartosci np. "4*seconds". */ BOOST_UNITS_STATIC_CONSTANT(meter,length); BOOST_UNITS_STATIC_CONSTANT(meters,length); BOOST_UNITS_STATIC_CONSTANT(kilogram,mass); BOOST_UNITS_STATIC_CONSTANT(kilograms,mass); BOOST_UNITS_STATIC_CONSTANT(second,time); BOOST_UNITS_STATIC_CONSTANT(seconds,time); BOOST_UNITS_STATIC_CONSTANT(square_meter,area); BOOST_UNITS_STATIC_CONSTANT(square_meters,area); BOOST_UNITS_STATIC_CONSTANT(joule,energy); BOOST_UNITS_STATIC_CONSTANT(joules,energy); } // namespace test /** * Tworzymy obsluge napisowego opisu jednostek. Sluza one do wyprowadzania * wynikow obliczen na konsole lub innego strumienia. Mozna zdefiniowac pelna * nazwe jednostki i jej symbol. Funkcje te sa uzywane implicite przez operator * << dla strumieni. */ template<> struct base_unit_info<test::meter_base_unit> { static std::string name() { return "meter"; } static std::string symbol() { return "m"; } }; template<> struct base_unit_info<test::kilogram_base_unit> { static std::string name() { return "kilogram"; } static std::string symbol() { return "kg"; } }; template<> struct base_unit_info<test::second_base_unit> { static std::string name() { return "second"; } static std::string symbol() { return "s"; } }; } // namespace units } // namespace boost /** * Cialo programu testujacego */ int main(void) { using namespace boost::units; using namespace boost::units::test; { /** * Deklaracja zmiennych skojarzonych z odpowiednia jednostka. */ quantity<length> L = 2.0*meters; quantity<energy> E = kilograms*pow<2>(L/seconds); /** * Demonstracja obliczeń wykonywanych na jednostkach. * Prosze zwrocic uwage na zastosowanie stalych "kilograms", "seconds", itp. */ std::cout << "L = " << L << std::endl << "L+L = " << L+L << std::endl << "L-L = " << L-L << std::endl << "L*L = " << L*L << std::endl << "L/L = " << L/L << std::endl << "L*meter = " << L*meter << std::endl << "kilograms*(L/seconds)*(L/seconds) = " << kilograms*(L/seconds)*(L/seconds) << std::endl << "kilograms*(L/seconds)^2 = " << kilograms*pow<2>(L/seconds) << std::endl << "L^3 = " << pow<3>(L) << std::endl << "L^(3/2) = " << pow<static_rational<3,2> >(L) << std::endl << "2vL = " << root<2>(L) << std::endl << "(3/2)vL = " << root<static_rational<3,2> >(L) << std::endl << std::endl; } return 0; }
Stanisław Nowak, I1ISI
snowak2@stud.elka.pw.edu.pl