Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/rational/rational_test.cpp @ 35

Last change on this file since 35 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 20.0 KB
Line 
1/*
2 *  A test program for boost/rational.hpp.
3 *  Change the typedef at the beginning of run_tests() to try out different
4 *  integer types.  (These tests are designed only for signed integer
5 *  types.  They should work for short, int and long.)
6 *
7 *  (C) Copyright Stephen Silver, 2001. Permission to copy, use, modify, sell
8 *  and distribute this software is granted provided this copyright notice
9 *  appears in all copies. This software is provided "as is" without express or
10 *  implied warranty, and with no claim as to its suitability for any purpose.
11 *
12 *  Incorporated into the boost rational number library, and modified and
13 *  extended, by Paul Moore, with permission.
14 */
15
16// Revision History
17// 18 Oct 06  Various fixes for old compilers (Joaquín M López Muñoz)
18// 27 Dec 05  Add testing for Boolean conversion operator (Daryle Walker)
19// 24 Dec 05  Change code to use Boost.Test (Daryle Walker)
20// 04 Mar 01  Patches for Intel C++ and GCC (David Abrahams)
21
22#define BOOST_TEST_MAIN  "Boost::Rational unit tests"
23
24#include <boost/mpl/list.hpp>
25#include <boost/operators.hpp>
26#include <boost/preprocessor/stringize.hpp>
27
28#include <boost/rational.hpp>
29
30#include <boost/test/unit_test.hpp>
31#include <boost/test/floating_point_comparison.hpp>
32#include <boost/test/test_case_template.hpp>
33
34#include <iostream>
35#include <istream>
36#include <ostream>
37#include <sstream>
38
39// We can override this on the compile, as -DINT_TYPE=short or whatever.
40// The default test is against rational<long>.
41#ifndef INT_TYPE
42#define INT_TYPE long
43#endif
44
45namespace {
46
47// This is a trivial user-defined wrapper around the built in int type.
48// It can be used as a test type for rational<>
49class MyInt : boost::operators<MyInt>
50{
51    int val;
52public:
53    MyInt(int n = 0) : val(n) {}
54    friend MyInt operator+ (const MyInt&);
55    friend MyInt operator- (const MyInt&);
56    MyInt& operator+= (const MyInt& rhs) { val += rhs.val; return *this; }
57    MyInt& operator-= (const MyInt& rhs) { val -= rhs.val; return *this; }
58    MyInt& operator*= (const MyInt& rhs) { val *= rhs.val; return *this; }
59    MyInt& operator/= (const MyInt& rhs) { val /= rhs.val; return *this; }
60    MyInt& operator%= (const MyInt& rhs) { val %= rhs.val; return *this; }
61    MyInt& operator|= (const MyInt& rhs) { val |= rhs.val; return *this; }
62    MyInt& operator&= (const MyInt& rhs) { val &= rhs.val; return *this; }
63    MyInt& operator^= (const MyInt& rhs) { val ^= rhs.val; return *this; }
64    const MyInt& operator++() { ++val; return *this; }
65    const MyInt& operator--() { --val; return *this; }
66    bool operator< (const MyInt& rhs) const { return val < rhs.val; }
67    bool operator== (const MyInt& rhs) const { return val == rhs.val; }
68    bool operator! () const { return !val; }
69    friend std::istream& operator>>(std::istream&, MyInt&);
70    friend std::ostream& operator<<(std::ostream&, const MyInt&);
71};
72
73inline MyInt operator+(const MyInt& rhs) { return rhs; }
74inline MyInt operator-(const MyInt& rhs) { return MyInt(-rhs.val); }
75inline std::istream& operator>>(std::istream& is, MyInt& i) { is >> i.val; return is; }
76inline std::ostream& operator<<(std::ostream& os, const MyInt& i) { os << i.val; return os; }
77inline MyInt abs(MyInt rhs) { if (rhs < MyInt()) rhs = -rhs; return rhs; }
78
79// This fixture replaces the check of rational's packing at the start of main.
80class rational_size_check
81{
82    typedef INT_TYPE                          int_type;
83    typedef ::boost::rational<int_type>  rational_type;
84
85public:
86    rational_size_check()
87    {
88        using ::std::cout;
89
90        char const * const  int_name = BOOST_PP_STRINGIZE( INT_TYPE );
91
92        cout << "Running tests for boost::rational<" << int_name << ">\n\n";
93
94        cout << "Implementation issue: the minimal size for a rational\n"
95             << "is twice the size of the underlying integer type.\n\n";
96
97        cout << "Checking to see if space is being wasted.\n"
98             << "\tsizeof(" << int_name << ") == " << sizeof( int_type )
99             << "\n";
100        cout <<  "\tsizeof(boost::rational<" << int_name << ">) == "
101             << sizeof( rational_type ) << "\n\n";
102
103        cout << "Implementation has "
104             << ( 
105                  (sizeof( rational_type ) > 2u * sizeof( int_type ))
106                  ? "included padding bytes"
107                  : "minimal size"
108                )
109             << "\n\n";
110    }
111};
112
113// This fixture groups all the common settings.
114class my_configuration
115{
116public:
117    template < typename T >
118    class hook
119    {
120    public:
121        typedef ::boost::rational<T>  rational_type;
122
123    private:
124        struct parts { rational_type parts_[ 9 ]; };
125
126        static  parts  generate_rationals()
127        {
128            rational_type  r1, r2( 0 ), r3( 1 ), r4( -3 ), r5( 7, 2 ),
129                           r6( 5, 15 ), r7( 14, -21 ), r8( -4, 6 ),
130                           r9( -14, -70 );
131            parts result;
132            result.parts_[0] = r1;
133            result.parts_[1] = r2;
134            result.parts_[2] = r3;
135            result.parts_[3] = r4;
136            result.parts_[4] = r5;
137            result.parts_[5] = r6;
138            result.parts_[6] = r7;
139            result.parts_[7] = r8;
140            result.parts_[8] = r9;
141
142            return result;
143        }
144
145        parts  p_;  // Order Dependency
146
147    public:
148        rational_type  ( &r_ )[ 9 ];  // Order Dependency
149
150        hook() : p_( generate_rationals() ), r_( p_.parts_ ) {}
151    };
152};
153
154// Instead of controlling the integer type needed with a #define, use a list of
155// all available types.  Since the headers #included don't change because of the
156// integer #define, only the built-in types and MyInt are available.  (Any other
157// arbitrary integer type introduced by the #define would get compiler errors
158// because its header can't be #included.)
159typedef ::boost::mpl::list<short, int, long>     builtin_signed_test_types;
160typedef ::boost::mpl::list<short, int, long, MyInt>  all_signed_test_types;
161
162// Without these explicit instantiations, MSVC++ 6.5/7.0 does not find
163// some friend operators in certain contexts.
164::boost::rational<short> dummy1;
165::boost::rational<int>   dummy2;
166::boost::rational<long>  dummy3;
167::boost::rational<MyInt> dummy4;
168
169// Should there be tests with unsigned integer types?
170
171} // namespace
172
173
174// Check if rational is the smallest size possible
175BOOST_GLOBAL_FIXTURE( rational_size_check )
176
177
178// The factoring function template suite
179BOOST_AUTO_TEST_SUITE( factoring_suite )
180
181// GCD tests
182BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_test, T, all_signed_test_types )
183{
184    BOOST_CHECK_EQUAL( boost::gcd<T>(  1,  -1), static_cast<T>( 1) );
185    BOOST_CHECK_EQUAL( boost::gcd<T>( -1,   1), static_cast<T>( 1) );
186    BOOST_CHECK_EQUAL( boost::gcd<T>(  1,   1), static_cast<T>( 1) );
187    BOOST_CHECK_EQUAL( boost::gcd<T>( -1,  -1), static_cast<T>( 1) );
188    BOOST_CHECK_EQUAL( boost::gcd<T>(  0,   0), static_cast<T>( 0) );
189    BOOST_CHECK_EQUAL( boost::gcd<T>(  7,   0), static_cast<T>( 7) );
190    BOOST_CHECK_EQUAL( boost::gcd<T>(  0,   9), static_cast<T>( 9) );
191    BOOST_CHECK_EQUAL( boost::gcd<T>( -7,   0), static_cast<T>( 7) );
192    BOOST_CHECK_EQUAL( boost::gcd<T>(  0,  -9), static_cast<T>( 9) );
193    BOOST_CHECK_EQUAL( boost::gcd<T>( 42,  30), static_cast<T>( 6) );
194    BOOST_CHECK_EQUAL( boost::gcd<T>(  6,  -9), static_cast<T>( 3) );
195    BOOST_CHECK_EQUAL( boost::gcd<T>(-10, -10), static_cast<T>(10) );
196    BOOST_CHECK_EQUAL( boost::gcd<T>(-25, -10), static_cast<T>( 5) );
197}
198
199// LCM tests
200BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_test, T, all_signed_test_types )
201{
202    BOOST_CHECK_EQUAL( boost::lcm<T>(  1,  -1), static_cast<T>( 1) );
203    BOOST_CHECK_EQUAL( boost::lcm<T>( -1,   1), static_cast<T>( 1) );
204    BOOST_CHECK_EQUAL( boost::lcm<T>(  1,   1), static_cast<T>( 1) );
205    BOOST_CHECK_EQUAL( boost::lcm<T>( -1,  -1), static_cast<T>( 1) );
206    BOOST_CHECK_EQUAL( boost::lcm<T>(  0,   0), static_cast<T>( 0) );
207    BOOST_CHECK_EQUAL( boost::lcm<T>(  6,   0), static_cast<T>( 0) );
208    BOOST_CHECK_EQUAL( boost::lcm<T>(  0,   7), static_cast<T>( 0) );
209    BOOST_CHECK_EQUAL( boost::lcm<T>( -5,   0), static_cast<T>( 0) );
210    BOOST_CHECK_EQUAL( boost::lcm<T>(  0,  -4), static_cast<T>( 0) );
211    BOOST_CHECK_EQUAL( boost::lcm<T>( 18,  30), static_cast<T>(90) );
212    BOOST_CHECK_EQUAL( boost::lcm<T>( -6,   9), static_cast<T>(18) );
213    BOOST_CHECK_EQUAL( boost::lcm<T>(-10, -10), static_cast<T>(10) );
214    BOOST_CHECK_EQUAL( boost::lcm<T>( 25, -10), static_cast<T>(50) );
215}
216
217BOOST_AUTO_TEST_SUITE_END()
218
219
220// The basic test suite
221BOOST_FIXTURE_TEST_SUITE( basic_rational_suite, my_configuration )
222
223// Initialization tests
224BOOST_AUTO_TEST_CASE_TEMPLATE( rational_initialization_test, T,
225 all_signed_test_types )
226{
227    my_configuration::hook<T>  h;
228    boost::rational<T>  &r1 = h.r_[ 0 ], &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ],
229                        &r4 = h.r_[ 3 ], &r5 = h.r_[ 4 ], &r6 = h.r_[ 5 ],
230                        &r7 = h.r_[ 6 ], &r8 = h.r_[ 7 ], &r9 = h.r_[ 8 ];
231
232    BOOST_CHECK_EQUAL( r1.numerator(), static_cast<T>( 0) );
233    BOOST_CHECK_EQUAL( r2.numerator(), static_cast<T>( 0) );
234    BOOST_CHECK_EQUAL( r3.numerator(), static_cast<T>( 1) );
235    BOOST_CHECK_EQUAL( r4.numerator(), static_cast<T>(-3) );
236    BOOST_CHECK_EQUAL( r5.numerator(), static_cast<T>( 7) );
237    BOOST_CHECK_EQUAL( r6.numerator(), static_cast<T>( 1) );
238    BOOST_CHECK_EQUAL( r7.numerator(), static_cast<T>(-2) );
239    BOOST_CHECK_EQUAL( r8.numerator(), static_cast<T>(-2) );
240    BOOST_CHECK_EQUAL( r9.numerator(), static_cast<T>( 1) );
241
242    BOOST_CHECK_EQUAL( r1.denominator(), static_cast<T>(1) );
243    BOOST_CHECK_EQUAL( r2.denominator(), static_cast<T>(1) );
244    BOOST_CHECK_EQUAL( r3.denominator(), static_cast<T>(1) );
245    BOOST_CHECK_EQUAL( r4.denominator(), static_cast<T>(1) );
246    BOOST_CHECK_EQUAL( r5.denominator(), static_cast<T>(2) );
247    BOOST_CHECK_EQUAL( r6.denominator(), static_cast<T>(3) );
248    BOOST_CHECK_EQUAL( r7.denominator(), static_cast<T>(3) );
249    BOOST_CHECK_EQUAL( r8.denominator(), static_cast<T>(3) );
250    BOOST_CHECK_EQUAL( r9.denominator(), static_cast<T>(5) );
251}
252
253// Assignment (non-operator) tests
254BOOST_AUTO_TEST_CASE_TEMPLATE( rational_assign_test, T, all_signed_test_types )
255{
256    my_configuration::hook<T>  h;
257    boost::rational<T> &       r = h.r_[ 0 ];
258
259    r.assign( 6, 8 );
260    BOOST_CHECK_EQUAL( r.numerator(),   static_cast<T>(3) );
261    BOOST_CHECK_EQUAL( r.denominator(), static_cast<T>(4) );
262
263    r.assign( 0, -7 );
264    BOOST_CHECK_EQUAL( r.numerator(),   static_cast<T>(0) );
265    BOOST_CHECK_EQUAL( r.denominator(), static_cast<T>(1) );
266}
267
268// Comparison tests
269BOOST_AUTO_TEST_CASE_TEMPLATE( rational_comparison_test, T,
270 all_signed_test_types )
271{
272    my_configuration::hook<T>  h;
273    boost::rational<T>  &r1 = h.r_[ 0 ], &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ],
274                        &r4 = h.r_[ 3 ], &r5 = h.r_[ 4 ], &r6 = h.r_[ 5 ],
275                        &r7 = h.r_[ 6 ], &r8 = h.r_[ 7 ], &r9 = h.r_[ 8 ];
276
277    BOOST_CHECK( r1 == r2 );
278    BOOST_CHECK( r2 != r3 );
279    BOOST_CHECK( r4 <  r3 );
280    BOOST_CHECK( r4 <= r5 );
281    BOOST_CHECK( r1 <= r2 );
282    BOOST_CHECK( r5 >  r6 );
283    BOOST_CHECK( r5 >= r6 );
284    BOOST_CHECK( r7 >= r8 );
285
286    BOOST_CHECK( !(r3 == r2) );
287    BOOST_CHECK( !(r1 != r2) );
288    BOOST_CHECK( !(r1 <  r2) );
289    BOOST_CHECK( !(r5 <  r6) );
290    BOOST_CHECK( !(r9 <= r2) );
291    BOOST_CHECK( !(r8 >  r7) );
292    BOOST_CHECK( !(r8 >  r2) );
293    BOOST_CHECK( !(r4 >= r6) );
294
295    BOOST_CHECK( r1 == static_cast<T>( 0) );
296    BOOST_CHECK( r2 != static_cast<T>(-1) );
297    BOOST_CHECK( r3 <  static_cast<T>( 2) );
298    BOOST_CHECK( r4 <= static_cast<T>(-3) );
299    BOOST_CHECK( r5 >  static_cast<T>( 3) );
300    BOOST_CHECK( r6 >= static_cast<T>( 0) );
301
302    BOOST_CHECK( static_cast<T>( 0) == r2 );
303    BOOST_CHECK( static_cast<T>( 0) != r7 );
304    BOOST_CHECK( static_cast<T>(-1) <  r8 );
305    BOOST_CHECK( static_cast<T>(-2) <= r9 );
306    BOOST_CHECK( static_cast<T>( 1) >  r1 );
307    BOOST_CHECK( static_cast<T>( 1) >= r3 );
308}
309
310// Increment & decrement tests
311BOOST_AUTO_TEST_CASE_TEMPLATE( rational_1step_test, T, all_signed_test_types )
312{
313    my_configuration::hook<T>  h;
314    boost::rational<T>  &r1 = h.r_[ 0 ], &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ],
315                        &r7 = h.r_[ 6 ], &r8 = h.r_[ 7 ];
316
317    BOOST_CHECK(   r1++ == r2 );
318    BOOST_CHECK(   r1   != r2 );
319    BOOST_CHECK(   r1   == r3 );
320    BOOST_CHECK( --r1   == r2 );
321    BOOST_CHECK(   r8-- == r7 );
322    BOOST_CHECK(   r8   != r7 );
323    BOOST_CHECK( ++r8   == r7 );
324}
325
326// Absolute value tests
327BOOST_AUTO_TEST_CASE_TEMPLATE( rational_abs_test, T, all_signed_test_types )
328{
329    typedef my_configuration::hook<T>           hook_type;
330    typedef typename hook_type::rational_type   rational_type;
331
332    hook_type      h;
333    rational_type  &r2 = h.r_[ 1 ], &r5 = h.r_[ 4 ], &r8 = h.r_[ 7 ];
334
335#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
336    // This is a nasty hack, required because some compilers do not implement
337    // "Koenig Lookup."  Basically, if I call abs(r), the C++ standard says that
338    // the compiler should look for a definition of abs in the namespace which
339    // contains r's class (in this case boost)--among other places.
340
341    using boost::abs;
342#endif
343
344    BOOST_CHECK_EQUAL( abs(r2), r2 );
345    BOOST_CHECK_EQUAL( abs(r5), r5 );
346    BOOST_CHECK_EQUAL( abs(r8), rational_type(2, 3) );
347}
348
349// Unary operator tests
350BOOST_AUTO_TEST_CASE_TEMPLATE( rational_unary_test, T, all_signed_test_types )
351{
352    my_configuration::hook<T>  h;
353    boost::rational<T>         &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ],
354                               &r4 = h.r_[ 3 ], &r5 = h.r_[ 4 ];
355
356    BOOST_CHECK_EQUAL( +r5, r5 );
357
358    BOOST_CHECK( -r3 != r3 );
359    BOOST_CHECK_EQUAL( -(-r3), r3 );
360    BOOST_CHECK_EQUAL( -r4, static_cast<T>(3) );
361
362    BOOST_CHECK( !r2 );
363    BOOST_CHECK( !!r3 );
364
365    BOOST_CHECK( ! static_cast<bool>(r2) );
366    BOOST_CHECK( r3 );
367}
368
369BOOST_AUTO_TEST_SUITE_END()
370
371
372// The rational arithmetic operations suite
373BOOST_AUTO_TEST_SUITE( rational_arithmetic_suite )
374
375// Addition & subtraction tests
376BOOST_AUTO_TEST_CASE_TEMPLATE( rational_additive_test, T,
377 all_signed_test_types )
378{
379    typedef boost::rational<T>  rational_type;
380
381    BOOST_CHECK_EQUAL( rational_type( 1, 2) + rational_type(1, 2),
382     static_cast<T>(1) );
383    BOOST_CHECK_EQUAL( rational_type(11, 3) + rational_type(1, 2),
384     rational_type( 25,  6) );
385    BOOST_CHECK_EQUAL( rational_type(-8, 3) + rational_type(1, 5),
386     rational_type(-37, 15) );
387    BOOST_CHECK_EQUAL( rational_type(-7, 6) + rational_type(1, 7),
388     rational_type(  1,  7) - rational_type(7, 6) );
389    BOOST_CHECK_EQUAL( rational_type(13, 5) - rational_type(1, 2),
390     rational_type( 21, 10) );
391    BOOST_CHECK_EQUAL( rational_type(22, 3) + static_cast<T>(1),
392     rational_type( 25,  3) );
393    BOOST_CHECK_EQUAL( rational_type(12, 7) - static_cast<T>(2),
394     rational_type( -2,  7) );
395    BOOST_CHECK_EQUAL(    static_cast<T>(3) + rational_type(4, 5),
396     rational_type( 19,  5) );
397    BOOST_CHECK_EQUAL(    static_cast<T>(4) - rational_type(9, 2),
398     rational_type( -1,  2) );
399
400    rational_type  r( 11 );
401
402    r -= rational_type( 20, 3 );
403    BOOST_CHECK_EQUAL( r, rational_type(13,  3) );
404
405    r += rational_type( 1, 2 );
406    BOOST_CHECK_EQUAL( r, rational_type(29,  6) );
407
408    r -= static_cast<T>( 5 );
409    BOOST_CHECK_EQUAL( r, rational_type( 1, -6) );
410
411    r += rational_type( 1, 5 );
412    BOOST_CHECK_EQUAL( r, rational_type( 1, 30) );
413
414    r += static_cast<T>( 2 );
415    BOOST_CHECK_EQUAL( r, rational_type(61, 30) );
416}
417
418// Assignment tests
419BOOST_AUTO_TEST_CASE_TEMPLATE( rational_assignment_test, T,
420 all_signed_test_types )
421{
422    typedef boost::rational<T>  rational_type;
423
424    rational_type  r;
425
426    r = rational_type( 1, 10 );
427    BOOST_CHECK_EQUAL( r, rational_type( 1, 10) );
428
429    r = static_cast<T>( -9 );
430    BOOST_CHECK_EQUAL( r, rational_type(-9,  1) );
431}
432
433// Multiplication tests
434BOOST_AUTO_TEST_CASE_TEMPLATE( rational_multiplication_test, T,
435 all_signed_test_types )
436{
437    typedef boost::rational<T>  rational_type;
438
439    BOOST_CHECK_EQUAL( rational_type(1, 3) * rational_type(-3, 4),
440     rational_type(-1, 4) );
441    BOOST_CHECK_EQUAL( rational_type(2, 5) * static_cast<T>(7),
442     rational_type(14, 5) );
443    BOOST_CHECK_EQUAL(  static_cast<T>(-2) * rational_type(1, 6),
444     rational_type(-1, 3) );
445
446    rational_type  r = rational_type( 3, 7 );
447
448    r *= static_cast<T>( 14 );
449    BOOST_CHECK_EQUAL( r, static_cast<T>(6) );
450
451    r *= rational_type( 3, 8 );
452    BOOST_CHECK_EQUAL( r, rational_type(9, 4) );
453}
454
455// Division tests
456BOOST_AUTO_TEST_CASE_TEMPLATE( rational_division_test, T,
457 all_signed_test_types )
458{
459    typedef boost::rational<T>  rational_type;
460
461    BOOST_CHECK_EQUAL( rational_type(-1, 20) / rational_type(4, 5),
462     rational_type(-1, 16) );
463    BOOST_CHECK_EQUAL( rational_type( 5,  6) / static_cast<T>(7),
464     rational_type( 5, 42) );
465    BOOST_CHECK_EQUAL(     static_cast<T>(8) / rational_type(2, 7),
466     static_cast<T>(28) );
467
468    rational_type  r = rational_type( 4, 3 );
469
470    r /= rational_type( 5, 4 );
471    BOOST_CHECK_EQUAL( r, rational_type(16, 15) );
472
473    r /= static_cast<T>( 4 );
474    BOOST_CHECK_EQUAL( r, rational_type( 4, 15) );
475
476    BOOST_CHECK_EQUAL( rational_type(-1) / rational_type(-3),
477     rational_type(1, 3) );
478}
479
480// Tests for operations on self
481BOOST_AUTO_TEST_CASE_TEMPLATE( rational_self_operations_test, T,
482 all_signed_test_types )
483{
484    typedef boost::rational<T>  rational_type;
485
486    rational_type  r = rational_type( 4, 3 );
487
488    r += r;
489    BOOST_CHECK_EQUAL( r, rational_type( 8, 3) );
490
491    r *= r;
492    BOOST_CHECK_EQUAL( r, rational_type(64, 9) );
493
494    r /= r;
495    BOOST_CHECK_EQUAL( r, rational_type( 1, 1) );
496
497    r -= r;
498    BOOST_CHECK_EQUAL( r, rational_type( 0, 1) );
499}
500
501BOOST_AUTO_TEST_SUITE_END()
502
503
504// The non-basic rational operations suite
505BOOST_AUTO_TEST_SUITE( rational_extras_suite )
506
507// Output test
508BOOST_AUTO_TEST_CASE_TEMPLATE( rational_output_test, T, all_signed_test_types )
509{
510    std::ostringstream  oss;
511   
512    oss << boost::rational<T>( 44, 14 );
513    BOOST_CHECK_EQUAL( oss.str(), "22/7" );
514}
515
516// Input test, failing
517BOOST_AUTO_TEST_CASE_TEMPLATE( rational_input_failing_test, T,
518 all_signed_test_types )
519{
520    std::istringstream  iss( "" );
521    boost::rational<T>  r;
522
523    iss >> r;
524    BOOST_CHECK( !iss );
525
526    iss.clear();
527    iss.str( "42" );
528    iss >> r;
529    BOOST_CHECK( !iss );
530
531    iss.clear();
532    iss.str( "57A" );
533    iss >> r;
534    BOOST_CHECK( !iss );
535
536    iss.clear();
537    iss.str( "20-20" );
538    iss >> r;
539    BOOST_CHECK( !iss );
540
541    iss.clear();
542    iss.str( "1/" );
543    iss >> r;
544    BOOST_CHECK( !iss );
545
546    iss.clear();
547    iss.str( "1/ 2" );
548    iss >> r;
549    BOOST_CHECK( !iss );
550
551    iss.clear();
552    iss.str( "1 /2" );
553    iss >> r;
554    BOOST_CHECK( !iss );
555}
556
557// Input test, passing
558BOOST_AUTO_TEST_CASE_TEMPLATE( rational_input_passing_test, T,
559 all_signed_test_types )
560{
561    typedef boost::rational<T>  rational_type;
562
563    std::istringstream  iss( "1/2 12" );
564    rational_type       r;
565    int                 n = 0;
566
567    BOOST_CHECK( iss >> r >> n );
568    BOOST_CHECK_EQUAL( r, rational_type(1, 2) );
569    BOOST_CHECK_EQUAL( n, 12 );
570
571    iss.clear();
572    iss.str( "34/67" );
573    BOOST_CHECK( iss >> r );
574    BOOST_CHECK_EQUAL( r, rational_type(34, 67) );
575
576    iss.clear();
577    iss.str( "-3/-6" );
578    BOOST_CHECK( iss >> r );
579    BOOST_CHECK_EQUAL( r, rational_type(1, 2) );
580}
581
582// Conversion test
583BOOST_AUTO_TEST_CASE( rational_cast_test )
584{
585    // Note that these are not generic.  The problem is that rational_cast<T>
586    // requires a conversion from IntType to T.  However, for a user-defined
587    // IntType, it is not possible to define such a conversion except as an
588    // "operator T()".  This causes problems with overloading resolution.
589    boost::rational<int> const  half( 1, 2 );
590
591    BOOST_CHECK_CLOSE( boost::rational_cast<double>(half), 0.5, 0.01 );
592    BOOST_CHECK_EQUAL( boost::rational_cast<int>(half), 0 );
593    BOOST_CHECK_EQUAL( boost::rational_cast<MyInt>(half), MyInt() );
594}
595
596// Dice tests (a non-main test)
597BOOST_AUTO_TEST_CASE_TEMPLATE( dice_roll_test, T, all_signed_test_types )
598{
599    typedef boost::rational<T>  rational_type;
600
601    // Determine the mean number of times a fair six-sided die
602    // must be thrown until each side has appeared at least once.
603    rational_type  r = T( 0 );
604
605    for ( int  i = 1 ; i <= 6 ; ++i )
606    {
607        r += rational_type( 1, i );
608    }
609    r *= static_cast<T>( 6 );
610
611    BOOST_CHECK_EQUAL( r, rational_type(147, 10) );
612}
613
614BOOST_AUTO_TEST_SUITE_END()
Note: See TracBrowser for help on using the repository browser.