
on Tue Nov 08 2011, Lorenzo Caminiti <lorcaminiti-AT-gmail.com> wrote:
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?
No because my syntax also supports non-variadic compilers
Oh!
and the above will have to become (Value)(int) which forces extra parenthesis around (Value) even when there is no default. `..., default ...` is consistently used to indicate default parameter value (template or functional) and in my experience you get used to it pretty quickly.
I don't mind "default" at all, but the fact that it is separated by a comma from "in typename Value", with no grouping to distinguish that comma from the commas that separate parameters, is ugly. If it's the only way to make it work, then so be it, but I'd prefer to have the default value grouped somehow with the parameter name.
In fact, I personally prefer Value, default int to (Value, int) (because in the second there is no description of the semantic of the 2nd token int).
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?
This is a way of passing a named value template parameter by wrapping within a type template parameter as you suggested...
Well, it may be, but I don't understand how it works.
is there a better way to do this? I want to pass:
template< typename Value, Value default_value = 1 >
Where both Value and default_value are named using Boost.Parameter.
If I were you I would try to think a little beyond the limitations of Boost.Parameter. If there's an interface we can implement that better supports this use-case, we'll add it. Is there?
Have you thought of using decltype in the implementation, to avoid writing ::type up there?
I'm not using C++1 features. (The C++11-looking auto, static_assert, etc that you see in Boost.Contract are all handled by the pp and implemented using C++03.)
Wow! But decltype might be (a little) different, since we can emulate it with Boost.Typeof. Just something to consider.
Something like boost::mpl::_::type seems like maybe it should be spelled "auto" (if possible).
It cannot because it is nested inside the named parameter type predicate so the pp has to way to parse it.
Right. Well, boost::contract::auto_ then? I know, yuck :-P
::type is needed because I am using a type to wrap a value so the value template parameter can be named (as indicated above).
I don't understand what you're saying here yet.
) requires( boost::Copyable<Value> ) // Concepts. struct (positive) ) { CONTRACT_CLASS_INVARIANT_TPL( // Contracts.
Because it's an invariant for a class template, not an invariant template. At least, IIUC.
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.
This will be detailed in Boost.Contract docs (it's an addition over N1962). All assertions within static class(...) specify /static class invariants/. (Non-static) class invariants are not checked at entry/exit of static functions or at constructor entry. However, static class invariants are also checked at entry/exit of static functions and at constructor entry.
Hm, OK.
Obviously, static class invaraints cannot refer to the object (but only to static member data/functions). In addition, this one static class invariant is using a static assertion (for this example, given that the assertion is static it could also have been programmed as part of the non-static class invariants and get the same type of checking which is always at compile-time for static_assert).
[OK. It would be good to have an example in the end product that doesn't include that kind of redundancy.]
Static class invariants were discussed with N1962 authors 1+ years ago over the Boost ML (no one had objections on them but no one seemed to think they will be useful in real life).
In that case, I think you should omit them. Premature generalization is the root of all evil ;-)
get() > 0 )
CONTRACT_CONSTRUCTOR_TPL( public (positive) ( void )
Is "void" mandatory here?
No if your compiler supports empty macro parameters or variadics. However, often MSVC (which in theory supports both) gets confused and generates pp-error. So I always use void to indicate and empty (parameter) list so the code is most portable.
Ah.
initialize( value_(Default::value) ) ) {}
What is "value_"?
A private member variable.
OK, thanks.
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?
Because assertion requirements are specified using integral static constants and not nullary metafunctions. This could be (esaily) changed to be more consistent with named parameter requires that uses unary metafunctions... I'll think about it.
Please do.
This is very nice, but still could use some explanation and simplification.
Explanation will definitely go in the docs. What simplifications would you suggest?
E.g. leaving out the "namespace" stuff and the features that nobody thinks will be useful. -- Dave Abrahams BoostPro Computing http://www.boostpro.com