• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2019 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 // compile only test to test constexpr casting
8 
9 #include <boost/safe_numerics/safe_integer.hpp>
10 #include <boost/safe_numerics/native.hpp>
11 #include <boost/safe_numerics/exception_policies.hpp>
12 
13 template <class T>
14 using safe_t = boost::safe_numerics::safe<
15     T,
16     boost::safe_numerics::native,
17     boost::safe_numerics::trap_exception
18 >;
19 
20 constexpr const char * test_casting_results[] = {
21 //      0       0       0       0
22 //      012345670123456701234567012345670
23 //      012345678901234567890123456789012
24 /* 0*/ ".....xxx.xxx.xxx.xxx.xxx.xxx.xxx.",
25 /* 1*/ ".........xxx.xxx...x.xxx.xxx.xxx.",
26 /* 2*/ ".............xxx...x...x.xxx.xxx.",
27 /* 3*/ "...................x...x...x.xxx.",
28 /* 4*/ "..xx.xxx.xxx.xxx..xx.xxx.xxx.xxx.",
29 /* 5*/ "..xx..xx.xxx.xxx......xx.xxx.xxx.",
30 /* 6*/ "..xx..xx..xx.xxx..........xx.xxx.",
31 /* 7*/ "..xx..xx..xx..xx..............xx.",
32 };
33 
34 #include <boost/safe_numerics/safe_integer_literal.hpp>
35 using namespace boost::safe_numerics;
36 
37 #include <boost/mp11/algorithm.hpp>
38 
39 using namespace boost::mp11;
40 
41 template<class T>
42 struct p {
43     constexpr static bool value = '.' == test_casting_results[mp_first<T>::value][mp_second<T>::value];
44 };
45 
46 template<class T2, class T1>
test_cast_constexpr(const T1 & v1)47 constexpr bool test_cast_constexpr(const T1 & v1){
48     // if we don't expect the operation to pass, we can't
49     // check the constexpr version of the calculation so
50     // just return success.
51     #pragma GCC diagnostic push
52     #pragma GCC diagnostic ignored "-Wunused-value"
53     static_cast<safe_t<T2>>(v1);
54     static_cast<T2>(v1);
55     #pragma GCC diagnostic pop
56     return true;
57 }
58 
59 #include "test_values.hpp"
60 
61 template<typename L2>
62 struct test {
63     static_assert(mp_is_list<L2>(), "must be a list of two indices");
64     const static std::size_t i = mp_first<L2>();
65     const static std::size_t j = mp_second<L2>();
66     using T = mp_at_c<test_types, i>; // first element is a type
67     using T1 = typename mp_at_c<test_values, j>::value_type;
68     const static T1 v = mp_at_c<test_values, j>::value;
69     const static bool value =
70         test_cast_constexpr<T>(make_safe_literal(v, native, trap_exception));
71 };
72 
main()73 int main(){
74     using namespace boost::safe_numerics;
75 
76     using type_indices = mp_iota_c<mp_size<test_types>::value>;
77     using value_indices = mp_iota_c<mp_size<test_values>::value>;
78 
79     // generate all combinations of types <- value
80     using l = mp_product<mp_list,type_indices,value_indices>;
81     //boost::safe_numerics::utility::print_types<l> lp;
82 
83     // filter out the invalid ones
84     using l1 = mp_copy_if<l, p>;
85     //boost::safe_numerics::utility::print_types<l1> l1p;
86 
87     // verify that all valid ones compile without error
88     static_assert(mp_all_of<l1, test>(), "testing all valid casts");
89     return 0;
90 }
91