Boost logo

Boost :

Subject: Re: [boost] [contract] syntax redesign
From: Dave Abrahams (dave_at_[hidden])
Date: 2011-11-08 14:07:44


on Tue Nov 08 2011, Lorenzo Caminiti <lorcaminiti-AT-gmail.com> wrote:

> The following turned out to be a decent example that uses together a
> bit of all the different features (contracts, concepts, and named
> parameters) so I decided to cut-n-paste it here in an email:
>
> #include <contract.hpp>
> #include <boost/concept_check.hpp>
> #include <boost/type_traits/has_equal_to.hpp>
> #include <boost/mpl/placeholders.hpp>
> #include <boost/mpl/int.hpp>
> #include <boost/mpl/long.hpp>
> #include <boost/mpl/char.hpp>
> #include <iostream>
>
> namespace num
> {
>
> namespace tag // Namespace `tag` already used here, use `keywords` instead.
> {
> typedef int Value; // Dummy declarations...
> typedef boost::mpl::int_<1> Default;
> Value value = Default::value;
> }

The point of the above is just to have an excuse to use the "namespace"
option below? I would leave this out of the example (and leave out that
option); it's not useful to show corner-case handling like this in early
examples.

> // Also use `Param` and `_param` postfixes instead of `_` prefix.
> CONTRACT_TEMPLATE_PARAMETER((ValueParam, keywords) Value)
> CONTRACT_TEMPLATE_PARAMETER((DefaultParam, keywords) Default)
> CONTRACT_PARAMETER((value_param, keywords) value)

Ditto, I think.

> CONTRACT_CLASS(
> template( // Named parameters.
> namespace keywords, // Use namespace `keywords` instead of `tag`.
> in typename Value, default int,

I presume this is essentially "typename Value=int". I don't love
separating one argument with a comma that way. Would

  in typename (Value, int)

or something similar be practical?

> in requires(is_same<boost::mpl::_::type, Value>) Default,
> default boost::mpl::int_<1>

I don't understand what this is supposed to be saying. Could you
explain it?

Have you thought of using decltype in the implementation, to avoid
writing ::type up there?

Something like boost::mpl::_::type seems like maybe it should be spelled
"auto" (if possible).

> ) requires( boost::Copyable<Value> ) // Concepts.
> struct (positive)
> ) {
> CONTRACT_CLASS_INVARIANT_TPL( // Contracts.

Why is that a better spelling than CONTRACT_CLASS_TPL_INVARIANT?

> static class(
> static_assert(Default::value > 0, "positive default value")
> ),

I don't understand what the "static class(...)" construct is doing here.

>
> get() > 0 )
>
> CONTRACT_CONSTRUCTOR_TPL(
> public (positive) ( void )

Is "void" mandatory here?

>
> initialize( value_(Default::value) ) ) {}

What is "value_"?

> CONTRACT_FUNCTION_TPL(
> public void (set) ( namespace keywords, in (Value const&) value )
> precondition( value > 0 )
> postcondition(
> get() == value, requires boost::has_equal_to<Value>::value

Why must ::value appear in the previous line?

> )
> ) {
> value_ = value;
> }
>
> CONTRACT_FUNCTION_TPL(
> public (Value const&) (get) ( void ) const
> ) {
> return value_;
> }
>
> private:
> Value value_;
> };
>
> } // namespace num
>
> int main ( void )
> {
> num::positive< char, boost::mpl::char_<'z'> > p;
> num::positive< > q;
>
> // Use `...Param` instead of `_...`.
> num::positive< num::DefaultParam< boost::mpl::int_<10> > > r;
> num::positive<
> num::DefaultParam< boost::mpl::long_<10> >
> , num::ValueParam<long>
> > s;
>
> std::cout << s.get() << std::endl;
> s.set(num::value_param = 123); // Use `..._param` instead of `_...`.
> std::cout << s.get() << std::endl;
>
> return 0;
> }
>
> The goal here is to use Boost.Contract to /completely/ specify the
> interface for the positive abstract data type.

This is very nice, but still could use some explanation and
simplification.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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