Added pre-conditions and post-conditions. Changed name of class.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@899 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
c6d6cada99
commit
19dd1dfe3d
1 changed files with 154 additions and 91 deletions
|
@ -4,9 +4,9 @@
|
||||||
// Copyright (c) 2008 Rich Sposato
|
// Copyright (c) 2008 Rich Sposato
|
||||||
// The copyright on this file is protected under the terms of the MIT license.
|
// The copyright on this file is protected under the terms of the MIT license.
|
||||||
//
|
//
|
||||||
// Permission to use, copy, modify, distribute and sell this software for any
|
// Permission to use, copy, modify, distribute and sell this software for any
|
||||||
// purpose is hereby granted without fee, provided that the above copyright
|
// purpose is hereby granted without fee, provided that the above copyright
|
||||||
// notice appear in all copies and that both that copyright notice and this
|
// notice appear in all copies and that both that copyright notice and this
|
||||||
// permission notice appear in supporting documentation.
|
// permission notice appear in supporting documentation.
|
||||||
//
|
//
|
||||||
// The author makes no representations about the suitability of this software
|
// The author makes no representations about the suitability of this software
|
||||||
|
@ -31,14 +31,14 @@
|
||||||
namespace Loki
|
namespace Loki
|
||||||
{
|
{
|
||||||
|
|
||||||
/** @par Checker and StaticChecker Overview
|
/** @par ContractChecker and StaticChecker Overview
|
||||||
The Checker and StaticChecker classes have two purposes:
|
The ContractChecker and StaticChecker classes have two purposes:
|
||||||
- provide a mechanism by which programmers can determine which functions
|
- provide a mechanism by which programmers can determine which functions
|
||||||
violate class/data invariants,
|
violate class/data invariants,
|
||||||
- and determine which exception safety a function provides.
|
- and determine which exception safety a function provides.
|
||||||
|
|
||||||
@par Class & Data Invariants
|
@par Class & Data Invariants
|
||||||
The Checker and StaticChecker utilities define invariants as "expressions that
|
The ContractChecker and StaticChecker define invariants as "expressions that
|
||||||
are true for particular data". They uses a function which returns true if all
|
are true for particular data". They uses a function which returns true if all
|
||||||
data are valid, and returns false if any datum is invalid. This is called the
|
data are valid, and returns false if any datum is invalid. This is called the
|
||||||
validator function, and the host class or function provides a pointer to it.
|
validator function, and the host class or function provides a pointer to it.
|
||||||
|
@ -52,19 +52,21 @@ namespace Loki
|
||||||
Years ago, David Abrahams formalized a framework for assessing the exception
|
Years ago, David Abrahams formalized a framework for assessing the exception
|
||||||
safety level a function provides. His framework describes three levels of
|
safety level a function provides. His framework describes three levels of
|
||||||
guarantees. Any function which does not provide any of these levels is
|
guarantees. Any function which does not provide any of these levels is
|
||||||
considered unsafe. Checker and StaticChecker determine a function's safety
|
considered unsafe. ContractChecker and StaticChecker determine a function's
|
||||||
level through the use of policy classes. Checker's policy classes can show if
|
safety level through the use of policy classes. Checker's policy classes can
|
||||||
a function provides any of these three guarantees. (Caveat: Checker can't
|
show if a function provides any of these three guarantees. Since there is no
|
||||||
detect leaks directly by itself, but it can call a validator which does.)
|
universal way to detect leaks, this facility provides no mechanism for finding
|
||||||
StaticChecker's policy classes only provide direct checking for the no-throw
|
leaks, but users may create their own validators which do. StaticChecker's
|
||||||
and invariant guarantees. With some finesse, a programmer can write a
|
policy classes only provide direct checking for the no-throw and invariant
|
||||||
validator for StaticChecker that checks for the Strong guarantee.
|
guarantees. With some finesse, a programmer can write a validator for
|
||||||
|
StaticChecker that checks for the Strong guarantee.
|
||||||
|
|
||||||
- No-throw guarantee: A function will not throw any exceptions.
|
- No-throw guarantee: A function will not throw any exceptions.
|
||||||
- Strong guarantee: A function will not change data if an exception occurs.
|
- Strong guarantee: A function will not change data if an exception occurs.
|
||||||
(Also called the no-change guarantee.)
|
(Which I call the no-change guarantee.)
|
||||||
- Basic guarantee: A function will not leak resources and data will remain
|
- Basic guarantee: A function will not leak resources and data will remain
|
||||||
in a valid state if an exception occurs. (Also called a no-leak guarantee.)
|
in a valid state if an exception occurs. (Which I call either the no-leak
|
||||||
|
or no-break guarantee depending on context.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -72,9 +74,9 @@ namespace Loki
|
||||||
/** @class CheckForNoThrow
|
/** @class CheckForNoThrow
|
||||||
|
|
||||||
@par Exception Safety Level:
|
@par Exception Safety Level:
|
||||||
This exception-checking policy class for Checker asserts if an exception exists.
|
This exception-checking policy class for ContractChecker asserts if an
|
||||||
Host classes can use this to show that some member functions provide the no-throw
|
exception exists. Host classes can use this to show that a member function
|
||||||
exception safety guarantees.
|
provides the no-throw exception safety guarantees.
|
||||||
|
|
||||||
@par Requirements For Host Class:
|
@par Requirements For Host Class:
|
||||||
This policy imposes no requirements on a host class.
|
This policy imposes no requirements on a host class.
|
||||||
|
@ -86,9 +88,11 @@ public:
|
||||||
|
|
||||||
inline explicit CheckForNoThrow( const Host * ) {}
|
inline explicit CheckForNoThrow( const Host * ) {}
|
||||||
|
|
||||||
inline void Check( const Host * ) const
|
inline bool Check( const Host * ) const
|
||||||
{
|
{
|
||||||
assert( !::std::uncaught_exception() );
|
const bool okay = ( !::std::uncaught_exception() );
|
||||||
|
assert( okay );
|
||||||
|
return okay;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,10 +101,10 @@ public:
|
||||||
/** @class CheckForNoChange
|
/** @class CheckForNoChange
|
||||||
|
|
||||||
@par Exception Safety Level:
|
@par Exception Safety Level:
|
||||||
This exception-checking policy class for Checker asserts only if a copy of the
|
This exception-checking policy class for ContractChecker asserts only if a
|
||||||
host differs from the host object when an exception occurs. Host classes can
|
copy of the host differs from the host object when an exception occurs. Host
|
||||||
use this policy to show which member functions provide the strong exception
|
classes can use this policy to show which member functions provide the strong
|
||||||
guarantee.
|
exception guarantee.
|
||||||
|
|
||||||
@par Requirements:
|
@par Requirements:
|
||||||
This policy requires hosts to provide both the copy-constructor and the
|
This policy requires hosts to provide both the copy-constructor and the
|
||||||
|
@ -116,12 +120,12 @@ public:
|
||||||
inline explicit CheckForNoChange( const Host * host ) :
|
inline explicit CheckForNoChange( const Host * host ) :
|
||||||
m_compare( *host ) {}
|
m_compare( *host ) {}
|
||||||
|
|
||||||
inline void Check( const Host * host ) const
|
inline bool Check( const Host * host ) const
|
||||||
{
|
{
|
||||||
if ( ::std::uncaught_exception() )
|
const bool okay = ( !::std::uncaught_exception() )
|
||||||
{
|
|| ( m_compare == *host );
|
||||||
assert( m_compare == *host );
|
assert( okay );
|
||||||
}
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -133,10 +137,10 @@ private:
|
||||||
/** @class CheckForNoChangeOrThrow
|
/** @class CheckForNoChangeOrThrow
|
||||||
|
|
||||||
@par Exception Safety Level:
|
@par Exception Safety Level:
|
||||||
This exception-checking policy class for Checker asserts either if a copy of
|
This exception-checking policy class for ContractChecker asserts either if a
|
||||||
the host differs from the original host object, or if an exception occurs.
|
copy of the host differs from the original host object, or if an exception
|
||||||
Host classes can use this policy to show which member functions provide the
|
occurs. Host classes can use this policy to show which member functions provide
|
||||||
no-throw exception guarantee, and would never change data anyway.
|
the no-throw exception guarantee, and would never change data anyway.
|
||||||
|
|
||||||
@par Requirements For Host Class:
|
@par Requirements For Host Class:
|
||||||
This policy requires hosts to provide both the copy-constructor and the
|
This policy requires hosts to provide both the copy-constructor and the
|
||||||
|
@ -151,10 +155,13 @@ public:
|
||||||
inline explicit CheckForNoChangeOrThrow( const Host * host ) :
|
inline explicit CheckForNoChangeOrThrow( const Host * host ) :
|
||||||
m_compare( *host ) {}
|
m_compare( *host ) {}
|
||||||
|
|
||||||
inline void Check( const Host * host ) const
|
inline bool Check( const Host * host ) const
|
||||||
{
|
{
|
||||||
assert( !::std::uncaught_exception() );
|
bool okay = ( !::std::uncaught_exception() );
|
||||||
assert( m_compare == *host );
|
assert( okay );
|
||||||
|
okay = ( m_compare == *host );
|
||||||
|
assert( okay );
|
||||||
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -166,8 +173,7 @@ private:
|
||||||
/** @class CheckForEquality
|
/** @class CheckForEquality
|
||||||
|
|
||||||
@par Exception Safety Level:
|
@par Exception Safety Level:
|
||||||
This exception-checking policy class for Checker asserts only if a copy of the
|
This exception-checking policy class for ContractChecker asserts if a copy of the host differs from the host object regardless of whether an exception occurs.
|
||||||
host differs from the host object regardless of whether an exception occurs.
|
|
||||||
Host classes can use this policy to show which member functions never change
|
Host classes can use this policy to show which member functions never change
|
||||||
data members, and thereby provide the strong exception safety level by default.
|
data members, and thereby provide the strong exception safety level by default.
|
||||||
|
|
||||||
|
@ -184,9 +190,11 @@ public:
|
||||||
inline explicit CheckForEquality( const Host * host ) :
|
inline explicit CheckForEquality( const Host * host ) :
|
||||||
m_compare( *host ) {}
|
m_compare( *host ) {}
|
||||||
|
|
||||||
inline void Check( const Host * host ) const
|
inline bool Check( const Host * host ) const
|
||||||
{
|
{
|
||||||
assert( m_compare == *host );
|
const bool okay = ( m_compare == *host );
|
||||||
|
assert( okay );
|
||||||
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -198,10 +206,10 @@ private:
|
||||||
/** @class CheckForNothing
|
/** @class CheckForNothing
|
||||||
|
|
||||||
@par Exception Safety Level:
|
@par Exception Safety Level:
|
||||||
This exception-checking policy class for Checker does nothing when called.
|
This exception-checking policy class for ContractChecker does nothing when
|
||||||
Host classes can use this to show which member functions provide neither the
|
called. Host classes can use this to show which member functions provide
|
||||||
strong nor no-throw exception guarantees. The best guarantee such functions
|
neither the strong nor no-throw exception guarantees. The best guarantee such
|
||||||
can provide is that nothing gets leaked.
|
functions can provide is that nothing gets leaked.
|
||||||
|
|
||||||
@par Requirements For Host Class:
|
@par Requirements For Host Class:
|
||||||
This policy imposes no requirements on a host class.
|
This policy imposes no requirements on a host class.
|
||||||
|
@ -212,15 +220,18 @@ class CheckForNothing
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline explicit CheckForNothing( const Host * ) {}
|
inline explicit CheckForNothing( const Host * ) {}
|
||||||
inline void Check( const Host * ) const {}
|
inline bool Check( const Host * ) const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/** @class Checker
|
/** @class ContractChecker
|
||||||
This class checks if a host class violated an invariant. This asserts if any
|
This class determines if a function violated any class invariant, but it also
|
||||||
check for an invariant failed. It can also demonstrate which functions provide
|
determines if a function fulfills its contract with client code. In the
|
||||||
which exception safety level.
|
"Design by Contract" paradigm, each function has certain pre-conditions and
|
||||||
|
post-conditions which may differ from the class invariants. This asserts if a
|
||||||
|
check for an invariant fails as well as if any pre- or post-condition fails.
|
||||||
|
It also demonstrate which exception safety level a function provides.
|
||||||
|
|
||||||
@par Usage
|
@par Usage
|
||||||
-# Implement a function that checks each class invariant. The function must
|
-# Implement a function that checks each class invariant. The function must
|
||||||
|
@ -229,18 +240,24 @@ public:
|
||||||
- The function should return true if everything is okay, but false if
|
- The function should return true if everything is okay, but false if
|
||||||
something is wrong.
|
something is wrong.
|
||||||
- Or it could assert if anything is wrong.
|
- Or it could assert if anything is wrong.
|
||||||
|
- Ideally, it should be private.
|
||||||
|
-# Implement similar functions to check for pre-conditions and post-conditions.
|
||||||
|
Functions which verify pre-conditions and post-conditions do not need to
|
||||||
|
check all class invariants, just conditions specific to certain public
|
||||||
|
functions in the host class.
|
||||||
-# Declare some typedef's inside the class declaration like these. Make one
|
-# Declare some typedef's inside the class declaration like these. Make one
|
||||||
typedef for each exception policy you use. I typedef'ed the CheckForNothing
|
typedef for each exception policy you use. I typedef'ed the CheckForNothing
|
||||||
policy as CheckInvariants because even if a function can't provide either the
|
policy as CheckInvariants because even if a function can't provide either the
|
||||||
no-throw nor the no-change policies, it should still make sure the object
|
no-throw nor the no-change policies, it should still make sure the object
|
||||||
remains in a valid state.
|
remains in a valid state.
|
||||||
- typedef ::Loki::Checker< Host, ::Loki::CheckForNoThrow > CheckForNoThrow;
|
- typedef ::Loki::ContractChecker< Host, ::Loki::CheckForNoThrow > CheckForNoThrow;
|
||||||
- typedef ::Loki::Checker< Host, ::Loki::CheckForNoChange > CheckForNoChange;
|
- typedef ::Loki::ContractChecker< Host, ::Loki::CheckForNoChange > CheckForNoChange;
|
||||||
- typedef ::Loki::Checker< Host, ::Loki::CheckForEquality > CheckForEquality;
|
- typedef ::Loki::ContractChecker< Host, ::Loki::CheckForEquality > CheckForEquality;
|
||||||
- typedef ::Loki::Checker< Host, ::Loki::CheckForNothing > CheckInvariants;
|
- typedef ::Loki::ContractChecker< Host, ::Loki::CheckForNothing > CheckInvariants;
|
||||||
-# Construct a checker near the top of each member function - except in the
|
-# Construct a checker near the top of each member function - except in the
|
||||||
validator member function. Pass the this pointer and the address of your
|
validator member function. Pass the this pointer and the address of your
|
||||||
validator function into the checker's constructor.
|
validator function into the checker's constructor. You may also pass in pointers
|
||||||
|
to function which check pre- and post-conditions.
|
||||||
- If the function never throws, then use the CheckForNoThrow policy.
|
- If the function never throws, then use the CheckForNoThrow policy.
|
||||||
- If the function never changes any data members, then use CheckForEquality
|
- If the function never changes any data members, then use CheckForEquality
|
||||||
policy.
|
policy.
|
||||||
|
@ -248,8 +265,8 @@ public:
|
||||||
data remains unchanged when any exceptions occur, then use the
|
data remains unchanged when any exceptions occur, then use the
|
||||||
CheckForNoChange policy.
|
CheckForNoChange policy.
|
||||||
- Otherwise use the CheckInvariants policy.
|
- Otherwise use the CheckInvariants policy.
|
||||||
-# Recompile a debug version of your program, run it, and look for which
|
-# Recompile a debug version of your program, run the program and all the unit
|
||||||
assertions failed.
|
tests, and look for which assertions failed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template
|
template
|
||||||
|
@ -257,7 +274,7 @@ template
|
||||||
class Host,
|
class Host,
|
||||||
template < class > class ExceptionPolicy
|
template < class > class ExceptionPolicy
|
||||||
>
|
>
|
||||||
class Checker : public ExceptionPolicy< Host >
|
class ContractChecker : public ExceptionPolicy< Host >
|
||||||
{
|
{
|
||||||
/// Shorthand for the ExceptionPolicy class.
|
/// Shorthand for the ExceptionPolicy class.
|
||||||
typedef ExceptionPolicy< Host > Ep;
|
typedef ExceptionPolicy< Host > Ep;
|
||||||
|
@ -269,55 +286,78 @@ public:
|
||||||
|
|
||||||
/** The constructor makes sure the host is valid at the time the checker
|
/** The constructor makes sure the host is valid at the time the checker
|
||||||
was created, thus insuring the host object was not corrupt from the start.
|
was created, thus insuring the host object was not corrupt from the start.
|
||||||
|
@par host Pointer to host object.
|
||||||
|
@par validator Pointer to function that checks class invariants.
|
||||||
|
@par pre Optional pointer to function that checks pre-conditions.
|
||||||
|
@par post Optional pointer to function that checks post-conditions.
|
||||||
*/
|
*/
|
||||||
inline Checker( const Host * host, Validator validator ) :
|
inline ContractChecker( const Host * host, Validator validator,
|
||||||
|
Validator pre = 0, Validator post = 0 ) :
|
||||||
Ep( host ),
|
Ep( host ),
|
||||||
m_host( host ),
|
m_host( host ),
|
||||||
m_validator( validator )
|
m_validator( validator ),
|
||||||
|
m_pre( pre ),
|
||||||
|
m_post( post )
|
||||||
{
|
{
|
||||||
Check();
|
assert( Check() );
|
||||||
|
if ( 0 != m_pre )
|
||||||
|
assert( ( m_host->*( m_pre ) )() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The destructor checks if any Host invariants failed, and then calls the
|
/** The destructor checks if any Host invariants failed, and then calls the
|
||||||
ExceptionPolicy's Check function to determine what to do in case of an
|
ExceptionPolicy's Check function to determine what to do in case of an
|
||||||
exception.
|
exception.
|
||||||
*/
|
*/
|
||||||
inline ~Checker( void )
|
inline ~ContractChecker( void )
|
||||||
{
|
{
|
||||||
Check();
|
assert( Check() );
|
||||||
Ep::Check( m_host );
|
if ( 0 != m_post )
|
||||||
|
assert( ( m_host->*( m_post ) )() );
|
||||||
|
assert( Ep::Check( m_host ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This first checks the invariants for Checker, and then calls the
|
/** This first checks the invariants for ContractChecker, and then calls the
|
||||||
validator function for the host to make sure no class invariants
|
validator function for the host to make sure no class invariants were
|
||||||
were broken by the host within the Host's member function body. The
|
broken by the host within the Host's member function body. The host
|
||||||
host member function can call Check directly to verify the object
|
member function can call Check directly to verify the object remains valid
|
||||||
remains valid at any time.
|
at any time. This does not care if the pre- and post-condition validator
|
||||||
|
pointers are null since a host class may pass in NULL pointers for either
|
||||||
|
to indicate the pre-conditions or post-conditions are the same as the
|
||||||
|
overall class invariants.
|
||||||
*/
|
*/
|
||||||
inline void Check( void ) const
|
inline bool Check( void ) const
|
||||||
{
|
{
|
||||||
assert( 0 != this );
|
assert( 0 != this );
|
||||||
assert( 0 != m_host );
|
assert( 0 != m_host );
|
||||||
assert( 0 != m_validator );
|
assert( 0 != m_validator );
|
||||||
// Now that this confirms the pointers to the host and validation
|
// Now that this confirms the pointers to the host and validation
|
||||||
// functions are not null, go ahead and validate the host object.
|
// functions are not null, go ahead and validate the host object.
|
||||||
assert( ( m_host->*( m_validator ) )() );
|
const bool okay = ( m_host->*( m_validator ) )();
|
||||||
|
assert( okay );
|
||||||
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// Default constructor is not implemented.
|
/// Default constructor is not implemented.
|
||||||
Checker( void );
|
ContractChecker( void );
|
||||||
/// Copy constructor is not implemented.
|
/// Copy constructor is not implemented.
|
||||||
Checker( const Checker & );
|
ContractChecker( const ContractChecker & );
|
||||||
/// Copy-assignment operator is not implemented.
|
/// Copy-assignment operator is not implemented.
|
||||||
Checker & operator = ( const Checker & );
|
ContractChecker & operator = ( const ContractChecker & );
|
||||||
|
|
||||||
/// Pointer to the host object.
|
/// Pointer to the host object.
|
||||||
const Host * m_host;
|
const Host * m_host;
|
||||||
|
|
||||||
/// Pointer to member function that checks Host object's invariants.
|
/// Pointer to member function that checks Host object's invariants.
|
||||||
Validator m_validator;
|
Validator m_validator;
|
||||||
|
|
||||||
|
/// Pointer to member function that checks Host object's pre-conditions.
|
||||||
|
Validator m_pre;
|
||||||
|
|
||||||
|
/// Pointer to member function that checks Host object's post-conditions.
|
||||||
|
Validator m_post;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -332,9 +372,11 @@ private:
|
||||||
class CheckStaticForNoThrow
|
class CheckStaticForNoThrow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static inline void Check( void )
|
inline bool Check( void )
|
||||||
{
|
{
|
||||||
assert( !::std::uncaught_exception() );
|
const bool okay = !::std::uncaught_exception();
|
||||||
|
assert( okay );
|
||||||
|
return okay;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -350,7 +392,7 @@ public:
|
||||||
class CheckStaticForNothing
|
class CheckStaticForNothing
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static inline void Check( void ) {}
|
inline bool Check( void ) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -373,15 +415,15 @@ public:
|
||||||
you use. I typedef'ed the CheckForNothing policy as CheckInvariants because
|
you use. I typedef'ed the CheckForNothing policy as CheckInvariants because
|
||||||
even if a function can't provide the no-throw guarantee, it should still
|
even if a function can't provide the no-throw guarantee, it should still
|
||||||
make sure that static data remains in a valid state.
|
make sure that static data remains in a valid state.
|
||||||
- typedef ::Loki::StaticChecker< ::Loki::CheckForNoThrow > CheckStaticForNoThrow;
|
- typedef ::Loki::StaticChecker< ::Loki::CheckForNoThrow > CheckStaticForNoThrow;
|
||||||
- typedef ::Loki::StaticChecker< ::Loki::CheckForNothing > CheckStaticInvariants;
|
- typedef ::Loki::StaticChecker< ::Loki::CheckForNothing > CheckStaticInvariants;
|
||||||
-# Construct a checker near the top of each member function - except in the
|
-# Construct a checker near the top of each member function - except in the
|
||||||
validator member function. Pass the address of your validator function into
|
validator member function. Pass the address of your validator function into
|
||||||
the checker's constructor.
|
the checker's constructor.
|
||||||
- If the function never throws, then use the CheckForNoThrow policy.
|
- If the function never throws, then use the CheckForNoThrow policy.
|
||||||
- Otherwise use the CheckInvariants policy.
|
- Otherwise use the CheckInvariants policy.
|
||||||
-# Recompile a debug version of your program, run it, and look for which
|
-# Recompile a debug version of your program, run it, and see if an assertion
|
||||||
assertions failed.
|
fails.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template
|
template
|
||||||
|
@ -400,12 +442,20 @@ public:
|
||||||
|
|
||||||
/** The constructor makes sure the host is valid at the time the checker
|
/** The constructor makes sure the host is valid at the time the checker
|
||||||
was created, thus insuring the host object was not corrupt from the start.
|
was created, thus insuring the host object was not corrupt from the start.
|
||||||
|
@par validator Pointer to function that checks class invariants.
|
||||||
|
@par pre Optional pointer to function that checks pre-conditions.
|
||||||
|
@par post Optional pointer to function that checks post-conditions.
|
||||||
*/
|
*/
|
||||||
inline explicit StaticChecker( Validator validator ) :
|
inline explicit StaticChecker( Validator validator,
|
||||||
|
Validator pre = 0, Validator post = 0 ) :
|
||||||
Ep(),
|
Ep(),
|
||||||
m_validator( validator )
|
m_validator( validator ),
|
||||||
|
m_pre( pre ),
|
||||||
|
m_post( post )
|
||||||
{
|
{
|
||||||
Check();
|
assert( Check() );
|
||||||
|
if ( 0 != m_pre )
|
||||||
|
assert( m_pre() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The destructor checks if any Host invariants failed, and then calls the
|
/** The destructor checks if any Host invariants failed, and then calls the
|
||||||
|
@ -414,22 +464,29 @@ public:
|
||||||
*/
|
*/
|
||||||
inline ~StaticChecker( void )
|
inline ~StaticChecker( void )
|
||||||
{
|
{
|
||||||
Check();
|
assert( Check() );
|
||||||
Ep::Check();
|
if ( 0 != m_post )
|
||||||
|
assert( m_post() );
|
||||||
|
assert( Ep::Check() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This first checks its own invariants, and then calls the validator
|
/** This first checks its own invariants, and then calls the validator
|
||||||
function to make sure no invariants were broken by the function which
|
function to make sure no invariants were broken by the function which
|
||||||
created this checker. That function can call Check directly to verify
|
created this checker. That function can call Check directly to verify the
|
||||||
the data remains valid at any time.
|
data remains valid at any time. This does not care if the pre- and post-
|
||||||
|
condition validator pointers are null since a host class may pass in NULL
|
||||||
|
pointers for either to indicate the pre-conditions or post-conditions are
|
||||||
|
the same as the overall class invariants.
|
||||||
*/
|
*/
|
||||||
inline void Check( void ) const
|
inline bool Check( void ) const
|
||||||
{
|
{
|
||||||
assert( 0 != this );
|
assert( 0 != this );
|
||||||
assert( 0 != m_validator );
|
assert( 0 != m_validator );
|
||||||
// Now that this confirms the pointers to the host and validation
|
// Now that this confirms the pointers to the host and validation
|
||||||
// functions are not null, go ahead and validate the host object.
|
// functions are not null, go ahead and validate the host object.
|
||||||
assert( ( m_validator )() );
|
const bool okay = m_validator();
|
||||||
|
assert( okay );
|
||||||
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -441,9 +498,15 @@ private:
|
||||||
/// Copy-assignment operator is not implemented.
|
/// Copy-assignment operator is not implemented.
|
||||||
StaticChecker & operator = ( const StaticChecker & );
|
StaticChecker & operator = ( const StaticChecker & );
|
||||||
|
|
||||||
/// Pointer to member function that checks Host object's invariants.
|
/// Pointer to member function that checks Host object's invariants.
|
||||||
Validator m_validator;
|
Validator m_validator;
|
||||||
|
|
||||||
|
/// Pointer to member function that checks Host object's pre-conditions.
|
||||||
|
Validator m_pre;
|
||||||
|
|
||||||
|
/// Pointer to member function that checks Host object's post-conditions.
|
||||||
|
Validator m_post;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue