Subject: [boost] [contract] syntax redesign
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-05-31 14:49:54
Hello all,
After a long time of inactivity for Boost.Contract, I am considering
how to re-design its macro syntax to make it simpler.
I can eliminate a large number of extra parenthesis based on a few pp
tricks I've learned in processing Boost.Local's `const bind(type)&
var`. Plus, I can provide (optional) support for variadics macros so
to use comma-separated pp tuplets instead of parenthesized pp
sequences on preprocessors with variadics.
For example, I _think_ (but I've not implemented this yet) that I can
simplify the syntax like this:
#include <contract.hpp>
#include <vector>
#include "myvector/pushable.hpp"
// Wrapper class that adds contracts to std::vector.
CONTRACT_CLASS(
template( typename T )
class (myvector) extends( public pushable<T> ) // Subcontracting.
) {
CONTRACT_CLASS_INVARIANT(
empty() == (size() == 0)
// More invariants here (comma separated)...
)
CONTRACT_FUNCTION(
public void (push_back)( (const T&) element )
precondition(
size() < max_size()
// More preconditions here (comma separated)...
)
postcondition(
auto old_size = CONTRACT_OLDOF(size()), // Old value.
size() == old_size + 1
// More postconditions here (comma separated)...
)
) {
vector_.push_back(element); // Implementation.
}
// Rest of the class here (with more contracts if needed)...
public:
typedef typename std::vector<T>::size_type size_type;
size_type size(void) const { return vector_.size(); }
size_type max_size(void) const { return vector_.max_size(); }
bool empty(void) const { return vector_.empty(); }
const T& back(void) const { return vector_.back(); }
private:
std::vector<T> vector_;
};
For a side-by-side comparison with N1962 syntax:
For a comparison of the entire std::vector (plus Boost.ConceptCheck concepts):
For a comparison for all Boost.Contract features (plus
Boost.ConceptCheck concepts and Boost.Parameter named parameters):
(Don't pay attention to the rest of the docs that are way out of date.)
A few notes:
* Extra parenthesis are still needed around class and function names.
* Extra parenthesis are still needed around types (like for the
parameter `(T) element`) but only if the type is not a C++ keyword (no
parenthesis needed aournd int, double, void, etc) or it contains a
symbol (parenthesis needed if & or * are used `(int&) x`, etc).
* In postconditions, the `auto old_size = CONTRACT_OLDOF(size())` only
copies the vector size (and not the entire vector :)) ). Similarly,
`auto result = return` can be used to access the return value for
non-void functions. (The `auto ...` is parsed by the pp and it's
implemented using Boost.Typeof so no C++0x is required.)
* Template declaration (but not instantiation) angular parenthesis <>
are replaced by round parenthesis ().
All of this _should_ be implementable in pure ISO C++.
What do you think? Based on the discontent that the previous
"parenthesized" syntax generated among Boosters, the key question is:
Would you consider this new syntax usable??
Thanks,
--Lorenzo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk