
On Wed, Nov 9, 2011 at 6:16 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
The goal here is to use Boost.Contract to /completely/ specify the interface for the positive abstract data type.
For whomever is curious, the Boost.Contract named and deduced parameter examples now compile: https://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html/cont... Here's an example that uses a bit of everything: Contracts, concepts, named/deduced function and template parameters: #include <boost/python.hpp> #include <contract.hpp> #include <contract/parameter.hpp> // For named parameters. #include <contract/concept.hpp> // For concepts. #include <boost/concept_check.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/mpl/not.hpp> #include <boost/mpl/or.hpp> #include <boost/shared_ptr.hpp> #include <boost/noncopyable.hpp> #include <boost/regex.hpp> namespace py { // Helpers. bool is_identifier ( char const* name ) { static const boost::regex re("(\\l|\\u|_)(\\l|\\u|\\d|_)*"); return boost::regex_match(name, re); } // Class template with named parameters. CONTRACT_TEMPLATE_PARAMETER(ClassType) CONTRACT_TEMPLATE_PARAMETER(Bases) CONTRACT_TEMPLATE_PARAMETER(HeldType) CONTRACT_TEMPLATE_PARAMETER(Copyable) CONTRACT_PARAMETER(name) CONTRACT_CLASS( template( // Required named template parameter. in typename requires(boost::is_class<boost::mpl::_>) ClassType, // Deduced and optional named template parameters with type requirements. deduce in typename requires(boost::python::detail::specifies_bases< boost::mpl::_>) Bases, default boost::python::bases<>, deduce in typename requires(BOOST_IDENTITY_TYPE((boost::mpl::not_< boost::mpl::or_< boost::python::detail::specifies_bases<boost::mpl::_> , boost::is_same<boost::noncopyable, boost::mpl::_> > >))) HeldType, default boost::python::detail::not_specified, deduce in typename requires(BOOST_IDENTITY_TYPE(( boost::is_same<boost::noncopyable, boost::mpl::_> ))) Copyable, default boost::python::detail::not_specified // Note: Non-type template parameters are not supported by named parameters. ) requires( boost::DefaultConstructible<ClassType> ) // Concepts. class (class_) extends( BOOST_IDENTITY_TYPE(( boost::python::class_<ClassType, Bases, HeldType, Copyable>)) ) ) { CONTRACT_CLASS_INVARIANT_TPL( void ) // Contracts. typedef boost::python::class_<ClassType, Bases, HeldType, Copyable> boost_python_class; public: CONTRACT_CONSTRUCTOR_TPL( public (class_) ( in (char const*) name ) precondition( is_identifier(name) ) initialize( boost_python_class(CONTRACT_CONSTRUCTOR_ARG(name)) ) ) {} }; } // namespace py struct bx { virtual ~bx ( void ) {} }; struct x : bx {}; struct by { virtual ~by ( void ) {} }; struct y : by { }; // Python module, in a Python shell from this directory run: // >>> import pyclass # This will check contracts (preconditions, etc). // >>> help("pyclass"), xx = pyclass.x(), yy = pyclass.x() BOOST_PYTHON_MODULE(pyclass) { // Named parameters. py::class_<py::_ClassType<bx>, py::_Copyable<boost::noncopyable> >("bx"); py::class_<x, py::_HeldType<boost::shared_ptr<x> >, py::_Bases<boost::python::bases<bx> > >("x"); // Deduced parameters. py::class_<by, boost::noncopyable>("by"); py::class_<y, boost::shared_ptr<y>, boost::python::bases<by> >( py::_name = "y"); } Comments welcome. --Lorenzo