#ifndef INVARIANTS_HPP
#define INVARIANTS_HPP
 
#include ensure.h
 
_OPEN_NAMESPACE(DBC)
 
template< typename Derived >
struct invariants
{
#ifndef NDEBUG
    typedef invariants< Derived > invars_t;
    struct trigobj //instantiate in derived class public,
    //non-const functions. May instantiate in const ones
    //also, if paranoid. May NOT instantiate in private
    //or protected functions!!!
    {
        trigobj( invariants const * pinv )
        : pinv_( pinv )
        {
            _ensure_ pinv_;
            if( pinv_ )
                pinv_->verf_invars();
        }
        ~trigobj()
        {
            _ensure_ pinv_;
            if( pinv_ )
                pinv_->verf_invars();
            pinv_ = 0;
        }
     private:
        invariants const * pinv_;
        trigobj(); //no default ctor.
        trigobj( trigobj const & );
        void operator=( trigobj const & );
    };
    //invariants base is copy-wise immutable...
    invariants(invars_t const &) : enabled_(false) {}
    invars_t & operator=(invars_t const &)
    {
        return *this;
    }
    void verf_invars() const
    {
        _ensure_ enabled_;   //forgot to enable?
        verify_invariants(this);
    }
 protected:
    invariants() : enabled_(false) {}
    void first_verify() const
    {
        _ensure_ ! enabled_; //enable again? !!!
        enabled_ = true;
        verify_invariants(this);
    }
    void last_verify() const
    {
        _ensure_ enabled_;   //forgot to ever enable?...
        verify_invariants(this); //...or disabling again?
        enabled_ = false;
    }
    ~invariants()
    {
        _ensure_ ! enabled_; //no disable in derived dtor?
        enabled_ = false;
    }
    mutable char enabled_;
 private:
    virtual void verify_invariants(invars_t const *) const = 0;
#endif
};
 
_CLOSE_NAMESPACE_(DBC)
 
#define INVARIANTS_BASE  public invariants
 
#ifndef NDEBUG
 
# define INVARIANTS() friend struct invariants< type >; \
void verify_invariants(invariants< type > const *) const
# define _INVARIANTS_CHECKED_ invariants< type >::trigobj TRGBJ(this);
# define FIRST_INVARIANTS_CHECK() invariants< type >::first_verify()
# define LAST_INVARIANTS_CHECK() invariants< type >::last_verify()
 
#else //Release mode:
 
# define INVARIANTS() template<int ZZZ> void zzz() const
# define _INVARIANTS_CHECKED_
# define FIRST_INVARIANTS_CHECK() do{}while(0)
# define LAST_INVARIANTS_CHECK() do{}while(0)
 
#endif
 
#endif
 
code/root/inc/invariant.h.txt · Last modified: 2006/10/09 22:37 by chuck_starchaser