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