Boost.Test > Components > The Test Tools > custom predicate support

# The custom predicate support

## Synopsis

    class extended_predicate_value {
    public:
        extended_predicate_value( bool predicate_value_ );
        extended_predicate_value( extended_predicate_value const& rhs );

        bool    operator!() const;
        void    operator=( bool predicate_value_ );

        readonly_property<bool>              p_predicate_value;
        boost::shared_ptr<wrap_stringstream> p_message;
    };

### Description

There two layers of custom predicate support implemented by the Test Tools:

- Simple predicate one or two arity without custom error message support
- Arbitrary predicate with custom error message support

To use first layer use BOOST_CHECK_PREDICATE tool. You could implement any custom check and report the result by returning boolean value from your predicate. For detailed description of this see reference.

To use second layer you predicate should be defined to return boost::test_tools::extended_predicate_value. This class encapsulate both boolean result value and error/info message in case if result is true/false. Be aware that message returned in extended_predicate_value will be the only one logged by the framework in case of error (actually plus error location). Usual error notification gets skipped.

Usually you construct the instance of extended_predicate_value inside your predicate and return it by value. The constructor expects one argument - the boolean result value. The constructor is implicit, meaning that you could simply return boolean value from your predicate - extended_predicate_value get implicitly constructed to hold your value and empty error message. In case if you want to update this value after construction use method operator=( bool ). Would you need to check the current predicate value use method operator!() or directly access public read only property p_predicate_value. To create/modify error message you should use public read/write property p_message. p_message is a shared pointer to the class wrap_stringstream. You will need to allocate instance of it dynamically in you predicate. It gets destroyed after error is logged. Use usual ostream interface to create the error message.

### Example

    // custom comparison predicate that only checks for lists size
    extended_predicate_value
    compare_lists( std::list<int> const& l1, std::list<int> const& l2 )
    {
        if( l1.size() != l2.size() ) {
            extended_predicate_value res( false );

            res.p_message.reset( new boost::wrap_stringstream );

            *res.p_message << " Different sizes [" << l1.size() << "!=" << l2.size() << "]";

            return res;
        }

        return true;
    }

    ...

    void my_test_case()
    {
        ...
        BOOST_CHECK( compare_lists( l1, l2 ) );
    }