numeric_ops.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright Aleksey Gurtovoy 2003-2004
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/mpl for documentation.
  8. // $Id$
  9. // $Date$
  10. // $Revision$
  11. #include <boost/mpl/arithmetic.hpp>
  12. #include <boost/mpl/comparison.hpp>
  13. #include <boost/mpl/and.hpp>
  14. #include <boost/mpl/int.hpp>
  15. #include <boost/mpl/long.hpp>
  16. #include <boost/mpl/aux_/test.hpp>
  17. struct complex_tag : int_<10> {};
  18. template< typename Re, typename Im > struct complex
  19. {
  20. typedef complex_tag tag;
  21. typedef complex type;
  22. typedef Re real;
  23. typedef Im imag;
  24. };
  25. template< typename C > struct real : C::real {};
  26. template< typename C > struct imag : C::imag {};
  27. namespace boost { namespace mpl {
  28. template<> struct BOOST_MPL_AUX_NUMERIC_CAST< integral_c_tag,complex_tag >
  29. {
  30. template< typename N > struct apply
  31. : complex< N, integral_c< typename N::value_type, 0 > >
  32. {
  33. };
  34. };
  35. template<>
  36. struct plus_impl< complex_tag,complex_tag >
  37. {
  38. template< typename N1, typename N2 > struct apply
  39. : complex<
  40. plus< typename N1::real, typename N2::real >
  41. , plus< typename N1::imag, typename N2::imag >
  42. >
  43. {
  44. };
  45. };
  46. template<>
  47. struct times_impl< complex_tag,complex_tag >
  48. {
  49. template< typename N1, typename N2 > struct apply
  50. : complex<
  51. minus<
  52. times< typename N1::real, typename N2::real >
  53. , times< typename N1::imag, typename N2::imag >
  54. >
  55. , plus<
  56. times< typename N1::real, typename N2::imag >
  57. , times< typename N1::imag, typename N2::real >
  58. >
  59. >
  60. {
  61. };
  62. };
  63. template<>
  64. struct equal_to_impl< complex_tag,complex_tag >
  65. {
  66. template< typename N1, typename N2 > struct apply
  67. : and_<
  68. equal_to< typename N1::real, typename N2::real >
  69. , equal_to< typename N1::imag, typename N2::imag >
  70. >
  71. {
  72. };
  73. };
  74. }}
  75. typedef int_<2> i;
  76. typedef complex< int_<5>, int_<-1> > c1;
  77. typedef complex< int_<-5>, int_<1> > c2;
  78. MPL_TEST_CASE()
  79. {
  80. typedef plus<c1,c2>::type r1;
  81. MPL_ASSERT_RELATION( real<r1>::value, ==, 0 );
  82. MPL_ASSERT_RELATION( imag<r1>::value, ==, 0 );
  83. typedef plus<c1,c1>::type r2;
  84. MPL_ASSERT_RELATION( real<r2>::value, ==, 10 );
  85. MPL_ASSERT_RELATION( imag<r2>::value, ==, -2 );
  86. typedef plus<c2,c2>::type r3;
  87. MPL_ASSERT_RELATION( real<r3>::value, ==, -10 );
  88. MPL_ASSERT_RELATION( imag<r3>::value, ==, 2 );
  89. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  90. typedef plus<c1,i>::type r4;
  91. MPL_ASSERT_RELATION( real<r4>::value, ==, 7 );
  92. MPL_ASSERT_RELATION( imag<r4>::value, ==, -1 );
  93. typedef plus<i,c2>::type r5;
  94. MPL_ASSERT_RELATION( real<r5>::value, ==, -3 );
  95. MPL_ASSERT_RELATION( imag<r5>::value, ==, 1 );
  96. #endif
  97. }
  98. MPL_TEST_CASE()
  99. {
  100. typedef times<c1,c2>::type r1;
  101. MPL_ASSERT_RELATION( real<r1>::value, ==, -24 );
  102. MPL_ASSERT_RELATION( imag<r1>::value, ==, 10 );
  103. typedef times<c1,c1>::type r2;
  104. MPL_ASSERT_RELATION( real<r2>::value, ==, 24 );
  105. MPL_ASSERT_RELATION( imag<r2>::value, ==, -10 );
  106. typedef times<c2,c2>::type r3;
  107. MPL_ASSERT_RELATION( real<r3>::value, ==, 24 );
  108. MPL_ASSERT_RELATION( imag<r3>::value, ==, -10 );
  109. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  110. typedef times<c1,i>::type r4;
  111. MPL_ASSERT_RELATION( real<r4>::value, ==, 10 );
  112. MPL_ASSERT_RELATION( imag<r4>::value, ==, -2 );
  113. typedef times<i,c2>::type r5;
  114. MPL_ASSERT_RELATION( real<r5>::value, ==, -10 );
  115. MPL_ASSERT_RELATION( imag<r5>::value, ==, 2 );
  116. #endif
  117. }
  118. MPL_TEST_CASE()
  119. {
  120. MPL_ASSERT(( equal_to<c1,c1> ));
  121. MPL_ASSERT(( equal_to<c2,c2> ));
  122. MPL_ASSERT_NOT(( equal_to<c1,c2> ));
  123. MPL_ASSERT(( equal_to<c1, complex< long_<5>, long_<-1> > > ));
  124. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  125. MPL_ASSERT_NOT(( equal_to<c1,i> ));
  126. MPL_ASSERT_NOT(( equal_to<i,c2> ));
  127. #endif
  128. }