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