Parent Directory
|
Revision Log
add allow_unit_conversions function
1 #ifndef QUAN_META_MPL_UNIT_HPP_INCLUDED 2 #define QUAN_META_MPL_UNIT_HPP_INCLUDED 3 #if (defined _MSC_VER) && (_MSC_VER >= 1200) 4 # pragma once 5 #endif 6 7 // Copyright Andrew Little 2005 8 // 9 // Distributed under the Boost Software License, Version 1.0. 10 // (See accompanying file LICENSE_1_0.txt or copy at 11 // http://www.boost.org/LICENSE_1_0.txt) 12 // 13 // See http://www.boost.org/libs/mpl for documentation. 14 15 /* 16 simple model of StaticUnit using the Boost.Mpl library 17 */ 18 19 #include <quan/config.hpp> 20 //#include <quan/meta/mpl/reciprocal.hpp> 21 //#include <quan/meta/mpl/pow.hpp> 22 #include <quan/meta/si_unit_system.hpp> 23 #include <quan/meta/static_unit_concept.hpp> 24 #include <quan/meta/conversion_factor.hpp> 25 26 #include <boost/mpl/arithmetic.hpp> 27 #include <boost/mpl/bool.hpp> 28 #include <boost/mpl/if.hpp> 29 #include <boost/mpl/equal.hpp> 30 #include <boost/mpl/equal_to.hpp> 31 #include <boost/mpl/not_equal_to.hpp> 32 #include <boost/mpl/int.hpp> 33 #include <boost/mpl/eval_if.hpp> 34 #include <boost/mpl/transform.hpp> 35 #include <boost/mpl/placeholders.hpp> 36 #include <boost/mpl/find_if.hpp> 37 #include <boost/mpl/at.hpp> 38 #include <boost/mpl/assert.hpp> 39 40 #include <boost/type_traits/is_same.hpp> 41 #include <boost/typeof/typeof.hpp> 42 43 #ifdef QUAN_USE_BOOST_TYPEOF_BINARY_OPERATION 44 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() 45 BOOST_TYPEOF_REGISTER_TEMPLATE(quan::meta::mpl::unit, 1); 46 #endif 47 48 namespace quan{ namespace meta{namespace mpl{ 49 50 template< 51 typename Dimension 52 > 53 struct unit{ 54 typedef Dimension dimension; 55 typedef unit type; 56 }; 57 58 }}}// quan::meta::mpl 59 60 namespace quan{ namespace meta{ 61 62 template < 63 typename DimensionL, 64 typename DimensionR 65 > 66 struct dimensionally_equivalent< 67 quan::meta::mpl::unit< 68 DimensionL 69 >, 70 quan::meta::mpl::unit< 71 DimensionR 72 > 73 > : boost::mpl::equal< 74 DimensionL, 75 DimensionR, 76 boost::mpl::equal_to< 77 boost::mpl::_1, 78 boost::mpl::_2 79 > 80 >{}; 81 82 template <typename Dimension> 83 struct is_dimensionless< 84 quan::meta::mpl::unit<Dimension> 85 > : boost::is_same < 86 typename ::boost::mpl::find_if< 87 Dimension, 88 boost::mpl::not_equal_to< 89 boost::mpl::_1, 90 boost::mpl::minus<boost::mpl::_1,boost::mpl::_1> 91 > 92 >::type , 93 typename boost::mpl::end<Dimension>::type 94 >{}; 95 96 template <typename Dimension> 97 struct make_anonymous< 98 quan::meta::mpl::unit<Dimension> 99 > : quan::meta::mpl::unit<Dimension>{}; 100 101 template <typename Dimension> 102 struct get_quantity_system< 103 quan::meta::mpl::unit<Dimension> 104 > : quan::meta::si_unit_system {}; 105 106 template <typename Dimension> 107 struct is_si < 108 quan::meta::mpl::unit<Dimension> 109 > : boost::mpl::true_{}; 110 111 template <typename Dimension> 112 struct is_named_quantity < 113 quan::meta::mpl::unit<Dimension> 114 > : boost::mpl::false_{}; 115 116 template < 117 typename DimensionL, 118 typename DimensionR 119 > 120 struct is_same_quantity < 121 quan::meta::mpl::unit<DimensionL>, 122 quan::meta::mpl::unit<DimensionR> 123 > : dimensionally_equivalent< 124 quan::meta::mpl::unit<DimensionL>, 125 quan::meta::mpl::unit<DimensionR> 126 >{}; 127 128 template <typename Dimension> 129 struct get_conversion_factor < 130 quan::meta::mpl::unit<Dimension> 131 > : quan::meta::conversion_factor<>{}; 132 133 template <typename Dimension> 134 struct allow_implicit_unit_conversions< 135 quan::meta::mpl::unit<Dimension> 136 > : boost::mpl::false_{}; 137 138 template <typename Dimension> 139 struct get_nearest_si < 140 quan::meta::mpl::unit<Dimension> 141 > : quan::meta::mpl::unit<Dimension>{}; 142 143 template <typename Dimension> 144 struct get_named_quantity_traits< 145 quan::meta::mpl::unit<Dimension> 146 > : anonymous_quantity_traits{}; 147 148 #define QUAN_META_GET_DIMENSION(Q,Pos) \ 149 template <typename Dimension> \ 150 struct BOOST_PP_CAT(BOOST_PP_CAT(get_,Q),_dimension) <\ 151 quan::meta::mpl::unit<Dimension> \ 152 > : boost::mpl::at_c<Dimension, Pos >{}; 153 QUAN_META_GET_DIMENSION(length,0) 154 QUAN_META_GET_DIMENSION(time,1) 155 QUAN_META_GET_DIMENSION(mass,2) 156 QUAN_META_GET_DIMENSION(temperature,3) 157 QUAN_META_GET_DIMENSION(current,4) 158 QUAN_META_GET_DIMENSION(substance,5) 159 QUAN_META_GET_DIMENSION(intensity,6) 160 #undef QUAN_META_GET_DIMENSION 161 162 163 }}//quan::meta 164 165 namespace boost{namespace mpl{ 166 167 template< 168 typename DimensionL, 169 typename DimensionR 170 > 171 struct plus< 172 quan::meta::mpl::unit<DimensionL>, 173 quan::meta::mpl::unit<DimensionR> 174 > : quan::meta::mpl::unit< 175 typename transform< 176 DimensionL, 177 DimensionR, 178 plus<_1,_2> 179 >::type 180 >{}; 181 182 template< 183 typename DimensionL, 184 typename DimensionR 185 > 186 struct minus< 187 quan::meta::mpl::unit<DimensionL>, 188 quan::meta::mpl::unit<DimensionR> 189 > : quan::meta::mpl::unit< 190 typename transform< 191 DimensionL, 192 DimensionR, 193 minus<_1,_2> 194 >::type 195 >{}; 196 197 template< 198 typename Dimension 199 > 200 struct negate< 201 quan::meta::mpl::unit<Dimension> 202 > : quan::meta::mpl::unit< 203 typename transform< 204 Dimension, 205 negate<_1> 206 >::type 207 >{}; 208 209 template< 210 typename Dimension, 211 typename C 212 > 213 struct times< 214 quan::meta::mpl::unit<Dimension>,C 215 > : quan::meta::mpl::unit< 216 typename transform< 217 Dimension, 218 times<_1,typename quan::meta::numerator<C>::type> 219 >::type 220 >{ 221 BOOST_MPL_ASSERT(( 222 boost::mpl::equal_to< 223 quan::meta::denominator<C>::type, 224 boost::mpl::int_<1> 225 > 226 )); 227 }; 228 // not required? 229 /* template< 230 typename Dimension, 231 typename C 232 > 233 struct divides< 234 quan::meta::mpl::unit<Dimension>,C 235 > : quan::meta::mpl::unit< 236 typename transform< 237 Dimension, 238 divides<_1,typename quan::meta::numerator<C>::type> 239 >::type 240 >{ 241 BOOST_MPL_ASSERT(( boost::mpl::equal_to< 242 quan::meta::denominator<C>::type 243 boost::mpl::int_<1> 244 )); 245 };*/ 246 247 }}//boost::mpl 248 249 namespace quan{ namespace meta{ 250 251 template <typename DL, typename DR> 252 struct binary_operation< 253 quan::meta::mpl::unit<DL>,plus,quan::meta::mpl::unit<DR> 254 > { 255 256 BOOST_MPL_ASSERT(( 257 dimensionally_equivalent< 258 quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR> 259 > 260 )); 261 typedef quan::meta::mpl::unit<DL> type; 262 }; 263 264 template <typename DL, typename DR> 265 struct binary_operation< 266 quan::meta::mpl::unit<DL>,minus,quan::meta::mpl::unit<DR> 267 > { 268 269 BOOST_MPL_ASSERT(( 270 dimensionally_equivalent< 271 quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR> 272 > 273 )); 274 typedef quan::meta::mpl::unit<DL> type; 275 }; 276 277 template <typename DL, typename DR> 278 struct binary_operation< 279 quan::meta::mpl::unit<DL>,times,quan::meta::mpl::unit<DR> 280 > { 281 typedef typename boost::mpl::plus< 282 quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR> 283 >::type type; 284 }; 285 286 template <typename DL, typename DR> 287 struct binary_operation< 288 quan::meta::mpl::unit<DL>,divides,quan::meta::mpl::unit<DR> 289 > { 290 typedef typename boost::mpl::minus< 291 quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR> 292 >::type type; 293 }; 294 295 template <typename DL, typename Exp> 296 struct binary_operation< 297 quan::meta::mpl::unit<DL>,pow, Exp 298 > { 299 typedef typename boost::mpl::times< 300 quan::meta::mpl::unit<DL>,Exp 301 >::type type; 302 }; 303 304 template <typename D> 305 struct unary_operation< 306 reciprocal,quan::meta::mpl::unit<D> 307 > { 308 typedef typename boost::mpl::negate< 309 quan::meta::mpl::unit<D> 310 >::type type; 311 }; 312 313 }} 314 315 // add binary and unary ops 316 317 #endif