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