Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/optional/test/optional_test.cpp @ 29

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

updated boost from 1_33_1 to 1_34_1

File size: 21.1 KB
Line 
1// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
2//
3// Use, modification, and distribution is subject to the Boost Software
4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/lib/optional for documentation.
8//
9// You are welcome to contact the author at:
10//  fernando_cacciola@hotmail.com
11//
12#include<iostream>
13#include<stdexcept>
14#include<string>
15
16#define BOOST_ENABLE_ASSERT_HANDLER
17
18#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
19
20#include "boost/optional/optional.hpp"
21
22#ifdef __BORLANDC__
23#pragma hdrstop
24#endif
25
26#include "boost/none.hpp"
27
28#include "boost/test/minimal.hpp"
29
30#include "optional_test_common.cpp"
31
32void test_implicit_construction ( optional<double> opt, double v, double z )
33{
34  check_value(opt,v,z);
35}
36
37void test_implicit_construction ( optional<X> opt, X const& v, X const& z )
38{
39  check_value(opt,v,z);
40}
41
42void test_default_implicit_construction ( double, optional<double> opt )
43{
44  BOOST_CHECK(!opt);
45}
46
47void test_default_implicit_construction ( X const&, optional<X> opt )
48{
49  BOOST_CHECK(!opt);
50}
51
52//
53// Basic test.
54// Check ordinary functionality:
55//   Initialization, assignment, comparison and value-accessing.
56//
57template<class T>
58void test_basics( T const* )
59{
60  TRACE( std::endl << BOOST_CURRENT_FUNCTION  );
61
62  T z(0);
63
64  T a(1);
65
66  // Default construction.
67  // 'def' state is Uninitialized.
68  // T::T() is not called (and it is not even defined)
69  optional<T> def ;
70  check_uninitialized(def);
71
72  // Implicit construction
73  // The first parameter is implicitely converted to optional<T>(a);
74  test_implicit_construction(a,a,z);
75
76  // Direct initialization.
77  // 'oa' state is Initialized with 'a'
78  // T::T( T const& x ) is used.
79  set_pending_copy( ARG(T) ) ;
80  optional<T> oa ( a ) ;
81  check_is_not_pending_copy( ARG(T) );
82  check_initialized(oa);
83  check_value(oa,a,z);
84
85  T b(2);
86
87  optional<T> ob ;
88
89  // Value-Assignment upon Uninitialized optional.
90  // T::T( T const& x ) is used.
91  set_pending_copy( ARG(T) ) ;
92  ob = a ;
93  check_is_not_pending_copy( ARG(T) ) ;
94  check_initialized(ob);
95  check_value(ob,a,z);
96
97  // Value-Assignment upon Initialized optional.
98  // T::operator=( T const& x ) is used
99  set_pending_assign( ARG(T) ) ;
100  set_pending_copy  ( ARG(T) ) ;
101  set_pending_dtor  ( ARG(T) ) ;
102  ob = b ;
103  check_is_not_pending_assign( ARG(T) ) ;
104  check_is_pending_copy      ( ARG(T) ) ;
105  check_is_pending_dtor      ( ARG(T) ) ;
106  check_initialized(ob);
107  check_value(ob,b,z);
108
109  // Assignment initialization.
110  // T::T ( T const& x ) is used to copy new value.
111  set_pending_copy( ARG(T) ) ;
112  optional<T> const oa2 ( oa ) ;
113  check_is_not_pending_copy( ARG(T) ) ;
114  check_initialized_const(oa2);
115  check_value_const(oa2,a,z);
116
117  // Assignment
118  // T::operator= ( T const& x ) is used to copy new value.
119  set_pending_assign( ARG(T) ) ;
120  oa = ob ;
121  check_is_not_pending_assign( ARG(T) ) ;
122  check_initialized(oa);
123  check_value(oa,b,z);
124
125  // Uninitializing Assignment upon Initialized Optional
126  // T::~T() is used to destroy previous value in oa.
127  set_pending_dtor( ARG(T) ) ;
128  set_pending_copy( ARG(T) ) ;
129  oa = def ;
130  check_is_not_pending_dtor( ARG(T) ) ;
131  check_is_pending_copy    ( ARG(T) ) ;
132  check_uninitialized(oa);
133
134  // Uninitializing Assignment upon Uninitialized Optional
135  // (Dtor is not called this time)
136  set_pending_dtor( ARG(T) ) ;
137  set_pending_copy( ARG(T) ) ;
138  oa = def ;
139  check_is_pending_dtor( ARG(T) ) ;
140  check_is_pending_copy( ARG(T) ) ;
141  check_uninitialized(oa);
142
143  // Deinitialization of Initialized Optional
144  // T::~T() is used to destroy previous value in ob.
145  set_pending_dtor( ARG(T) ) ;
146  ob.reset();
147  check_is_not_pending_dtor( ARG(T) ) ;
148  check_uninitialized(ob);
149
150  // Deinitialization of Uninitialized Optional
151  // (Dtor is not called this time)
152  set_pending_dtor( ARG(T) ) ;
153  ob.reset();
154  check_is_pending_dtor( ARG(T) ) ;
155  check_uninitialized(ob);
156 
157}
158
159template<class T>
160void test_conditional_ctor_and_get_valur_or ( T const* )
161{
162  TRACE( std::endl << BOOST_CURRENT_FUNCTION  );
163 
164  T a(321);
165 
166  T z(123);
167 
168  optional<T> const cdef0(false,a);
169 
170  optional<T> def0(false,a);
171  optional<T> def1 = boost::make_optional(false,a); //  T is not within boost so ADL won't find make_optional unqualified
172  check_uninitialized(def0);
173  check_uninitialized(def1);
174
175  optional<T> const co0(true,a);
176 
177  optional<T> o0(true,a);
178  optional<T> o1 = boost::make_optional(true,a); //  T is not within boost so ADL won't find make_optional unqualified
179
180  check_initialized(o0);
181  check_initialized(o1);
182  check_value(o0,a,z);
183  check_value(o1,a,z);
184 
185  T b = def0.get_value_or(z);
186  BOOST_CHECK( b == z ) ;
187 
188  b = get_optional_value_or(def0,z);
189  BOOST_CHECK( b == z ) ;
190 
191  b = o0.get_value_or(z);
192  BOOST_CHECK( b == a ) ;
193
194  b = get_optional_value_or(o0,z);
195  BOOST_CHECK( b == a ) ;
196 
197 
198  T const& crz = z ;
199  T&        rz = z ;
200 
201  T const& crzz = def0.get_value_or(crz);
202  BOOST_CHECK( crzz == crz ) ;
203 
204  T& rzz = def0.get_value_or(rz);
205  BOOST_CHECK( rzz == rz ) ;
206 
207  T const& crzzz = get_optional_value_or(cdef0,crz);
208  BOOST_CHECK( crzzz == crz ) ;
209 
210  T& rzzz = get_optional_value_or(def0,rz);
211  BOOST_CHECK( rzzz == rz ) ;
212 
213  T const& crb = o0.get_value_or(crz);
214  BOOST_CHECK( crb == a ) ;
215 
216  T& rb = o0.get_value_or(rz);
217  BOOST_CHECK( rb == b ) ;
218 
219  T const& crbb = get_optional_value_or(co0,crz);
220  BOOST_CHECK( crbb == b ) ;
221 
222  T const& crbbb = get_optional_value_or(o0,crz);
223  BOOST_CHECK( crbbb == b ) ;
224 
225  T& rbb = get_optional_value_or(o0,rz);
226  BOOST_CHECK( rbb == b ) ;
227 
228  T& ra = a ;
229 
230  optional<T&> defref(false,ra);
231  BOOST_CHECK(!defref);
232 
233  optional<T&> ref(true,ra);
234  BOOST_CHECK(!!ref);
235 
236  a = T(432);
237 
238  BOOST_CHECK( *ref == a ) ;
239 
240  T& r1 = defref.get_value_or(z);
241  BOOST_CHECK( r1 == z ) ;
242 
243  T& r2 = ref.get_value_or(z);
244  BOOST_CHECK( r2 == a ) ;
245}
246
247//
248// Test Direct Value Manipulation
249//
250template<class T>
251void test_direct_value_manip( T const* )
252{
253  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
254
255  T x(3);
256
257  optional<T> const c_opt0(x) ;
258  optional<T>         opt0(x);
259
260  BOOST_CHECK( c_opt0.get().V() == x.V() ) ;
261  BOOST_CHECK(   opt0.get().V() == x.V() ) ;
262
263  BOOST_CHECK( c_opt0->V() == x.V() ) ;
264  BOOST_CHECK(   opt0->V() == x.V() ) ;
265
266  BOOST_CHECK( (*c_opt0).V() == x.V() ) ;
267  BOOST_CHECK( (*  opt0).V() == x.V() ) ;
268
269  T y(4);
270  opt0 = y ;
271  BOOST_CHECK( get(opt0).V() == y.V() ) ;
272}
273
274//
275// Test Uninitialized access assert
276//
277template<class T>
278void test_uninitialized_access( T const* )
279{
280  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
281
282  optional<T> def ;
283
284  bool passed = false ;
285  try
286  {
287    // This should throw because 'def' is uninitialized
288    T const& n = def.get() ;
289    unused_variable(n);
290    passed = true ;
291  }
292  catch (...) {}
293  BOOST_CHECK(!passed);
294
295  passed = false ;
296  try
297  {
298    // This should throw because 'def' is uninitialized
299    T const& n = *def ;
300    unused_variable(n);
301    passed = true ;
302  }
303  catch (...) {}
304  BOOST_CHECK(!passed);
305
306  passed = false ;
307  try
308  {
309    T v(5) ;
310    unused_variable(v);
311    // This should throw because 'def' is uninitialized
312    *def = v ;
313    passed = true ;
314  }
315  catch (...) {}
316  BOOST_CHECK(!passed);
317
318  passed = false ;
319  try
320  {
321    // This should throw because 'def' is uninitialized
322    T v = *(def.operator->()) ;
323    unused_variable(v);
324    passed = true ;
325  }
326  catch (...) {}
327  BOOST_CHECK(!passed);
328}
329
330#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0
331void prevent_buggy_optimization( bool v ) {}
332#endif
333
334//
335// Test Direct Initialization of optional for a T with throwing copy-ctor.
336//
337template<class T>
338void test_throwing_direct_init( T const* )
339{
340  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
341
342  T a(6);
343
344  int count = get_instance_count( ARG(T) ) ;
345
346  set_throw_on_copy( ARG(T) ) ;
347
348  bool passed = false ;
349  try
350  {
351    // This should:
352    //   Attempt to copy construct 'a' and throw.
353    // 'opt' won't be constructed.
354    set_pending_copy( ARG(T) ) ;
355
356#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0
357    // Intel C++ 7.0 specific:
358    //    For some reason, when "check_is_not_pending_copy",
359    //    after the exception block is reached,
360    //    X::pending_copy==true even though X's copy ctor set it to false.
361    //    I guessed there is some sort of optimization bug,
362    //    and it seems to be the since the following additional line just
363    //    solves the problem (!?)
364    prevent_buggy_optimization(X::pending_copy);
365#endif
366
367    optional<T> opt(a) ;
368    passed = true ;
369  }
370  catch ( ... ){}
371
372  BOOST_CHECK(!passed);
373  check_is_not_pending_copy( ARG(T) );
374  check_instance_count(count, ARG(T) );
375
376  reset_throw_on_copy( ARG(T) ) ;
377
378}
379
380//
381// Test Value Assignment to an Uninitialized optional for a T with a throwing copy-ctor
382//
383template<class T>
384void test_throwing_val_assign_on_uninitialized( T const* )
385{
386  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
387
388  T a(7);
389
390  int count = get_instance_count( ARG(T) ) ;
391
392  set_throw_on_copy( ARG(T) ) ;
393
394  optional<T> opt ;
395
396  bool passed = false ;
397  try
398  {
399    // This should:
400    //   Attempt to copy construct 'a' and throw.
401    //   opt should be left uninitialized.
402    set_pending_copy( ARG(T) ) ;
403    opt.reset( a );
404    passed = true ;
405  }
406  catch ( ... ) {}
407
408  BOOST_CHECK(!passed);
409
410  check_is_not_pending_copy( ARG(T) );
411  check_instance_count(count, ARG(T) );
412  check_uninitialized(opt);
413
414  reset_throw_on_copy( ARG(T) ) ;
415}
416
417//
418// Test Value Reset on an Initialized optional for a T with a throwing copy-ctor
419//
420template<class T>
421void test_throwing_val_assign_on_initialized( T const* )
422{
423  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
424
425  T z(0);
426  T a(8);
427  T b(9);
428  T x(-1);
429
430  int count = get_instance_count( ARG(T) ) ;
431
432  optional<T> opt ( b ) ;
433  ++ count ;
434
435  check_instance_count(count, ARG(T) );
436
437  check_value(opt,b,z);
438
439  set_throw_on_assign( ARG(T) ) ;
440
441  bool passed = false ;
442  try
443  {
444    // This should:
445    //   Attempt to assign 'a' and throw.
446    //   opt is kept initialized but its value not neccesarily fully assigned
447    //   (in this test, incompletely assigned is flaged with the value -1 being set)
448    set_pending_assign( ARG(T) ) ;
449    opt.reset ( a ) ;
450    passed = true ;
451  }
452  catch ( ... ) {}
453
454  BOOST_CHECK(!passed);
455
456  check_is_not_pending_assign( ARG(T) );
457  check_instance_count(count, ARG(T) );
458  check_initialized(opt);
459  check_value(opt,x,z);
460
461  reset_throw_on_assign ( ARG(T) ) ;
462}
463
464//
465// Test Copy Initialization from an Initialized optional for a T with a throwing copy-ctor
466//
467template<class T>
468void test_throwing_copy_initialization( T const* )
469{
470  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
471
472  T z(0);
473  T a(10);
474
475  optional<T> opt (a);
476
477  int count = get_instance_count( ARG(T) ) ;
478
479  set_throw_on_copy( ARG(T) ) ;
480
481  bool passed = false ;
482  try
483  {
484    // This should:
485    //   Attempt to copy construct 'opt' and throw.
486    //   opt1 won't be constructed.
487    set_pending_copy( ARG(T) ) ;
488    optional<T> opt1 = opt ;
489    passed = true ;
490  }
491  catch ( ... ) {}
492
493  BOOST_CHECK(!passed);
494
495  check_is_not_pending_copy( ARG(T) );
496  check_instance_count(count, ARG(T) );
497
498  // Nothing should have happened to the source optional.
499  check_initialized(opt);
500  check_value(opt,a,z);
501
502  reset_throw_on_copy( ARG(T) ) ;
503}
504
505//
506// Test Assignment to an Uninitialized optional from an Initialized optional
507// for a T with a throwing copy-ctor
508//
509template<class T>
510void test_throwing_assign_to_uninitialized( T const* )
511{
512  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
513
514  T z(0);
515  T a(11);
516
517  optional<T> opt0 ;
518  optional<T> opt1(a) ;
519
520  int count = get_instance_count( ARG(T) ) ;
521
522  set_throw_on_copy( ARG(T) ) ;
523
524  bool passed = false ;
525  try
526  {
527    // This should:
528    //   Attempt to copy construct 'opt1.value()' into opt0 and throw.
529    //   opt0 should be left uninitialized.
530    set_pending_copy( ARG(T) ) ;
531    opt0 = opt1 ;
532    passed = true ;
533  }
534  catch ( ... ) {}
535
536  BOOST_CHECK(!passed);
537
538  check_is_not_pending_copy( ARG(T) );
539  check_instance_count(count, ARG(T) );
540  check_uninitialized(opt0);
541
542  reset_throw_on_copy( ARG(T) ) ;
543}
544
545//
546// Test Assignment to an Initialized optional from an Initialized optional
547// for a T with a throwing copy-ctor
548//
549template<class T>
550void test_throwing_assign_to_initialized( T const* )
551{
552  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
553
554  T z(0);
555  T a(12);
556  T b(13);
557  T x(-1);
558
559  optional<T> opt0(a) ;
560  optional<T> opt1(b) ;
561
562  int count = get_instance_count( ARG(T) ) ;
563
564  set_throw_on_assign( ARG(T) ) ;
565
566  bool passed = false ;
567  try
568  {
569    // This should:
570    //   Attempt to copy construct 'opt1.value()' into opt0 and throw.
571    //   opt0 is kept initialized but its value not neccesarily fully assigned
572    //   (in this test, incompletely assigned is flaged with the value -1 being set)
573    set_pending_assign( ARG(T) ) ;
574    opt0 = opt1 ;
575    passed = true ;
576  }
577  catch ( ... ) {}
578
579  BOOST_CHECK(!passed);
580
581  // opt0 was left uninitialized
582  check_is_not_pending_assign( ARG(T) );
583  check_instance_count(count, ARG(T) );
584  check_initialized(opt0);
585  check_value(opt0,x,z);
586
587  reset_throw_on_assign( ARG(T) ) ;
588}
589
590//
591// Test swap in a no-throwing case
592//
593template<class T>
594void test_no_throwing_swap( T const* )
595{
596  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
597
598  T z(0);
599  T a(14);
600  T b(15);
601
602  optional<T> def0 ;
603  optional<T> def1 ;
604  optional<T> opt0(a) ;
605  optional<T> opt1(b) ;
606
607  int count = get_instance_count( ARG(T) ) ;
608
609  swap(def0,def1);
610  check_uninitialized(def0);
611  check_uninitialized(def1);
612
613  swap(def0,opt0);
614  check_uninitialized(opt0);
615  check_initialized(def0);
616  check_value(def0,a,z);
617
618  // restore def0 and opt0
619  swap(def0,opt0);
620
621  swap(opt0,opt1);
622  check_instance_count(count, ARG(T) );
623  check_initialized(opt0);
624  check_initialized(opt1);
625  check_value(opt0,b,z);
626  check_value(opt1,a,z);
627}
628
629//
630// Test swap in a throwing case
631//
632template<class T>
633void test_throwing_swap( T const* )
634{
635  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
636
637  T a(16);
638  T b(17);
639  T x(-1);
640
641  optional<T> opt0(a) ;
642  optional<T> opt1(b) ;
643
644  set_throw_on_assign( ARG(T) ) ;
645
646  //
647  // Case 1: Both Initialized.
648  //
649  bool passed = false ;
650  try
651  {
652    // This should attempt to swap optionals and fail at swap(X&,X&).
653    swap(opt0,opt1);
654
655    passed = true ;
656  }
657  catch ( ... ) {}
658
659  BOOST_CHECK(!passed);
660
661  // optional's swap doesn't affect the initialized states of the arguments. Therefore,
662  // the following must hold:
663  check_initialized(opt0);
664  check_initialized(opt1);
665  check_value(opt0,x,a);
666  check_value(opt1,b,x);
667
668
669  //
670  // Case 2: Only one Initialized.
671  //
672  reset_throw_on_assign( ARG(T) ) ;
673
674  opt0.reset();
675  opt1.reset(a);
676
677  set_throw_on_copy( ARG(T) ) ;
678
679  passed = false ;
680  try
681  {
682    // This should attempt to swap optionals and fail at opt0.reset(*opt1)
683    // Both opt0 and op1 are left unchanged (unswaped)
684    swap(opt0,opt1);
685
686    passed = true ;
687  }
688  catch ( ... ) {}
689
690  BOOST_CHECK(!passed);
691
692  check_uninitialized(opt0);
693  check_initialized(opt1);
694  check_value(opt1,a,x);
695
696  reset_throw_on_copy( ARG(T) ) ;
697}
698
699//
700// This verifies relational operators.
701//
702template<class T>
703void test_relops( T const* )
704{
705  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
706
707  T v0(0);
708  T v1(1);
709  T v2(1);
710
711  optional<T> def0 ;
712  optional<T> def1 ;
713  optional<T> opt0(v0);
714  optional<T> opt1(v1);
715  optional<T> opt2(v2);
716 
717  // Check identity
718  BOOST_CHECK ( def0 == def0 ) ;
719  BOOST_CHECK ( opt0 == opt0 ) ;
720  BOOST_CHECK ( !(def0 != def0) ) ;
721  BOOST_CHECK ( !(opt0 != opt0) ) ;
722
723  // Check when both are uininitalized.
724  BOOST_CHECK (   def0 == def1  ) ; // both uninitialized compare equal
725  BOOST_CHECK ( !(def0 <  def1) ) ; // uninitialized is never less    than uninitialized
726  BOOST_CHECK ( !(def0 >  def1) ) ; // uninitialized is never greater than uninitialized
727  BOOST_CHECK ( !(def0 != def1) ) ;
728  BOOST_CHECK (   def0 <= def1  ) ;
729  BOOST_CHECK (   def0 >= def1  ) ;
730
731  // Check when only lhs is uninitialized.
732  BOOST_CHECK (   def0 != opt0  ) ; // uninitialized is never equal to initialized
733  BOOST_CHECK ( !(def0 == opt0) ) ;
734  BOOST_CHECK (   def0 <  opt0  ) ; // uninitialized is always less than initialized
735  BOOST_CHECK ( !(def0 >  opt0) ) ;
736  BOOST_CHECK (   def0 <= opt0  ) ;
737  BOOST_CHECK ( !(def0 >= opt0) ) ;
738
739  // Check when only rhs is uninitialized.
740  BOOST_CHECK (   opt0 != def0  ) ; // initialized is never equal to uninitialized
741  BOOST_CHECK ( !(opt0 == def0) ) ;
742  BOOST_CHECK ( !(opt0 <  def0) ) ; // initialized is never less than uninitialized
743  BOOST_CHECK (   opt0 >  def0  ) ;
744  BOOST_CHECK ( !(opt0 <= def0) ) ;
745  BOOST_CHECK (   opt0 >= opt0  ) ;
746
747  // If both are initialized, values are compared
748  BOOST_CHECK ( opt0 != opt1 ) ;
749  BOOST_CHECK ( opt1 == opt2 ) ;
750  BOOST_CHECK ( opt0 <  opt1 ) ;
751  BOOST_CHECK ( opt1 >  opt0 ) ;
752  BOOST_CHECK ( opt1 <= opt2 ) ;
753  BOOST_CHECK ( opt1 >= opt0 ) ;
754 
755  // Compare against a value directly
756  BOOST_CHECK ( opt0 == v0 ) ;
757  BOOST_CHECK ( opt0 != v1 ) ;
758  BOOST_CHECK ( opt1 == v2 ) ;
759  BOOST_CHECK ( opt0 <  v1 ) ;
760  BOOST_CHECK ( opt1 >  v0 ) ;
761  BOOST_CHECK ( opt1 <= v2 ) ;
762  BOOST_CHECK ( opt1 >= v0 ) ;
763  BOOST_CHECK ( v0 != opt1 ) ;
764  BOOST_CHECK ( v1 == opt2 ) ;
765  BOOST_CHECK ( v0 <  opt1 ) ;
766  BOOST_CHECK ( v1 >  opt0 ) ;
767  BOOST_CHECK ( v1 <= opt2 ) ;
768  BOOST_CHECK ( v1 >= opt0 ) ;
769  BOOST_CHECK (   def0 != v0  ) ;
770  BOOST_CHECK ( !(def0 == v0) ) ;
771  BOOST_CHECK (   def0 <  v0  ) ;
772  BOOST_CHECK ( !(def0 >  v0) ) ;
773  BOOST_CHECK (   def0 <= v0  ) ;
774  BOOST_CHECK ( !(def0 >= v0) ) ;
775  BOOST_CHECK (   v0 != def0  ) ;
776  BOOST_CHECK ( !(v0 == def0) ) ;
777  BOOST_CHECK ( !(v0 <  def0) ) ;
778  BOOST_CHECK (   v0 >  def0  ) ;
779  BOOST_CHECK ( !(v0 <= def0) ) ;
780  BOOST_CHECK (   v0 >= opt0  ) ;
781}
782
783template<class T>
784void test_none( T const* )
785{
786  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
787
788  using boost::none ;
789
790  optional<T> def0 ;
791  optional<T> def1(none) ;
792  optional<T> non_def( T(1234) ) ;
793
794  BOOST_CHECK ( def0    == none ) ;
795  BOOST_CHECK ( non_def != none ) ;
796  BOOST_CHECK ( !def1           ) ;
797  BOOST_CHECK ( !(non_def <  none) ) ; 
798  BOOST_CHECK (   non_def >  none  ) ;
799  BOOST_CHECK ( !(non_def <= none) ) ;
800  BOOST_CHECK (   non_def >= none  ) ;
801
802  non_def = none ;
803  BOOST_CHECK ( !non_def ) ;
804
805  test_default_implicit_construction(T(1),none);
806}
807
808template<class T>
809void test_arrow( T const* )
810{
811  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
812
813  T a(1234);
814
815  optional<T>        oa(a) ;
816  optional<T> const coa(a) ;
817 
818  BOOST_CHECK ( coa->V() == 1234 ) ;
819 
820  oa->V() = 4321 ;
821 
822  BOOST_CHECK (     a.V() = 1234 ) ;
823  BOOST_CHECK ( (*oa).V() = 4321 ) ;
824}
825
826void test_with_builtin_types()
827{
828  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
829
830  test_basics( ARG(double) );
831  test_conditional_ctor_and_get_valur_or( ARG(double) );
832  test_uninitialized_access( ARG(double) );
833  test_no_throwing_swap( ARG(double) );
834  test_relops( ARG(double) ) ;
835  test_none( ARG(double) ) ;
836}
837
838void test_with_class_type()
839{
840  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
841
842  test_basics( ARG(X) );
843  test_conditional_ctor_and_get_valur_or( ARG(X) );
844  test_direct_value_manip( ARG(X) );
845  test_uninitialized_access( ARG(X) );
846  test_throwing_direct_init( ARG(X) );
847  test_throwing_val_assign_on_uninitialized( ARG(X) );
848  test_throwing_val_assign_on_initialized( ARG(X) );
849  test_throwing_copy_initialization( ARG(X) );
850  test_throwing_assign_to_uninitialized( ARG(X) );
851  test_throwing_assign_to_initialized( ARG(X) );
852  test_no_throwing_swap( ARG(X) );
853  test_throwing_swap( ARG(X) );
854  test_relops( ARG(X) ) ;
855  test_none( ARG(X) ) ;
856  test_arrow( ARG(X) ) ;
857  BOOST_CHECK ( X::count == 0 ) ;
858}
859
860int eat ( bool ) { return 1 ; }
861int eat ( char ) { return 1 ; }
862int eat ( int  ) { return 1 ; }
863int eat ( void const* ) { return 1 ; }
864
865template<class T> int eat ( T ) { return 0 ; }
866
867//
868// This verifies that operator safe_bool() behaves properly.
869//
870template<class T>
871void test_no_implicit_conversions_impl( T const& )
872{
873  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
874
875  optional<T> def ;
876  BOOST_CHECK ( eat(def) == 0 ) ;
877}
878
879void test_no_implicit_conversions()
880{
881  TRACE( std::endl << BOOST_CURRENT_FUNCTION   );
882
883  bool b = false ;
884  char c = 0 ;
885  int i = 0 ;
886  void const* p = 0 ;
887
888  test_no_implicit_conversions_impl(b);
889  test_no_implicit_conversions_impl(c);
890  test_no_implicit_conversions_impl(i);
891  test_no_implicit_conversions_impl(p);
892}
893
894struct A {} ;
895void test_conversions1()
896{
897  TRACE( std::endl << BOOST_CURRENT_FUNCTION );
898
899#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
900  char c = 20 ;
901  optional<char> opt0(c);
902  optional<int> opt1(opt0);
903  BOOST_CHECK(*opt1 == static_cast<int>(c));
904#endif
905
906#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
907  float f = 21.22f ;
908  double d = f ;
909  optional<float> opt2(f) ;
910  optional<double> opt3 ;
911  opt3 = opt2 ;
912  BOOST_CHECK(*opt3 == d);
913#endif
914}
915
916void test_conversions2()
917{
918  TRACE( std::endl << BOOST_CURRENT_FUNCTION );
919
920  char c = 20 ;
921  optional<int> opt(c);
922  BOOST_CHECK( get(opt) == static_cast<int>(c));
923
924  float f = 21.22f ;
925  optional<double> opt1;
926  opt1 = f ;
927  BOOST_CHECK(*get(&opt1) == static_cast<double>(f));
928}
929
930int test_main( int, char* [] )
931{
932  try
933  {
934    test_with_class_type();
935    test_with_builtin_types();
936    test_no_implicit_conversions();
937    test_conversions1();
938    test_conversions2();
939  }
940  catch ( ... )
941  {
942    BOOST_ERROR("Unexpected Exception caught!");
943  }
944
945  return 0;
946}
947
948
Note: See TracBrowser for help on using the repository browser.