1 | // Boost.Units - A C++ library for zero-overhead dimensional analysis and |
2 | // unit/quantity manipulation and conversion |
3 | // |
4 | // Copyright (C) 2003-2008 Matthias Christian Schabel |
5 | // Copyright (C) 2007-2008 Steven Watanabe |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See |
8 | // accompanying file LICENSE_1_0.txt or copy at |
9 | // http://www.boost.org/LICENSE_1_0.txt) |
10 | |
11 | #ifndef BOOST_UNITS_DIM_HPP |
12 | #define BOOST_UNITS_DIM_HPP |
13 | |
14 | #include <boost/static_assert.hpp> |
15 | |
16 | #include <boost/type_traits/is_same.hpp> |
17 | |
18 | #include <boost/mpl/arithmetic.hpp> |
19 | |
20 | #include <boost/units/config.hpp> |
21 | #include <boost/units/static_rational.hpp> |
22 | #include <boost/units/detail/dim_impl.hpp> |
23 | |
24 | /// \file dim.hpp |
25 | /// \brief Handling of fundamental dimension/exponent pairs. |
26 | |
27 | namespace boost { |
28 | |
29 | namespace units { |
30 | |
31 | namespace detail { |
32 | |
33 | struct dim_tag { }; |
34 | |
35 | } |
36 | |
37 | /// \brief Dimension tag/exponent pair for a single fundamental dimension. |
38 | /// |
39 | /// \details |
40 | /// The dim class represents a single dimension tag/dimension exponent pair. |
41 | /// That is, @c dim<tag_type,value_type> is a pair where @c tag_type represents the |
42 | /// fundamental dimension being represented and @c value_type represents the |
43 | /// exponent of that fundamental dimension as a @c static_rational. @c tag_type must |
44 | /// be a derived from a specialization of @c base_dimension. |
45 | /// Specialization of the following Boost.MPL metafunctions are provided |
46 | /// |
47 | /// - @c mpl::plus for two @c dims |
48 | /// - @c mpl::minus for two @c dims |
49 | /// - @c mpl::negate for a @c dim |
50 | /// |
51 | /// These metafunctions all operate on the exponent, and require |
52 | /// that the @c dim operands have the same base dimension tag. |
53 | /// In addition, multiplication and division by @c static_rational |
54 | /// is supported. |
55 | /// |
56 | /// - @c mpl::times for a @c static_rational and a @c dim in either order |
57 | /// - @c mpl::divides for a @c static_rational and a @c dim in either order |
58 | /// |
59 | /// These metafunctions likewise operate on the exponent only. |
60 | template<typename T,typename V> |
61 | struct dim |
62 | { |
63 | typedef dim type; |
64 | typedef detail::dim_tag tag; |
65 | typedef T tag_type; |
66 | typedef V value_type; |
67 | }; |
68 | |
69 | } // namespace units |
70 | |
71 | } // namespace boost |
72 | |
73 | #if BOOST_UNITS_HAS_BOOST_TYPEOF |
74 | |
75 | #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() |
76 | |
77 | BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::dim, 2) |
78 | |
79 | #endif |
80 | |
81 | #ifndef BOOST_UNITS_DOXYGEN |
82 | |
83 | namespace boost { |
84 | |
85 | namespace mpl { |
86 | |
87 | // define MPL operators acting on dim<T,V> |
88 | |
89 | template<> |
90 | struct plus_impl<boost::units::detail::dim_tag,boost::units::detail::dim_tag> |
91 | { |
92 | template<class T0, class T1> |
93 | struct apply |
94 | { |
95 | BOOST_STATIC_ASSERT((boost::is_same<typename T0::tag_type,typename T1::tag_type>::value == true)); |
96 | typedef boost::units::dim<typename T0::tag_type, typename mpl::plus<typename T0::value_type, typename T1::value_type>::type> type; |
97 | }; |
98 | }; |
99 | |
100 | template<> |
101 | struct minus_impl<boost::units::detail::dim_tag,boost::units::detail::dim_tag> |
102 | { |
103 | template<class T0, class T1> |
104 | struct apply |
105 | { |
106 | BOOST_STATIC_ASSERT((boost::is_same<typename T0::tag_type,typename T1::tag_type>::value == true)); |
107 | typedef boost::units::dim<typename T0::tag_type, typename mpl::minus<typename T0::value_type, typename T1::value_type>::type> type; |
108 | }; |
109 | }; |
110 | |
111 | template<> |
112 | struct times_impl<boost::units::detail::dim_tag,boost::units::detail::static_rational_tag> |
113 | { |
114 | template<class T0, class T1> |
115 | struct apply |
116 | { |
117 | typedef boost::units::dim<typename T0::tag_type, typename mpl::times<typename T0::value_type, T1>::type> type; |
118 | }; |
119 | }; |
120 | |
121 | template<> |
122 | struct times_impl<boost::units::detail::static_rational_tag,boost::units::detail::dim_tag> |
123 | { |
124 | template<class T0, class T1> |
125 | struct apply |
126 | { |
127 | typedef boost::units::dim<typename T1::tag_type, typename mpl::times<T0, typename T1::value_type>::type> type; |
128 | }; |
129 | }; |
130 | |
131 | template<> |
132 | struct divides_impl<boost::units::detail::dim_tag,boost::units::detail::static_rational_tag> |
133 | { |
134 | template<class T0, class T1> |
135 | struct apply |
136 | { |
137 | typedef boost::units::dim<typename T0::tag_type, typename mpl::divides<typename T0::value_type, T1>::type> type; |
138 | }; |
139 | }; |
140 | |
141 | template<> |
142 | struct divides_impl<boost::units::detail::static_rational_tag,boost::units::detail::dim_tag> |
143 | { |
144 | template<class T0, class T1> |
145 | struct apply |
146 | { |
147 | typedef boost::units::dim<typename T1::tag_type, typename mpl::divides<T0, typename T1::value_type>::type> type; |
148 | }; |
149 | }; |
150 | |
151 | template<> |
152 | struct negate_impl<boost::units::detail::dim_tag> |
153 | { |
154 | template<class T0> |
155 | struct apply |
156 | { |
157 | typedef boost::units::dim<typename T0::tag_type,typename mpl::negate<typename T0::value_type>::type> type; |
158 | }; |
159 | }; |
160 | |
161 | } // namespace mpl |
162 | |
163 | } // namespace boost |
164 | |
165 | #endif |
166 | |
167 | #endif // BOOST_UNITS_DIM_HPP |
168 | |