|
  1 #ifndef _COMPILER_CALCULATION_H 2 #define _COMPILER_CALCULATION_H 3 4 //================================================================ 5 //编译期计算模板 6 namespace fredazsq 7  { 8 9 //====计算整数的阶: n*(n-1)*(n-2)* .*1========================== 10 template<int n> 11 struct IntegerRank 12  { 13 enum {value = IntegerRank<n-1>::value * n}; 14 }; 15 16 template<> 17 struct IntegerRank<1> 18  { 19 enum {value = 1}; 20 }; 21 22 23 //====计算整数的和: n + (n-1) + (n-2) + .+1===================== 24 template<int n> 25 struct IntegerSum 26  { 27 enum {value = IntegerSum<n-1>::value + n}; 28 }; 29 30 template<> 31 struct IntegerSum<1> 32  { 33 enum {value = 1}; 34 }; 35 36 //====计算整数的1!+2!+3!+………n!===================== 37 template<int n> 38 struct IntegerRankSum 39  { 40 enum {value = IntegerRankSum<n-1>::value + IntegerRank<n>::value}; 41 }; 42 43 template<> 44 struct IntegerRankSum<1> 45  { 46 enum {value = 1}; 47 }; 48 49 //====计算k的n次方================================================ 50 template<int k, int n> 51 struct Pow 52  { 53 enum { value = Pow<k, n-1>::value * k }; 54 }; 55 56 template<int k> 57 struct Pow<k, 0> 58  { 59 enum {value = 1}; 60 }; 61 62 63 //====计算平方根================================================== 64 //方法1:编译速度慢 65 template <int N, int LO=1, int HI=N> 66 class Sqrt2 67  { 68 public: 69 //compute the midpoint, rounded up 70 enum { mid = (LO+HI+1)/2 }; 71 72 //search a not too large value in a halved interval 73 enum { value = (N<mid*mid) ? Sqrt2<N,LO,mid-1>::result : Sqrt2<N,mid,HI>::value }; 74 }; 75 76 // partial specialization for the case when LO equals HI 77 template<int N, int M> 78 class Sqrt2<N, M, M> 79  { 80 public: 81 enum { value = M }; 82 }; 83 84 //以下代码需要Loki支持. 85 //====方法2:最佳解法,需要偏特化支持============================== 86 template<int N, int LO=1, int HI=N> 87 class Sqrt 88  { 89 public: 90 // compute the midpoint, rounded up 91 enum { mid = (LO+HI+1)/2 }; 92 93 // search a not too large value in a halved interval 94 typedef typename Loki::Select<(N < mid*mid), Sqrt<N, LO, mid-1>, Sqrt<N, mid, HI> >::Result SubT; 95 enum { value = SubT::value }; 96 }; 97 98 // partial specialization for end of recursion criterion 99 template<int N, int S> 100 class Sqrt<N, S, S> 101  { 102 public: 103 enum { value = S }; 104 }; 105 106 107 //====编译器链接出错报告质数 so funny!============================= 108 //主模板:Prime_print 109 //prime number computation by Erwin Unruh 110 111 //判断是否素数的模板 112 template <int m, int i=m-1> 113 struct is_prime 114  { 115 enum { prim = (m==2) || (m%i) && is_prime<(i>2?m:0),i-1>::prim }; 116 }; 117 118 template<> 119 struct is_prime<0, 0> 120  { 121 enum {prim=1}; 122 }; 123 124 template<> 125 struct is_prime<0, 1> 126  { 127 enum {prim=1}; 128 }; 129 130 template <int i> 131 struct ErrMsg 132  { 133 ErrMsg(int) {} 134 ErrMsg(float);//不定义函数体以造成无法解析的外部符号错误. 135 }; 136 137 // primary template for loop to print prime numbers 138 template <int i> 139 struct Prime_print 140  { 141 enum { prim = is_prime<i>::prim }; 142 void operator()() 143 { 144 //ErrMsg<i> d = prim? 1.0f : 1L; 145 //会导致编译器在测试语法时就同时检查两种可能发生的错误. 146 //这时可用Select并同时应用重载技巧排除. 147 ErrMsg<i> d = Loki::Select<prim, float, int>::Result(); 148 Prime_print<i-1>()();//递归,只要不调用函数,模板实例化是永远正确的. 149 } 150 }; 151 152 // full specialization to end the loop 153 template<> 154 struct Prime_print<1> 155  { 156 void operator()() {} 157 }; 158 159 #define PRINT_PRIME(x) fredazsq::Prime_print<x>()() 160 161 162 //====出错信息打印Fabonacci数列====================================== 163 //====该技巧演示了如何不用特化模板结束 Unroll Loops. 164 //====u: 在u以内的数列项. 165 template<int u, int k=1, int n=1> 166 struct Fabonacci 167  { 168 void operator()() 169 { 170 ErrMsg<k> d = 1.0f; 171 Loki::Select<(n < u), Fabonacci<u, n, k+n>, Prime_print<1> >::Result()(); 172 } 173 }; 174 175 //====出错信息打印某种递归数列(n ? n+1 = n+2)========================================== 176 //====该技巧演示了如何不用特化模板结束 Unroll Loops. 177 //====RecursionPolicy: 接受2个模板参数的模板,并定义value为k ? n的结果. 178 //====u: 在u以内的数列项. 179 //VS2003不支持, gc++支持. 180 template<template<int, int> class RecursionPolicy, int u, int k=1, int n=1> 181 struct RecursionNumber 182  { 183 void operator()() 184 { 185 ErrMsg<k> d = 1.0f; 186 Loki::Select<(n < u), RecursionNumber<RecursionPolicy, u, n, RecursionPolicy<k, n>::value>, Prime_print<1> >::Result()(); 187 } 188 }; 189 190 191 //====将质数数列值送入执行期==================================== 192 //====i: i以内的质数 193 //====PrimeTypelist最终的Result类型为携带数列值的 194 //====Loki的TYPELIST(参阅Modern C++ Design) 195 template <int i> 196 struct PrimeTypelist 197  { 198 //将来要输出的由类型携带的数列值. 199 enum { value = i }; 200 enum { prim = is_prime<i>::prim }; 201 202 //当前递归所处类型 203 typedef PrimeTypelist<i> thisType; 204 205 //递归处理 206 typedef typename PrimeTypelist<i-1>::Result ResultTypelist; 207 208 //将每次递归的类型加入typelist, Result是最终输出的结果TYPELIST. 209 typedef typename Loki::Select<prim, typename Loki::TL::Append<ResultTypelist, thisType>::Result, ResultTypelist>::Result Result; 210 }; 211 212 // full specialization to end the loop 213 template<> 214 struct PrimeTypelist<1> 215  { 216 typedef Loki::NullType Result; 217 }; 218 219 220 221 //====将Fabonacci数列值送入执行期==================================== 222 //====u: u个数值. k,n: 起始项 223 //====FabonacciArray最终的Result类型为携带数列值的/ 224 //====Loki的TYPELIST(参阅Modern C++ Design) 225 //====Unroll Loops技法不再适用. 226 template<int u, int k=1, int n=1> 227 struct FabonacciTypelist 228  { 229 //将来要输出的由类型携带的数列值. 230 enum {value = k}; 231 232 //当前递归所处类型 233 typedef FabonacciTypelist<u, k, n> thisType; 234 235 //递归处理 236 typedef typename FabonacciTypelist<u-1, n, k+n>::Result ResultTypelist; 237 //typedef typename Loki::Select<(n < u), typename FabonacciTypelist<u, n, k+n>::Result, Loki::NullType>::Result ResultTypelist; 238 239 //将每次递归的类型加入typelist, Result是最终输出的结果TYPELIST. 240 typedef typename Loki::TL::Append<ResultTypelist, thisType>::Result Result; 241 }; 242 243 //特化u=0结束 244 template<int k, int n> 245 struct FabonacciTypelist<0, k, n> 246  { 247 typedef Loki::NullType Result; 248 }; 249 250 251 //====将递归数列值送入执行期==================================== 252 //====u: u个数值. k,n: 起始项 253 //====FabonacciArray最终的Result类型为携带数列值的/ 254 //====Loki的TYPELIST(参阅Modern C++ Design) 255 //====RecursionPolicy: 接受2个模板参数的模板,并定义value为k ? n的结果. 256 template<template<int, int> class RecursionPolicy, int u, int k=1, int n=1> 257 struct RecursionNumberTypelist 258  { 259 //将来要输出的由类型携带的数列值. 260 enum {value = k}; 261 262 //当前递归所处类型 263 typedef RecursionNumberTypelist<RecursionPolicy, u, k, n> thisType; 264 265 //递归处理 266 typedef typename RecursionNumberTypelist<RecursionPolicy, u-1, n, RecursionPolicy<k, n>::value>::Result ResultTypelist; 267 268 //将每次递归的类型加入typelist, Result是最终输出的结果TYPELIST. 269 typedef typename Loki::TL::Append<ResultTypelist, thisType>::Result Result; 270 }; 271 272 //特化u=0结束 273 template<template<int, int> class RecursionPolicy, int k, int n> 274 struct RecursionNumberTypelist<RecursionPolicy, 0, k, n> 275  { 276 typedef Loki::NullType Result; 277 }; 278 279 280 //====将Fabonacci数列值送入执行期==================================== 281 //====u: u以内的数值. k,n: 起始项 282 //====展示默认参数和模板特化联合时的威力. 283 //====如何解决在100内结束的问题. 284 template<int u, int k=1, int n=1, bool b = (k < u)> 285 struct FabonacciTypelist2 286  { 287 //将来要输出的由类型携带的数列值. 288 enum {value = k}; 289 290 //当前递归所处类型 291 typedef FabonacciTypelist2<u, k, n, b> thisType; 292 293 //递归处理 294 typedef typename FabonacciTypelist2<u, n, k+n>::Result ResultTypelist; 295 //typedef typename Loki::Select<(n < u), typename FabonacciTypelist<u, n, k+n>::Result, Loki::NullType>::Result ResultTypelist; 296 297 //将每次递归的类型加入typelist, Result是最终输出的结果TYPELIST. 298 typedef typename Loki::TL::Append<ResultTypelist, thisType>::Result Result; 299 }; 300 301 //特化b = (k < u) = false即 k > u结束. 302 template<int u, int k, int n> 303 struct FabonacciTypelist2<u, k, n, false> 304  { 305 typedef Loki::NullType Result; 306 }; 307 308 309 /**//////////////////////////////////////////////////////////////////////////////////////////////// 310 //====将递归数列值送入执行期==================================== 311 //====u: u以内的数值. k,n: 起始项 312 //====RecursionPolicy: 接受2个模板参数的模板,并定义value为k ? n的结果. 313 template<template<int, int> class RecursionPolicy, int u, int k=1, int n=1, bool b = (k < u)> 314 struct RecursionNumberTypelist2 315  { 316 //将来要输出的由类型携带的数列值. 317 enum {value = k}; 318 319 //当前递归所处类型 320 typedef RecursionNumberTypelist2<RecursionPolicy, u, k, n, b> thisType; 321 322 //递归处理 323 typedef typename RecursionNumberTypelist2<RecursionPolicy, u, n, RecursionPolicy<k, n>::value>::Result ResultTypelist; 324 325 //将每次递归的类型加入typelist, Result是最终输出的结果TYPELIST. 326 typedef typename Loki::TL::Append<ResultTypelist, thisType>::Result Result; 327 }; 328 329 //特化u=0结束 330 template<template<int, int> class RecursionPolicy, int k, int n> 331 struct RecursionNumberTypelist2<RecursionPolicy, 0, k, n, false> 332  { 333 typedef Loki::NullType Result; 334 }; 335 /**//////////////////////////////////////////////////////////////////////////////////////////////// 336 337 338 // 使用范例 339 // 执行时赋值good 340 // template<typename T> struct ExtractDataType { 341 // int operator()() {return T::value;} }; 342 // typedef Loki::TL::IterateTypes<MyTL, ExtractDataType> TypelistValueGenerator; 343 // std::vector<int> vecData; 344 // TypelistValueGenerator()(std::back_inserter(vecData)); 345 346 // 编译期初始赋值,still need macro TYPEVALUE_N. 347 // typedef fredazsq::SomeTypelist<6>::Result MyTL; 348 // int data[6] = {TYPEVALUE_6(MyTL)}; 349 #define TYPEVALUE(tl, idx) Loki::TL::TypeAt<tl, idx>::Result::value 350 #define TYPEVALUE_1(tl) TYPEVALUE(tl, 0) 351 #define TYPEVALUE_2(tl) TYPEVALUE_1(tl),TYPEVALUE(tl, 1) 352 #define TYPEVALUE_3(tl) TYPEVALUE_2(tl),TYPEVALUE(tl, 2) 353 #define TYPEVALUE_4(tl) TYPEVALUE_3(tl),TYPEVALUE(tl, 3) 354 #define TYPEVALUE_5(tl) TYPEVALUE_4(tl),TYPEVALUE(tl, 4) 355 #define TYPEVALUE_6(tl) TYPEVALUE_5(tl),TYPEVALUE(tl, 5) 356 #define TYPEVALUE_7(tl) TYPEVALUE_6(tl),TYPEVALUE(tl, 6) 357 #define TYPEVALUE_8(tl) TYPEVALUE_7(tl),TYPEVALUE(tl, 7) 358 #define TYPEVALUE_9(tl) TYPEVALUE_8(tl),TYPEVALUE(tl, 8) 359 #define TYPEVALUE_10(tl) TYPEVALUE_9(tl),TYPEVALUE(tl, 9) 360 #define TYPEVALUE_11(tl) TYPEVALUE_10(tl),TYPEVALUE(tl, 10) 361 #define TYPEVALUE_12(tl) TYPEVALUE_11(tl),TYPEVALUE(tl, 11) 362 #define TYPEVALUE_13(tl) TYPEVALUE_12(tl),TYPEVALUE(tl, 12) 363 #define TYPEVALUE_14(tl) TYPEVALUE_13(tl),TYPEVALUE(tl, 13) 364 365 namespace Private 366  { 367 //m:测试对象 368 //t:测试数 369 template<int m, int t> 370 struct CaculMinMutiplePrime 371 { 372 //运算过程是由(t=2)->(t=m)进行逐个判断 373 //如果m被t整除,则t一定是最小素数约数. 374 enum {value = m%t? CaculMinMutiplePrime<m, t+1>::value : t}; 375 }; 376 template<int t> struct CaculMinMutiplePrime<1, t> 377 { 378 enum {value = 1}; 379 }; 380 template<int m> struct CaculMinMutiplePrime<m, m> 381 { 382 enum {value = m}; 383 }; 384 385 386 //求乘积为v的mTL, nTL的公倍数////////////////////////////////////////////////////////////////////////////////// 387 template<int v, typename mTL, typename nTL> struct CaculCommonMultiple; 388 template<int v, typename T, typename U, typename nTL> 389 struct CaculCommonMultiple<v, Loki::Typelist<T, U>, nTL> 390 { 391 //nTL中是否存在T::value. 392 enum {bHasEnumValueTypeT = EnumValueTL::HasEnumValueType<T::value, nTL>::isTrue}; 393 394 //存在则扣除nTL中的携T::value值的类型 395 typedef typename EnumValueTL::EraseEnumValueType<T::value, nTL>::Result Result; 396 397 //后续递归的计算结果. 398 enum {recurse_value = CaculCommonMultiple<v, U, Result>::value}; 399 400 //递归,值为后续递归的计算结果除当前若携T::value值. 401 enum {value = bHasEnumValueTypeT? recurse_value/T::value : recurse_value}; 402 }; 403 template<int v, typename T, typename nTL> 404 struct CaculCommonMultiple<v, Loki::Typelist<T, Loki::NullType>, nTL> 405 { 406 enum {bHasEnumValueTypeT = EnumValueTL::HasEnumValueType<T::value, nTL>::isTrue}; 407 enum {value = bHasEnumValueTypeT?v/T::value:v}; 408 }; 409 410 411 //mTL, nTL的最小公约数////////////////////////////////////////////////////////////////////////////////// 412 template<int v, typename mTL, typename nTL> struct CaculCommonSubmultiple; 413 template<int v, typename T, typename U, typename nTL> 414 struct CaculCommonSubmultiple<v, Loki::Typelist<T, U>, nTL> 415 { 416 //nTL中是否存在T::value. 417 enum {bHasEnumValueTypeT = EnumValueTL::HasEnumValueType<T::value, nTL>::isTrue}; 418 419 //存在则扣除nTL中的携T::value值的类型 420 typedef typename EnumValueTL::EraseEnumValueType<T::value, nTL>::Result Result; 421 422 //后续递归的计算结果. 423 enum {recurse_value = CaculCommonSubmultiple<v, U, Result>::value}; 424 425 //递归,值为后续递归的计算结果除当前若携T::value值. 426 enum {value = bHasEnumValueTypeT? recurse_value*T::value : recurse_value}; 427 }; 428 template<int v, typename T, typename nTL> 429 struct CaculCommonSubmultiple<v, Loki::Typelist<T, Loki::NullType>, nTL> 430 { 431 enum {bHasEnumValueTypeT = EnumValueTL::HasEnumValueType<T::value, nTL>::isTrue}; 432 enum {value = bHasEnumValueTypeT?v*T::value:v}; 433 }; 434 }; 435 436 /**//////////////////////////////////////////////////////////////////////////////////////////////// 437 //====求m的最小素数约数======================================== 438 template<int m> 439 struct MinMutiplePrime 440  { 441 enum {value = Private::CaculMinMutiplePrime<m, 2>::value}; 442 }; 443 /**//////////////////////////////////////////////////////////////////////////////////////////////// 444 445 446 /////////////////////////////////////////////////////////////////////////////////////////////// 447 //====将一个整数拆成素数的乘积================================= 448 //====结果Result以TYPELIST形式输出 449 template<int m> 450 struct PrimeMutiple 451  { 452 //将来要输出的由类型携带的数列值. 453 //求m的最小素数约数 454 enum { value = MinMutiplePrime<m>::value }; 455 456 //当前类型 457 typedef PrimeMutiple<m> thisType; 458 459 //递归处理 460 //求除去m的最小约数后的整数的素数乘积 461 typedef typename PrimeMutiple<m/value>::Result ResultTypelist; 462 463 //将每次递归的类型加入typelist, Result是最终输出的结果TYPELIST. 464 typedef typename Loki::TL::Append<ResultTypelist, thisType>::Result Result; 465 }; 466 template<> struct PrimeMutiple<1> 467  { 468 typedef Loki::NullType Result; 469 }; 470 /**//////////////////////////////////////////////////////////////////////////////////////////////// 471 472 473 /////////////////////////////////////////////////////////////////////////////////////////////// 474 //=====计算m和n的最小公倍数=============================================================== 475 template<int m, int n> 476 struct CommonMultiple 477  { 478 //求m的素数乘积序列 479 typedef typename PrimeMutiple<m>::Result PrimeMutiple_mTL; 480 481 //求n的素数乘积序列 482 typedef typename PrimeMutiple<n>::Result PrimeMutiple_nTL; 483 484 //调用私有空间的核心计算模板 485 enum {value = Private::CaculCommonMultiple<m*n, PrimeMutiple_mTL, PrimeMutiple_nTL>::value}; 486 }; 487 template<int n> struct CommonMultiple<1, n> 488  { 489 enum {value = n}; 490 }; 491 template<int m> struct CommonMultiple<m, 1> 492  { 493 enum {value = m}; 494 }; 495 /**//////////////////////////////////////////////////////////////////////////////////////////////// 496 497 498 /////////////////////////////////////////////////////////////////////////////////////////////// 499 //=====计算m和n的最大公约数=============================================================== 500 template<int m, int n> 501 struct CommonSubmultiple 502  { 503 //求m的素数乘积序列 504 typedef typename PrimeMutiple<m>::Result PrimeMutiple_mTL; 505 506 //求n的素数乘积序列 507 typedef typename PrimeMutiple<n>::Result PrimeMutiple_nTL; 508 509 //调用私有空间的核心计算模板 510 enum {value = Private::CaculCommonSubmultiple<1, PrimeMutiple_mTL, PrimeMutiple_nTL>::value}; 511 }; 512 template<int n> struct CommonSubmultiple<1, n> 513  { 514 enum {value = n}; 515 }; 516 template<int m> struct CommonSubmultiple<m, 1> 517  { 518 enum {value = m}; 519 }; 520 /**//////////////////////////////////////////////////////////////////////////////////////////////// 521 522 //====出错信息打印当前时间 523 // template <char*> 524 // struct _Print_NowTime; \ 525 // _Print_NowTime<__TIME__> 526 527 }//namespace fredazsq 528 #endif //_COMPILER_CALCULATION_H 529 530 531 // Loki的Select实现 532 //template <bool flag, typename T, typename U> 533 //struct Select 534 //{ 535 // typedef T Result; 536 //}; 537 //template <typename T, typename U> 538 //struct Select<false, T, U> 539 //{ 540 // typedef U Result; 541 //}; 542 543 //Sample.h 544 //#include <iostream> 545 //#include <stdlib.h> 546 //#include <vector> 547 //#define _USE_LOKI_ 548 //#include <STL/CompilerCaculation.h> 549 //#include <DataGenerators.h> 550 // 551 //using namespace std; 552 // 553 //template<typename T> 554 //struct ExtractDataType 555 //{ 556 // int operator()() 557 // { 558 // return T::value; 559 // } 560 //}; 561 // 562 //template<int k, int n> 563 //struct MyRecursePolicy 564 //{ 565 // enum {value = n+6}; 566 //}; 567 // 568 //int main(int argc, char *argv[]) 569 //{ 570 // typedef fredazsq::RecursionNumberTypelist<MyRecursePolicy, 16>::Result MyTL; 571 // typedef Loki::TL::IterateTypes<MyTL, ExtractDataType> TypelistValueGenerator; 572 // std::vector<int> vecData; 573 // TypelistValueGenerator()(std::back_inserter(vecData)); 574 // 575 // for(std::vector<int>::reverse_iterator it = vecData.rbegin(); it != vecData.rend(); ++it) 576 // { 577 // std::cout << *it << ","; 578 // } 579 // std::cout << std::endl; 580 // 581 // system("PAUSE"); 582 // return 0; 583 //} 584 585 586 //std::stringstream stream; 587 //const num = 368; 588 //typedef PrimeMutiple<num>::Result MyTL; 589 //typedef Loki::TL::IterateTypes<MyTL, ExtractDataType> TypelistValueGenerator; 590 //std::vector<int> vecData; 591 //TypelistValueGenerator()(std::back_inserter(vecData)); 592 // 593 //stream << num << " = "; 594 //for(std::vector<int>::reverse_iterator it = vecData.rbegin(); it != vecData.rend(); ++it) 595 //{ 596 // stream << *it << " * "; 597 //} 598 // 599 //MessageBox(stream.str().substr(0, stream.str().length()-2).c_str()); 600 601 602 /**//* 603 泛型编程的语义 604 1.if语义 605 a.typedef Loki::Select<bool, ClassA, ClassB> ExecuteType; 606 ExecuteType()(); 607 b.模板特化 608 c.重载选型. 609 610 2.else语义 611 a.多个模板重载项的非特化项. 612 613 3.真假语义 614 a.编译期bool常量 615 616 4.switch语义 617 a.多个模板重载项 618 619 5.for语义 620 struct EmptyFunctor 621 { 622 void operator(){} 623 }; 624 625 6.do while语义 626 */
|