[Home]CPPTM Answers - Exercise 3-5

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

 // (by Ariel Badichi)
 #include <iostream>

 #include <boost/static_assert.hpp>
 #include <boost/mpl/vector_c.hpp>
 #include <boost/mpl/transform.hpp>
 #include <boost/mpl/placeholders.hpp>
 #include <boost/mpl/plus.hpp>
 #include <boost/mpl/equal.hpp>
 #include <boost/mpl/minus.hpp>

 namespace mpl = boost::mpl;
 using namespace mpl::placeholders;

 typedef mpl::vector_c<int, 1, 0, 0, 0, 0, 0, 0> mass;
 typedef mpl::vector_c<int, 0, 1, 0, 0, 0, 0, 0> length;
 typedef mpl::vector_c<int, 0, 0, 1, 0, 0, 0, 0> time;
 typedef mpl::vector_c<int, 0, 0, 0, 1, 0, 0, 0> charge;
 typedef mpl::vector_c<int, 0, 0, 0, 0, 1, 0, 0> temperature;
 typedef mpl::vector_c<int, 0, 0, 0, 0, 0, 1, 0> intensity;
 typedef mpl::vector_c<int, 0, 0, 0, 0, 0, 0, 1> angle;

 typedef mpl::vector_c<int, 0, 1,-1, 0, 0, 0, 0> velocity;
 typedef mpl::vector_c<int, 0, 1,-2, 0, 0, 0, 0> acceleration;
 typedef mpl::vector_c<int, 1, 1,-1, 0, 0, 0, 0> momentum;
 typedef mpl::vector_c<int, 1, 1,-2, 0, 0, 0, 0> force;

 typedef mpl::vector_c<int, 0, 0, 0, 0, 0, 0, 0> scalar;

 template<typename T, typename Dimensions>
 class quantity
 {
 public:
     explicit quantity(T x) : m_value(x) {}

     template<typename OtherDimensions?>
     quantity(quantity<T, OtherDimensions?> q)
     : m_value(q.value())
     {
         BOOST_STATIC_ASSERT((mpl::equal<Dimensions, OtherDimensions?>::type::value));
     }

     T value() const
     {
         return m_value;
     }

 private:
     T m_value;
 };

 // We need the static asserts in operator+/operator- so even expressions that
 // are not converted into a target quantity type, like:
 // a + m;
 // won't compile.

 template<typename T, typename D1, typename D2>
 quantity<T, D1> operator+ (quantity<T, D1> q1, quantity<T, D2> q2)
 {
     BOOST_STATIC_ASSERT((mpl::equal<D1, D2>::type::value));
     return quantity<T, D1>(q1.value() + q2.value());
 }

 template<typename T, typename D1, typename D2>
 quantity<T, D1> operator- (quantity<T, D1> q1, quantity<T, D2> q2)
 {
     BOOST_STATIC_ASSERT((mpl::equal<D1, D2>::type::value));
     return quantity<T, D1>(q1.value() - q2.value());
 }

 template<typename D1, typename D2>
 struct multiply_dimensions : mpl::transform<D1, D2, mpl::plus<_, _> > {};

 template<typename T, typename D1, typename D2>
 quantity<T, typename multiply_dimensions<D1, D2>::type> operator* (quantity<T, D1> q1, quantity<T, D2> q2)
 {
     typedef typename multiply_dimensions<D1, D2>::type dim;
     return quantity<T, dim>(q1.value() * q2.value());
 }

 template<typename D1, typename D2>
 struct divide_dimensions : mpl::transform<D1, D2, mpl::minus<_, _> > {};

 template<typename T, typename D1, typename D2>
 quantity<T, typename divide_dimensions<D1, D2>::type> operator/ (quantity<T, D1> q1, quantity<T, D2> q2)
 {
     typedef typename divide_dimensions<D1, D2>::type dim;
     return quantity<T, dim>(q1.value() / q2.value());
 }

 template<typename S, typename T, typename D>
 S & operator<< (S & out, quantity<T, D> q)
 {
     return out << q.value();
 }

 int main()
 {
     quantity<float, mass> m(1.5f);
     quantity<float, acceleration> a(9.8f);

     quantity<float, mass> m2(0.5f);
     m = m + m2;

     quantity<float, force> f(1.0f);

     f = f + m * a;
     std::cout << "f = " << f << "\n";

     quantity<float, acceleration> a2 = f / m;

     return 0;
 }

BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited March 26, 2005 8:03 am (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers