* Alf P. Steinbach /Usenet, on 17.07.2010 11:50:
[Cross-posted comp.lang.c++ and comp.lang.python]

[snip]
this occurred to me:

     #define CPPY_GETSET_FORWARDERS( name )                          \
         ::progrock::cppy::forwardersGetSet(                         \
             &CppClass::name                                         \
             ).themForwarders< &CppClass::name >()

Here forwardersGetSet is a templated function that via argument type
deduction produces an instance of a templated struct, thereby "knowing"
the member type, which struct in turn has a member function templated on
the member pointer, which the macro supplies *twice*, once as run-time
arg and once as compile-time.

That trick allowed uniform treatment of data and function member pointers. :-)

So, with cppy the complete noddy2 example from the docs (I'm sort of working my way through the Python doc examples) now looks as shown below.

The "typelessness" of the 'first' and 'last' members is in order to recreate as close as possible the noddy2 functionality, or, lack of it. Also, I haven't got around to sort of backporting the 'Exposition' scheme to modules. So, exposure of module functionality looks a little different from same for types, for now.


<code>
// The Python 3.1.1 docs' Noddy 2 example rewritten using cppy.
// Docs: "Extending and Embedding the Python Interpreter" ยง2.1.1

#include <progrock/cppy/PyClass.h>      // PyWeakPtr, PyPtr, PyModule, PyClass
using namespace progrock;

namespace {
    using namespace cppy;

    struct Noddy
    {
        PyPtr       first;
        PyPtr       last;
        int         number;

        Noddy( PyWeakPtr pySelf, PyPtr args, PyPtr kwArgs )
            : number( 0 )
        {
            devsupport::suppressUnusedWarning( pySelf );

            PyWeakPtr   pFirstName  = 0;
            PyWeakPtr   pLastName   = 0;

            static char*    kwlist[] = { "first", "last", "number", 0 };

            ::PyArg_ParseTupleAndKeywords(
                args.rawPtr(), kwArgs.rawPtr(), "|OOi", kwlist,
                pointerTo( pFirstName ), pointerTo( pLastName ), &number
                )
                >> Accept< IsNonZero >()
                || throwX( "Invalid args" );

            if( pFirstName != 0 )   { first = pFirstName; }
            if( pLastName != 0 )    { last = pLastName; }
        }

        PyPtr name()
        {
            (first != 0)
                || throwX( ::PyExc_AttributeError, "first" );
            (last != 0)
                || throwX( ::PyExc_AttributeError, "last" );
            return (PyString( first ) + L" " + PyString( last )).pyPtr();
        }
    };

    struct NoddyPyClass: PyClass< Noddy >
    {
        NoddyPyClass( PyModule& m, PyString const& name, PyString const& doc )
            : PyClass< Noddy >( m, name, doc, Exposition()
                .method(
                    L"name",    CPPY_GLUE( name ),
                    L"Return the name, combining the first and last name"
                    )
                .attribute(
                    L"first",   CPPY_GLUE( first ),     L"first name"
                    )
                .attribute(
                    L"last",    CPPY_GLUE( last ),      L"last name"
                    )
                .attribute(
                    L"number",  CPPY_GLUE( number ),    L"noddy number"
                    )
                )
        {}
    };

    class NoddyModule: public PyModule
    {
    private:
        NoddyPyClass    noddyPyClass_;

    public:
        NoddyModule()
            : PyModule(
                L"noddy2", L"Example module that creates an extension type." )
            , noddyPyClass_( *this,
                L"Noddy", L"A Noddy object has a name and a noddy number" )
        {}
    };
}    // namespace <anon>


PyMODINIT_FUNC
PyInit_noddy2()
{
    return cppy::safeInit< NoddyModule >();
}
</code>


I wonder if this is readable / self-documenting, or not?


Cheers,

- Alf

--
blog at <url: http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to