|
Boost : |
Subject: Re: [boost] [contract] syntax redesign
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-12-11 06:37:35
On Wed, Nov 9, 2011 at 6:16 AM, Lorenzo Caminiti <lorcaminiti_at_[hidden]> 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/contract__/examples.html#contract__.examples.__named_parameters___depth_first_search__required_and_optional_named_parameters
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk