diff -r 000000000000 -r e4d67989cc36 genericopenlibs/cppstdlib/stl/test/eh/LeakCheck.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/cppstdlib/stl/test/eh/LeakCheck.h Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 1997 + * Mark of the Unicorn, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Mark of the Unicorn makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ +/*********************************************************************************** + LeakCheck.h + + SUMMARY: A suite of template functions for verifying the behavior of + operations in the presence of exceptions. Requires that the operations + be written so that each operation that could cause an exception causes + simulate_possible_failure() to be called (see "nc_alloc.h"). + +***********************************************************************************/ +#ifndef INCLUDED_MOTU_LeakCheck +#define INCLUDED_MOTU_LeakCheck 1 + +#include "Prefix.h" + +#include "nc_alloc.h" + +#include +#include +#include + +#include + +EH_BEGIN_NAMESPACE + +template +inline ostream& operator << ( +ostream& s, +const pair & p) { + return s<<'['< +void CheckInvariant(const C&) +{} + +/*=================================================================================== + WeakCheck + + EFFECTS: Given a value and an operation, repeatedly applies the operation to a + copy of the value triggering the nth possible exception, where n increments + with each repetition until no exception is thrown or max_iters is reached. + Reports any detected memory leaks and checks any invariant defined for the + value type whether the operation succeeds or fails. +====================================================================================*/ +template +void WeakCheck(const Value& v, const Operation& op, long max_iters = 2000000) { + bool succeeded = false; + bool failed = false; + gTestController.SetCurrentTestCategory("weak"); + for (long count = 0; !succeeded && !failed && count < max_iters; ++count) { + gTestController.BeginLeakDetection(); + { + Value dup = v; +#ifndef EH_NO_EXCEPTIONS + try { +#endif + gTestController.SetFailureCountdown(count); + op( dup ); + succeeded = true; +#ifndef EH_NO_EXCEPTIONS + } + catch (...) {} // Just try again. +#endif + gTestController.CancelFailureCountdown(); + CheckInvariant(dup); + } + failed = gTestController.ReportLeaked(); + EH_ASSERT( !failed ); + + if ( succeeded ) + gTestController.ReportSuccess(count); + } + EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over +} + +/*=================================================================================== + ConstCheck + + EFFECTS: Similar to WeakCheck (above), but for operations which may not modify + their arguments. The operation is performed on the value itself, and no + invariant checking is performed. Leak checking still occurs. +====================================================================================*/ +template +void ConstCheck(const Value& v, const Operation& op, long max_iters = 2000000) { + bool succeeded = false; + bool failed = false; + gTestController.SetCurrentTestCategory("const"); + for (long count = 0; !succeeded && !failed && count < max_iters; ++count) { + gTestController.BeginLeakDetection(); + { +#ifndef EH_NO_EXCEPTIONS + try { +#endif + gTestController.SetFailureCountdown(count); + op( v ); + succeeded = true; +#ifndef EH_NO_EXCEPTIONS + } + catch(...) {} // Just try again. +# endif + gTestController.CancelFailureCountdown(); + } + failed = gTestController.ReportLeaked(); + EH_ASSERT( !failed ); + + if ( succeeded ) + gTestController.ReportSuccess(count); + } + EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over +} + +/*=================================================================================== + StrongCheck + + EFFECTS: Similar to WeakCheck (above), but additionally checks a component of + the "strong guarantee": if the operation fails due to an exception, the + value being operated on must be unchanged, as checked with operator==(). + + CAVEATS: Note that this does not check everything required for the strong + guarantee, which says that if an exception is thrown, the operation has no + effects. Do do that we would have to check that no there were no side-effects + on objects which are not part of v (e.g. iterator validity must be preserved). + +====================================================================================*/ +template +void StrongCheck(const Value& v, const Operation& op, long max_iters = 2000000) { + bool succeeded = false; + bool failed = false; + gTestController.SetCurrentTestCategory("strong"); + for ( long count = 0; !succeeded && !failed && count < max_iters; count++ ) { + gTestController.BeginLeakDetection(); + + { + Value dup = v; + { +#ifndef EH_NO_EXCEPTIONS + try { +#endif + gTestController.SetFailureCountdown(count); + op( dup ); + succeeded = true; + gTestController.CancelFailureCountdown(); +# ifndef EH_NO_EXCEPTIONS + } + catch (...) { + gTestController.CancelFailureCountdown(); + bool unchanged = (dup == v); + EH_ASSERT( unchanged ); + + if ( !unchanged ) { +#if 0 + typedef typename Value::value_type value_type; + EH_STD::ostream_iterator o(EH_STD::cerr, " "); + EH_STD::cerr<<"EH test FAILED:\nStrong guaranee failed !\n"; + EH_STD::copy(dup.begin(), dup.end(), o); + EH_STD::cerr<<"\nOriginal is:\n"; + EH_STD::copy(v.begin(), v.end(), o); + EH_STD::cerr<