165 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			165 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | // Boost.Units - A C++ library for zero-overhead dimensional analysis and  | ||
|  | // unit/quantity manipulation and conversion | ||
|  | // | ||
|  | // Copyright (C) 2003-2008 Matthias Christian Schabel | ||
|  | // Copyright (C) 2008 Steven Watanabe | ||
|  | // | ||
|  | // Distributed under the Boost Software License, Version 1.0. (See | ||
|  | // accompanying file LICENSE_1_0.txt or copy at | ||
|  | // http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | #ifndef BOOST_UNITS_OPERATORS_HPP  | ||
|  | #define BOOST_UNITS_OPERATORS_HPP | ||
|  | 
 | ||
|  | 
 | ||
|  | /// | ||
|  | /// \file | ||
|  | /// \brief Compile time operators and typeof helper classes. | ||
|  | /// \details | ||
|  | ///   These operators declare the compile-time operators needed to support dimensional | ||
|  | ///   analysis algebra.  They require the use of Boost.Typeof, emulation or native. | ||
|  | ///   Typeof helper classes define result type for heterogeneous operators on value types. | ||
|  | ///   These must be defined through specialization for powers and roots. | ||
|  | /// | ||
|  | 
 | ||
|  | #include <boost/static_assert.hpp> | ||
|  | #include <boost/type_traits/is_same.hpp> | ||
|  | 
 | ||
|  | #include <boost/units/config.hpp> | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | namespace units { | ||
|  | 
 | ||
|  | #if BOOST_UNITS_HAS_TYPEOF | ||
|  | 
 | ||
|  | #ifndef BOOST_UNITS_DOXYGEN | ||
|  | 
 | ||
|  | // to avoid need for default constructor and eliminate divide by zero errors. | ||
|  | namespace typeof_ { | ||
|  | 
 | ||
|  | /// INTERNAL ONLY | ||
|  | template<class T> T make(); | ||
|  | 
 | ||
|  | } // namespace typeof_ | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  | #if (BOOST_UNITS_HAS_BOOST_TYPEOF) | ||
|  | 
 | ||
|  | template<typename X> struct unary_plus_typeof_helper             | ||
|  | { | ||
|  |     BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (+typeof_::make<X>())) | ||
|  |     typedef typename nested::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename X> struct unary_minus_typeof_helper            | ||
|  | { | ||
|  |     BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (-typeof_::make<X>())) | ||
|  |     typedef typename nested::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct add_typeof_helper         | ||
|  | { | ||
|  |     BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()+typeof_::make<Y>())) | ||
|  |     typedef typename nested::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct subtract_typeof_helper    | ||
|  | { | ||
|  |     BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()-typeof_::make<Y>())) | ||
|  |     typedef typename nested::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct multiply_typeof_helper    | ||
|  | { | ||
|  |     BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()*typeof_::make<Y>())) | ||
|  |     typedef typename nested::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct divide_typeof_helper      | ||
|  | { | ||
|  |     BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (typeof_::make<X>()/typeof_::make<Y>())) | ||
|  |     typedef typename nested::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | #elif (BOOST_UNITS_HAS_MWERKS_TYPEOF) | ||
|  | 
 | ||
|  | template<typename X> struct unary_plus_typeof_helper            { typedef __typeof__((+typeof_::make<X>())) type; }; | ||
|  | template<typename X> struct unary_minus_typeof_helper           { typedef __typeof__((-typeof_::make<X>())) type; }; | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct add_typeof_helper        { typedef __typeof__((typeof_::make<X>()+typeof_::make<Y>())) type; }; | ||
|  | template<typename X,typename Y> struct subtract_typeof_helper   { typedef __typeof__((typeof_::make<X>()-typeof_::make<Y>())) type; }; | ||
|  | template<typename X,typename Y> struct multiply_typeof_helper   { typedef __typeof__((typeof_::make<X>()*typeof_::make<Y>())) type; }; | ||
|  | template<typename X,typename Y> struct divide_typeof_helper     { typedef __typeof__((typeof_::make<X>()/typeof_::make<Y>())) type; }; | ||
|  | 
 | ||
