[contract] with Boost.Parameter (was "Contract Programming Library")

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.Parameter together with the current implementation of Boost.Contract. However, I have not yet verified compatibility with the entire set of Boost.Parameter features (template parameters, free-functions, etc). #include <boost/parameter.hpp> #include <boost/graph/depth_first_search.hpp> #include <contract.hpp> #include <iostream> namespace graphs { BOOST_PARAMETER_NAME(graph) BOOST_PARAMETER_NAME(visitor) BOOST_PARAMETER_NAME(root_vertex) BOOST_PARAMETER_NAME(index_map) BOOST_PARAMETER_NAME(color_map) struct g { CONTRACT_CLASS( (g) ) BOOST_PARAMETER_MEMBER_FUNCTION( (void), depth_first_search, tag, (required (graph, *) ) (optional (visitor, *, boost::dfs_visitor<>()) (root_vertex, *, *vertices(graph).first) (index_map, *, get(boost::vertex_index, graph)) (in_out(color_map), *, default_color_map(num_verticies(graph), index_map)) ) ) CONTRACT_FUNCTION( (public) (template)( (typename)(graph_type) (typename)(visitor_type) (typename)(root_vertex_type) (typename)(index_map_type) (typename)(color_map_type) ) (void) (depth_firt_search)( (graph_type&)(graph) (visitor_type&)(visitor) (root_vertex_type&)(root_vertex) (index_map_type&)(index_map) (copyable)(color_map_type&)(color_map) ) (postcondition) ({ CONTRACT_ASSERT( color_map == CONTRACT_OLDOF(color_map) + 10 ); }) (body) ({ color_map += 10; std::cout << "graph=" << graph << std::endl; std::cout << "visitor=" << visitor << std::endl; std::cout << "root_vertex=" << root_vertex << std::endl; std::cout << "index_map=" << index_map << std::endl; std::cout << "color_map=" << color_map << std::endl; }) ) }; } // namespace int main() { using namespace graphs; g gg; int cm = 0; gg.depth_first_search(1, 2, 3, 4, cm); std::cout << std::endl; gg.depth_first_search("1", '2', _color_map = cm, _index_map = "4", _root_vertex = "3"); return 0; } This function declaration syntax is terrible as it mixes the syntactic complexity of both Boost.Parameter and Boost.Contract... I will try to provide the following syntax instead: CONTRACT_FUNCTION( (public) (void) (depth_first_search)( // No (tag)(namespace-id) so use `tag`. // (auto) for no type requirements (preprocessor can't use `*`). (auto) (graph) // (default) for optional param. (auto) (visitor) (default)(boost::dfs_visitor<>()) (auto) (root_vertex) (vertices(graph).first) (auto) (index_map) (default)(get(boost::vertex_index, graph)) // (inout) for in-out type. (copyable)(inout)(auto) (color_map) (default) (default_color_map(num_verticies(graph), index_map)) // Plus, (deduced)( parameter-sequence ) for deduced params. ) (postcondition) ( (color_map == CONTRACT_OLDOF(color_map) + 10) ) ({ color_map += 10; std::cout << "graph=" << graph << std::endl; ... }) (IMO, this syntax looks cleaner that the original Boost.Parameter one.) -- Lorenzo
participants (1)
-
Lorenzo Caminiti