1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/test/eh/LeakCheck.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,198 @@
1.4 +/*
1.5 + * Copyright (c) 1997
1.6 + * Mark of the Unicorn, Inc.
1.7 + *
1.8 + * Permission to use, copy, modify, distribute and sell this software
1.9 + * and its documentation for any purpose is hereby granted without fee,
1.10 + * provided that the above copyright notice appear in all copies and
1.11 + * that both that copyright notice and this permission notice appear
1.12 + * in supporting documentation. Mark of the Unicorn makes no
1.13 + * representations about the suitability of this software for any
1.14 + * purpose. It is provided "as is" without express or implied warranty.
1.15 + */
1.16 +/***********************************************************************************
1.17 + LeakCheck.h
1.18 +
1.19 + SUMMARY: A suite of template functions for verifying the behavior of
1.20 + operations in the presence of exceptions. Requires that the operations
1.21 + be written so that each operation that could cause an exception causes
1.22 + simulate_possible_failure() to be called (see "nc_alloc.h").
1.23 +
1.24 +***********************************************************************************/
1.25 +#ifndef INCLUDED_MOTU_LeakCheck
1.26 +#define INCLUDED_MOTU_LeakCheck 1
1.27 +
1.28 +#include "Prefix.h"
1.29 +
1.30 +#include "nc_alloc.h"
1.31 +
1.32 +#include <cstdio>
1.33 +#include <cassert>
1.34 +#include <iterator>
1.35 +
1.36 +#include <iostream>
1.37 +
1.38 +EH_BEGIN_NAMESPACE
1.39 +
1.40 +template <class T1, class T2>
1.41 +inline ostream& operator << (
1.42 +ostream& s,
1.43 +const pair <T1, T2>& p) {
1.44 + return s<<'['<<p.first<<":"<<p.second<<']';
1.45 +}
1.46 +EH_END_NAMESPACE
1.47 +
1.48 +/*===================================================================================
1.49 + CheckInvariant
1.50 +
1.51 + EFFECTS: Generalized function to check an invariant on a container. Specialize
1.52 + this for particular containers if such a check is available.
1.53 +====================================================================================*/
1.54 +template <class C>
1.55 +void CheckInvariant(const C&)
1.56 +{}
1.57 +
1.58 +/*===================================================================================
1.59 + WeakCheck
1.60 +
1.61 + EFFECTS: Given a value and an operation, repeatedly applies the operation to a
1.62 + copy of the value triggering the nth possible exception, where n increments
1.63 + with each repetition until no exception is thrown or max_iters is reached.
1.64 + Reports any detected memory leaks and checks any invariant defined for the
1.65 + value type whether the operation succeeds or fails.
1.66 +====================================================================================*/
1.67 +template <class Value, class Operation>
1.68 +void WeakCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
1.69 + bool succeeded = false;
1.70 + bool failed = false;
1.71 + gTestController.SetCurrentTestCategory("weak");
1.72 + for (long count = 0; !succeeded && !failed && count < max_iters; ++count) {
1.73 + gTestController.BeginLeakDetection();
1.74 + {
1.75 + Value dup = v;
1.76 +#ifndef EH_NO_EXCEPTIONS
1.77 + try {
1.78 +#endif
1.79 + gTestController.SetFailureCountdown(count);
1.80 + op( dup );
1.81 + succeeded = true;
1.82 +#ifndef EH_NO_EXCEPTIONS
1.83 + }
1.84 + catch (...) {} // Just try again.
1.85 +#endif
1.86 + gTestController.CancelFailureCountdown();
1.87 + CheckInvariant(dup);
1.88 + }
1.89 + failed = gTestController.ReportLeaked();
1.90 + EH_ASSERT( !failed );
1.91 +
1.92 + if ( succeeded )
1.93 + gTestController.ReportSuccess(count);
1.94 + }
1.95 + EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over
1.96 +}
1.97 +
1.98 +/*===================================================================================
1.99 + ConstCheck
1.100 +
1.101 + EFFECTS: Similar to WeakCheck (above), but for operations which may not modify
1.102 + their arguments. The operation is performed on the value itself, and no
1.103 + invariant checking is performed. Leak checking still occurs.
1.104 +====================================================================================*/
1.105 +template <class Value, class Operation>
1.106 +void ConstCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
1.107 + bool succeeded = false;
1.108 + bool failed = false;
1.109 + gTestController.SetCurrentTestCategory("const");
1.110 + for (long count = 0; !succeeded && !failed && count < max_iters; ++count) {
1.111 + gTestController.BeginLeakDetection();
1.112 + {
1.113 +#ifndef EH_NO_EXCEPTIONS
1.114 + try {
1.115 +#endif
1.116 + gTestController.SetFailureCountdown(count);
1.117 + op( v );
1.118 + succeeded = true;
1.119 +#ifndef EH_NO_EXCEPTIONS
1.120 + }
1.121 + catch(...) {} // Just try again.
1.122 +# endif
1.123 + gTestController.CancelFailureCountdown();
1.124 + }
1.125 + failed = gTestController.ReportLeaked();
1.126 + EH_ASSERT( !failed );
1.127 +
1.128 + if ( succeeded )
1.129 + gTestController.ReportSuccess(count);
1.130 + }
1.131 + EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over
1.132 +}
1.133 +
1.134 +/*===================================================================================
1.135 + StrongCheck
1.136 +
1.137 + EFFECTS: Similar to WeakCheck (above), but additionally checks a component of
1.138 + the "strong guarantee": if the operation fails due to an exception, the
1.139 + value being operated on must be unchanged, as checked with operator==().
1.140 +
1.141 + CAVEATS: Note that this does not check everything required for the strong
1.142 + guarantee, which says that if an exception is thrown, the operation has no
1.143 + effects. Do do that we would have to check that no there were no side-effects
1.144 + on objects which are not part of v (e.g. iterator validity must be preserved).
1.145 +
1.146 +====================================================================================*/
1.147 +template <class Value, class Operation>
1.148 +void StrongCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
1.149 + bool succeeded = false;
1.150 + bool failed = false;
1.151 + gTestController.SetCurrentTestCategory("strong");
1.152 + for ( long count = 0; !succeeded && !failed && count < max_iters; count++ ) {
1.153 + gTestController.BeginLeakDetection();
1.154 +
1.155 + {
1.156 + Value dup = v;
1.157 + {
1.158 +#ifndef EH_NO_EXCEPTIONS
1.159 + try {
1.160 +#endif
1.161 + gTestController.SetFailureCountdown(count);
1.162 + op( dup );
1.163 + succeeded = true;
1.164 + gTestController.CancelFailureCountdown();
1.165 +# ifndef EH_NO_EXCEPTIONS
1.166 + }
1.167 + catch (...) {
1.168 + gTestController.CancelFailureCountdown();
1.169 + bool unchanged = (dup == v);
1.170 + EH_ASSERT( unchanged );
1.171 +
1.172 + if ( !unchanged ) {
1.173 +#if 0
1.174 + typedef typename Value::value_type value_type;
1.175 + EH_STD::ostream_iterator<value_type> o(EH_STD::cerr, " ");
1.176 + EH_STD::cerr<<"EH test FAILED:\nStrong guaranee failed !\n";
1.177 + EH_STD::copy(dup.begin(), dup.end(), o);
1.178 + EH_STD::cerr<<"\nOriginal is:\n";
1.179 + EH_STD::copy(v.begin(), v.end(), o);
1.180 + EH_STD::cerr<<EH_STD::endl;
1.181 +#endif
1.182 + failed = true;
1.183 + }
1.184 + } // Just try again.
1.185 +# endif
1.186 + CheckInvariant(v);
1.187 + }
1.188 + }
1.189 +
1.190 + bool leaked = gTestController.ReportLeaked();
1.191 + EH_ASSERT( !leaked );
1.192 + if ( leaked )
1.193 + failed = true;
1.194 +
1.195 + if ( succeeded )
1.196 + gTestController.ReportSuccess(count);
1.197 + }
1.198 + EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over
1.199 +}
1.200 +
1.201 +#endif // INCLUDED_MOTU_LeakCheck