summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/numeric/conversion/test/test_helpers3.cpp
blob: de345ba860df9ab88c4c78b8c7634c830e874b51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// 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)
//


//
// NOTE: This file is intended to be used ONLY by the test files
//       from the Numeric Conversions Library
//

// The conversion test is performed using a class whose instances encapsulate
// a particular specific conversion defnied explicitely.
// A ConversionInstance object includes the source type, the target type,
// the source value and the expected result, including possible exceptions.
//

enum PostCondition { c_converted, c_overflow, c_neg_overflow, c_pos_overflow } ;

template<class Converter>
struct ConversionInstance
{
  typedef Converter converter ;

  typedef typename Converter::argument_type argument_type ;
  typedef typename Converter::result_type   result_type   ;

  typedef typename Converter::traits traits ;
  typedef typename traits::target_type target_type ;
  typedef typename traits::source_type source_type ;

  ConversionInstance ( result_type a_result, argument_type a_source, PostCondition a_post)
    :
    source(a_source),
    result(a_result),
    post(a_post)
  {}

  std::string to_string() const
    {
      return   std::string("converter<")
             + typeid(target_type).name()
             + std::string(",")
             + typeid(source_type).name()
             + std::string(">::convert(") ;
    }

  argument_type source ;
  result_type   result ;
  PostCondition post   ;
} ;

//
// Main conversion test point.
// Exercises a specific conversion described by 'conv'.
//
template<class Instance>
void test_conv_base( Instance const& conv )
{
  typedef typename Instance::argument_type argument_type ;
  typedef typename Instance::result_type   result_type   ;
  typedef typename Instance::converter     converter ;

  argument_type source = conv.source ;

  try
  {
    result_type result = converter::convert(source);

    if ( conv.post == c_converted )
    {
      BOOST_CHECK_MESSAGE( result == conv.result,
                           conv.to_string() <<  printable(source) << ")= " << printable(result) << ". Expected:" << printable(conv.result)
                         ) ;
    }
    else
    {
      BOOST_ERROR( conv.to_string() << printable(source) << ") = " << printable(result)
                   << ". Expected:" << ( conv.post == c_neg_overflow ? " negative_overflow" : "positive_overflow" )
                 ) ;
    }
  }
  catch ( boost::numeric::negative_overflow const& )
  {
    if ( conv.post == c_neg_overflow )
    {
      BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = negative_overflow, as expected" ) ;
    }
    else
    {
      BOOST_ERROR( conv.to_string() << printable(source) << ") = negative_overflow. Expected:" <<  printable(conv.result) ) ;
    }
  }
  catch ( boost::numeric::positive_overflow const& )
  {
    if ( conv.post == c_pos_overflow )
    {
      BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = positive_overflow, as expected" ) ;
    }
    else
    {
      BOOST_ERROR( conv.to_string() << printable(source) << ") = positive_overflow. Expected:" <<  printable(conv.result) ) ;
    }
  }
  catch ( boost::numeric::bad_numeric_cast const& )
  {
    if ( conv.post == c_overflow )
    {
      BOOST_CHECK_MESSAGE( true, conv.to_string() << printable(source) << ") = bad_numeric_cast, as expected" ) ;
    }
    else
    {
      BOOST_ERROR( conv.to_string() << printable(source) << ") = bad_numeric_cast. Expected:" <<  printable(conv.result) ) ;
    }
  }
}


#define TEST_SUCCEEDING_CONVERSION(Conv,typeT,typeS,valueT,valueS) \
        test_conv_base( ConversionInstance< Conv >(valueT, valueS, c_converted ) )

#define TEST_POS_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \
        test_conv_base( ConversionInstance< Conv >( static_cast< typeT >(0), valueS, c_pos_overflow ) )

#define TEST_NEG_OVERFLOW_CONVERSION(Conv,typeT,typeS,valueS) \
        test_conv_base( ConversionInstance< Conv >( static_cast< typeT >(0), valueS, c_neg_overflow ) )

#define DEF_CONVERTER(T,S) boost::numeric::converter< T , S >

#define TEST_SUCCEEDING_CONVERSION_DEF(typeT,typeS,valueT,valueS) \
        TEST_SUCCEEDING_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueT, valueS )

#define TEST_POS_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \
        TEST_POS_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS )

#define TEST_NEG_OVERFLOW_CONVERSION_DEF(typeT,typeS,valueS) \
        TEST_NEG_OVERFLOW_CONVERSION( DEF_CONVERTER(typeT,typeS), typeT, typeS, valueS )


//
///////////////////////////////////////////////////////////////////////////////////////////////