00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef IMG_PHYSICS_UNITS_HH
00021 #define IMG_PHYSICS_UNITS_HH
00022
00023 #include <boost/mpl/vector_c.hpp>
00024 #include<boost/mpl/placeholders.hpp>
00025 #include <boost/mpl/plus.hpp>
00026 #include <boost/mpl/transform.hpp>
00027 #include <ost/base.hh>
00028
00029 namespace ost { namespace img { namespace physics{
00030
00031 namespace detail{
00032
00033 namespace mpl = boost::mpl;
00034
00035 typedef mpl::vector_c<int,1,0,0,0,0,0,0> mass_dimension;
00036 typedef mpl::vector_c<int,0,1,0,0,0,0,0> length_dimension;
00037 typedef mpl::vector_c<int,0,0,1,0,0,0,0> time_dimension;
00038 typedef mpl::vector_c<int,0,0,0,1,0,0,0> charge_dimension;
00039 typedef mpl::vector_c<int,0,0,0,0,1,0,0> temperature_dimension;
00040 typedef mpl::vector_c<int,0,0,0,0,0,1,0> intensity_dimension;
00041 typedef mpl::vector_c<int,0,0,0,0,0,0,1> amount_dimension;
00042 typedef mpl::vector_c<int,0,1,-1,0,0,0,0> velocity_dimension;
00043 typedef mpl::vector_c<int,0,1,-2,0,0,0,0> acceleration_dimension;
00044 typedef mpl::vector_c<int,1,1,-1,0,0,0,0> momentum_dimension;
00045 typedef mpl::vector_c<int,1,1,-2,0,0,0,0> force_dimension;
00046 typedef mpl::vector_c<int,0,0,0,0,0,0,0> scalar_dimension;
00047
00048
00049 template <class Dimensions>
00050 class quantity
00051 {
00052 public:
00053 quantity();
00054 template <class D2>
00055 quantity(const quantity<D2>& rhs);
00056 explicit quantity(Real x);
00057 Real value() const;
00058
00059 protected:
00060 Real value_;
00061 };
00062
00063 template <class D>
00064 quantity<D> operator+(quantity<D> x, quantity<D> y);
00065 template <class D>
00066 quantity<D> operator-(quantity<D> x, quantity<D> y);
00067
00068
00069 template <class D1, class D2>
00070 struct multiply_dimensions: mpl::transform<D1,D2,mpl::plus<mpl::placeholders::_1,mpl::placeholders::_2> >
00071 {
00072 };
00073 template <class D1, class D2>
00074 quantity<typename multiply_dimensions<D1,D2>::type> operator*(quantity<D1> x, quantity<D2> y);
00075
00076 template <class D1, class D2>
00077 struct divide_dimensions: mpl::transform<D1,D2,mpl::minus<mpl::placeholders::_1,mpl::placeholders::_2> >
00078 {
00079 };
00080 template <class D1, class D2>
00081 quantity<typename divide_dimensions<D1,D2>::type> operator/(quantity<D1> x, quantity<D2> y);
00082
00083
00084 }
00085
00086
00087 typedef detail::quantity<detail::mass_dimension> Mass;
00088 typedef detail::quantity<detail::length_dimension> Length;
00089 typedef detail::quantity<detail::time_dimension> Time;
00090 typedef detail::quantity<detail::charge_dimension> Charge;
00091 typedef detail::quantity<detail::temperature_dimension> Temperature;
00092 typedef detail::quantity<detail::intensity_dimension> Intensity;
00093 typedef detail::quantity<detail::amount_dimension> Amount;
00094 typedef detail::quantity<detail::velocity_dimension> Velocity;
00095 typedef detail::quantity<detail::momentum_dimension> Momentum;
00096 typedef detail::quantity<detail::force_dimension> Force;
00097
00098
00099
00100 class Scalar : public detail::quantity<detail::scalar_dimension>
00101 {
00102 public:
00103 Scalar(Real x): detail::quantity<detail::scalar_dimension>(x)
00104 {
00105 }
00106
00107 operator Real()
00108 {
00109 return value_;
00110 }
00111
00112 };
00113 }}}
00114
00115 #endif