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_DETAIL_UNSCALE_HPP_INCLUDED
12#define BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED
13
14#include <string>
15
16#include <boost/mpl/bool.hpp>
17#include <boost/mpl/size.hpp>
18#include <boost/mpl/begin.hpp>
19#include <boost/mpl/next.hpp>
20#include <boost/mpl/deref.hpp>
21#include <boost/mpl/plus.hpp>
22#include <boost/mpl/times.hpp>
23#include <boost/mpl/negate.hpp>
24#include <boost/mpl/less.hpp>
25
26#include <boost/units/config.hpp>
27#include <boost/units/dimension.hpp>
28#include <boost/units/scale.hpp>
29#include <boost/units/static_rational.hpp>
30#include <boost/units/units_fwd.hpp>
31#include <boost/units/detail/one.hpp>
32
33namespace boost {
34
35namespace units {
36
37template<class T>
38struct heterogeneous_system;
39
40template<class T, class D, class Scale>
41struct heterogeneous_system_impl;
42
43template<class T, class E>
44struct heterogeneous_system_dim;
45
46template<class S, class Scale>
47struct scaled_base_unit;
48
49/// removes all scaling from a unit or a base unit.
50template<class T>
51struct unscale
52{
53#ifndef BOOST_UNITS_DOXYGEN
54 typedef T type;
55#else
56 typedef detail::unspecified type;
57#endif
58};
59
60/// INTERNAL ONLY
61template<class S, class Scale>
62struct unscale<scaled_base_unit<S, Scale> >
63{
64 typedef typename unscale<S>::type type;
65};
66
67/// INTERNAL ONLY
68template<class D, class S>
69struct unscale<unit<D, S> >
70{
71 typedef unit<D, typename unscale<S>::type> type;
72};
73
74/// INTERNAL ONLY
75template<class Scale>
76struct scale_list_dim;
77
78/// INTERNAL ONLY
79template<class T>
80struct get_scale_list
81{
82 typedef dimensionless_type type;
83};
84
85/// INTERNAL ONLY
86template<class S, class Scale>
87struct get_scale_list<scaled_base_unit<S, Scale> >
88{
89 typedef typename mpl::times<list<scale_list_dim<Scale>, dimensionless_type>, typename get_scale_list<S>::type>::type type;
90};
91
92/// INTERNAL ONLY
93template<class D, class S>
94struct get_scale_list<unit<D, S> >
95{
96 typedef typename get_scale_list<S>::type type;
97};
98
99/// INTERNAL ONLY
100struct scale_dim_tag {};
101
102/// INTERNAL ONLY
103template<class Scale>
104struct scale_list_dim : Scale
105{
106 typedef scale_dim_tag tag;
107 typedef scale_list_dim type;
108};
109
110} // namespace units
111
112#ifndef BOOST_UNITS_DOXYGEN
113
114namespace mpl {
115
116/// INTERNAL ONLY
117template<>
118struct less_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
119{
120 template<class T0, class T1>
121 struct apply : mpl::bool_<((T0::base) < (T1::base))> {};
122};
123
124}
125
126#endif
127
128namespace units {
129
130namespace detail {
131
132template<class Scale>
133struct is_empty_dim<scale_list_dim<Scale> > : mpl::false_ {};
134
135template<long N>
136struct is_empty_dim<scale_list_dim<scale<N, static_rational<0, 1> > > > : mpl::true_ {};
137
138template<int N>
139struct eval_scale_list_impl
140{
141 template<class Begin>
142 struct apply
143 {
144 typedef typename eval_scale_list_impl<N-1>::template apply<typename Begin::next> next_iteration;
145 typedef typename multiply_typeof_helper<typename next_iteration::type, typename Begin::item::value_type>::type type;
146 static BOOST_CONSTEXPR type value()
147 {
148 return(next_iteration::value() * Begin::item::value());
149 }
150 };
151};
152
153template<>
154struct eval_scale_list_impl<0>
155{
156 template<class Begin>
157 struct apply
158 {
159 typedef one type;
160 static BOOST_CONSTEXPR one value()
161 {
162 return(one());
163 }
164 };
165};
166
167}
168
169/// INTERNAL ONLY
170template<class T>
171struct eval_scale_list : detail::eval_scale_list_impl<T::size::value>::template apply<T> {};
172
173} // namespace units
174
175#ifndef BOOST_UNITS_DOXYGEN
176
177namespace mpl {
178
179/// INTERNAL ONLY
180template<>
181struct plus_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
182{
183 template<class T0, class T1>
184 struct apply
185 {
186 typedef boost::units::scale_list_dim<
187 boost::units::scale<
188 (T0::base),
189 typename mpl::plus<typename T0::exponent, typename T1::exponent>::type
190 >
191 > type;
192 };
193};
194
195/// INTERNAL ONLY
196template<>
197struct negate_impl<boost::units::scale_dim_tag>
198{
199 template<class T0>
200 struct apply
201 {
202 typedef boost::units::scale_list_dim<
203 boost::units::scale<
204 (T0::base),
205 typename mpl::negate<typename T0::exponent>::type
206 >
207 > type;
208 };
209};
210
211/// INTERNAL ONLY
212template<>
213struct times_impl<boost::units::scale_dim_tag, boost::units::detail::static_rational_tag>
214{
215 template<class T0, class T1>
216 struct apply
217 {
218 typedef boost::units::scale_list_dim<
219 boost::units::scale<
220 (T0::base),
221 typename mpl::times<typename T0::exponent, T1>::type
222 >
223 > type;
224 };
225};
226
227/// INTERNAL ONLY
228template<>
229struct divides_impl<boost::units::scale_dim_tag, boost::units::detail::static_rational_tag>
230{
231 template<class T0, class T1>
232 struct apply
233 {
234 typedef boost::units::scale_list_dim<
235 boost::units::scale<
236 (T0::base),
237 typename mpl::divides<typename T0::exponent, T1>::type
238 >
239 > type;
240 };
241};
242
243} // namespace mpl
244
245#endif
246
247} // namespace boost
248
249#endif
250

source code of boost/libs/units/include/boost/units/detail/unscale.hpp