genericopenlibs/cppstdlib/stl/test/eh/LeakCheck.h
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * Copyright (c) 1997
       
     3  * Mark of the Unicorn, Inc.
       
     4  *
       
     5  * Permission to use, copy, modify, distribute and sell this software
       
     6  * and its documentation for any purpose is hereby granted without fee,
       
     7  * provided that the above copyright notice appear in all copies and
       
     8  * that both that copyright notice and this permission notice appear
       
     9  * in supporting documentation.  Mark of the Unicorn makes no
       
    10  * representations about the suitability of this software for any
       
    11  * purpose.  It is provided "as is" without express or implied warranty.
       
    12  */
       
    13 /***********************************************************************************
       
    14   LeakCheck.h
       
    15 
       
    16     SUMMARY: A suite of template functions for verifying the behavior of
       
    17       operations in the presence of exceptions. Requires that the operations
       
    18       be written so that each operation that could cause an exception causes
       
    19       simulate_possible_failure() to be called (see "nc_alloc.h").
       
    20 
       
    21 ***********************************************************************************/
       
    22 #ifndef INCLUDED_MOTU_LeakCheck
       
    23 #define INCLUDED_MOTU_LeakCheck 1
       
    24 
       
    25 #include "Prefix.h"
       
    26 
       
    27 #include "nc_alloc.h"
       
    28 
       
    29 #include <cstdio>
       
    30 #include <cassert>
       
    31 #include <iterator>
       
    32 
       
    33 #include <iostream>
       
    34 
       
    35 EH_BEGIN_NAMESPACE
       
    36 
       
    37 template <class T1, class T2>
       
    38 inline ostream& operator << (
       
    39 ostream& s,
       
    40 const pair <T1, T2>& p) {
       
    41     return s<<'['<<p.first<<":"<<p.second<<']';
       
    42 }
       
    43 EH_END_NAMESPACE
       
    44 
       
    45 /*===================================================================================
       
    46   CheckInvariant
       
    47 
       
    48   EFFECTS:  Generalized function to check an invariant on a container. Specialize
       
    49     this for particular containers if such a check is available.
       
    50 ====================================================================================*/
       
    51 template <class C>
       
    52 void CheckInvariant(const C&)
       
    53 {}
       
    54 
       
    55 /*===================================================================================
       
    56   WeakCheck
       
    57 
       
    58   EFFECTS: Given a value and an operation, repeatedly applies the operation to a
       
    59     copy of the value triggering the nth possible exception, where n increments
       
    60     with each repetition until no exception is thrown or max_iters is reached.
       
    61     Reports any detected memory leaks and checks any invariant defined for the
       
    62     value type whether the operation succeeds or fails.
       
    63 ====================================================================================*/
       
    64 template <class Value, class Operation>
       
    65 void WeakCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
       
    66   bool succeeded = false;
       
    67   bool failed = false;
       
    68   gTestController.SetCurrentTestCategory("weak");
       
    69   for (long count = 0; !succeeded && !failed && count < max_iters; ++count) {
       
    70     gTestController.BeginLeakDetection();
       
    71     {
       
    72       Value dup = v;
       
    73 #ifndef EH_NO_EXCEPTIONS
       
    74       try {
       
    75 #endif
       
    76         gTestController.SetFailureCountdown(count);
       
    77         op( dup );
       
    78         succeeded = true;
       
    79 #ifndef EH_NO_EXCEPTIONS
       
    80       }
       
    81       catch (...) {}  // Just try again.
       
    82 #endif
       
    83       gTestController.CancelFailureCountdown();
       
    84       CheckInvariant(dup);
       
    85     }
       
    86     failed = gTestController.ReportLeaked();
       
    87     EH_ASSERT( !failed );
       
    88 
       
    89     if ( succeeded )
       
    90       gTestController.ReportSuccess(count);
       
    91   }
       
    92   EH_ASSERT( succeeded || failed );  // Make sure the count hasn't gone over
       
    93 }
       
    94 
       
    95 /*===================================================================================
       
    96   ConstCheck
       
    97 
       
    98   EFFECTS:  Similar to WeakCheck (above), but for operations which may not modify
       
    99     their arguments. The operation is performed on the value itself, and no
       
   100     invariant checking is performed. Leak checking still occurs.
       
   101 ====================================================================================*/
       
   102 template <class Value, class Operation>
       
   103 void ConstCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
       
   104   bool succeeded = false;
       
   105   bool failed = false;
       
   106   gTestController.SetCurrentTestCategory("const");
       
   107   for (long count = 0; !succeeded && !failed && count < max_iters; ++count) {
       
   108     gTestController.BeginLeakDetection();
       
   109     {
       
   110 #ifndef EH_NO_EXCEPTIONS
       
   111       try {
       
   112 #endif
       
   113         gTestController.SetFailureCountdown(count);
       
   114         op( v );
       
   115         succeeded = true;
       
   116 #ifndef EH_NO_EXCEPTIONS
       
   117       }
       
   118       catch(...) {}  // Just try again.
       
   119 # endif
       
   120       gTestController.CancelFailureCountdown();
       
   121     }
       
   122     failed = gTestController.ReportLeaked();
       
   123     EH_ASSERT( !failed );
       
   124 
       
   125     if ( succeeded )
       
   126       gTestController.ReportSuccess(count);
       
   127   }
       
   128   EH_ASSERT( succeeded || failed );  // Make sure the count hasn't gone over
       
   129 }
       
   130 
       
   131 /*===================================================================================
       
   132   StrongCheck
       
   133 
       
   134   EFFECTS:  Similar to WeakCheck (above), but additionally checks a component of
       
   135     the "strong guarantee": if the operation fails due to an exception, the
       
   136     value being operated on must be unchanged, as checked with operator==().
       
   137 
       
   138   CAVEATS: Note that this does not check everything required for the strong
       
   139     guarantee, which says that if an exception is thrown, the operation has no
       
   140     effects. Do do that we would have to check that no there were no side-effects
       
   141     on objects which are not part of v (e.g. iterator validity must be preserved).
       
   142 
       
   143 ====================================================================================*/
       
   144 template <class Value, class Operation>
       
   145 void StrongCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
       
   146   bool succeeded = false;
       
   147   bool failed = false;
       
   148   gTestController.SetCurrentTestCategory("strong");
       
   149   for ( long count = 0; !succeeded && !failed && count < max_iters; count++ ) {
       
   150     gTestController.BeginLeakDetection();
       
   151 
       
   152     {
       
   153       Value dup = v;
       
   154       {
       
   155 #ifndef EH_NO_EXCEPTIONS
       
   156         try {
       
   157 #endif
       
   158           gTestController.SetFailureCountdown(count);
       
   159           op( dup );
       
   160           succeeded = true;
       
   161           gTestController.CancelFailureCountdown();
       
   162 # ifndef EH_NO_EXCEPTIONS
       
   163         }
       
   164         catch (...) {
       
   165           gTestController.CancelFailureCountdown();
       
   166           bool unchanged = (dup == v);
       
   167           EH_ASSERT( unchanged );
       
   168 
       
   169           if ( !unchanged ) {
       
   170 #if 0
       
   171             typedef typename Value::value_type value_type;
       
   172             EH_STD::ostream_iterator<value_type> o(EH_STD::cerr, " ");
       
   173             EH_STD::cerr<<"EH test FAILED:\nStrong guaranee failed !\n";
       
   174             EH_STD::copy(dup.begin(), dup.end(), o);
       
   175             EH_STD::cerr<<"\nOriginal is:\n";
       
   176             EH_STD::copy(v.begin(), v.end(), o);
       
   177             EH_STD::cerr<<EH_STD::endl;
       
   178 #endif
       
   179             failed = true;
       
   180           }
       
   181         }  // Just try again.
       
   182 # endif
       
   183         CheckInvariant(v);
       
   184       }
       
   185     }
       
   186 
       
   187     bool leaked = gTestController.ReportLeaked();
       
   188     EH_ASSERT( !leaked );
       
   189     if ( leaked )
       
   190       failed = true;
       
   191 
       
   192     if ( succeeded )
       
   193       gTestController.ReportSuccess(count);
       
   194   }
       
   195   EH_ASSERT( succeeded || failed );  // Make sure the count hasn't gone over
       
   196 }
       
   197 
       
   198 #endif // INCLUDED_MOTU_LeakCheck