• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2012 Robert Ramey
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 // test constructors
8 
9 #include <iostream>
10 
11 #include <boost/safe_numerics/safe_compare.hpp>
12 #include <boost/safe_numerics/safe_integer.hpp>
13 
14 template<class T2, class T1>
test_construction(T1 t1,const char * t2_name,const char * t1_name)15 bool test_construction(T1 t1, const char *t2_name, const char *t1_name){
16     using namespace boost::safe_numerics;
17     std::cout
18         << "testing constructions to " << t2_name << " from " << t1_name
19         << std::endl;
20     {
21         /* (1) test construction of safe<T1> from T1 type */
22         try{
23             safe<T1> s1(t1);
24             // should always arrive here!
25         }
26         catch(const std::exception &){
27             // should never, ever arrive here
28             std::cout
29                 << "erroneously detected error in construction "
30                 << "safe<" << t1_name << "> (" << t1_name << ")"
31                 << std::endl;
32             try{
33                 safe<T1> s1(t1); // try again for debugging
34             }
35             catch(const std::exception &){}
36             return false;
37         }
38     }
39     {
40         /* (2) test construction of safe<T2> from T1 type */
41         T2 t2;
42         try{
43             t2 = safe<T2>(t1);
44             if(! safe_compare::equal(t2 , t1)){
45                 std::cout
46                     << "failed to detect error in construction "
47                     << "safe<" << t2_name << "> (" << t1_name << ")"
48                     << std::endl;
49                 safe<T2> s2x(t1);
50                 return false;
51             }
52         }
53         catch(const std::exception &){
54             if(safe_compare::equal(t2, t1)){
55                 std::cout
56                     << "erroneously detected error in construction "
57                     << "safe<" << t2_name << "> (" << t1_name << ")"
58                     << std::endl;
59                 try{
60                     safe<T2> sx2(t1); // try again for debugging
61                 }
62                 catch(const std::exception &){}
63                 return false;
64             }
65         }
66     }
67     {
68         /* (3) test construction of safe<T1> from safe<T1> type */
69         safe<T1> s1x(t1);
70         try{
71             safe<T1> s1(s1x);
72             if(! (s1 == s1x)){
73                 std::cout
74                     << "copy constructor altered value "
75                     << "safe<" << t1_name << "> (safe<" << t1_name << ">(" << t1 << "))"
76                     << std::endl;
77                 //safe<T1> s1(s1x);
78                 return false;
79             }
80         }
81         catch(const std::exception &){
82             // should never arrive here
83             std::cout
84                 << "erroneously detected error in construction "
85                 << "safe<" << t1_name << "> (safe<" << t1_name << ">(" << t1 << "))"
86                 << std::endl;
87             try{
88                 safe<T1> s1(t1);
89             }
90             catch(const std::exception &){}
91             return false;
92         }
93     }
94     {
95         /* (4) test construction of safe<T2> from safe<T1> type */
96         T2 t2;
97         try{
98             safe<T1> s1(t1);
99             safe<T2> s2(s1);
100             t2 = static_cast<T2>(s2);
101             if(! (safe_compare::equal(t1, t2))){
102                 std::cout
103                     << "failed to detect error in construction "
104                     << "safe<" << t1_name << "> (safe<" << t2_name << ">(" << t1 << "))"
105                     << std::endl;
106                 safe<T2> s1x(t1);
107                 return false;
108             }
109         }
110         catch(const std::exception &){
111             if(safe_compare::equal(t1, t2)){
112                 std::cout
113                     << "erroneously detected error in construction "
114                     << "safe<" << t2_name << "> (safe<" << t1_name << ">(" << t1 << "))"
115                     << std::endl;
116                 try{
117                     safe<T2> s1(t1);
118                 }
119                 catch(const std::exception &){}
120                 return false;
121             }
122         }
123     }
124     return true;
125 }
126 
127 #include <boost/mp11/algorithm.hpp>
128 #include <boost/core/demangle.hpp>
129 #include "test_values.hpp"
130 
131 using namespace boost::mp11;
132 
133 struct test {
134     bool m_error;
testtest135     test(bool b = true) : m_error(b) {}
operator booltest136     operator bool(){
137         return m_error;
138     }
139     template<typename T>
operator ()test140     void operator()(const T &){
141         static_assert(mp_is_list<T>(), "must be a list of two types");
142         using T1 = mp_first<T>; // first element is a type
143         // second element is an integral constant
144         using T2 = typename mp_second<T>::value_type; // get it's type
145         constexpr T2 v2 = mp_second<T>(); // get it's value
146         m_error &= test_construction<T1>(
147             v2,
148             boost::core::demangle(typeid(T1).name()).c_str(),
149             boost::core::demangle(typeid(T2).name()).c_str()
150         );
151     }
152 };
153 
154 template<typename T>
155 using extract_value_type = typename T::value_type;
156 using test_types = mp_unique<
157     mp_transform<
158         extract_value_type,
159         test_values
160     >
161 >;
162 
main()163 int main(){
164     test rval(true);
165 
166     mp_for_each<
167         mp_product<mp_list, test_types, test_values>
168     >(rval);
169 
170     std::cout << (rval ? "success!" : "failure") << std::endl;
171     return ! rval ;
172 }
173