Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2003-05-02 17:44:31


Thomas Wenisch wrote:
>>> INVARIANT( (i < j) || (i == 0) || (j == 1)) (i) (j) ;
>>>
>>
>> This would look incredibly cool!
>> However, I spent some time, and I don't know how to implement it.

Below is a sample implementation that just checks the invariant. If false, it
outputs any trailing expressions/values and then aborts the program. (This is
all customizable of course, but I don't know exactly what you want because I
haven't been closely following this thread.)

Usage syntax is as follows:

invariant:
    BOOST_INVARIANT ( non-comma-expression ) extended-info[opt]

extended-info:
    ( non-comma-expression ) extended-info[opt]

// --------------------------------------------- //

#include <cstdlib>
#include <iostream>

namespace boost {

enum { BOOST_INVARIANT_A, BOOST_INVARIANT_B };

struct invariant {
    inline ~invariant() {
        std::abort();
        return;
    }
};

#define BOOST_INVARIANT(expr) \
    if (!(expr)) \
        boost::invariant(), \
        std::clog << "invariant failure: " #expr, \
        boost::BOOST_INVARIANT_A \
    /**/

#define BOOST_INVARIANT_A(x) BOOST_INVARIANT_OP(x, B)
#define BOOST_INVARIANT_B(x) BOOST_INVARIANT_OP(x, A)

#define BOOST_INVARIANT_OP(x, next) \
    BOOST_INVARIANT_A, \
    std::clog << #x"=" << (x) << &std::endl, \
    boost::BOOST_INVARIANT_ ## next \
    /**/

} // boost

int main(int argc, char* argv[]) {
    BOOST_INVARIANT(argc > 1)(argc);
    return 0;
}

// --------------------------------------------- //

>> However, just using (i) (j) I'm not sure we can do this. I may be
>> wrong, but this should not work:
>>
>> #define OP1(x) std::cout << #x << "=" << (x) << std::endl;
>> #define OP2(x) std::cout << #x << "=" << (x) << std::endl; OP1
>>
>> Then, the question is, will 'OP2(i)(j)' output the values of i and j?

Yes, this is legal and will work as expected, but it means that you'd have to
explicitly say how many arguments you're going to output. The above, or
similar, can take any number of "extended" arguments.

> I suggest you check with Paul Mensonides on how to make this (i)(j)
> syntax possible. This looks similar to the PP library's sequence
> data structure
> to me (same kind of problems). If it can be done, I am sure he can
> tell
> you how.

:)

Paul Mensonides


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