# CPPTM Answers - Exercise 3-5

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

No diff available--this is the first major revision. (no other diffs)
``` // (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