test_checked_cast.cpp 3.0 KB

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