| 1 | // (C) 2003, Fernando Luis Cacciola Carballal. |
|---|
| 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 | |
|---|
| 8 | |
|---|
| 9 | // |
|---|
| 10 | // NOTE: This file is intended to be used ONLY by the test files |
|---|
| 11 | // from the Numeric Conversions Library |
|---|
| 12 | // |
|---|
| 13 | |
|---|
| 14 | // The conversion test is performed using a class whose instances encapsulate |
|---|
| 15 | // a particular specific conversion defnied explicitely. |
|---|
| 16 | // A ConversionInstance object includes the source type, the target type, |
|---|
| 17 | // the source value and the expected result, including possible exceptions. |
|---|
| 18 | // |
|---|
| 19 | |
|---|
| 20 | enum PostCondition { c_converted, c_overflow, c_neg_overflow, c_pos_overflow } ; |
|---|
| 21 | |
|---|
| 22 | template<class Converter> |
|---|
| 23 | struct ConversionInstance |
|---|
| 24 | { |
|---|
| 25 | typedef Converter converter ; |
|---|
| 26 | |
|---|
| 27 | typedef typename Converter::argument_type argument_type ; |
|---|
| 28 | typedef typename Converter::result_type result_type ; |
|---|
| 29 | |
|---|
| 30 | typedef typename Converter::traits traits ; |
|---|
| 31 | typedef typename traits::target_type target_type ; |
|---|
| 32 | typedef typename traits::source_type source_type ; |
|---|
| 33 | |
|---|
| 34 | ConversionInstance ( result_type a_result, argument_type a_source, PostCondition a_post) |
|---|
| 35 | : |
|---|
| 36 | source(a_source), |
|---|
| 37 | result(a_result), |
|---|
| 38 | post(a_post) |
|---|
| 39 | {} |
|---|
| 40 | |
|---|
| 41 | std::string to_string() const |
|---|
| 42 | { |
|---|
| 43 | return std::string("converter<") |
|---|
| 44 | + typeid(target_type).name() |
|---|
| 45 | + std::string(",") |
|---|
| 46 | + typeid(source_type).name() |
|---|
| 47 | + std::string(">::convert(") ; |
|---|
| 48 | } |
|---|
| 49 | |
|---|
| 50 | argument_type source ; |
|---|
| 51 | result_type result ; |
|---|
| 52 | PostCondition post ; |
|---|
| 53 | } ; |
|---|
| 54 | |
|---|
| 55 | // |
|---|
| 56 | // Main conversion test point. |
|---|
| 57 | // Exercises a specific conversion described by 'conv'. |
|---|
| 58 | // |
|---|
| 59 | template<class Instance> |
|---|
| 60 | void test_conv_base( Instance const& conv ) |
|---|
| 61 | { |
|---|
| 62 | typedef typename Instance::argument_type argument_type ; |
|---|
| 63 | typedef typename Instance::result_type result_type ; |
|---|
| 64 | typedef typename Instance::converter converter ; |
|---|
| 65 | |
|---|
| 66 | argument_type source = conv.source ; |
|---|
| 67 | |
|---|
| 68 | try |
|---|
| 69 | { |
|---|
| 70 | result_type result = converter::convert(source); |
|---|
| 71 | |
|---|
| 72 | if ( conv.post == c_converted ) |
|---|
| 73 | { |
|---|
| 74 | BOOST_CHECK_MESSAGE( result == conv.result, |
|---|
| 75 | conv.to_string() << printable(source) << ")= " << printable(result) << ". Expected:" << printable(conv.result) |
|---|
| 76 | ) ; |
|---|
| 77 | } |
|---|
| 78 | else |
|---|
| 79 | { |
|---|
| 80 | BOOST_ERROR( conv.to_string() << printable(source) << ") = " << printable(result) |
|---|
| 81 | << ". Expected:" << ( conv.post == c_neg_overflow ? " negative_overflow" : "positive_overflow" ) |
|---|
| 82 | ) ; |
|---|
| 83 | } |
|---|
| 84 | } |
|---|
| 85 | catch ( boost::numeric::negative_overflow const& ) |
|---|
| 86 | { |
|---|
| 87 | if ( conv.post == c_neg_overflow ) |
|---|
| 88 | { |
|---|
| 89 | BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = negative_overflow, as expected" ) ; |
|---|
| 90 | } |
|---|
| 91 | else |
|---|
| 92 | { |
|---|
| 93 | BOOST_ERROR( conv.to_string() << printable(source) << ") = negative_overflow. Expected:" << printable(conv.result) ) ; |
|---|
| 94 | } |
|---|
| 95 | } |
|---|
| 96 | catch ( boost::numeric::positive_overflow const& ) |
|---|
| 97 | { |
|---|
| 98 | if ( conv.post == c_pos_overflow ) |
|---|
| 99 | { |
|---|
| 100 | BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = positive_overflow, as expected" ) ; |
|---|
| 101 | } |
|---|
| 102 | else |
|---|
| 103 | { |
|---|
| 104 | BOOST_ERROR( conv.to_string() << printable(source) << ") = positive_overflow. Expected:" << printable(conv.result) ) ; |
|---|
| 105 | } |
|---|
| 106 | } |
|---|
| 107 | catch ( boost::numeric::bad_numeric_cast const& ) |
|---|
| 108 | { |
|---|
| 109 | if ( conv.post == c_overflow ) |
|---|
| 110 | { |
|---|
| 111 | BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = bad_numeric_cast, as expected" ) ; |
|---|
| 112 | } |
|---|
| 113 | else |
|---|
| 114 | { |
|---|
| 115 | BOOST_ERROR( conv.to_string() << printable(source) << ") = bad_numeric_cast. Expected:" << printable(conv.result) ) ; |
|---|
| 116 | } |
|---|
| 117 | } |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | #define TEST_SUCCEEDING_CONVERSION(Conv,typeT,typeS,valueT,valueS) \ |
|---|
| 122 | test_conv_base( ConversionInstance< Conv >(valueT, valueS, c_converted ) ) |
|---|
| 123 | |
|---|
| 124 | #define TEST_POS_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \ |
|---|
| 125 | test_conv_base( ConversionInstance< Conv >( static_cast< typeT >(0), valueS, c_pos_overflow ) ) |
|---|
| 126 | |
|---|
| 127 | #define TEST_NEG_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \ |
|---|
| 128 | test_conv_base( ConversionInstance< Conv >( static_cast< typeT >(0), valueS, c_neg_overflow ) ) |
|---|
| 129 | |
|---|
| 130 | #define DEF_CONVERTER(T,S) boost::numeric::converter< T , S > |
|---|
| 131 | |
|---|
| 132 | #define TEST_SUCCEEDING_CONVERSION_DEF(typeT,typeS,valueT,valueS) \ |
|---|
| 133 | TEST_SUCCEEDING_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueT, valueS ) |
|---|
| 134 | |
|---|
| 135 | #define TEST_POS_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \ |
|---|
| 136 | TEST_POS_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS ) |
|---|
| 137 | |
|---|
| 138 | #define TEST_NEG_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \ |
|---|
| 139 | TEST_NEG_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS ) |
|---|
| 140 | |
|---|
| 141 | |
|---|
| 142 | // |
|---|
| 143 | /////////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 144 | |
|---|