// Copyright (c) 2012 Robert Ramey // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // test constructors #include #include #include template bool test_construction(T1 t1, const char *t2_name, const char *t1_name){ using namespace boost::safe_numerics; std::cout << "testing constructions to " << t2_name << " from " << t1_name << std::endl; { /* (1) test construction of safe from T1 type */ try{ safe s1(t1); // should always arrive here! } catch(const std::exception &){ // should never, ever arrive here std::cout << "erroneously detected error in construction " << "safe<" << t1_name << "> (" << t1_name << ")" << std::endl; try{ safe s1(t1); // try again for debugging } catch(const std::exception &){} return false; } } { /* (2) test construction of safe from T1 type */ T2 t2; try{ t2 = safe(t1); if(! safe_compare::equal(t2 , t1)){ std::cout << "failed to detect error in construction " << "safe<" << t2_name << "> (" << t1_name << ")" << std::endl; safe s2x(t1); return false; } } catch(const std::exception &){ if(safe_compare::equal(t2, t1)){ std::cout << "erroneously detected error in construction " << "safe<" << t2_name << "> (" << t1_name << ")" << std::endl; try{ safe sx2(t1); // try again for debugging } catch(const std::exception &){} return false; } } } { /* (3) test construction of safe from safe type */ safe s1x(t1); try{ safe s1(s1x); if(! (s1 == s1x)){ std::cout << "copy constructor altered value " << "safe<" << t1_name << "> (safe<" << t1_name << ">(" << t1 << "))" << std::endl; //safe s1(s1x); return false; } } catch(const std::exception &){ // should never arrive here std::cout << "erroneously detected error in construction " << "safe<" << t1_name << "> (safe<" << t1_name << ">(" << t1 << "))" << std::endl; try{ safe s1(t1); } catch(const std::exception &){} return false; } } { /* (4) test construction of safe from safe type */ T2 t2; try{ safe s1(t1); safe s2(s1); t2 = static_cast(s2); if(! (safe_compare::equal(t1, t2))){ std::cout << "failed to detect error in construction " << "safe<" << t1_name << "> (safe<" << t2_name << ">(" << t1 << "))" << std::endl; safe s1x(t1); return false; } } catch(const std::exception &){ if(safe_compare::equal(t1, t2)){ std::cout << "erroneously detected error in construction " << "safe<" << t2_name << "> (safe<" << t1_name << ">(" << t1 << "))" << std::endl; try{ safe s1(t1); } catch(const std::exception &){} return false; } } } return true; } #include #include #include "test_values.hpp" using namespace boost::mp11; struct test { bool m_error; test(bool b = true) : m_error(b) {} operator bool(){ return m_error; } template void operator()(const T &){ static_assert(mp_is_list(), "must be a list of two types"); using T1 = mp_first; // first element is a type // second element is an integral constant using T2 = typename mp_second::value_type; // get it's type constexpr T2 v2 = mp_second(); // get it's value m_error &= test_construction( v2, boost::core::demangle(typeid(T1).name()).c_str(), boost::core::demangle(typeid(T2).name()).c_str() ); } }; template using extract_value_type = typename T::value_type; using test_types = mp_unique< mp_transform< extract_value_type, test_values > >; int main(){ test rval(true); mp_for_each< mp_product >(rval); std::cout << (rval ? "success!" : "failure") << std::endl; return ! rval ; }