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_OPERATORS_HPP
12#define BOOST_UNITS_OPERATORS_HPP
13
14
15///
16/// \file
17/// \brief Compile time operators and typeof helper classes.
18/// \details
19/// These operators declare the compile-time operators needed to support dimensional
20/// analysis algebra. They require the use of Boost.Typeof, emulation or native.
21/// Typeof helper classes define result type for heterogeneous operators on value types.
22/// These must be defined through specialization for powers and roots.
23///
24
25#include <boost/static_assert.hpp>
26#include <boost/type_traits/is_same.hpp>
27
28#include <boost/units/config.hpp>
29
30namespace boost {
31namespace units {
32
33#if BOOST_UNITS_HAS_TYPEOF
34
35#ifndef BOOST_UNITS_DOXYGEN
36
37// to avoid need for default constructor and eliminate divide by zero errors.
38namespace typeof_ {
39
40/// INTERNAL ONLY
41template<class T> T make();
42
43} // namespace typeof_
44
45#endif
46
47#if (BOOST_UNITS_HAS_BOOST_TYPEOF)
48
49template<typename X> struct unary_plus_typeof_helper
50{
51 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (+typeof_::make<X>()))
52 typedef typename nested::type type;
53};
54
55template<typename X> struct unary_minus_typeof_helper
56{
57 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (-typeof_::make<X>()))
58 typedef typename nested::type type;
59};
60
61template<typename X,typename Y> struct add_typeof_helper
62{
63 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()+typeof_::make<Y>()))
64 typedef typename nested::type type;
65};
66
67template<typename X,typename Y> struct subtract_typeof_helper
68{
69 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()-typeof_::make<Y>()))
70 typedef typename nested::type type;
71};
72
73template<typename X,typename Y> struct multiply_typeof_helper
74{
75 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()*typeof_::make<Y>()))
76 typedef typename nested::type type;
77};
78
79template<typename X,typename Y> struct divide_typeof_helper
80{
81 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()/typeof_::make<Y>()))
82 typedef typename nested::type type;
83};
84
85#elif (BOOST_UNITS_HAS_MWERKS_TYPEOF)
86
87template<typename X> struct unary_plus_typeof_helper { typedef __typeof__((+typeof_::make<X>())) type; };
88template<typename X> struct unary_minus_typeof_helper { typedef __typeof__((-typeof_::make<X>())) type; };
89
90template<typename X,typename Y> struct add_typeof_helper { typedef __typeof__((typeof_::make<X>()+typeof_::make<Y>())) type; };
91template<typename X,typename Y> struct subtract_typeof_helper { typedef __typeof__((typeof_::make<X>()-typeof_::make<Y>())) type; };
92template<typename X,typename Y> struct multiply_typeof_helper { typedef __typeof__((typeof_::make<X>()*typeof_::make<Y>())) type; };
93template<typename X,typename Y> struct divide_typeof_helper { typedef __typeof__((typeof_::make<X>()/typeof_::make<Y>())) type; };
94
95#elif (BOOST_UNITS_HAS_GNU_TYPEOF) || defined(BOOST_UNITS_DOXYGEN)
96
97template<typename X> struct unary_plus_typeof_helper { typedef typeof((+typeof_::make<X>())) type; };
98template<typename X> struct unary_minus_typeof_helper { typedef typeof((-typeof_::make<X>())) type; };
99
100template<typename X,typename Y> struct add_typeof_helper { typedef typeof((typeof_::make<X>()+typeof_::make<Y>())) type; };
101template<typename X,typename Y> struct subtract_typeof_helper { typedef typeof((typeof_::make<X>()-typeof_::make<Y>())) type; };
102template<typename X,typename Y> struct multiply_typeof_helper { typedef typeof((typeof_::make<X>()*typeof_::make<Y>())) type; };
103template<typename X,typename Y> struct divide_typeof_helper { typedef typeof((typeof_::make<X>()/typeof_::make<Y>())) type; };
104
105#endif
106
107#else // BOOST_UNITS_HAS_TYPEOF
108
109template<typename X> struct unary_plus_typeof_helper { typedef X type; };
110template<typename X> struct unary_minus_typeof_helper { typedef X type; };
111
112template<typename X,typename Y> struct add_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
113template<typename X,typename Y> struct subtract_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
114template<typename X,typename Y> struct multiply_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
115template<typename X,typename Y> struct divide_typeof_helper { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; };
116
117#endif // BOOST_UNITS_HAS_TYPEOF
118
119template<typename X,typename Y> struct power_typeof_helper;
120template<typename X,typename Y> struct root_typeof_helper;
121
122#ifdef BOOST_UNITS_DOXYGEN
123
124/// A helper used by @c pow to raise
125/// a runtime object to a compile time
126/// known exponent. This template is intended to
127/// be specialized. All specializations must
128/// conform to the interface shown here.
129/// @c Exponent will be either the exponent
130/// passed to @c pow or @c static_rational<N>
131/// for and integer argument, N.
132template<typename BaseType, typename Exponent>
133struct power_typeof_helper
134{
135 /// specifies the result type
136 typedef detail::unspecified type;
137 /// Carries out the runtime calculation.
138 static type value(const BaseType& base);
139};
140
141/// A helper used by @c root to take a root
142/// of a runtime object using a compile time
143/// known index. This template is intended to
144/// be specialized. All specializations must
145/// conform to the interface shown here.
146/// @c Index will be either the type
147/// passed to @c pow or @c static_rational<N>
148/// for and integer argument, N.
149template<typename Radicand, typename Index>
150struct root_typeof_helper
151{
152 /// specifies the result type
153 typedef detail::unspecified type;
154 /// Carries out the runtime calculation.
155 static type value(const Radicand& base);
156};
157
158#endif
159
160} // namespace units
161
162} // namespace boost
163
164#endif // BOOST_UNITS_OPERATORS_HPP
165

source code of boost/boost/units/operators.hpp