]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
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> | |
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 | ||
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 | } |