
On Wed, Feb 17, 2010 at 4:05 AM, Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
it is inevitable, etc., but.. read on. I know at least one library in Boost that also spoils function declarations in order to provide additional functionality: Concept Check library; they may be others too (MPL?). My suggestion is that if there are (or will be) libraries that require spoiling function declarations, they should all provide the same "spoiled" syntax. Otherwise I will be always asking "how do I declare a function in this library?". It would be very convenient if Boost provided one alternative function definition syntax that when used would enable all its libraries to work.
I agree. However, in the past I did look into harmonizing my library API with the ones of Boost.ConceptCheck and/or Boost.Parameter but it did not seem feasible... I will double check it.
This is not only about clarity. As a super-correct programmer I may want to apply both concept checking and pre-/post-conditions checking to my functions.
Perhaps, if the 'compromise' syntax is possible, it requires changing concept-checking library.
I have verified that it is possible to use Boost.ConceptCheck together with the current implementation of Boost.Contract as shown below. I will look into doing something similar also for Boost.Parameter. #include <boost/concept_check.hpp> #include <boost/concept/requires.hpp> #include <contract.hpp> #include <iostream> struct x { CONTRACT_CLASS( (x) ) template<typename T> BOOST_CONCEPT_REQUIRES( ((boost::Integer<T>)), (int)) f(const T& x) CONTRACT_FUNCTION( (public) (template)( (typename)(T) ) (int) (f)( (const T&)(x) ) (precondition) ({ CONTRACT_ASSERT( x >= 0 ); }) (postcondition) (result) ({ CONTRACT_ASSERT( result == x ); }) (body) ({ return x; }) ) }; int main() { x xx; std::cout << xx.f(123) << std::endl; // OK: Passes both concept and contract checks. // std::cout << xx.f(1.23) << std::endl; // Error: Fails concept check (compile-time). // std::cout << xx.f(-123) << std::endl; // Error: Fails contract precondition check (run-time). return 0; } This works because CONTRACT_FUNCTION() follows the function declaration which can be spoiled by BOOST_CONCEPT_REQUIRES() as usual to support concepts. However, I am planning to change CONTRACT_FUNCTION() so the function declaration tokens do not need to be repeated and I will add concept support following ConceptC++ syntax: CONTRACT_FUNCTION( (public) (template)( (typename)(T) ) (requires)( (boost::Integer<T>) ) (int) (f)( (const T&)(x) ) (precondition)( (x >= 0) ) (postcondition)(result)( (result == x) ) ({ return x; }) ) This will call Boost.ConceptCheck behind the scenes. Even after this change to CONTRACT_FUNCTION(), Boost.Contract will still provide a CONTRACT_FUNCTION_DEF() that will follow the function declaration (as the current implementation of CONTRACT_FUNCTION() does). Therefore, the example above where Boost.ConceptCheck is used directly can still be programmed using the DEF() macro. Lorenzo