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 #include <iostream>
8
9 #include "test_checked_cast.hpp"
10 #include <boost/safe_numerics/checked_integer.hpp>
11
12 // test conversion to TResult from different literal types
13 template<class TResult, class TArg>
test_cast(const TArg & v,const char * tresult_name,const char * targ_name,char expected_result)14 bool test_cast(
15 const TArg & v,
16 const char *tresult_name,
17 const char *targ_name,
18 char expected_result
19 ){
20 std::cout
21 << "testing static_cast<" << tresult_name << ">(" << targ_name << ")"
22 << std::endl;
23
24 boost::safe_numerics::checked_result<TResult> r2 =
25 boost::safe_numerics::checked::cast<TResult>(v);
26
27 if(expected_result == 'x' && ! r2.exception()){
28 std::cout
29 << "failed to detect error in construction "
30 << tresult_name << "<-" << targ_name
31 << std::endl;
32 boost::safe_numerics::checked::cast<TResult>(v);
33 return false;
34 }
35 if(expected_result == '.' && r2.exception()){
36 std::cout
37 << "erroneously emitted error "
38 << tresult_name << "<-" << targ_name
39 << std::endl;
40 boost::safe_numerics::checked::cast<TResult>(v);
41 return false;
42 }
43 return true; // passed test
44 }
45
46 #include <boost/mp11/algorithm.hpp>
47 #include <boost/core/demangle.hpp>
48
49 using namespace boost::mp11;
50
51 // given a list of integral constants I, return a list of values
52 template<typename I>
53 struct get_values {
54 static_assert(mp_is_list<I>(), "must be a list of two types");
55 static_assert(2 == mp_size<I>::value, "must be a list of two types");
56 static constexpr const size_t first = mp_first<I>(); // index of first argument
57 static constexpr const size_t second = mp_second<I>();// index of second argument
58 };
59
60 struct test_pair {
61 bool m_error;
test_pairtest_pair62 test_pair(bool b = true) : m_error(b) {}
operator booltest_pair63 operator bool(){
64 return m_error;
65 }
66 template<typename I>
operator ()test_pair67 void operator()(const I &){
68 using pair = get_values<I>;
69 using TResult = mp_at<test_types, mp_first<I>>;
70 using TArg = typename mp_at<test_values, mp_second<I>>::value_type;
71 static constexpr TArg v = mp_at<test_values, mp_second<I>>()();
72 m_error &= test_cast<TResult>(
73 v,
74 boost::core::demangle(typeid(TResult).name()).c_str(),
75 boost::core::demangle(typeid(TArg).name()).c_str(),
76 test_result_cast[pair::first][pair::second]
77 );
78 }
79 };
80
main()81 int main(){
82 // list of indices for values (integral constants)
83 using value_indices = mp_iota_c<mp_size<test_values>::value>;
84 // list of indices for types (integral constants)
85 using type_indices = mp_iota_c<mp_size<test_types>::value>;
86
87 // test runtime behavior
88 test_pair rval(true);
89 mp_for_each<
90 mp_product<mp_list, type_indices, value_indices>
91 >(rval);
92
93 std::cout << (rval ? "success!" : "failure") << std::endl;
94 return ! rval ;
95 }
96