1 /*
2     Copyright (C) 2013 Tom Bachmann
3 
4     This file is part of FLINT.
5 
6     FLINT is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
10 */
11 
12 // XXX NOTE: the forwarding code was never completed, and neither was this
13 //           test file.
14 
15 #include <iostream>
16 #include <sstream>
17 
18 #include "flintxx/forwarding.h"
19 
20 #include "flintxx/test/myint.h"
21 #include "flintxx/test/helpers.h"
22 
23 using namespace flint;
24 
25 template<class Operation, class Data>
26 class forwarded_expression
27     : public expression<derived_wrapper<forwarded_expression>, Operation, Data>
28 {
29 public:
forwarded_expression()30     forwarded_expression() {};
31     template<class T>
forwarded_expression(const T & t)32     explicit forwarded_expression(const T& t)
33         : expression<derived_wrapper< ::forwarded_expression>,
34               Operation, Data>(t) {}
35 
36     template<class T>
operator =(const T & t)37     forwarded_expression& operator=(const T& t)
38     {
39         this->set(t);
40         return *this;
41     }
42 
43 protected:
forwarded_expression(const Data & d)44     explicit forwarded_expression(const Data& d)
45         : expression<derived_wrapper< ::forwarded_expression>,
46               Operation, Data>(d) {}
47 
48     template<class D, class O, class Da>
49     friend class ::flint::expression;
50 };
51 
52 struct hide_myint
53 {
54     myint i;
55     template<class T>
hide_myinthide_myint56     hide_myint(const T& t) : i(t) {}
hide_myinthide_myint57     hide_myint() {}
58 };
59 
60 typedef forwarded_expression<operations::immediate, hide_myint> fwint;
61 
62 namespace flint {
63 namespace forwarding {
64 template<>
65 struct enable<fwint>
66     : mp::true_
67 {
68     typedef myint underlying_t;
get_underlyingflint::forwarding::enable69     static const myint& get_underlying(const fwint& fwd)
70     {
71         return fwd._data().i;
72     }
get_underlyingflint::forwarding::enable73     static myint& get_underlying(fwint& fwd)
74     {
75         return fwd._data().i;
76     }
77 };
78 
79 }
80 }
81 
82 void
test_print()83 test_print()
84 {
85     fwint fwd(4);
86     std::ostringstream oss;
87     oss << fwd;
88     tassert(oss.str() == "4");
89 }
90 
91 void
test_assignment()92 test_assignment()
93 {
94     fwint f1, f2(4);
95 
96     f1 = WORD(3); // TODO understand why "3" seems to lead to circular dependency
97     tassert(f1 == 3);
98 
99     f1 = f2;
100     tassert(f1 == 4);
101 }
102 
103 void
test_equals()104 test_equals()
105 {
106     fwint f1(4), f2(5);
107     myint m1(4);
108 
109     tassert(f1 == f1);
110     tassert(f1 != f2);
111     tassert(f1 == 4);
112     tassert(5 != f1);
113     tassert(f1 == m1);
114     tassert(m1 != f2);
115 }
116 
117 void
test_conversion()118 test_conversion()
119 {
120     fwint a(4);
121 
122     tassert(typed_equals(a.to<int>(), 4));
123 }
124 
125 void
test_evaluation()126 test_evaluation()
127 {
128     fwint a(4);
129     myint b(5);
130 
131     tassert(typed_equals((a + a).evaluate(), myint(8)));
132     tassert(a + b == 9);
133     tassert(a + 6 == 10);
134     tassert((a + 6) + b == 15);
135 }
136 
137 int
main()138 main()
139 {
140     std::cout << "forwarding....";
141 
142     test_print();
143     test_assignment();
144     // TODO test cmp
145     test_equals();
146     test_conversion();
147     test_evaluation();
148 
149     std::cout << "PASS" << std::endl;
150     return 0;
151 }
152