Boost logo

Boost :

Subject: Re: [boost] [contract] Mixin Boost.Contract and Boost.STM
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-03-16 18:54:31


Hi,
----- Original Message -----
From: "Lorenzo Caminiti" <lorcaminiti_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, February 26, 2010 3:26 PM
Subject: [boost] [contract] Released Contract Programming Library onSourceForge

>
> Hi all,
>
> I have released on SourceForge a library that implements Contract
> Programming (a.k.a. Design by Contract(TM) ) for C++. I am considering
> to submit this library to Boost (as Boost.Contract).
>
> Contract++ Library
> * Download http://sourceforge.net/projects/dbcpp/
> * Documentation http://dbcpp.sourceforge.net/
> * Examples http://dbcpp.sourceforge.net/contract__/examples.html
>
> Comments?

I wanted to tell you that I wanted to mix Boost.Contract with Boost.STM. Software Transactional Memory needs already to
backup the data that is modified, so it can be rolled back on abort. Thus we can use this backup to get the value of the Old values.

As the copy is done always, we don't need any more to specify that we need to copy to be able to get the Old values as in

    void push_back(const T& element)
    CONTRACT_FUNCTION( (class) (copyable)(myvector)
            (inherit)(pushable<T>)
            (public) (void) (push_back)( (const T&)(element) )
    (precondition) ({
        CONTRACT_ASSERT( size() < max_size() );
    })
    (postcondition) ({
        CONTRACT_ASSERT( size() == (CONTRACT_OLDOF(this)->size() + 1) );
    })
    (body) ({
        vector_.push_back(element);
    }) )

BTW, does it means that CP can not be applied to non CopyConstructible classes?
In addition Boost.STM works also for classes that are not CopyConstructible, but that follows the Shallow Copy
semantics. This will allow to test for Old values on these kind of classes.

I have two questions. What (copyable) does on the constructor? Why it is not used on the destructor?

I know that this will take long time, but I'm sure that the integration will be fruitful.

I was wondering if instead of repeating the fuction signature and the class 'signature'

    void push_back(const T& element)
    CONTRACT_FUNCTION( (class) (copyable)(myvector)
            (inherit)(pushable<T>)
            (public) (void) (push_back)( (const T&)(element) )

you could be able to provide a macro CONTRACT_FUNCTION2 that allows to just write

#define CONTRACT_CLASS (class) (myvector) (inherit)(pushable<T>)

    CONTRACT_FUNCTION2(
            ((public) (void) (push_back)( (const T&)(element) ))
    (precondition)({
        CONTRACT_ASSERT( size() < max_size() );
        ... // More preconditions.
    })
    (postcondition)({
        CONTRACT_ASSERT( size() == (CONTRACT_OLDOF(this)->size() + 1) );
        ... // More postconditions.
    })
    (body)({
        vector_.push_back(element); // Original implementation.
    }) )
    
    ... // Rest of the class.

#undef CONTRACT_CLASS

CONTRACT_FUNCTION2 will just use the CONTRACT_CLASS macro to get the class 'signature'. Note that the first argument of CONTRACT_FUNCTION2 contain itself a PP sequence.

CONTRACT_FUNCTION2( (signature-sequence)
    precondition-sequence
    postcondition-sequence
    body-sequence )
==
REMOVE_PARENTHESIS(signature-sequence)
CONTRACT_FUNCTION( ( CONTRACT_CLASS signature-sequence)
    precondition-sequence
    postcondition-sequence
    body-sequence )

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk