Boost logo

Boost :

Subject: Re: [boost] [contract] extra type requirements for contracts
From: lcaminiti (lorcaminiti_at_[hidden])
Date: 2011-09-22 13:09:20


Jeffrey Lee Hellrung, Jr.-2 wrote:
>
> On Thu, Sep 22, 2011 at 8:03 AM, lcaminiti <lorcaminiti_at_[hidden]>
> wrote:
> [...]
>
>> Hello all,
>>
>> I am trying to program an assertion that is compiled and checked at
>> run-time
>> only when an integral boolean expression expressing the assertion
>> requirements is true.
>>
>> For example, the following code asserts back() == value only when
>> can_call_equal<T>::value is true. However, is there a better way to do
>> this
>> that does not require the extra function call to post1?
>>
>
> I'm not sure how you can get away *without* conditionally compiling the
> "back() == value" expression, and since your condition is only known at
> instantiation time, it seems the only way to effect this is through a
> function overload or class specialization. What is undesirable about the
> "extra function call"?
>
> #include &lt;boost/mpl/bool.hpp&gt;
>> #include &lt;boost/type_traits/can_call_equal.hpp&gt;
>> #include <vector>
>> #include <cassert>
>> #include <iostream>
>>
>> template< typename T >
>> struct myvector {
>>
>> // CONTRACT_FUNCTION_TPL(
>> // public void (push_back) ( (T const&) value )
>> // postcondition(
>> // back() == value, requires boost::can_call_equal<T>::value
>> // )
>> // ) { vector_.push_back(value); }
>>
>> void post1 ( boost::mpl::true_, T const& value ) const {
>> std::clog << "actual assertion\n";
>> assert( /**/ back() == value /**/ );
>> }
>> void post1 ( boost::mpl::false_, T const& value ) const {
>> std::clog << "trivial assertion\n";
>> }
>> void push_back ( T const& value ) {
>> body(value);
>> post1(typename boost::mpl::bool_<
>> /**/ boost::can_call_equal<T>::value /**/ >::type(),
>> value);
>> }
>> void body ( T const& value )
>> /**/ { vector_.push_back(value); } /**/
>>
>> T const& back ( void ) const { return vector_.back(); }
>>
>> private:
>> std::vector<T> vector_;
>> };
>>
>> struct pod {};
>>
>> int main ( ) {
>> myvector<int> v;
>> std::clog << "push 123\n";
>> v.push_back(123);
>>
>> myvector<pod> w;
>> std::clog << "push POD\n";
>> w.push_back(pod());
>> return 0;
>> }
>>
>> Note that post1(boost::mpl::true_, ...) is not even compiled for
>> myvector<pod> and that is essential because such a compilation attempt
>> will
>> fail because pod does not have an operator==.
>>
>
> Agreed. Again, can you be specific about what the problems with this are?
>

Yes, the issues are (small):
1) It's harder for me to implement the macros to deal with the extra post1
function definition and call (harder but possible, I think).
2) The run-time overhead of the extra post1 function call-- but if you are
really concerned about run-time performances, you'd disable contracts (and
especially postconditions) anyway by #defining
CONTRACT_CONFIG_NO_POSTCONDITIONS, etc.

So I guess I just roll up my sleeves and implement the macros to expand the
extra function calls ;) but I wanted to check with Boosters if there are
alternatives to implement this (BTW, I can only use C++03 features to do
this).

Thanks a lot!
--Lorenzo

--
View this message in context: http://boost.2283326.n4.nabble.com/boost-contract-extra-type-requirements-for-contracts-tp3824535p3834049.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

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