]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/units/include/boost/units/unit.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / units / include / boost / units / unit.hpp
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) 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_UNIT_HPP
12 #define BOOST_UNITS_UNIT_HPP
13
14 #include <boost/static_assert.hpp>
15 #include <boost/mpl/bool.hpp>
16 #include <boost/mpl/assert.hpp>
17 #include <boost/type_traits/is_same.hpp>
18
19 #include <boost/units/config.hpp>
20 #include <boost/units/dimension.hpp>
21 #include <boost/units/operators.hpp>
22 #include <boost/units/units_fwd.hpp>
23 #include <boost/units/homogeneous_system.hpp>
24 #include <boost/units/heterogeneous_system.hpp>
25 #include <boost/units/is_dimension_list.hpp>
26 #include <boost/units/reduce_unit.hpp>
27 #include <boost/units/static_rational.hpp>
28
29 namespace boost {
30
31 namespace units {
32
33 /// class representing a model-dependent unit with no associated value
34
35 /// (e.g. meters, Kelvin, feet, etc...)
36 template<class Dim,class System, class Enable>
37 class unit
38 {
39 public:
40 typedef unit<Dim, System> unit_type;
41 typedef unit<Dim,System> this_type;
42 typedef Dim dimension_type;
43 typedef System system_type;
44
45 unit() { }
46 unit(const this_type&) { }
47 //~unit() { }
48
49 this_type& operator=(const this_type&) { return *this; }
50
51 // sun will ignore errors resulting from templates
52 // instantiated in the return type of a function.
53 // Make sure that we get an error anyway by putting.
54 // the check in the destructor.
55 #ifdef __SUNPRO_CC
56 ~unit() {
57 BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
58 BOOST_MPL_ASSERT((is_dimension_list<Dim>));
59 }
60 #else
61 private:
62 BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
63 BOOST_MPL_ASSERT((is_dimension_list<Dim>));
64 #endif
65 };
66
67 }
68
69 }
70
71 #if BOOST_UNITS_HAS_BOOST_TYPEOF
72
73 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
74
75 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::unit, 2)
76
77 #endif
78
79 namespace boost {
80
81 namespace units {
82
83 /// Returns a unique type for every unit.
84 template<class Dim, class System>
85 struct reduce_unit<unit<Dim, System> >
86 {
87 typedef unit<
88 Dim,
89 typename detail::make_heterogeneous_system<
90 Dim,
91 System
92 >::type
93 > type;
94 };
95
96 /// INTERNAL ONLY
97 template<class S1,class S2>
98 struct is_implicitly_convertible :
99 boost::is_same<typename reduce_unit<S1>::type, typename reduce_unit<S2>::type>
100 { };
101
102 /// unit unary plus typeof helper
103 /// INTERNAL ONLY
104 template<class Dim,class System>
105 struct unary_plus_typeof_helper< unit<Dim,System> >
106 {
107 typedef unit<Dim,System> type;
108 };
109
110 /// unit unary minus typeof helper
111 /// INTERNAL ONLY
112 template<class Dim,class System>
113 struct unary_minus_typeof_helper< unit<Dim,System> >
114 {
115 typedef unit<Dim,System> type;
116 };
117
118 /// unit add typeof helper
119 /// INTERNAL ONLY
120 template<class Dim,
121 class System>
122 struct add_typeof_helper< unit<Dim,System>,unit<Dim,System> >
123 {
124 typedef unit<Dim,System> type;
125 };
126
127 /// unit subtract typeof helper
128 /// INTERNAL ONLY
129 template<class Dim,
130 class System>
131 struct subtract_typeof_helper< unit<Dim,System>,unit<Dim,System> >
132 {
133 typedef unit<Dim,System> type;
134 };
135
136 /// unit multiply typeof helper for two identical homogeneous systems
137 /// INTERNAL ONLY
138 template<class Dim1,
139 class Dim2,
140 class System>
141 struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System> >,
142 unit<Dim2,homogeneous_system<System> > >
143 {
144 typedef unit<typename mpl::times<Dim1,Dim2>::type,homogeneous_system<System> > type;
145 };
146
147 /// unit multiply typeof helper for two different homogeneous systems
148 /// INTERNAL ONLY
149 template<class Dim1,
150 class Dim2,
151 class System1,
152 class System2>
153 struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
154 unit<Dim2,homogeneous_system<System2> > >
155 {
156 typedef unit<
157 typename mpl::times<Dim1,Dim2>::type,
158 typename detail::multiply_systems<
159 typename detail::make_heterogeneous_system<Dim1, System1>::type,
160 typename detail::make_heterogeneous_system<Dim2, System2>::type
161 >::type
162 > type;
163 };
164
165 /// unit multiply typeof helper for a heterogeneous and a homogeneous system
166 /// INTERNAL ONLY
167 template<class Dim1,
168 class Dim2,
169 class System1,
170 class System2>
171 struct multiply_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
172 unit<Dim2,homogeneous_system<System2> > >
173 {
174 typedef unit<
175 typename mpl::times<Dim1,Dim2>::type,
176 typename detail::multiply_systems<
177 heterogeneous_system<System1>,
178 typename detail::make_heterogeneous_system<Dim2, System2>::type
179 >::type
180 > type;
181 };
182
183 /// unit multiply typeof helper for a homogeneous and a heterogeneous system
184 /// INTERNAL ONLY
185 template<class Dim1,
186 class Dim2,
187 class System1,
188 class System2>
189 struct multiply_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
190 unit<Dim2,heterogeneous_system<System2> > >
191 {
192 typedef unit<
193 typename mpl::times<Dim1,Dim2>::type,
194 typename detail::multiply_systems<
195 typename detail::make_heterogeneous_system<Dim1, System1>::type,
196 heterogeneous_system<System2>
197 >::type
198 > type;
199 };
200
201 /// unit multiply typeof helper for two heterogeneous systems
202 /// INTERNAL ONLY
203 template<class Dim1,
204 class Dim2,
205 class System1,
206 class System2>
207 struct multiply_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
208 unit<Dim2,heterogeneous_system<System2> > >
209 {
210 typedef unit<
211 typename mpl::times<Dim1,Dim2>::type,
212 typename detail::multiply_systems<
213 heterogeneous_system<System1>,
214 heterogeneous_system<System2>
215 >::type
216 > type;
217 };
218
219 /// unit divide typeof helper for two identical homogeneous systems
220 /// INTERNAL ONLY
221 template<class Dim1,
222 class Dim2,
223 class System>
224 struct divide_typeof_helper< unit<Dim1,homogeneous_system<System> >,
225 unit<Dim2,homogeneous_system<System> > >
226 {
227 typedef unit<typename mpl::divides<Dim1,Dim2>::type,homogeneous_system<System> > type;
228 };
229
230 /// unit divide typeof helper for two different homogeneous systems
231 /// INTERNAL ONLY
232 template<class Dim1,
233 class Dim2,
234 class System1,
235 class System2>
236 struct divide_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
237 unit<Dim2,homogeneous_system<System2> > >
238 {
239 typedef unit<
240 typename mpl::divides<Dim1,Dim2>::type,
241 typename detail::divide_systems<
242 typename detail::make_heterogeneous_system<Dim1, System1>::type,
243 typename detail::make_heterogeneous_system<Dim2, System2>::type
244 >::type
245 > type;
246 };
247
248 /// unit divide typeof helper for a heterogeneous and a homogeneous system
249 /// INTERNAL ONLY
250 template<class Dim1,
251 class Dim2,
252 class System1,
253 class System2>
254 struct divide_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
255 unit<Dim2,homogeneous_system<System2> > >
256 {
257 typedef unit<
258 typename mpl::divides<Dim1,Dim2>::type,
259 typename detail::divide_systems<
260 heterogeneous_system<System1>,
261 typename detail::make_heterogeneous_system<Dim2, System2>::type
262 >::type
263 > type;
264 };
265
266 /// unit divide typeof helper for a homogeneous and a heterogeneous system
267 /// INTERNAL ONLY
268 template<class Dim1,
269 class Dim2,
270 class System1,
271 class System2>
272 struct divide_typeof_helper< unit<Dim1,homogeneous_system<System1> >,
273 unit<Dim2,heterogeneous_system<System2> > >
274 {
275 typedef unit<
276 typename mpl::divides<Dim1,Dim2>::type,
277 typename detail::divide_systems<
278 typename detail::make_heterogeneous_system<Dim1, System1>::type,
279 heterogeneous_system<System2>
280 >::type
281 > type;
282 };
283
284 /// unit divide typeof helper for two heterogeneous systems
285 /// INTERNAL ONLY
286 template<class Dim1,
287 class Dim2,
288 class System1,
289 class System2>
290 struct divide_typeof_helper< unit<Dim1,heterogeneous_system<System1> >,
291 unit<Dim2,heterogeneous_system<System2> > >
292 {
293 typedef unit<
294 typename mpl::divides<Dim1,Dim2>::type,
295 typename detail::divide_systems<
296 heterogeneous_system<System1>,
297 heterogeneous_system<System2>
298 >::type
299 > type;
300 };
301
302 /// raise unit to a @c static_rational power
303 template<class Dim,class System,long N,long D>
304 struct power_typeof_helper<unit<Dim,System>,static_rational<N,D> >
305 {
306 typedef unit<typename static_power<Dim,static_rational<N,D> >::type,typename static_power<System, static_rational<N,D> >::type> type;
307
308 static type value(const unit<Dim,System>&)
309 {
310 return type();
311 }
312 };
313
314 /// take the @c static_rational root of a unit
315 template<class Dim,class System,long N,long D>
316 struct root_typeof_helper<unit<Dim,System>,static_rational<N,D> >
317 {
318 typedef unit<typename static_root<Dim,static_rational<N,D> >::type,typename static_root<System, static_rational<N,D> >::type> type;
319
320 static type value(const unit<Dim,System>&)
321 {
322 return type();
323 }
324 };
325
326 /// unit runtime unary plus
327 template<class Dim,class System>
328 typename unary_plus_typeof_helper< unit<Dim,System> >::type
329 operator+(const unit<Dim,System>&)
330 {
331 typedef typename unary_plus_typeof_helper< unit<Dim,System> >::type type;
332
333 return type();
334 }
335
336 /// unit runtime unary minus
337 template<class Dim,class System>
338 typename unary_minus_typeof_helper< unit<Dim,System> >::type
339 operator-(const unit<Dim,System>&)
340 {
341 typedef typename unary_minus_typeof_helper< unit<Dim,System> >::type type;
342
343 return type();
344 }
345
346 /// runtime add two units
347 template<class Dim1,
348 class Dim2,
349 class System1,
350 class System2>
351 typename add_typeof_helper< unit<Dim1,System1>,
352 unit<Dim2,System2> >::type
353 operator+(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
354 {
355 BOOST_STATIC_ASSERT((boost::is_same<System1,System2>::value == true));
356
357 typedef System1 system_type;
358 typedef typename add_typeof_helper< unit<Dim1,system_type>,
359 unit<Dim2,system_type> >::type type;
360
361 return type();
362 }
363
364 /// runtime subtract two units
365 template<class Dim1,
366 class Dim2,
367 class System1,
368 class System2>
369 typename subtract_typeof_helper< unit<Dim1,System1>,
370 unit<Dim2,System2> >::type
371 operator-(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
372 {
373 BOOST_STATIC_ASSERT((boost::is_same<System1,System2>::value == true));
374
375 typedef System1 system_type;
376 typedef typename subtract_typeof_helper< unit<Dim1,system_type>,
377 unit<Dim2,system_type> >::type type;
378
379 return type();
380 }
381
382 /// runtime multiply two units
383 template<class Dim1,
384 class Dim2,
385 class System1,
386 class System2>
387 typename multiply_typeof_helper< unit<Dim1,System1>,
388 unit<Dim2,System2> >::type
389 operator*(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
390 {
391 typedef typename multiply_typeof_helper< unit<Dim1,System1>,
392 unit<Dim2,System2> >::type type;
393
394 return type();
395 }
396
397 /// runtime divide two units
398 template<class Dim1,
399 class Dim2,
400 class System1,
401 class System2>
402 typename divide_typeof_helper< unit<Dim1,System1>,
403 unit<Dim2,System2> >::type
404 operator/(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
405 {
406 typedef typename divide_typeof_helper< unit<Dim1,System1>,
407 unit<Dim2,System2> >::type type;
408
409 return type();
410 }
411
412 /// unit runtime @c operator==
413 template<class Dim1,
414 class Dim2,
415 class System1,
416 class System2>
417 inline
418 bool
419 operator==(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
420 {
421 return boost::is_same<typename reduce_unit<unit<Dim1,System1> >::type, typename reduce_unit<unit<Dim2,System2> >::type>::value;
422 }
423
424 /// unit runtime @c operator!=
425 template<class Dim1,
426 class Dim2,
427 class System1,
428 class System2>
429 inline
430 bool
431 operator!=(const unit<Dim1,System1>&,const unit<Dim2,System2>&)
432 {
433 return !boost::is_same<typename reduce_unit<unit<Dim1,System1> >::type, typename reduce_unit<unit<Dim2,System2> >::type>::value;
434 }
435
436 } // namespace units
437
438 } // namespace boost
439
440 #endif // BOOST_UNITS_UNIT_HPP