00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <boost/mpl/vector.hpp>
00018 #include <boost/mpl/size.hpp>
00019 #include <boost/mpl/find.hpp>
00020 #include <boost/mpl/push_back.hpp>
00021 #include <boost/mpl/at.hpp>
00022 #include <boost/mpl/map.hpp>
00023 #include <boost/mpl/insert.hpp>
00024 #include <boost/mpl/pair.hpp>
00025 #include <boost/mpl/fold.hpp>
00026 #include <boost/mpl/multiplies.hpp>
00027 #include <boost/mpl/transform.hpp>
00028 #include <boost/mpl/erase_key.hpp>
00029 #include <boost/type_traits/is_same.hpp>
00030 #include <boost/static_assert.hpp>
00031 #include <boost/mpl/equal.hpp>
00032
00033
00034 #include "physical/detail/static_rational.hpp"
00035 using mcs::units::static_rational;
00036 using mcs::units::static_multiply;
00037 using mcs::units::static_divide;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 template<int V> struct static_abs {
00049 BOOST_STATIC_CONSTANT(int, value= V>=0? V : -V);
00050 };
00051
00052
00053 template<typename R1> struct static_invert {
00054 typedef typename static_divide<static_rational<1,1>, R1>::type type;
00055 };
00056
00057
00058 template<typename R1, int EXP> struct static_power_impl {
00059 BOOST_STATIC_ASSERT(EXP>0);
00060 typedef typename static_power_impl<R1, EXP-1>::type part;
00061 typedef typename static_multiply<part, R1>::type type;
00062 };
00063
00064
00065 template<typename R1> struct static_power_impl<R1, 1> {
00066 typedef R1 type;
00067 };
00068
00069 template<typename R1> struct static_power_impl<R1, 0> {
00070 typedef static_rational<1,1> type;
00071 };
00072
00073
00074 template<typename R1, int EXP> struct static_power {
00075 BOOST_STATIC_CONSTANT(int, E = static_abs<EXP>::value);
00076 BOOST_STATIC_ASSERT(E>=0);
00077 typedef typename static_power_impl<R1, E>::type part;
00078 typedef typename boost::mpl::if_c< (EXP>0), part, typename static_invert<part>::type>::type type;
00079 };
00080
00081
00082
00083 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, -3>::type, static_rational<1,8> >::type::value));
00084 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, -2>::type, static_rational<1,4> >::type::value));
00085 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, -1>::type, static_rational<1,2> >::type::value));
00086 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, -0>::type, static_rational<1,1> >::type::value));
00087 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, 0>::type, static_rational<1,1> >::type::value));
00088 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, 1>::type, static_rational<2,1> >::type::value));
00089 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, 2>::type, static_rational<4,1> >::type::value));
00090 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<2,1>, 3>::type, static_rational<8,1> >::type::value));
00091
00092 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, -3>::type, static_rational<8,1> >::type::value));
00093 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, -2>::type, static_rational<4,1> >::type::value));
00094 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, -1>::type, static_rational<2,1> >::type::value));
00095 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, -0>::type, static_rational<1,1> >::type::value));
00096 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, 0>::type, static_rational<1,1> >::type::value));
00097 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, 1>::type, static_rational<1,2> >::type::value));
00098 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, 2>::type, static_rational<1,4> >::type::value));
00099 BOOST_STATIC_ASSERT(( boost::is_same<static_power< static_rational<1,2>, 3>::type, static_rational<1,8> >::type::value));
00100
00101
00102
00103
00104 namespace old_primes {
00105
00106 struct yes { BOOST_STATIC_CONSTANT(int, value = 1); };
00107
00108 struct no { BOOST_STATIC_CONSTANT(int, value = 0); };
00109
00110 template<int a, int b> struct is_divisible {
00111 typedef typename boost::mpl::if_c< (a/b)*b==a, yes, no>::type type;
00112 BOOST_STATIC_CONSTANT( int, value = type::value);
00113 };
00114
00115 BOOST_STATIC_ASSERT(( is_divisible<8,1>::type::value ));
00116 BOOST_STATIC_ASSERT(( is_divisible<8,2>::type::value ));
00117 BOOST_STATIC_ASSERT(( is_divisible<8,4>::type::value ));
00118 BOOST_STATIC_ASSERT(( is_divisible<8,8>::type::value ));
00119 BOOST_STATIC_ASSERT(( !is_divisible<8,16>::type::value ));
00120 BOOST_STATIC_ASSERT(( !is_divisible<8,3>::type::value ));
00121
00122
00123
00124
00125
00126 template<int n> struct primes;
00127
00128 template<> struct primes<1> {
00129 typedef boost::mpl::vector<> type;
00130 };
00131
00132 template<> struct primes<2> {
00133 typedef boost::mpl::vector<boost::mpl::integral_c<int,2> > type;
00134 };
00135
00136 template<> struct primes<3> {
00137 typedef boost::mpl::push_back<primes<2>::type, boost::mpl::integral_c<int,3> >::type type;
00138 };
00139
00140
00141
00142
00143 template<typename n, typename upto> struct prime_decomposition;
00144
00145
00146 template<typename n> struct prime_decomposition<n, boost::mpl::integral_c<int, 1> >{
00147 typedef boost::mpl::vector<> list;
00148 typedef n remainder;
00149 };
00150
00151
00152
00153 template<typename n, typename upto> struct prime_decomposition {
00154 typedef boost::mpl::integral_c<int, upto::value-1> upto_m1;
00155 BOOST_STATIC_ASSERT(( upto_m1::value >= 1));
00156
00157 typedef typename prime_decomposition<n, upto_m1> part_decomposition;
00158 typedef typename part_decomposition::remainder part_remainder;
00159
00160 typedef typename boost::mpl::if_c< is_divisible<part_remainder::value, upto::value>::type::value,
00161 typename boost::mpl::push_back<typename part_decomposition::list, boost::mpl::integral_c<int, upto::value> >::type,
00162 typename part_decomposition::list >::type list;
00163
00164 typedef typename boost::mpl::if_c< is_divisible<part_decomposition::remainder::value, upto::value>::type::value,
00165 boost::mpl::integral_c<int, (part_decomposition::remainder::value / upto::value) >,
00166 typename part_decomposition::remainder >::type remainder;
00167
00168 };
00169
00170
00171
00172 BOOST_STATIC_ASSERT(( boost::mpl::equal<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 1> >::list, boost::mpl::vector<> >::type::value ));
00173 BOOST_STATIC_ASSERT(( boost::is_same<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 1> >::remainder, boost::mpl::integral_c<int, 5> >::type::value ));
00174
00175 BOOST_STATIC_ASSERT(( boost::mpl::equal<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 2> >::list, boost::mpl::vector<> >::type::value ));
00176 BOOST_STATIC_ASSERT(( boost::is_same<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 2> >::remainder, boost::mpl::integral_c<int, 5> >::type::value ));
00177
00178 BOOST_STATIC_ASSERT(( boost::mpl::equal<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 3> >::list, boost::mpl::vector<> >::type::value ));
00179 BOOST_STATIC_ASSERT(( boost::is_same<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 3> >::remainder, boost::mpl::integral_c<int, 5> >::type::value ));
00180
00181 BOOST_STATIC_ASSERT(( boost::mpl::equal<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 4> >::list, boost::mpl::vector<> >::type::value ));
00182 BOOST_STATIC_ASSERT(( boost::is_same<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 4> >::remainder, boost::mpl::integral_c<int, 5> >::type::value ));
00183
00184 BOOST_STATIC_ASSERT(( boost::mpl::equal<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 5> >::list, boost::mpl::vector<boost::mpl::integral_c<int, 5> > >::type::value ));
00185 BOOST_STATIC_ASSERT(( boost::is_same<typename prime_decomposition<boost::mpl::integral_c<int, 5>, boost::mpl::integral_c<int, 5> >::remainder, boost::mpl::integral_c<int, 1> >::type::value ));
00186
00187 BOOST_STATIC_ASSERT(( boost::mpl::equal<typename prime_decomposition<boost::mpl::integral_c<int, 10>, boost::mpl::integral_c<int, 4> >::list, boost::mpl::vector<boost::mpl::integral_c<int, 2> > >::type::value ));
00188 BOOST_STATIC_ASSERT(( boost::is_same<typename prime_decomposition<boost::mpl::integral_c<int, 10>, boost::mpl::integral_c<int, 4> >::remainder, boost::mpl::integral_c<int, 5> >::type::value ));
00189
00190 BOOST_STATIC_ASSERT(( boost::mpl::equal<typename prime_decomposition<boost::mpl::integral_c<int, 10>, boost::mpl::integral_c<int, 5> >::list, boost::mpl::vector<boost::mpl::integral_c<int, 2>, boost::mpl::integral_c<int, 5> > >::type::value ));
00191 BOOST_STATIC_ASSERT(( boost::is_same<typename prime_decomposition<boost::mpl::integral_c<int, 10>, boost::mpl::integral_c<int, 5> >::remainder, boost::mpl::integral_c<int, 1> >::type::value ));
00192
00193 };
00194
00195
00196 namespace primes {
00197
00198 namespace mpl=boost::mpl;
00199
00200 struct yes { BOOST_STATIC_CONSTANT(int, value = 1); };
00201
00202 struct no { BOOST_STATIC_CONSTANT(int, value = 0); };
00203
00204 template<int a, int b> struct is_divisible {
00205 typedef typename boost::mpl::if_c< (a/b)*b==a, yes, no>::type type;
00206 BOOST_STATIC_CONSTANT( int, value = type::value);
00207 };
00208
00209 BOOST_STATIC_ASSERT(( is_divisible<8,1>::type::value ));
00210 BOOST_STATIC_ASSERT(( is_divisible<8,2>::type::value ));
00211 BOOST_STATIC_ASSERT(( is_divisible<8,4>::type::value ));
00212 BOOST_STATIC_ASSERT(( is_divisible<8,8>::type::value ));
00213 BOOST_STATIC_ASSERT(( !is_divisible<8,16>::type::value ));
00214 BOOST_STATIC_ASSERT(( !is_divisible<8,3>::type::value ));
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 template<class Map, class Pair> struct add_pair_impl {
00227 typedef typename Pair::first key;
00228 typedef typename Pair::second value;
00229 BOOST_STATIC_ASSERT(( mpl::has_key<Map, key>::type::value ));
00230 typedef typename mpl::at<Map, key>::type old_value;
00231 typedef typename mpl::erase_key<Map, key>::type map_erased;
00232 typedef typename mpl::insert< map_erased, mpl::pair<key, typename mpl::plus<old_value,value>::type > >::type type;
00233 };
00234
00235
00236 template<class Map, class Pair, bool> struct add_pair_dispatch;
00237
00238 template<class Map, class Pair> struct add_pair_dispatch<Map, Pair, true> {
00239 typedef typename add_pair_impl<Map, Pair>::type type;
00240 };
00241
00242 template<class Map, class Pair> struct add_pair_dispatch<Map, Pair, false> {
00243 typedef typename mpl::insert< Map, Pair >::type type;
00244 };
00245
00246 template<class Map, class Pair> struct add_pair {
00247 typedef typename Pair::first key;
00248 BOOST_STATIC_CONSTANT( bool, has_key = (mpl::has_key<Map, key>::value) );
00249 typedef typename add_pair_dispatch<Map, Pair, has_key>::type type;
00250 };
00251
00252 typedef mpl::map<> map_;
00253 typedef add_pair<map_, mpl::pair<mpl::integral_c<int, 5>, mpl::integral_c<int, 1> > >::type map_51;
00254 typedef add_pair<map_51, mpl::pair<mpl::integral_c<int, 5>, mpl::integral_c<int, 1> > >::type map_52;
00255
00256 BOOST_STATIC_ASSERT(( mpl::size<map_>::type::value == 0 ));
00257 BOOST_STATIC_ASSERT(( mpl::size<map_51>::type::value == 1 ));
00258 BOOST_STATIC_ASSERT(( mpl::size<map_52>::type::value == 1 ));
00259
00260
00261
00262
00263
00264
00265 template<class Map, class Remainder> struct partial_prime_represenation {
00266 typedef Map map;
00267 typedef Remainder remainder;
00268 };
00269
00270
00271 template<class PrimeDecomp, class p> struct reduce_prime_impl;
00272
00273
00274 template<class Map, class Remainder, class p> struct reduce_prime_impl<partial_prime_represenation<Map, Remainder>, p> {
00275 BOOST_STATIC_ASSERT(( is_divisible<Remainder::value, p::value>::type::value ));
00276 typedef typename boost::mpl::integral_c<int, Remainder::value/p::value>::type remainder;
00277
00278 typedef typename add_pair<Map, mpl::pair<p, mpl::integral_c<int, 1> > >::type map;
00279 typedef partial_prime_represenation<map, remainder> type;
00280 };
00281
00282
00283
00284 typedef mpl::map<> empty_map;
00285 typedef mpl::map<mpl::pair<mpl::integral_c<int, 2>, mpl::integral_c<int, 1> > > map_2;
00286 typedef mpl::map<mpl::pair<mpl::integral_c<int, 2>, mpl::integral_c<int, 2> > > map_2_2;
00287 typedef mpl::map<mpl::pair<mpl::integral_c<int, 3>, mpl::integral_c<int, 1> > > map_3;
00288 typedef mpl::map<mpl::pair<mpl::integral_c<int, 3>, mpl::integral_c<int, 2> > > map_3_3;
00289 typedef mpl::map<mpl::pair<mpl::integral_c<int, 2>, mpl::integral_c<int, 1> >,
00290 mpl::pair<mpl::integral_c<int, 3>, mpl::integral_c<int, 1> > > map_2_3;
00291
00292 BOOST_STATIC_ASSERT(( mpl::size<empty_map>::type::value == 0 ));
00293 BOOST_STATIC_ASSERT(( mpl::size<map_2>::type::value == 1 ));
00294
00295
00296
00297 using mpl::placeholders::_;
00298 using mpl::placeholders::_1;
00299 using mpl::placeholders::_2;
00300 typedef mpl::vector<mpl::integral_c<int,2>, mpl::integral_c<int,3>, mpl::integral_c<int,5> > prime_list_2_3_5;
00301 typedef mpl::fold<prime_list_2_3_5, mpl::integral_c<int, 1>, mpl::multiplies<_,_> >::type product_2_3_5;
00302 BOOST_STATIC_ASSERT(( product_2_3_5::value == 2*3*5 ));
00303
00304 template<class n, class k> struct power_impl {
00305 typedef mpl::integral_c<int, 1> one;
00306 typedef typename mpl::multiplies< typename power_impl<n, typename mpl::minus<k,one>::type >::type, n>::type type;
00307 };
00308
00309 template<class n> struct power_impl<n, mpl::integral_c<int, 1> > {
00310 typedef n type;
00311 };
00312
00313 template<class n> struct power_impl<n, mpl::integral_c<int, 0> > {
00314 typedef mpl::integral_c<int, 1> type;
00315 };
00316
00317
00318 template<class n, class k> struct static_power {
00319 typedef typename power_impl<n, k>::type type;
00320 };
00321
00322
00323 template<int n, int k> struct int_power {
00324 typedef typename power_impl<mpl::integral_c<int, n>, mpl::integral_c<int, k> >::type type;
00325 BOOST_STATIC_CONSTANT(int, value = type::value);
00326 };
00327
00328
00329 template<class pair> struct pair_power {
00330 typedef typename power_impl<typename pair::first, typename pair::second>::type type;
00331 };
00332
00333 BOOST_STATIC_ASSERT(( int_power<1,1>::value == 1 ));
00334 BOOST_STATIC_ASSERT(( int_power<2,1>::value == 2 ));
00335 BOOST_STATIC_ASSERT(( int_power<2,2>::value == 4 ));
00336 BOOST_STATIC_ASSERT(( int_power<2,3>::value == 8 ));
00337
00338
00339 template<class V> struct static_abs;
00340 template<int k> struct static_abs<mpl::integral_c<int, k> > {
00341 typedef typename mpl::if_c< (k>0), mpl::integral_c<int, k>, mpl::integral_c<int, -k> >::type type;
00342 };
00343
00344
00345 template<class n, class k> struct rational_power {
00346 typedef mpl::integral_c<int, 1> one;
00347 typedef typename static_abs<k>::type exp;
00348 typedef typename power_impl<n, exp>::type part;
00349 typedef typename mpl::if_c< (k::value>=0), static_rational<part::value, one::value>, static_rational<one::value, part::value> >::type type;
00350 };
00351
00352
00353 typedef mpl::pair<mpl::integral_c<int, 2>, mpl::integral_c<int, 3> > pair_2_3;
00354 BOOST_STATIC_ASSERT(( pair_power<pair_2_3>::type::value == 8 ));
00355
00356
00357 typedef mpl::vector<mpl::pair<mpl::integral_c<int, 2>, mpl::integral_c<int, 1> >,
00358 mpl::pair<mpl::integral_c<int, 3>, mpl::integral_c<int, 1> > > vec_map_2_3;
00359
00360 typedef mpl::transform< vec_map_2_3, pair_power<_> >::type vec_map_2_3_powers;
00361 typedef mpl::fold<vec_map_2_3_powers, mpl::integral_c<int, 1>, mpl::multiplies<_,_> >::type vec_map_2_3_total;
00362 BOOST_STATIC_ASSERT(( vec_map_2_3_total::value == 6 ));
00363
00364
00365 typedef mpl::fold<map_2_3, mpl::integral_c<int, 1>, mpl::multiplies<_1, pair_power<_2> > >::type vec_from_map_2_3_product;
00366 BOOST_STATIC_ASSERT(( vec_from_map_2_3_product::value == 6 ));
00367
00368
00369 template<class Map> struct static_map_multiply {
00370 typedef typename mpl::fold<Map, mpl::integral_c<int, 1>, mpl::multiplies<_1, pair_power<_2> > >::type type;
00371 };
00372 BOOST_STATIC_ASSERT(( static_map_multiply<map_2>::type::value == 2 ));
00373 BOOST_STATIC_ASSERT(( static_map_multiply<map_2_2>::type::value == 4 ));
00374 BOOST_STATIC_ASSERT(( static_map_multiply<map_3>::type::value == 3 ));
00375 BOOST_STATIC_ASSERT(( static_map_multiply<map_3_3>::type::value == 9 ));
00376
00377 BOOST_STATIC_ASSERT(( static_map_multiply<map_>::type::value == 1 ));
00378 BOOST_STATIC_ASSERT(( static_map_multiply<map_51>::type::value == 5 ));
00379 BOOST_STATIC_ASSERT(( static_map_multiply<map_52>::type::value == 25 ));
00380
00381
00382
00383 template<class PrimeDecomp, class p> struct reduce_prime;
00384
00385 template<class PrimeDecomp, class p, bool divisible> struct reduce_prime_dispatch;
00386
00387 template<class PrimeDecomp, class p> struct reduce_prime_dispatch<PrimeDecomp, p, true> {
00388 typedef typename reduce_prime_impl<PrimeDecomp, p>::type reduced;
00389 typedef typename reduce_prime<reduced, p>::type type;
00390 };
00391
00392 template<class PrimeDecomp, class p> struct reduce_prime_dispatch<PrimeDecomp, p, false> {
00393 typedef PrimeDecomp type;
00394 };
00395
00396
00397
00398
00399 template<class PrimeDecomp, class p> struct reduce_prime {
00400 typedef typename PrimeDecomp::remainder Remainder;
00401 typedef typename reduce_prime_dispatch<PrimeDecomp, p, is_divisible<Remainder::value, p::value>::type::value>::type type;
00402 };
00403
00404
00405 template <class n> struct initial_decomp {
00406 BOOST_STATIC_ASSERT(( n::value >= 1 ));
00407 typedef typename partial_prime_represenation<mpl::map<>, n> type;
00408 };
00409
00410 typedef initial_decomp<mpl::integral_c<int, 25> >::type init_decomp_25;
00411 BOOST_STATIC_ASSERT(( init_decomp_25::remainder::type::value == 25 ));
00412 BOOST_STATIC_ASSERT(( mpl::size<init_decomp_25::map>::type::value == 0 ));
00413 BOOST_STATIC_ASSERT(( static_map_multiply<init_decomp_25::map>::type::value == 1 ));
00414
00415
00416 typedef reduce_prime<init_decomp_25, mpl::integral_c<int, 5> >::type reduced_25;
00417
00418 BOOST_STATIC_ASSERT(( reduced_25::remainder::type::value == 1 ));
00419 BOOST_STATIC_ASSERT(( mpl::size<reduced_25::map>::type::value == 1 ));
00420 BOOST_STATIC_ASSERT(( static_map_multiply<reduced_25::map>::type::value == 25 ));
00421
00422
00423 typedef initial_decomp<mpl::integral_c<int, 50> >::type init_decomp_50;
00424 BOOST_STATIC_ASSERT(( init_decomp_50::remainder::type::value == 50 ));
00425 BOOST_STATIC_ASSERT(( mpl::size<init_decomp_50::map>::type::value == 0 ));
00426 BOOST_STATIC_ASSERT(( static_map_multiply<init_decomp_50::map>::type::value == 1 ));
00427
00428 typedef reduce_prime<init_decomp_50, mpl::integral_c<int, 5> >::type reduced_50_5;
00429 BOOST_STATIC_ASSERT(( reduced_50_5::remainder::type::value == 2 ));
00430 BOOST_STATIC_ASSERT(( mpl::size<reduced_50_5::map>::type::value == 1 ));
00431 BOOST_STATIC_ASSERT(( static_map_multiply<reduced_50_5::map>::type::value == 25 ));
00432
00433 typedef reduce_prime<reduced_50_5, mpl::integral_c<int, 2> >::type reduced_50_5_2;
00434 BOOST_STATIC_ASSERT(( reduced_50_5_2::remainder::type::value == 1 ));
00435 BOOST_STATIC_ASSERT(( mpl::size<reduced_50_5_2::map>::type::value == 2 ));
00436 BOOST_STATIC_ASSERT(( static_map_multiply<reduced_50_5_2::map>::type::value == 50 ));
00437
00438
00439
00440
00441 template<typename n, typename upto> struct prime_decomposition {
00442 typedef boost::mpl::integral_c<int, upto::value-1> upto_m1;
00443 BOOST_STATIC_ASSERT(( upto_m1::value >= 1));
00444
00445
00446 typedef typename prime_decomposition<n, upto_m1>::type part_decomposition;
00447 typedef typename reduce_prime<part_decomposition, upto>::type type;
00448 };
00449
00450
00451
00452 template<typename n> struct prime_decomposition<n, mpl::integral_c<int, 1> > {
00453 typedef typename initial_decomp<n>::type type;
00454 };
00455
00456
00457 template<typename n> struct primes {
00458 typedef typename prime_decomposition<n, n>::type decomposition;
00459 typedef typename decomposition::map type;
00460 };
00461
00462
00463
00464 typedef primes<mpl::integral_c<int, 10> >::type primes_10;
00465 BOOST_STATIC_ASSERT(( mpl::size<primes_10>::type::value == 2 ));
00466 BOOST_STATIC_ASSERT(( static_map_multiply<primes_10>::type::value == 10 ));
00467
00468
00469 typedef primes<mpl::integral_c<int, 100> >::type primes_100;
00470 BOOST_STATIC_ASSERT(( mpl::size<primes_100>::type::value == 2 ));
00471 BOOST_STATIC_ASSERT(( static_map_multiply<primes_100>::type::value == 100 ));
00472
00473
00474 #if 1
00475
00476
00477 typedef primes<mpl::integral_c<int, 430> >::type primes_1000;
00478
00479 BOOST_STATIC_ASSERT(( static_map_multiply<primes_1000>::type::value == 430 ));
00480 #endif
00481
00482
00483 #if 0
00484
00485 typedef primes<1>::type primes_1;
00486 typedef primes<2>::type primes_2;
00487
00488
00489
00490
00491 BOOST_STATIC_ASSERT(( boost::mpl::size<primes_1>::type::value == 0 ));
00492
00493
00494
00495
00496
00497
00498
00499
00500 #endif
00501 }
00502
00503 namespace newprimes {
00504
00505
00506 };
00507 namespace blub {
00508
00509
00510
00511
00512 template <class UnitSystem, class BaseDimension>
00513 struct position {
00514 typedef typename boost::mpl::find<typename UnitSystem::base_dimensions, BaseDimension>::type iterator;
00515 BOOST_STATIC_CONSTANT(int, value = iterator::pos::value);
00516 };
00517
00518 template<class UnitSystem, class dimension, class unit>
00519 struct extended_unit_system {
00520 struct extended {
00521 typedef extended unitsystem;
00522 typedef typename boost::mpl::push_back<typename UnitSystem::base_dimensions, dimension>::type base_dimensions;
00523 typedef typename boost::mpl::push_back<typename UnitSystem::base_units, unit>::type base_units;
00524
00525 BOOST_STATIC_ASSERT(boost::mpl::size<typename UnitSystem::base_dimensions>::value == boost::mpl::size<typename UnitSystem::base_units>::value);
00526 BOOST_STATIC_ASSERT(boost::mpl::size<base_dimensions>::value == boost::mpl::size<typename UnitSystem::base_dimensions>::value+1);
00527 BOOST_STATIC_ASSERT(boost::mpl::size<base_units>::value == boost::mpl::size<typename UnitSystem::base_units>::value+1);
00528 BOOST_STATIC_ASSERT(boost::mpl::size<base_dimensions>::value == boost::mpl::size<base_units>::value);
00529
00530 BOOST_STATIC_CONSTANT(int, number_baseunits = boost::mpl::size<base_dimensions>::value);
00531 };
00532 typedef extended type;
00533 };
00534
00535
00536
00537 template<class unit1, class unit2> struct static_conversion_factor;
00538
00539
00540 template<class unit1> struct static_conversion_factor<unit1, unit1> {
00541 typedef typename static_rational<1,1>::type type;
00542 };
00543
00544
00545
00546 template<class source_UnitSystem, class target_UnitSystem, int source_position>
00547 struct convert_baseunit_to_other_unit_system {
00548
00549
00550 typedef typename boost::mpl::at<typename source_UnitSystem::base_dimensions, boost::mpl::int_<source_position> >::type BaseDimension;
00551
00552
00553 typedef typename boost::mpl::find<typename target_UnitSystem::base_dimensions, BaseDimension>::type target_iterator;
00554 BOOST_STATIC_CONSTANT(int, target_position = target_iterator::pos::value);
00555
00556
00557 typedef typename boost::mpl::at<typename source_UnitSystem::base_units, boost::mpl::int_<source_position> >::type source_unit;
00558
00559
00560 typedef typename boost::mpl::at<typename target_UnitSystem::base_units, boost::mpl::int_<target_position> >::type target_unit;
00561
00562 typedef typename static_conversion_factor<source_unit, target_unit>::type conversion_factor;
00563 };
00564
00565
00566
00567
00568
00569 struct length {};
00570 struct mass {};
00571 struct time {};
00572 struct electric_current {};
00573 struct temperature {};
00574 struct amount_of_substance {};
00575 struct luminous_intensity {};
00576
00577
00578
00579 struct meter {};
00580 struct kilogram {};
00581 struct second {};
00582 struct ampere {};
00583 struct kelvin {};
00584 struct mol {};
00585 struct candela {};
00586
00587 struct centimeter {};
00588 struct gram {};
00589
00590
00591 template<> struct static_conversion_factor<meter, centimeter> { typedef static_rational<100,1>::type type; };
00592 template<> struct static_conversion_factor<centimeter, meter> { typedef static_rational<1,100>::type type; };
00593
00594 template<> struct static_conversion_factor<kilogram, gram> { typedef static_rational<1000,1>::type type; };
00595 template<> struct static_conversion_factor<gram, kilogram> { typedef static_rational<1000,1>::type type; };
00596
00597
00598
00599
00600 struct SI {
00601 typedef SI unitsystem;
00602 typedef boost::mpl::vector<length, mass, time, electric_current, temperature, amount_of_substance, luminous_intensity> base_dimensions;
00603 typedef boost::mpl::vector<meter, kilogram, second, ampere, kelvin, mol, candela> base_units;
00604
00605 BOOST_STATIC_ASSERT(boost::mpl::size<base_dimensions>::value == boost::mpl::size<base_units>::value);
00606 BOOST_STATIC_CONSTANT(int, number_baseunits = boost::mpl::size<base_dimensions>::value);
00607 };
00608
00609
00610
00611
00612 struct MKS {
00613 typedef MKS unitsystem;
00614 typedef boost::mpl::vector<length, mass, time> base_dimensions;
00615 typedef boost::mpl::vector<meter, kilogram, second> base_units;
00616
00617 BOOST_STATIC_ASSERT(boost::mpl::size<base_dimensions>::value == boost::mpl::size<base_units>::value);
00618 BOOST_STATIC_CONSTANT(int, number_baseunits = boost::mpl::size<base_dimensions>::value);
00619 };
00620
00621
00622
00623
00624
00625 struct CGS {
00626 typedef CGS unitsystem;
00627 typedef boost::mpl::vector<length, mass, time> base_dimensions;
00628 typedef boost::mpl::vector<centimeter, gram, second> base_units;
00629
00630 BOOST_STATIC_ASSERT(boost::mpl::size<base_dimensions>::value == boost::mpl::size<base_units>::value);
00631 BOOST_STATIC_CONSTANT(int, number_baseunits = boost::mpl::size<base_dimensions>::value);
00632 };
00633
00634
00635
00636
00637 BOOST_STATIC_ASSERT((convert_baseunit_to_other_unit_system<MKS, CGS, 0>::target_position == 0));
00638 BOOST_STATIC_ASSERT((convert_baseunit_to_other_unit_system<MKS, CGS, 1>::target_position == 1));
00639 BOOST_STATIC_ASSERT((convert_baseunit_to_other_unit_system<MKS, CGS, 2>::target_position == 2));
00640
00641 BOOST_STATIC_ASSERT(( boost::is_same<convert_baseunit_to_other_unit_system<MKS, CGS, 0>::conversion_factor, static_rational<100,1> >::type::value ));
00642 BOOST_STATIC_ASSERT(( boost::is_same<convert_baseunit_to_other_unit_system<MKS, CGS, 1>::conversion_factor, static_rational<1000,1> >::type::value ));
00643 BOOST_STATIC_ASSERT(( boost::is_same<convert_baseunit_to_other_unit_system<MKS, CGS, 2>::conversion_factor, static_rational<1,1> >::type::value ));
00644
00645 BOOST_STATIC_ASSERT(( ! boost::is_same<convert_baseunit_to_other_unit_system<MKS, CGS, 0>::conversion_factor, static_rational<1,1> >::type::value ));
00646
00647
00648
00649 struct customer_satisfaction {};
00650 struct subjective {};
00651
00652 struct european_currency {};
00653 struct us_currency {};
00654
00655
00656
00657 typedef extended_unit_system<SI, customer_satisfaction, subjective>::type extended_SI;
00658
00659
00660 static const int meter_pos1 = position<SI, length>::value;
00661 static const int meter_pos2 = position<extended_SI, length>::value;
00662
00663
00664 BOOST_STATIC_ASSERT( meter_pos1 == meter_pos2 );
00665
00666
00667
00668
00669 };