• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
33 namespace boost {
34 
35 namespace units {
36 
37 template<class T>
38 struct heterogeneous_system;
39 
40 template<class T, class D, class Scale>
41 struct heterogeneous_system_impl;
42 
43 template<class T, class E>
44 struct heterogeneous_system_dim;
45 
46 template<class S, class Scale>
47 struct scaled_base_unit;
48 
49 /// removes all scaling from a unit or a base unit.
50 template<class T>
51 struct 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
61 template<class S, class Scale>
62 struct unscale<scaled_base_unit<S, Scale> >
63 {
64     typedef typename unscale<S>::type type;
65 };
66 
67 /// INTERNAL ONLY
68 template<class D, class S>
69 struct unscale<unit<D, S> >
70 {
71     typedef unit<D, typename unscale<S>::type> type;
72 };
73 
74 /// INTERNAL ONLY
75 template<class Scale>
76 struct scale_list_dim;
77 
78 /// INTERNAL ONLY
79 template<class T>
80 struct get_scale_list
81 {
82     typedef dimensionless_type type;
83 };
84 
85 /// INTERNAL ONLY
86 template<class S, class Scale>
87 struct 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
93 template<class D, class S>
94 struct get_scale_list<unit<D, S> >
95 {
96     typedef typename get_scale_list<S>::type type;
97 };
98 
99 /// INTERNAL ONLY
100 struct scale_dim_tag {};
101 
102 /// INTERNAL ONLY
103 template<class Scale>
104 struct 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 
114 namespace mpl {
115 
116 /// INTERNAL ONLY
117 template<>
118 struct 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 
128 namespace units {
129 
130 namespace detail {
131 
132 template<class Scale>
133 struct is_empty_dim<scale_list_dim<Scale> > : mpl::false_ {};
134 
135 template<long N>
136 struct is_empty_dim<scale_list_dim<scale<N, static_rational<0, 1> > > > : mpl::true_ {};
137 
138 template<int N>
139 struct 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;
valueboost::units::detail::eval_scale_list_impl::apply146         static BOOST_CONSTEXPR type value()
147         {
148             return(next_iteration::value() * Begin::item::value());
149         }
150     };
151 };
152 
153 template<>
154 struct eval_scale_list_impl<0>
155 {
156     template<class Begin>
157     struct apply
158     {
159         typedef one type;
valueboost::units::detail::eval_scale_list_impl::apply160         static BOOST_CONSTEXPR one value()
161         {
162             return(one());
163         }
164     };
165 };
166 
167 }
168 
169 /// INTERNAL ONLY
170 template<class T>
171 struct 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 
177 namespace mpl {
178 
179 /// INTERNAL ONLY
180 template<>
181 struct 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
196 template<>
197 struct 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
212 template<>
213 struct 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
228 template<>
229 struct 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