1// Copyright Louis Dionne 2013-2022
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4
5#include <boost/hana/equal.hpp>
6#include <boost/hana/minus.hpp>
7#include <boost/hana/plus.hpp>
8#include <boost/hana/tuple.hpp>
9#include <boost/hana/zip_with.hpp>
10
11#include <functional>
12namespace hana = boost::hana;
13
14
15//
16// Example of implementing basic dimensional analysis using Hana
17//
18
19
20// base dimensions M L T I K J N
21using mass = decltype(hana::tuple_c<int, 1, 0, 0, 0, 0, 0, 0>);
22using length = decltype(hana::tuple_c<int, 0, 1, 0, 0, 0, 0, 0>);
23using time_ = decltype(hana::tuple_c<int, 0, 0, 1, 0, 0, 0, 0>);
24using charge = decltype(hana::tuple_c<int, 0, 0, 0, 1, 0, 0, 0>);
25using temperature = decltype(hana::tuple_c<int, 0, 0, 0, 0, 1, 0, 0>);
26using intensity = decltype(hana::tuple_c<int, 0, 0, 0, 0, 0, 1, 0>);
27using amount = decltype(hana::tuple_c<int, 0, 0, 0, 0, 0, 0, 1>);
28
29// composite dimensions
30using velocity = decltype(hana::tuple_c<int, 0, 1, -1, 0, 0, 0, 0>); // M/T
31using acceleration = decltype(hana::tuple_c<int, 0, 1, -2, 0, 0, 0, 0>); // M/T^2
32using force = decltype(hana::tuple_c<int, 1, 1, -2, 0, 0, 0, 0>); // ML/T^2
33
34
35template <typename Dimensions>
36struct quantity {
37 double value_;
38
39 explicit quantity(double v) : value_(v) { }
40
41 template <typename OtherDimensions>
42 explicit quantity(quantity<OtherDimensions> other)
43 : value_(other.value_)
44 {
45 static_assert(Dimensions{} == OtherDimensions{},
46 "Constructing quantities with incompatible dimensions!");
47 }
48
49 explicit operator double() const { return value_; }
50};
51
52template <typename D1, typename D2>
53auto operator*(quantity<D1> a, quantity<D2> b) {
54 using D = decltype(hana::zip_with(std::plus<>{}, D1{}, D2{}));
55 return quantity<D>{static_cast<double>(a) * static_cast<double>(b)};
56}
57
58template <typename D1, typename D2>
59auto operator/(quantity<D1> a, quantity<D2> b) {
60 using D = decltype(hana::zip_with(std::minus<>{}, D1{}, D2{}));
61 return quantity<D>{static_cast<double>(a) / static_cast<double>(b)};
62}
63
64int main() {
65 quantity<mass> m{10.3};
66 quantity<length> d{3.6};
67 quantity<time_> t{2.4};
68 quantity<velocity> v{d / t};
69 quantity<acceleration> a{3.9};
70 quantity<force> f{m * a};
71}
72

source code of boost/libs/hana/example/misc/dimensional_analysis.cpp