|  | #elif (BOOST_UNITS_HAS_GNU_TYPEOF) || defined(BOOST_UNITS_DOXYGEN) | ||
|  | 
 | ||
|  | template<typename X> struct unary_plus_typeof_helper            { typedef typeof((+typeof_::make<X>())) type; }; | ||
|  | template<typename X> struct unary_minus_typeof_helper           { typedef typeof((-typeof_::make<X>())) type; }; | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct add_typeof_helper        { typedef typeof((typeof_::make<X>()+typeof_::make<Y>())) type; }; | ||
|  | template<typename X,typename Y> struct subtract_typeof_helper   { typedef typeof((typeof_::make<X>()-typeof_::make<Y>())) type; }; | ||
|  | template<typename X,typename Y> struct multiply_typeof_helper   { typedef typeof((typeof_::make<X>()*typeof_::make<Y>())) type; }; | ||
|  | template<typename X,typename Y> struct divide_typeof_helper     { typedef typeof((typeof_::make<X>()/typeof_::make<Y>())) type; }; | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  | #else // BOOST_UNITS_HAS_TYPEOF | ||
|  | 
 | ||
|  | template<typename X> struct unary_plus_typeof_helper            { typedef X type; }; | ||
|  | template<typename X> struct unary_minus_typeof_helper           { typedef X type; }; | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct add_typeof_helper        { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; | ||
|  | template<typename X,typename Y> struct subtract_typeof_helper   { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; | ||
|  | template<typename X,typename Y> struct multiply_typeof_helper   { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; | ||
|  | template<typename X,typename Y> struct divide_typeof_helper     { BOOST_STATIC_ASSERT((is_same<X,Y>::value == true)); typedef X type; }; | ||
|  | 
 | ||
|  | #endif // BOOST_UNITS_HAS_TYPEOF | ||
|  | 
 | ||
|  | template<typename X,typename Y> struct power_typeof_helper; | ||
|  | template<typename X,typename Y> struct root_typeof_helper; | ||
|  | 
 | ||
|  | #ifdef BOOST_UNITS_DOXYGEN | ||
|  | 
 | ||
|  | /// A helper used by @c pow to raise | ||
|  | /// a runtime object to a compile time | ||
|  | /// known exponent.  This template is intended to | ||
|  | /// be specialized.  All specializations must | ||
|  | /// conform to the interface shown here. | ||
|  | /// @c Exponent will be either the exponent | ||
|  | /// passed to @c pow or @c static_rational<N> | ||
|  | /// for and integer argument, N. | ||
|  | template<typename BaseType, typename Exponent> | ||
|  | struct power_typeof_helper | ||
|  | { | ||
|  |     /// specifies the result type | ||
|  |     typedef detail::unspecified type; | ||
|  |     /// Carries out the runtime calculation. | ||
|  |     static type value(const BaseType& base); | ||
|  | }; | ||
|  | 
 | ||
|  | /// A helper used by @c root to take a root | ||
|  | /// of a runtime object using a compile time | ||
|  | /// known index.  This template is intended to | ||
|  | /// be specialized.  All specializations must | ||
|  | /// conform to the interface shown here. | ||
|  | /// @c Index will be either the type | ||
|  | /// passed to @c pow or @c static_rational<N> | ||
|  | /// for and integer argument, N. | ||
|  | template<typename Radicand, typename Index> | ||
|  | struct root_typeof_helper | ||
|  | { | ||
|  |     /// specifies the result type | ||
|  |     typedef detail::unspecified type; | ||
|  |     /// Carries out the runtime calculation. | ||
|  |     static type value(const Radicand& base); | ||
|  | }; | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  | } // namespace units | ||
|  | 
 | ||
|  | } // namespace boost | ||
|  | 
 | ||
|  | #endif // BOOST_UNITS_OPERATORS_HPP |