Thread: [pygccxml-commit] SF.net SVN: pygccxml: [65] pyplusplus_dev/docs
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-05-08 17:08:39
|
Revision: 65 Author: roman_yakovenko Date: 2006-05-08 00:00:13 -0700 (Mon, 08 May 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=65&view=rev Log Message: ----------- adding introduction to call wrapper policies Added Paths: ----------- pyplusplus_dev/docs/call_wrapper_policies/ pyplusplus_dev/docs/call_wrapper_policies/introduction.rest pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py Added: pyplusplus_dev/docs/call_wrapper_policies/introduction.rest =================================================================== --- pyplusplus_dev/docs/call_wrapper_policies/introduction.rest (rev 0) +++ pyplusplus_dev/docs/call_wrapper_policies/introduction.rest 2006-05-08 07:00:13 UTC (rev 65) @@ -0,0 +1,241 @@ +===================== +call wrapper policies +===================== + +.. contents:: Table of contents + +------------------- +What is useful for? +------------------- +Not all C++ functions could be exposed to Python as is. For example, next function +could not be exposed: +:: + + void get_size( int& size ); + +In order to expose ``get_size`` function, an user need to create next wrapper: +:: + + int get_size_wrapper( ){ + int size(0); + get_size( size ); + return size; + } + +|cwp| will provide the user with simple and intuitive way to instruct +`pyplusplus`_ to generate right wrapper. Also, it will be possible to create +a custom policies. + +-------- +Analysis +-------- + +C++ function arguments usage +---------------------------- + +In C++ function argument can be used to: + +* to pass some data to function ( in ) + + there is no need to return variable from the function + +* to return some data from function ( out ) + + there is no need to force Python programmer to pass the variable as argument + to the function + +* both ( in/out ) + +Function-wrapper signature will be a little bit different in every case. + +Variable names +-------------- +I think it should be possible to apply few |cwp| on a single function. Thus, it +will be possible to create few convinience function, from one single function. +The main,read unresolved, issue, is management of variable names within function-wrapper. +I see next problems, that we should solve, before proceeding to implementation: + +1. To share variable name, between different pieces of code. + + Right now I think, that every |cwp| will have ``pre-call`` and ``post-call`` + code creators. This design will allow the user to mix few |cwp|'s within + single function-wrapper. + +2. To insure name uniqueness. + +3. To give meaningful name. + +I think, that is it very easy to solve the problem, if I remove "readability" +requirement. + +Call policies +------------- +I don't have any solution to the next problem. +I am going to change a little an example, from `boost.python`_ tutorials: +http://www.boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies +:: + + //C++ code + struct Y + { + X x; Z* z; + int z_value() { return z->value(); } + }; + + X& f(Y& y, Z* z, int& error) + { + y.z = z; + return y.x; + } + + //boost.python code + def("f", f, return_internal_reference<1, with_custodian_and_ward<1, 2> >() ); + +What is the difference? Function ``f`` now takes 3rd argument - ``int&``. This +function could not be called from `Python`_. ( Hint: numbers are immutable +objects in `Python`_ ). So in order to expose function ``f`` to `Python`_, +an user need to create a wrapper. And now he has a problem: how to wrap the function? + +I see only one solution user have to change signature of function ``f``. +Now some speculations: + +1. May be it is possible with `boost.python`_ library to set call policies on the + part of the return value? + :: + + boost::tuple f_wrapper( Y& y, Z* z ){ + int error(0); + X& x = f( y, z, error ); + return boost::tuple<X&, int>( x, error ); + } + + def("f", f_wrapper, smart call policies that will work only on first element within the tuple ); + +2. May be it is possible to create boost.python ``object`` with life-time management + hint? + :: + + boost::python::tuple f_wrapper( Y& y, Z* z ){ + int error(0); + X& x = f( y, z, error ); + boost::python::object x_obj( x, x is internal reference of y ); + return boost::python::make_tuple( x_obj, error ); + } + +Anyway, I think we will just ignore the problem - software ( == boost.python ) +should not be perfect - it should work in most ( != all ) cases! + +------------ +Common |cwp| +------------ +Those names are not final and could( may be should ) be changed. + +immutable by reference +----------------------- +:: + + //function to be exported + something f( int& i, std::string& str ) + +I suppose this is very common use case. More over this use case `pyplusplus`_ +can and will treat by its own - no user action is needed. The wrapper +generated by `pyplusplus`_ will very similar to the next code: +:: + + void f_wrapper( const int& i, const std::string& str ){ + int i_out( i ); + std::string str_out( str ); + boost::python::object f_return = f( i_out, str_out ); + return boost::python::make_tuple( f_return, i, str ); + } + + +The only customization available for user is to setup argument type: +[in\|out\|in,out] + +array +----- +Arrays are a little bit different beasts. Python does not have arrays. +So, `pyplusplus`_, should implement arrays convertion: from/to C++/Python. +This is not the only difference, consider next function: +:: + + void fill( char* buffer, int index ){ + buffer[ index ] = 'c'; + } + + +There are few ways to expose this function: +:: + + ??? fill_wrapper( boost::python:list buffer, index ){ + long buffer_size = boost::python::extract<long>( buffer.attr("__len__") ); + boost::scoped_array<char> buffer_( new char[ buffer_size ] ); + for( long i = 0; i < buffer_size; ++i ){ + buffer_[ i ] = boost::python::extract<char>( buffer[i] ); + } + fill( buffer_.get(), index ); + //Now the question: how to return buffer_ to the caller? + //by constructing new list? + boost::python::list return_; + for( long i = 0; i < buffer_size; ++i ){ + return_.insert( i, buffer_[i] ); + } + return return_; + //or by modifying the buffer argument? In this case `pyplusplus`_ will + //delete all items from buffer and will copy into it items from buffer_ + //variable. + } + +Arrays size +~~~~~~~~~~~ +1. static array - size of array is known at compile time. +2. dynamic array + + + size of array is one of the function arguments + + + other ( will not be implemented in the first phase ) + + - size of array is some global/local variable + + - ize of array is returned by invocation some function + + +status as exception +------------------- +There a lot of code, that returns success status and/or error description by +using one of the function arguments. It will be possible to instruct `pyplusplus`_ +to create wrapper for those functions, that will throw exception. +:: + + bool do_smth( error_description& error_desc ); + + bool do_smth_wrapper(){ + error_description error_desc; + bool return_ = do_smth( error_desc ); + if( some user code that will check that error_desc contains error ){ + throw some user code that will construct an exception from the error_desc; + } + return return_; + } + +pythread safe +------------- +Why not :-)? See next FAQ: http://boost.org/libs/python/doc/v2/faq.html#threadsupport +So, how `pyplusplus`_ can help? `pyplusplus`_ can generate exception safe code, +that will acquire and release Python global interpreter lock. + + +.. _`pyplusplus` : ./../pyplusplus.html +.. |cwp| replace:: *"call wrapper policies"* +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py =================================================================== --- pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/call_wrapper_policies/www_configuration.py 2006-05-08 07:00:13 UTC (rev 65) @@ -0,0 +1,2 @@ +name = 'call wrapper policies' +main_html_file = 'introduction.html' \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-06-03 18:24:04
|
Revision: 199 Author: roman_yakovenko Date: 2006-06-03 11:23:49 -0700 (Sat, 03 Jun 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=199&view=rev Log Message: ----------- adding apidocs directory, thus I will not have to modify setup script Added Paths: ----------- pyplusplus_dev/docs/apidocs/ pyplusplus_dev/docs/apidocs/www_configuration.py Added: pyplusplus_dev/docs/apidocs/www_configuration.py =================================================================== --- pyplusplus_dev/docs/apidocs/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/apidocs/www_configuration.py 2006-06-03 18:23:49 UTC (rev 199) @@ -0,0 +1,2 @@ +name = 'API docs' +main_html_file = 'index.html' \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-06-07 20:07:27
|
Revision: 202 Author: roman_yakovenko Date: 2006-06-03 22:40:31 -0700 (Sat, 03 Jun 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=202&view=rev Log Message: ----------- switching to Python terminology Added Paths: ----------- pyplusplus_dev/docs/peps/ Removed Paths: ------------- pyplusplus_dev/docs/call_wrapper_policies/ Copied: pyplusplus_dev/docs/peps (from rev 200, pyplusplus_dev/docs/call_wrapper_policies) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-09 19:09:07
|
Revision: 287 Author: roman_yakovenko Date: 2006-07-09 12:08:54 -0700 (Sun, 09 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=287&view=rev Log Message: ----------- adding indexing suite 2 documentatio Added Paths: ----------- pyplusplus_dev/docs/std_containers/ pyplusplus_dev/docs/std_containers/containers.rest pyplusplus_dev/docs/std_containers/indexing_suite_v2.html pyplusplus_dev/docs/std_containers/indexing_suite_v2_files/ pyplusplus_dev/docs/std_containers/indexing_suite_v2_files/boost.css pyplusplus_dev/docs/std_containers/indexing_suite_v2_files/cboost.gif pyplusplus_dev/docs/std_containers/www_configuration.py Added: pyplusplus_dev/docs/std_containers/containers.rest =================================================================== --- pyplusplus_dev/docs/std_containers/containers.rest (rev 0) +++ pyplusplus_dev/docs/std_containers/containers.rest 2006-07-09 19:08:54 UTC (rev 287) @@ -0,0 +1,176 @@ +====================== +C++ containers support +====================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +C++ has a bunch of containers classes: + + * list + * deque + * queue + * priority_queue + * vector + * stack + * map + * multimap + * hash_map + * hash_multimap + * set + * hash_set + * multiset + * hash_multiset + +It is not a trivial task to expose C++ container to Python. Boost.Python has +a functionality that will help you to expose some of STL containers to `Python`_. +This functionality called - "indexing suite". If you want, you can read more +about indexing suite `here`__. + +.. __ : http://boost.org/libs/python/doc/v2/indexing.html + +Boost.Python, out of the box, supports only ``vector``, ``map`` and ``hash_map`` +containers. In October 2003, Raoul Gough implemented support for the rest of +containers. Well, actually he did much more - he implemented new framework. +This framework provides support for almost all C++ containers and also an easy +way to add support for custom ones. You'd better read his `post`_ to +`boost.python`_ mailing list or `documentation`_ for the new indexing suite. + + +If this suite is soo good, why it is not in the main branch? You can find the +answer here(http://mail.python.org/pipermail/c++-sig/2006-June/010830.html) and +here(http://mail.python.org/pipermail/c++-sig/2006-June/010835.html). + +.. _`documentation` : ./indexing_suite_v2.html +.. _`post` : http://mail.python.org/pipermail/c++-sig/2003-October/005802.html + +------------------------------ +pyplusplus and indexing suites +------------------------------ +`pyplusplus`_ implements support for both indexing suites. More over, you can +freely mix indexing suites. For example you can expose ``std::vector<int>`` using +`boost.python`_ built-in indexing suite and ``std::map< int, std::string>`` using +Raoul Gough's indexing suite. + +----------------- +How does it work? +----------------- + +In both cases, `pyplusplus`_ provides almost "hands free" solution. `pyplusplus`_ +keeps track of all exported functions and variables, and if it sees that there is +a usage of stl container, it exports the container. In both cases, `pyplusplus`_ +analizes the container ``value_type`` ( or in case of mapping containers +``mapped_type`` ), in order to set reasonable defaults, when it generates the code. + +----------------------- +Code, show me the code! +----------------------- + +By default, `pyplusplus`_ works with built-in indexing suite. If you want to use +next version of indexing suite, you should tell this to ``module_builder_t.__init__`` +method: +:: + + mb = module_builder_t( ..., indexing_suite_version=2 ) + +Every declarated class has ``indexing_suite`` property. If the class is an +instantiation of stl container, this property containes reference to an instance +of ``indexing_suite1_t`` or ``indexing_suite2_t`` class. How does `pyplusplus`_ +know that the class represents stl container instantiation? Well, it uses +``pygccxml.declarations.container_traits`` to find out this. This class, provides +all functionality needed to identify container and to find out its ``value_type`` +( ``mapped_type`` ). May I give you small tip? You can use +``pygccxml.declarations.container_traits`` class in search functionality. + + +Built-in indexing suite +----------------------- +.. + + +Indexing suite v1 +----------------- +In this case, `pyplusplus` + +Generated code +-------------- +All generated code will have next form: +:: + + class_< container, other class parameters >(name) + .def( concrete indexing suite class< container, proxy, derived policies >() ) + ; + +Usage example +------------- +C++ code: +:: + + #include <map> + #include <vector> + +:: + + std::vector<string> get_options(){...} + +:: + + struct my_data{...}; + std::map< int, my_data > get_data(); + +Assumption: user wants to use ``get_options`` and ``get_data`` functions. Next +steps will describe what `pyplusplus`_ will do in this case: + +1. `pyplusplus`_ will analyze functions return type and arguments. + +2. It will understand that ``std::vector< std::string >`` and ``std::map< int, my_data >`` + classes should be exported too. + +3. It will understand that those classes should be exported using indexing suite + functionality provided by `boost.python`_ library or `pyplusplus`_ + ``code repository``. + +4. It will generate the code, that will use that functionality. + +So far, so good. Sometimes, there are use cases, when user has to change default +values, for example ``NoProxy`` or ``DerivedPolicies``. What interface `pyplusplus`_ +will provide in order to change the defaults? Well, ``std::vector< std::string >`` +is the class that could be found in declarations tree, right? User can find the +class and change the defaults: +:: + + mb = module_builder_t( ... ) + #the next line will not work, because the real name of std::vector< std::string > + #is platform dependent and much longer. It is there for simplicity. + vector_of_strings = mb.class_( "std::vector< std::string >" ) + vector_of_strings.alias = "StringVector" + vector_of_strings.held_type = ... + vector_of_strings.indexing_suite.no_proxy = False + + +Please, pay attention to the next line: +:: + + vector_of_strings.indexing_suite.no_proxy = False + +Every class, that represents instantiation of some std container will have +class variable ``indexing_suite``, that will be intitialized with relevant +indexing suite class. + + + +.. _`pyplusplus` : ./../pyplusplus.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/std_containers/indexing_suite_v2.html =================================================================== --- pyplusplus_dev/docs/std_containers/indexing_suite_v2.html (rev 0) +++ pyplusplus_dev/docs/std_containers/indexing_suite_v2.html 2006-07-09 19:08:54 UTC (rev 287) @@ -0,0 +1,2213 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html><head> + + + <meta name="generator" content="A human being"> + <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> + <link rel="stylesheet" type="text/css" href="indexing_suite_v2_files/boost.css"><title>Boost.Python - C++ Container Support</title></head><body> + <table summary="header" border="0" cellpadding="7" cellspacing="0" width="100%"> + <tbody><tr> + <td valign="top" width="300"> + <h3> + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/index.htm"><img alt="C++ Boost" src="indexing_suite_v2_files/cboost.gif" border="0" height="86" width="277"></a> + </h3> + </td> + <td valign="top"> + <h1 align="center"> + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/index.html">Boost.Python</a><br> + C++ Container Support + </h1> + </td> + </tr> + </tbody></table> + + <hr> + + <h2> + Contents + </h2> + + <dl class="page-index"> + <dt> + <a href="#introduction">Introduction</a> + </dt> + <dt> + <a href="#design_goals">Design goals</a> + </dt> + <dt> + <a href="#interface">Interface</a> + </dt> + <dd> + <dl class="page-index"> + <dt> + <a href="#container_suite">container_suite.hpp</a> + </dt> + <dt> + <a href="#specific">Container-specific headers</a> + </dt> + <dt> + <a href="#policies">Using policies</a> + </dt> + <dt> + <a href="#visitor_flags">Visitor flag values</a> + </dt> + <dt> + <a href="#extending">Extending and customizing</a> + </dt> + <dd> + <dl class="page-index"> + <dt> + <a href="#ValueTraits">ValueTraits</a> + </dt> + <dt> + <a href="#ContainerTraits">ContainerTraits</a> + </dt> + <dt> + <a href="#Algorithms">Algorithms</a> + </dt> + <dt> + <a href="#SliceHelper">SliceHelper</a> + </dt> + </dl> + </dd> + <dt> + <a href="#extending">Container adapters</a> + </dt> + <dd> + <dl class="page-index"> + <dt> + <a href="#container_proxy">container_proxy</a> + </dt> + <dt> + <a href="#iterator_range">iterator_range</a> + </dt> + </dl> + </dd> + <dt> + <a href="#workarounds">Compiler workarounds</a> + </dt> + <dt> + <a href="#limitations">Known limitations</a> + </dt> + </dl> + </dd> + <dt> + <a href="#references">References</a> + </dt> + <dt> + <a href="#acknoweldegments">Acknowledgements and Copyright</a> + </dt> + </dl> + + <h2><a name="introduction">Introduction</a></h2> + + The purpose of the container indexing suite is to allow Python + code to access C++ containers using regular Python + interfaces. Since each C++ container is different, it is + non-trivial to decide what Python methods can be emulated, and how + to map them to C++ function calls. The indexing suite provides a + framework for representing those decisions, as well as bindings + for the standard C++ container templates. The indexing headers are + in the Boost subdirectory + <i>boost/python/suite/indexing</i> and non-template + implementations are in + <i>libs/python/src/indexing</i>. Various tests, which can also + serve as examples are in <i>libs/python/test</i>. + + <h2><a name="design_goals">Design goals</a></h2> + + The primary design goals of the container indexing suite are as + follows. The suite should: + + <ul> + <li> + + Support instances of all useful standard container templates + + </li> + <li> + + Provide as much of the normal Python interface as is + reasonable for each container + + </li> + <li> + + Be extensible to user-defined container types + + </li> + <li> + + Support client-provided <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/CallPolicies.html">CallPolicies</a> + + </li> + </ul> + + Secondary design goals are as follows. The library should: + + <ul> + <li> + + Provide an emulation of Python reference semantics for + <i>values</i> in vector-like containers. + + </li> + <li> + + Provide an emulation of container semantics for iterator + ranges. + + </li> + </ul> + + <h2><a name="interface">Interface</a></h2> + + <p> + + The main iterface to the library is via the templated class + <code>container_suite</code>, an object of which adds a number + of Python functions to an extension class via a single + <code>def</code> call. Support is provided for all of the + standard container templates <a href="#Note1">[1]</a> via + container-specific header files, as shown in the following + example: + + </p> + +<pre>#include <boost/python/suite/indexing/container_suite.hpp> +#include <boost/python/suite/indexing/vector.hpp> +#include <boost/python/class.hpp> +#include <boost/python/module.hpp> +#include <vector> + +BOOST_PYTHON_MODULE(example) { + class_< std::vector<int> > ("vector_int") + .def (indexing::container_suite< std::vector<int> >()); +} +</pre> + + <p> + + The <code>container_suite</code> object achieves this using the + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/def_visitor.html">def_visitor interface</a>, which + provides a hook for the <code>def</code> function to install + multiple Python methods in one call. If the container element + type (<code>int</code> in the example above) is a user-defined + type, you would have to expose this type to Python via a + separate <code>class_</code> instance. + + </p> + <p> + + <a name="Note1">[1]</a> Automatic operation with the standard + containers works properly if your compiler supports partial + template specializations. Otherwise, refer to the <a href="#workarounds">compiler workarounds</a> section. + + </p> + + <h2><a name="container_suite">boost/python/suite/indexing/container_suite.hpp</a></h2> + + <p> + + The <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/boost/python/suite/indexing/container_suite.hpp"><code>container_suite.hpp</code></a> + header is summarized below: + + </p> + <p> +</p><pre>#include <boost/python/suite/indexing/algo_selector.hpp> +#include <boost/python/suite/indexing/visitor.hpp> + +#include <boost/python/return_by_value.hpp> +#include <boost/python/return_value_policy.hpp> + +namespace boost { namespace python { namespace indexing { + typedef return_value_policy<return_by_value> default_container_policies; + + template<class Container, + int Flags = 0, + class Algorithms = algo_selector<Container> > + struct container_suite + : public visitor<Algorithms, default_container_policies, Flags> + { + typedef Algorithms algorithms; + + template<typename Policy> + static visitor<Algorithms, Policy, Flags> + with_policies (Policy const &policy) + { + return visitor <Algorithms, Policy> (policy); + } + }; +} } } +</pre> + <p></p> + + <p> + + Some important points to note about <code>container_suite</code>: + + </p><ol> + <li> + + It does not include any of the container-specific headers + (like <code>vector.hpp</code> or <code>set.hpp</code>), so + these must be included separately to add support each type + of container. + + </li> + <li> + + It derives from the <code>indexing::visitor</code> + template, using a <code>return_by_value</code> return + policy. This is a reasonable default, and follows the + Boost.Python idiom of passing a default-constructed object + to the <code>def</code> function. + + </li> + <li> + + The <code>with_policies</code> static function template + generates different instances of the + <code>indexing::visitor</code> template, with + client-provided policies. + + </li> + <li> + + The template parameter <code>Flags</code> allows client code + to disable unneeded features in order to reduce code + size. Details are provided <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/visitor_flags">below</a>. + + </li> + </ol> + + <p></p> + + <h2><a name="specific">Container-specific headers</a></h2> + + <p> + + The container indexing suite includes support for many of the + standard C++ container templates, but note that the support code + for each is in a separate header file. These header files (in + the <i>boost/python/suite/indexing</i> subdirectory) are: + <code>vector.hpp</code>, <code>deque.hpp</code>, + <code>list.hpp</code>, <code>set.hpp</code> and + <code>map.hpp</code>. These correspond in the obvious way to the + standard headers <code>vector</code>, <code>deque</code>, + etc. The header files for the <a href="#container_proxy"><code>container_proxy</code></a> and <a href="#iterator_range"><code>iterator_range</code></a> templates + provide their own support implicitly. + + </p> + + <h2><a name="policies">Using policies</a></h2> + + You can select call policies using the + <code>container_suite</code> static member function + <code>with_policies</code> as in the following example: + +<pre> class_< std::list<heavy_class> > ("list_heavy_class") + .def (indexing::container_suite< std::list<heavy_class> > + ::with_policies (my_policies)); +</pre> + + <h3>Caution with policies</h3> + + <p> + + It can be tempting to use <code>return_internal_reference</code> + if the container elements are expensive to copy. However, this + can be quite dangerous, since references to the elements can + easily become invalid (e.g. if the element is deleted or + moved). The Boost.Python code for + <code>return_internal_reference</code> can only manage the + lifetime of the entire container object, and not those of the + elements actually being referenced. Various alternatives exist, + the best of which is to store the container elements indirectly, + using <code>boost::shared_ptr</code> or an equivalent. If this + is not possible, + <code><a href="#container_proxy">container_proxy</a></code> + may provide a + solution, at least for vector-like containers. + + </p> + + <h3>Internal policies detail</h3> + + <p> + + The <code>container_suite</code> object typically adds more than + one function to the Python class, and not all of those functions + can, or should, use exactly the same policies. For instance, the + Python <code>len</code> method, if provided, should always + return its result by value. The library actually uses up to + three different sets of policies derived from the one provided + to the <code>with_policies</code> function. These are: + + </p><ol> + <li> + + The supplied policies, unchanged + + </li> + <li> + + The supplied precall policy only, using <code>default_call_policies</code> for result conversion. + + </li> + <li> + + The supplied precall policies, and the supplied result + conversion policies applied to <i>each element</i> of a + returned list. + + </li> + </ol> + + Roughly speaking, methods returning a single container element + use the first option, while methods returning an integer value + (or <code>void</code>) use the second option. The third option + applies only to the slice version of <code>__getitem__</code>, + which generates a Python list by applying the return conversion + policies to each element in the list. + + <p></p> + + <h2><a name="visitor_flags">Visitor Flag values</a></h2> + + <p> + + The <code>container_suite</code> template has an optional + <code>Flags</code> parameter that allows client code to disable + various optional features of the suite. This can lead to + significant savings in the size of object files and executables + if features such as sorting or Python slice support are not + needed. The <code>Flags</code> parameter (an integer) can be any + bitwise combination of the following values (defined in the + <code>boost::python::indexing</code> namespace by <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/boost/python/suite/indexing/visitor.hpp"><code>visitor.hpp</code></a>): + + </p> + + <p> + + <table border="1"> + <tbody><tr> + <th>Flag</th> + <th>Effect</th> + </tr> + <tr> + + <td><code>disable_len</code></td> + + <td>omits the Python <code>__len__</code> method</td> + + </tr> + <tr> + + <td><code>disable_slices</code></td> + + <td>omits slice support code from <code>__getitem__</code>, + <code>__setitem__</code> and <code>__delitem__</code>.</td> + + </tr> + <tr> + + <td><code>disable_search</code></td> + + <td>omits the container search methods <code>count<code>, + </code>index</code> and <code>__contains__</code></td> + + </tr> + <tr> + + <td><code>disable_reorder</code></td> + + <td>omits the container reordering operations + <code>sort</code> and <code>reverse</code></td> + + </tr> + <tr> + + <td><code>disable_extend</code></td> + + <td>omits the <code>extend</code> method</td> + + </tr> + <tr> + + <td><code>disable_insert</code></td> + + <td>omits the <code>insert</code> method</td> + + </tr> + </tbody></table> + + </p> + + <p> + + Note that some containers don't support some of the optional + features at all, in which case the relevant flags are + ignored. The value <code>minimum_support</code> may be passed as + a flag value to disable all optional features. A simple example + is provided in <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/test/test_vector_disable.cpp"><code>test_vector_disable.cpp</code></a> + + </p> + + <h2><a name="extending">Extending and customizing</a></h2> + + <p> + + The <code>container_suite</code> template relies on seven main + support templates, five of which are suitable for specialization + or replacement by client code. The following diagram shows the + templates <a href="#Note2">[2]</a> and their dependencies, with + the replaceable ones highlighted in grey. For full details, + refer to the specific section on each component – what + follows here is an overview. + + </p> + + <table align="right"> + <tbody><tr> + <td> + + <img src="indexing_suite_v2_files/overview.png" alt="Dependencies between main templates" height="261" width="486"> + + </td> + </tr> + <tr> + <td><font size="-1"> + + Diagram 1. Overview of class dependencies + + </font></td> + </tr> + </tbody></table> + + <p> + + The <code>visitor</code> template, which implements the <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/def_visitor.html">def_visitor interface</a>, decides what + Python methods to provide for a container. It takes two template + parameters, <code>Algorithms</code> and <code>Policy</code> (the + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/CallPolicies.html">CallPolicies</a> for the Python + methods on the container). The <code>Algorithms</code> argument + must provide implementations for the Python methods that the + container supports, as well as a matching + <code>ContainerTraits</code> type. This type provides various + compile-time constants that <code>visitor</code> uses to decide + what Python features the container provides. It also provides a + <code>value_traits</code> typedef, which has similar + compile-time constants related to the values stored in the + container. If the <code>visitor</code> instance decides to + provide Python slice support for the container, it instantiates + the <code>slice_handler</code> template, which also takes + <code>Algorithms</code> and <code>Policy</code> parameters. In + such cases, the <code>Algorithms</code> argument must supply a + <code>SliceHelper</code> type and factory function. + + </p> + <p> + + The high-level <code>container_suite</code> template uses the + <code>algo_selector</code> template to determine what types to + use in the instantiation of <code>visitor</code>. The + <code>algo_selector</code> template has partial specializations + for all of the STL container templates. + + </p> + + <p> + + <a name="Note2">[2]</a> Note that <code>Algorithms</code> and + <code>ContainerTraits</code> don't represent individual + templates in the diagram, but <i>groups</i> of related + templates. For instance, there are actually templates called + <code>list_algorithms</code> and <code>assoc_algorithms</code>, + among others. + + </p> + + + <h2><a name="ValueTraits">ValueTraits</a></h2> + + <p> + + A <code>ValueTraits</code> class provides simple information + about the type of value stored within a container that will be + exposed to Python via the <code>container_suite</code> + interface. It controls the provision of some operations that are + dependant on the operations supported by container elements (for + instance, <code>find</code> requires a comparison operator for + the elements). A <code>ValueTraits</code> class also provides a + hook called during initialization of the Python class, which can + be used for custom processing at this point. + + </p> + <p> + + The following table lists the static constants required in a + <code>ValueTraits</code> class: + + </p> + + <p> + <table border="1"> + <tbody><tr> + <th align="left"> + Static constant + </th> + <th align="center"> + Type + </th> + <th align="left"> + Meaning + </th> + </tr> + + <tr> + <td> + <code>equality_comparable</code> + </td> + <td> + bool + </td> + <td> + + Whether the value supports comparison via + <code>operator==</code>. + + </td> + </tr> + + <tr> + <td> + <code>lessthan_comparable</code> + </td> + <td> + bool + </td> + <td> + + Whether the value supports comparison via + <code>operator<</code>. + + </td> + </tr> + + </tbody></table> + </p> + + <p> + + A <code>ValueTraits</code> class should provide the following + member function template, which will be called during execution + of the <code>def</code> call for the container suite: + + </p> + + <p> + +</p><pre>template <typename PythonClass, typename Policy> +static void visitor_helper (PythonClass &, Policy const &); +</pre> + + <p></p> + + <h3>Usage notes for ValueTraits</h3> + + <p> + + In order to include a custom <code>ValueTraits</code> class into + the container suite, it is easiest to supply it as a + specialization of the template + <code>indexing::value_traits</code> for the container's element + type. The existing <code>ContainerTraits</code> classes all + make use of + <code>value_traits<container::value_type></code>, and so + will use a specialization for the value type if available. The + default, unspecialized, version of <code>value_traits</code> + sets both of the static constants to <code>true</code> and has + an empty implementation of <code>visitor_helper</code>. + + </p> + <p> + + As an example, if a user defined type does not have any + comparison operations, then there will probably be compile-time + errors caused by an attempt to provide the Python + <code>find</code> or <code>sort</code> methods. The solution is + to write a specialized version of + <code>indexing::value_traits</code> that disables the + appropriate features. For example: + + </p> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<> + struct value_traits<my_type> : public value_traits<int> + { + static bool const equality_comparable = false; + static bool const lessthan_comparable = false; + }; +} } } +</pre> + <p></p> + + <p> + + In this example, there is no need to perform any processing in + the <code>visitor_helper</code> function, and deriving from an + unspecialized version of the template (e.g. + <code>value_traits<int></code>) exposes an empty + <code>visitor_helper</code>. + + </p> + + <h3>Synopsis: boost/python/suite/indexing/value_traits.hpp</h3> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<typename T> + struct value_traits { + static bool const equality_comparable = true; + static bool const lessthan_comparable = true; + + template<typename PythonClass, typename Policy> + static void visitor_helper (PythonClass &, Policy const &) + { } + }; +} } } +</pre> + <p></p> + + <h2><a name="ContainerTraits">ContainerTraits</a></h2> + + <p> + + A <code>ContainerTraits</code> class serves three + purposes. Firstly, it identifies what facilities the container + supports in principle (i.e. either directly or via some support + code). Secondly, it identifies the types used to pass values + into and out of the supported operations. Thirdly, it provides a + hook for additional code to run during initialization of the + Python class (i.e. during the <code>def</code> call for the + suite). + + </p> + <p> + + Note that a <code>ContainerTraits</code> class can be any class, + derived from the existing implementations or not, as long as it + meets the requirements listed in the following sections. + + </p> + + <h3>Static constants for ContainerTraits</h3> + + The following table lists the static constants that a + <code>ContainerTraits</code> class should define. Note that these + must be <i>compile-time constants</i>, since parts of the library + use these constants to select between template specializations. + The constants must at least be convertible to the type shown in + the second column. + + <p> + <table border="1"> + <tbody><tr> + <th align="left"> + Static constant + </th> + <th align="center"> + Type + </th> + <th align="left"> + Meaning + </th> + <th align="left"> + Influence + </th> + </tr> + <tr> + <td> + <code>has_copyable_iter</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether copies of an iterator are independant <a href="#Note3">[3]</a> + + </td> + <td> + + Required for <code>len</code> and <code>__iter__</code> + + </td> + </tr> + + <tr> + <td> + <code>is_reorderable</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether it is possible to re-order the contents of the + container. + + </td> + <td> + + Required for <code>reverse</code> and <code>sort</code> + + </td> + </tr> + + <tr> + <td> + <code>has_mutable_ref</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + Whether container elements can be altered via a reference + </td> + <td> + Determines <code>is_reorderable</code> for most containers. + </td> + </tr> + + <tr> + <td> + <code>has_find</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether find is possible in principle (via member function + or otherwise) + + </td> + <td> + <code>__contains__</code>, + <code>index</code>, + <code>count</code>, + <code>has_key</code> + </td> + </tr> + + <tr> + <td> + <code>has_insert</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether it is possible to insert new elements into the container. + + </td> + <td> + <code>insert</code>, + <code>extend</code>, + slice version of <code>__setitem__</code> + </td> + </tr> + + <tr> + <td> + <code>has_erase</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether it is possible to erase elements from the container. + + </td> + <td> + <code>__delitem__</code>, + slice version of <code>__setitem__</code> + </td> + </tr> + + <tr> + <td> + <code>has_push_back</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether container supports insertion at the end. + + </td> + <td> + <code>append</code> + </td> + </tr> + + <tr> + <td> + <code>has_pop_back</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether container supports element deletion at the end. + + </td> + <td> + Currently unused + </td> + </tr> + + <tr> + <td> + <code>index_style</code> + </td> + <td align="center"> + <code>index_style_t</code> + </td> + <td> + + Type of indexing the container supports <a href="#Note4">[4]</a> + + </td> + <td> + <code>__getitem__</code>, + <code>__setitem__</code>, + <code>__delitem__</code>, + <code>__iter__</code>, + <code>extend</code>, + <code>index</code>, + <code>count</code>, + <code>has_key</code> + </td> + </tr> + </tbody></table> + </p> + + <p> + </p><h3>Notes</h3> + + <table> + <tbody><tr> + <td valign="top"> + <a name="Note3">[3]</a> + </td> + <td> + + For example, copies of stream iterators are <i>not</i> + independant. All iterator copies refer to the same stream, + which has only one read and one write position. + + </td> + </tr> + + <tr> + <td valign="top"> + <a name="Note4">[4]</a> + </td> + <td> + + <code>index_style_none</code>, no indexing at all + (e.g. <code>list</code>)<br> + + <code>index_style_linear</code>, continuous integer-like + index type (e.g. <code>vector</code>)<br> + + <code>index_style_nonlinear</code>, indexing via other + types (e.g. <code>map</code>). + + </td> + </tr> + </tbody></table> + + <p></p> + + <h3>Member types for ContainerTraits</h3> + + <p> + + The following table lists the type names that must be defined in + a compatible implementation of <code>ContainerTraits</code>. + The large number of types is supposed to provide flexibility for + containers with differing interfaces. For example, + <code>map</code> uses the same type for searching and "indexing" + (i.e. <code>find</code> and <code>operator[]</code>) so + <code>key_type</code> and <code>index_type</code> would have to + be the same. In contrast, searching a <code>vector</code> would + typically use a different type to that used for indexing into a + vector. + + </p> + + <p> + <table border="1"> + <tbody><tr> + <th align="left"> + Type name + </th> + <th align="left"> + Meaning + </th> + </tr> + + <tr> + <td> + <code>container</code> + </td> + <td> + The type of the C++ container. + </td> + </tr> + + <tr> + <td> + <code>size_type</code> + </td> + <td> + + The type used to represent the number of elements in the + container. + + </td> + </tr> + + <tr> + <td> + <code>iterator</code> + </td> + <td> + + The container's iterator type. This should be a non-const + iterator unless the container itself is const. + + </td> + </tr> + + <tr> + <td> + <code>index_type</code> + </td> + <td> + + The type used to represent indexes extracted from a + <code>__getitem__</code> call (and others). For + <code>index_style_linear</code>, this <i>should be a + signed type</i>, so that negative indices can be + processed. For <code>index_style_nonlinear</code>, this + will most likely be the same type as + <code>key_type</code>. + + </td> + </tr> + + <tr> + <td> + <code>index_param</code> + </td> + <td> + + The type to use when passing <code>index_type</code> into + a function. + + </td> + </tr> + + <tr> + <td> + <code>value_type</code> + </td> + <td> + + The type to use when copying a value into or out of the + container. + + </td> + </tr> + + <tr> + <td> + <code>value_param</code> + </td> + <td> + + The type to use when passing <code>value_type</code> into + a function. + + </td> + </tr> + + <tr> + <td> + <code>key_type</code> + </td> + <td> + + The type used for search operations like <code>find</code> + and <code>count</code>. + + </td> + </tr> + + <tr> + <td> + <code>key_param</code> + </td> + <td> + + The type to use when passing <code>key_type</code> into a + function. + + </td> + </tr> + + <tr> + <td> + <code>reference</code> + </td> + <td> + + The type to use when returning a reference to a container + element. + + </td> + </tr> + + <tr> + <td> + <code>value_traits_</code> + </td> + <td> + + Traits for the container elements. See <a href="#ValueTraits">the ValueTraits section</a> for + information about the requirements on this type. + + </td> + </tr> + + </tbody></table> + + </p> + + <h3>Member functions for ContainerTraits</h3> + + In order to support additional initialization code to run, a + <code>ContainerTraits</code> class should provide a static member + function template as follows: + + <p> +</p><pre>template <typename PythonClass, typename Policy> +static void visitor_helper (PythonClass &, Policy const &); +</pre> + <p></p> + + <p> + + Typically, the implementation would just forward the call to the + equivalent function in the <code>value_traits_</code> class. + + </p> + + <h3>Usage notes for ContainerTraits</h3> + + <p> + + It may be possible to mix your own <code>ContainerTraits</code> + class with one of the existing <code>Algorithms</code> + implementations, thus saving yourself a fair bit of work. The + easiest way to do this would be to specialize the + <code>algo_selector</code> template for your container type, + using public deriviation to get the implementation from one of + the existing <code>Algorithms</code> templates. For example, + assuming that <code>default_algorithms</code> is suitable for + your container: + + </p> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<> + struct algo_selector<my_container> + : public default_algorithms<my_container_traits> + { + }; +} } } +</pre> + <p></p> + <p> + + Alternatively, you could select the algorithms and traits using + the <code>visitor</code> template directly, as described in the + <a href="#workarounds">compiler workarounds</a> section. + + </p> + + <h3><a name="simple_ctraits">Simplistic ContainerTraits example</a></h3> + + <p> + + The following block of code shows a simplistic implementation of + <code>ContainerTraits</code> for the container + <code>std::map<std::string, int></code>. The actual + implementation used by the suite relies on template + metaprogramming techniques, whereas this example is designed to + show only the essential elements of a + <code>ContainerTraits</code> implementation. + + </p> + + <p> +</p><pre>#include <map> +#include <string> +#include <boost/python/suite/indexing/suite_utils.hpp> +// Include suite_utils to get index_style_t + +struct simple_map_traits { + // Traits information for std::map<std::string, int> + + typedef std::map<std::string, int> container; + typedef container::size_type size_type; + typedef container::iterator iterator; + + typedef int value_type; + typedef int & reference; + typedef std::string key_type; + typedef std::string index_type; + + typedef int value_param; + typedef std::string const & key_param; + typedef std::string const & index_param; + + static bool const has_copyable_iter = true; + static bool const has_mutable_ref = true; + static bool const has_find = true; + static bool const has_insert = true; + static bool const has_erase = true; + static bool const has_pop_back = false; + static bool const has_push_back = false; + static bool const is_reorderable = false; + + static boost::python::indexing::index_style_t const index_style + = boost::python::indexing::index_style_nonlinear; + + struct value_traits_ { + // Traits information for our value_type + static bool const equality_comparable = true; + static bool const lessthan_comparable = true; + }; + + template<typename PythonClass, typename Policy> + static void visitor_helper (PythonClass &, Policy const &) + { + // Empty + } +}; +</pre> + <p></p> + + <p> + + Example usage of the <code>simple_map_traits</code>: + + </p> + + <p> +</p><pre>#include "simple_map_traits.hpp" + +#include <boost/python/suite/indexing/container_suite.hpp> + +#include <boost/python/module.hpp> +#include <boost/python/class.hpp> + +BOOST_PYTHON_MODULE(test_simple) { + using namespace boost::python; + + typedef std::map<std::string, int> container_t; + typedef indexing::map_algorithms<simple_map_traits> algorithms_t; + + class_<container_t> ("map") + .def (indexing::container_suite<container_t, algorithms_t>()); +} +</pre> + <p></p> + + <h2><a name="Algorithms">Algorithms</a></h2> + + <p> + + The <code>Algorithms</code> requirements are designed to provide + a predictable interface to any container, so that the same + <code>visitor</code> code can expose any supported container to + Python. An implemention of <code>Algorithms</code> does this by + providing functions and typedefs with fixed names. The exact + interfaces to the functions can vary to some extent, since the + <code>def</code> function calls used internally by the + <code>visitor</code> deduce the function type + automatically. However, certain points should be confomed to: + + </p><ol> + <li> + + The functions should be static, with + <code>container &</code> as first parameter. + + </li> + + <li> + + The functions should <i>not</i> be overloaded – this + avoids problems with type deduction. + + </li> + <li> + + Generally, not all of the possible functions need to be + implemented, dependant on the static constants in the + <code>ContainerTraits</code>. + + </li> + </ol> + + <p></p> + + <p> + + The block of code below shows the definition of the + <code>default_algorithms</code> class template, which is the + basis for all current implementations of + <code>Algorithms</code>. The typedefs that it defines are + primarily for convenience within the implementation itself, + however <code>container</code>, <code>reference</code> and + <code>slice_helper</code> are also required by the + <code>slice_handler</code> template, if slices are + supported. Note that <code>default_algorithms</code> derives all + of the type information from its <code>ContainerTraits</code> + template argument, which allows the same implementation to be + used for various container types. + + </p> + + <h3>Partial boost/python/suite/indexing/algorithms.hpp</h3> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<typename ContainerTraits, typename Ovr = detail::no_override> + class default_algorithms + { + typedef default_algorithms<ContainerTraits, Ovr> self_type; + + public: + typedef ContainerTraits container_traits; + + typedef typename ContainerTraits::container container; + typedef typename ContainerTraits::iterator iterator; + typedef typename ContainerTraits::reference reference; + typedef typename ContainerTraits::size_type size_type; + typedef typename ContainerTraits::value_type value_type; + typedef typename ContainerTraits::value_param value_param; + typedef typename ContainerTraits::index_param index_param; + typedef typename ContainerTraits::key_param key_param; + + typedef int_slice_helper<self_type, integer_slice> slice_helper; + + static size_type size (container &); + static iterator find (container &, key_param); + static size_type get_index (container &, key_param); + static size_type count (container &, key_param); + static bool contains (container &, key_param); + static void reverse (container &); + static reference get (container &, index_param); + static void assign (container &, index_param, value_param); + static void insert (container &, index_param, value_param); + static void erase_one (container &, index_param); + static void erase_range(container &, index_param, index_param); + static void push_back (container &, value_param); + static void sort (container &); + + static slice_helper make_slice_helper (container &c, slice const &); + + template<typename PythonClass, typename Policy> + static void visitor_helper (PythonClass &, Policy const &); + }; +} } } +</pre> + <p></p> + + <h3>Slice support</h3> + <p> + + For containers that support Python slices, the + <code>visitor</code> template will instantiate and use + internally the <code>slice_handler</code> template. This + template requires a type called <code>slice_helper</code> and a + factory function called <code>make_slice_helper</code> from its + <code>Algorithms</code> argument. More details are provided in + the section <a href="#SliceHelper">SliceHelper</a>. + + </p> + + <h3>Usage notes for Algorithms</h3> + + <p> + + The existing <code>indexing::algo_selector</code> template uses + partial specializations and public derivation to select an + <code>Algorithms</code> implementation suitable for any of the + standard container types. Exactly how it does this should be + considered an implementation detail, and uses some tricks to + reuse various existing <code>Algorithms</code> + implementations. In any case, client code can specialize the + <code>algo_selector</code> template for new container types, as + long as the specialized instances conform to the requirements + for <code>Algorithms</code> as already given. + + </p> + <p> + + A new implementation of <code>Algorithms</code> could derive + from any one of the existing implementation templates, or be + completely independant. The existing implementation templates + are listed in the following table. They each take one template + parameter, which should be a valid <code>ContainerTraits</code> + class, as specified in a <a href="#ContainerTraits">previous + section</a>. + + </p> + + <p> + <table border="1"> + <tbody><tr> + <th> + Template name + </th> + <th> + Description + </th> + </tr> + + <tr> + <td> + + <code>default_algorithms</code> + + </td> + <td> + + Uses standard iterator-based algorithms wherever + possible. Assumes that the container provides + <code>begin</code> and end <code>end</code> member + functions that return iterators, and some or all of + <code>size</code>, <code>insert</code>, <code>erase</code> + and <code>push_back</code>, depending on what functions get + instantiated. + + </td> + </tr> + + <tr> + <td> + + <code>list_algorithms</code> + + </td> + <td> + + Similar to the above (in fact, it derives from + <code>default_algorithms</code>) except that it uses + container member functions <code>reverse</code> and + <code>sort</code> instead of the iterator-based + versions. Defined in + <code>boost/python/suite/indexing/list.hpp</code>. + + </td> + </tr> + + <tr> + <td> + + <code>assoc_algorithms</code> + + </td> + <td> + + Also derived from <code>default_algorithms</code>, for use + with associative containers. Uses the container member + function <code>find</code> for indexing, and member + function <code>count</code> instead of iterator-based + implementations. + + </td> + </tr> + + <tr> + <td> + + <code>set_algorithms</code> + + </td> + <td> + + Derived from <code>assoc_algorithms</code> to handle + <code>set</code> insertion operations, which are slightly + different to the <code>map</code> versions. + + </td> + </tr> + + <tr> + <td> + + <code>map_algorithms</code> + + </td> + <td> + + Derived from <code>assoc_algorithms</code> to handle + <code>map</code> insertion and lookup, which are slightly + different to the <code>set</code> versions. + + </td> + </tr> + </tbody></table> + + </p> + <p> + + The <code>default_algorithms</code> template attempts to place + as few restrictions as possible on the container type, by using + iterators and standard algorithms in most of its functions. It + accepts an optional second template parameter, which can be used + via the curiously recurring template idiom to replace any of its + functions that it relies on internally. For instance, if you've + created an iterator-style interface to a container that is not + at all STL-like (let's call it <code>weird_container</code>), + you might be able to re-use most of + <code>default_algorithms</code> by replacing its basic functions + like this: + + </p> + <p> +</p><pre>namespace indexing = boost::python::indexing; + +struct my_algorithms + : public indexing::default_algorithms < + weird_container_traits, my_algorithms + > +{ + size_t size (weird_container const &c) { + return ...; + } + + my_iterator_t begin (weird_container &c) { + return ...; + } + + my_iterator_t end (weird_container &c) { + return ...; + } +}; +</pre> + <p></p> + + <h2><a name="SliceHelper">SliceHelper</a></h2> + + <p> + + Support code for Python slices is split into two portions, the + <code>slice_handler</code> template, and a "slice helper" that + can easily be replaced by client code via a typedef and factory + function in the <code>Algorithms</code> argument supplied to + <code>container_suite</code>. The slice helper object takes care + of reading and writing elements from a slice in a C++ container, + and optionally insertion and deletion. Effectively, the slice + helper object maintains a pointer to the current element of the + slice within the container, and provides a <code>next</code> + function to advance to the next element of the slice. The + container suite uses the following interface for slices: + + </p> + <p> + <table border="1"> + <tbody><tr> + <th> + + Expression + + </th> + <th> + + Return type + + </th> + <th> + + Notes + + </th> + </tr> + <tr> + <td> + + <code>Algorithms::</code> <code>make_slice_helper</code> + <code>(c, s)</code> + + </td> + <td> + + <code>Algorithms::</code> <code>slice_helper</code> + + </td> + <td> + + <code>c</code> is of type + <code>Algorithms::</code> <code>container &</code> and + <code>s</code> is of type <code>indexing::</code> + <code>slice const &</code>. + Returns a newly constructed <code>slice_helper</code> + object by value. + + </td> + </tr> + + <tr> + <td> + + <code>slice_helper.</code><code>next()</code> + + </td> + <td> + + <code>bool</code> + + </td> + <td> + + Advances the slice helper's current element pointer to the + next element of the slice. Returns true if such an element + exists, and false otherwise. The first time this function + is called, it should set the current pointer to the first + element of the slice (if any). + + </td> + </tr> + + <tr> + <td> + + <code>slice_helper.</code> <code>current()</code> + + </td> + <td> + + <code>Algorithms::</code> <code>reference</code> + + </td> + <td> + + Returns a reference to the current element of the + slice. This will only be called if the last call to + <code>next()</code> returned true. + + </td> + </tr> + <tr> + <td> + + <code>slice_helper.</code><code>write (v)</code> + + </td> + <td> + + <code>void</code> + + </td> + <td> + + The parameter <code>v</code> is of type + <code>Algorthims::value_param</code>. Advances to the + next element of the slice, as defined in + <code>next</code>, and writes the given value + <code>v</code> at the new location in the container.If the + slice is exhausted (i.e. <code>next</code> would return + false) then <code>write</code> <i>either</i> inserts the + value into the container at the next location (past the + end of the slice), <i>or</i> sets a Python exception and + throws. + + </td> + </tr> + <tr> + <td> + + <code>slice_helper.</code> <code>erase_remaining()</code> + + </td> + <td> + + <code>void</code> + + </td> + <td> + + <i>Either</i> erases any remaining elements in the slice + not already consumed by calls to <code>next</code> or + <code>write</code>, + <i>or</i> sets a Python exception and throws. + + </td> + </tr> + </tbody></table> + </p> + + <p> + + The container suite provides a generic implementation of the + <code>SliceHelper</code> requirements for containers that have + integer-like indexes. It is parameterized with a + <code>SliceType</code> parameter that allows the integer index + values to come from various different sources, the default being + the <code>PySlice_GetIndices</code> function. Refer to the + header file <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/boost/python/suite/indexing/int_slice_helper.hpp"><code>int_slice_helper.hpp</code></a> + and the references to it in the <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/boost/python/suite/indexing/algorithms.hpp"><code>algorithms.hpp</code></a> + header for details. + + </p> + + <h2><a name="container_proxy">container_proxy</a></h2> + + <p> + + The <code>container_proxy</code> template provides an emulation + of Python reference semantics for objects held by value in a + vector-like container. Of course, this introduces some + performance penalties in terms of memory usage and run time, so + the primary application of this template is in situations where + all of the following apply: + + </p><ol> + <li> + + It is not practical to switch to a container of shared + pointers + + </li> + <li> + + Python code requires reference semantics for the objects + within the container + + </li> + <li> + + Element insertion, deletion or assignment takes place, so + that using <code>return_internal_reference</code> would be + dangerous. + + </li> + </ol> + + <p></p> + + <p> + + + The <code>container_proxy</code> template wraps any vector-like + container and presents an interface that is similar to that of + <code>std::vector</code>, but which returns + <code>element_proxy</code> objects instead of plain references + to values stored in the wrapped container. During an operation + that alters the position of an element within the container + (e.g. <code>insert</code>) the <code>container_proxy</code> code + updates the relevant proxy objects, so that they still refer to + the <i>same</i> elements at their new locations. Any operation + that would delete or overwrite a value in the container + (e.g. <code>erase</code>) copies the to-be-deleted value into + its corresponding proxy object. This means that a proxy's + "reference" to an element is robust in the face of changes to + the ele... [truncated message content] |
From: <rom...@us...> - 2006-07-13 08:29:31
|
Revision: 305 Author: roman_yakovenko Date: 2006-07-13 01:27:50 -0700 (Thu, 13 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=305&view=rev Log Message: ----------- adding FAQs documentation to py++ Added Paths: ----------- pyplusplus_dev/docs/faqs/ pyplusplus_dev/docs/faqs/faqs.rest pyplusplus_dev/docs/faqs/www_configuration.py Added: pyplusplus_dev/docs/faqs/faqs.rest =================================================================== --- pyplusplus_dev/docs/faqs/faqs.rest (rev 0) +++ pyplusplus_dev/docs/faqs/faqs.rest 2006-07-13 08:27:50 UTC (rev 305) @@ -0,0 +1,73 @@ +====================== +C++ containers support +====================== + +.. contents:: Table of contents + +---------------------------------------- +How to add custom exception translation? +---------------------------------------- +:: + + struct my_exception{ + ... + const std::string& error() const; + ... + } + +Generate exception translation function. +---------------------------------------- + +First of all you have to generate a header file, that will contain exception +translation function: +:: + + void translate(const my_exception &exception){ + PyErr_SetString( PyExc_RuntimeError, exception.error().c_str() ); + } + +Register exception translation function. +---------------------------------------- + +:: + + from pyplusplus import code_creators + +:: + + mb.build_code_creator( ... ) + mb.code_creator.add_include( generated header file name ) + +:: + + code = "boost::python::register_exception_translator<my_exception>(&translate);" + my_exc_translator = code_creators.custom_text_t( code ) + mb.code_creator.body.adopt_creator( my_exc_translator ) + +Small usage advice. +------------------- + +`pyplusplus`_ allows you to define a query that will return you all exception classes: + +:: + + mb = module_builder_t( ... ) + exception_classes = mb.decls( lambda decl: decl.name.endswith( 'exception' ) ) + +Now you can iterate on ``exception_classes``, generate and register translate +code for every class. + +That's all. + +.. _`pyplusplus` : ./../pyplusplus.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/faqs/www_configuration.py =================================================================== --- pyplusplus_dev/docs/faqs/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/faqs/www_configuration.py 2006-07-13 08:27:50 UTC (rev 305) @@ -0,0 +1 @@ +name = 'FAQs' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-17 19:37:31
|
Revision: 309 Author: roman_yakovenko Date: 2006-07-17 12:37:17 -0700 (Mon, 17 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=309&view=rev Log Message: ----------- adding documentation to generated code Modified Paths: -------------- pyplusplus_dev/docs/pyplusplus.rest pyplusplus_dev/pyplusplus/module_builder/builder.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/fundamental_tester_base.py Added Paths: ----------- pyplusplus_dev/contrib/doc_extractors/ pyplusplus_dev/contrib/doc_extractors/doxygen.py pyplusplus_dev/contrib/doc_extractors/readme.txt Added: pyplusplus_dev/contrib/doc_extractors/doxygen.py =================================================================== --- pyplusplus_dev/contrib/doc_extractors/doxygen.py (rev 0) +++ pyplusplus_dev/contrib/doc_extractors/doxygen.py 2006-07-17 19:37:17 UTC (rev 309) @@ -0,0 +1,112 @@ +""" +extracting from C++ doxygen documented file +Author G.D. +""" + +class doc_extractor: + """ + extracts doxigen styled documentation from source + or generates from description + """ + def __init__(self): + #for caching source + self.file_name = None + self.source = None + + def __call__(self, declaration): + try: + if self.file_name != declaration.location.file_name: + self.file_name = declaration.location.file_name + self.source = open(declaration.location.file_name).readlines() + + find_block_end = False + doc_lines = [] + for lcount in xrange(declaration.location.line - 1, -1, -1): + line = source[lcount] + if not find_block_end: + try: + if line.rstrip()[-2:] == "*/": + find_block_end = True + except: + pass + if find_block_end: + try: + if line.lstrip()[:2] == "/*": + find_block_end = False + except: + pass + final_str = clear_str(line) + if not find_block_end and code(line): + break + if final_str: + doc_lines.insert(0, final_str) + + if doc_lines: + doc_lines.insert(0, self.get_generic_doc()) + return ''.join(doc_lines) + + except: + pass + + return self.get_generic_doc(declaration) + + def get_generic_doc(self, declaration): + """ + generate call information about function or method + """ + try: + return "Help on %s\n" % str(declaration) + except: + pass + + return '' + + +def clear_str(str): + """ + replace */! by Space and \breaf, \fn, \param, ... + """ + clean = lambda str, sym, change2 = '': str.replace(sym, change2) + + str = reduce(clean, [str, '/', '*', '!', "\brief", "\fn",\ + "@brief", "@fn", "@ref", "\ref"]) + + str = clean(str, "@param", "Param: ") + str = clean(str, "\param", "Param: ") + str = clean(str, "@ingroup", "Group") + str = clean(str, "\ingroup", "Group") + str = clean(str, "@return", "It return") + str = clean(str, "\return", "It return") + return " " + str.lstrip() + + +def code(str): + """ + detect str is code? + """ + try: + beg = str.lstrip()[:2] + return beg != "//" and beg != "/*" + except: + pass + return False + +if __name__ == '__main__': + class loc: + def __init__(self, f, l): + self.file_name = f + self.line = l + + class x_decl: + def __init__(self, str, file_name, line): + self.str = str + self.location = loc(file_name, line) + + def __str__(self): + return self.str + + print doc_extractor()(x_decl("myfunc(int x, int y)","core.h",45)) + print doc_extractor()(x_decl("","core.h",209)) + + + Added: pyplusplus_dev/contrib/doc_extractors/readme.txt =================================================================== --- pyplusplus_dev/contrib/doc_extractors/readme.txt (rev 0) +++ pyplusplus_dev/contrib/doc_extractors/readme.txt 2006-07-17 19:37:17 UTC (rev 309) @@ -0,0 +1,19 @@ +Content: + This directory contains functionality that extracts documentation string +from C++ source files. + +How to integrate the functionality with pyplusplus? + + mb = module_builder_t( ... ) + mb.build_code_creator( ..., doc_extractor=my_doc_extractor ) + +What is "my_doc_extractor"? Well, "my_doc_extractor" is callable object, +that takes only one argument - declaration reference and returns documentation +string. Something like this: + +def my_doc_extractor( decl ): + return decl.location.file_name + str( decl.location.line ) + +Yes, every declaration contains next information: + 1. Full path to file it was defined in. + 2. Line number. Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/docs/pyplusplus.rest 2006-07-17 19:37:17 UTC (rev 309) @@ -175,6 +175,9 @@ * user license is written at the top of every file + * extracting documentation from source files and integrating it with generated + source code + * ... ------- Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-17 19:37:17 UTC (rev 309) @@ -173,7 +173,8 @@ , call_policies_resolver_=None , types_db=None , target_configuration=None - , enable_indexing_suite=True): + , enable_indexing_suite=True + , doc_extractor=None): """ Creates L{module_t} code creator. @@ -187,6 +188,10 @@ @param call_policies_resolver_: callable, that will be invoked on every calldef object. It should return call policies. @type call_policies_resolver_: callable + + @param doc_extractor: callable, that takes as argument reference to declaration + and returns documentation string + @type doc_extractor: callable or None """ creator = mcreator_package.creator_t( self.global_ns , module_name @@ -195,7 +200,8 @@ , call_policies_resolver_ , types_db , target_configuration - , enable_indexing_suite) + , enable_indexing_suite + , doc_extractor) self.__code_creator = creator.create() #I think I should ask users, what they expect #self.__code_creator.user_defined_directories.append( self.__working_dir ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-07-17 19:37:17 UTC (rev 309) @@ -3,14 +3,15 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +import time +import types_database +import class_organizer +import call_policies_resolver from pygccxml import declarations +from pyplusplus import decl_wrappers from pyplusplus import code_creators -import class_organizer -import call_policies_resolver -import types_database from pyplusplus import code_repository -from sets import Set as set -from pyplusplus import decl_wrappers +from pyplusplus import _logging_ ACCESS_TYPES = declarations.ACCESS_TYPES VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES @@ -67,7 +68,8 @@ , call_policies_resolver_=None , types_db=None , target_configuration=None - , enable_indexing_suite=True): + , enable_indexing_suite=True + , doc_extractor=None): """Constructor. @param decls: Declarations that should be exposed in the final module. @@ -77,6 +79,7 @@ @param call_policies_resolver_: Callable that takes one declaration (calldef_t) as input and returns a call policy object which should be used for this declaration. @param types_db: ...todo... @param target_configuration: A target configuration object can be used to customize the generated source code to a particular compiler or a particular version of Boost.Python. + @param doc_extractor: callable, that takes as argument declaration reference and returns documentation string @type decls: list of declaration_t @type module_name: str @type boost_python_ns_name: str @@ -84,9 +87,11 @@ @type call_policies_resolver_: callable @type types_db: L{types_database_t<types_database.types_database_t>} @type target_configuration: L{target_configuration_t<code_creators.target_configuration_t>} + @type doc_extractor: callable """ declarations.decl_visitor_t.__init__(self) - + self.logger = _logging_.loggers.module_builder + self.__enable_indexing_suite = enable_indexing_suite self.__target_configuration = target_configuration if not self.__target_configuration: @@ -113,22 +118,32 @@ self.__module_body = code_creators.module_body_t( name=module_name ) self.__extmodule.adopt_creator( self.__module_body ) - decls = declarations.make_flatten( decls ) - self.__decls = self._filter_decls( self._reorder_decls( self._prepare_decls( decls ) ) ) + prepared_decls = self._prepare_decls( decls, doc_extractor ) + self.__decls = self._filter_decls( self._reorder_decls( prepared_decls ) ) self.curr_code_creator = self.__module_body self.curr_decl = None self.__cr_array_1_included = False self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] - - def _prepare_decls( self, decls ): + + def _prepare_decls( self, decls, doc_extractor ): + decls = declarations.make_flatten( decls ) #leave only declarations defined under namespace, but remove namespaces decls = filter( lambda x: not isinstance( x, declarations.namespace_t ) \ and isinstance( x.parent, declarations.namespace_t ) , decls ) #leave only decls that should be exported decls = filter( lambda x: not x.ignore, decls ) + if doc_extractor: + start_time = time.clock() + self.logger.debug( 'Documentation extraction process started.' ) + + for decl in decls: + decl.documentation = doc_extractor( decl ) + + self.logger.debug( 'Documentation extraction process finished in %F seconds' + % ( time.clock() - start_time ) ) return decls def _reorder_decls(self, decls ): Modified: pyplusplus_dev/unittests/fundamental_tester_base.py =================================================================== --- pyplusplus_dev/unittests/fundamental_tester_base.py 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/unittests/fundamental_tester_base.py 2006-07-17 19:37:17 UTC (rev 309) @@ -60,8 +60,9 @@ for decl in mb.decls(): decl.documentation = '"documentation"' self.customize( mb ) + doc_extractor = lambda decl: decl.documentation if not mb.has_code_creator(): - mb.build_code_creator( self.__module_name ) + mb.build_code_creator( self.__module_name, doc_extractor=doc_extractor ) mb.code_creator.std_directories.extend( autoconfig.scons_config.cpppath ) mb.code_creator.user_defined_directories.append( autoconfig.data_directory ) mb.code_creator.precompiled_header = "boost/python.hpp" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-20 05:04:33
|
Revision: 318 Author: roman_yakovenko Date: 2006-07-19 22:04:20 -0700 (Wed, 19 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=318&view=rev Log Message: ----------- moving indexing suite under documentation directory Added Paths: ----------- pyplusplus_dev/docs/documentation/ pyplusplus_dev/docs/documentation/containers.rest pyplusplus_dev/docs/documentation/index.rest pyplusplus_dev/docs/documentation/indexing_suite_v2.html pyplusplus_dev/docs/documentation/indexing_suite_v2_files/ pyplusplus_dev/docs/documentation/indexing_suite_v2_files/boost.css pyplusplus_dev/docs/documentation/indexing_suite_v2_files/cboost.gif pyplusplus_dev/docs/documentation/indexing_suite_v2_files/www_configuration.py pyplusplus_dev/docs/documentation/www_configuration.py Added: pyplusplus_dev/docs/documentation/containers.rest =================================================================== --- pyplusplus_dev/docs/documentation/containers.rest (rev 0) +++ pyplusplus_dev/docs/documentation/containers.rest 2006-07-20 05:04:20 UTC (rev 318) @@ -0,0 +1,202 @@ +====================== +C++ containers support +====================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +C++ has a bunch of container classes: + + * list + * deque + * queue + * priority_queue + * vector + * stack + * map + * multimap + * hash_map + * hash_multimap + * set + * hash_set + * multiset + * hash_multiset + +It is not a trivial task to expose C++ container to Python. Boost.Python has +a functionality that will help you to expose some of STL containers to `Python`_. +This functionality called - "indexing suite". If you want, you can read more +about indexing suite `here`__. + +.. __ : http://boost.org/libs/python/doc/v2/indexing.html + +Boost.Python, out of the box, supports only ``vector``, ``map`` and ``hash_map`` +containers. In October 2003, Raoul Gough implemented support for the rest of +containers. Well, actually he did much more - he implemented new framework. +This framework provides support for almost all C++ containers and also an easy +way to add support for custom ones. You'd better read his `post`_ to +`boost.python`_ mailing list or `documentation`_ for the new indexing suite. + + +Now, I am sure you have next question: if this suite is soo good, why it is not +in the main branch? The short answer is that this suite has some problems on +MSVC 6.0 compiler and there are few users, that still use that compiler. +The long answer is here: + +* http://mail.python.org/pipermail/c++-sig/2006-June/010830.html +* http://mail.python.org/pipermail/c++-sig/2006-June/010835.html + + +.. _`documentation` : ./indexing_suite_v2.html +.. _`post` : http://mail.python.org/pipermail/c++-sig/2003-October/005802.html + +------------------------------ +pyplusplus and indexing suites +------------------------------ +`pyplusplus`_ implements support for both indexing suites. More over, you can +freely mix indexing suites. For example you can expose ``std::vector<int>`` using +`boost.python`_ built-in indexing suite and ``std::map< int, std::string>`` using +Raoul Gough's indexing suite. + +----------------- +How does it work? +----------------- + +In both cases, `pyplusplus`_ provides almost "hands free" solution. `pyplusplus`_ +keeps track of all exported functions and variables, and if it sees that there is +a usage of stl container, it exports the container. In both cases, `pyplusplus`_ +analizes the container ``value_type`` ( or in case of mapping container +``mapped_type`` ), in order to set reasonable defaults, when it generates the code. + +------------------- +Indexing suites API +------------------- + +By default, `pyplusplus`_ works with built-in indexing suite. If you want to use +next version of indexing suite, you should tell this to the ``module_builder_t.__init__`` +method: +:: + + mb = module_builder_t( ..., indexing_suite_version=2 ) + +Every declarated class has ``indexing_suite`` property. If the class is an +instantiation of stl container, this property containes reference to an instance +of ``indexing_suite1_t`` or ``indexing_suite2_t`` class. + + +How does `pyplusplus`_ know, that a class represents stl container instantiation? +Well, it uses ``pygccxml.declarations.container_traits`` to find out this. +``pygccxml.declarations.container_traits`` class, provides all functionality +needed to identify container and to find out its ``value_type`` +( ``mapped_type`` ). + + +Built-in indexing suite API +--------------------------- + +`pyplusplus`_ defines ``indexing_suite1_t`` class. This class allows configure +any detail of generated code: + +* ``no_proxy`` - a boolean, if ``value_type`` is one of the next types + + * fundamental type + + * enumeration + + * std::string or std::wstring + + * boost::shared_ptr<?> + + then, ``no_proxy`` will be set to ``True``, otherwise to ``False``. + +* ``derived_policies`` - a string, that will be added as is to generated code + +* ``element_type`` - is a reference to container ``value_type`` or ``mapped_type``. + + +Next version of indexing suite API +---------------------------------- + +In this case there is no single place, where you can configure exported container +functionality. Please take a look on next C++ code: +:: + + struct item{ + ... + private: + bool operator==( const item& ) const; + bool operator<( const item& ) const; + }; + + struct my_data{ + std::vector<item> items; + std::map< std::string, item > name2item_mapping; + }; + + +`pyplusplus`_ declarations tree will contains ``item``, ``my_data``, +``vector<item>`` and ``map<string,item>`` class declarations. + +If ``value_type`` does not support "equal" or "less than" functionality, sort +and search functionality could not be exported. + +`pyplusplus`_ class declaration has two properties: ``equality_comparable`` and +``less_than_comparable``. The value of those properties is calculated on first +invocation. If `pyplusplus`_ can find ``operator==``, that works on ``value_type``, +then, ``equality_comparable`` property value will be set to ``True``, otherwise +to ``False``. Same process is applied on ``less_than_comparable`` property. + +In our case, `pyplusplus`_ will set both properties to ``False``, thus sort and +search functionality will not be exported. + +It is the time to introduce ``indexing_suite2_t`` class: + +* ``container_class`` - read only property, returns reference to container class + declaration + +* ``container_traits`` - read only property, returns reference to the relevant + container traits class. Container traits classes are defined in + ``pygccxml.declarations`` package. + +* ``element_type`` - is a reference to container ``value_type`` or ``mapped_type``. + +* ``call_policies`` - read/write property, in near future I will add code to + `pyplusplus`_ that will analize container ``value_type`` and will decide about + default call policies. Just an example: for non copy constructable classes + ``call_policies`` should be set to ``return_internal_reference``. + +* ``[disable|enable]_method`` - new indexing suite, allows to configure + functionality exported to Python, using simple bitwise operations on predefined + flags. `pyplusplus`_ allows you to specify what methods you want to disable + or enable. ``indexing_suite2_t.METHODS`` containes names of all supported methods. + +* ``[disable|enable]_methods_group`` - almost same as above, but allows you + to specify what group of methods you want to disable or enable. + ``indexing_suite2_t.METHOD_GROUPS`` containes names of all supported groups. + +Small tips/hints +---------------- + +1. If you set ``equality_comparable`` or ``less_than_comparable`` to ``False``. + The indexing suite will disable relevant functionality. You don't have + explicitly to disable method or mothods group. + +2. The documentation of new indexing suite containes few small mistakes. + I hope, I will have time to fix them. Any way, `pyplusplus`_ generates + correct code. + + +.. _`pyplusplus` : ./../pyplusplus.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/documentation/index.rest =================================================================== --- pyplusplus_dev/docs/documentation/index.rest (rev 0) +++ pyplusplus_dev/docs/documentation/index.rest 2006-07-20 05:04:20 UTC (rev 318) @@ -0,0 +1,24 @@ +============= +Documentation +============= + +.. contents:: Table of contents + +* `STL Containers`_ + +.. _`STL Containers` : ./containers.html + + + +.. _`pyplusplus` : ./../pyplusplus.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/documentation/indexing_suite_v2.html =================================================================== --- pyplusplus_dev/docs/documentation/indexing_suite_v2.html (rev 0) +++ pyplusplus_dev/docs/documentation/indexing_suite_v2.html 2006-07-20 05:04:20 UTC (rev 318) @@ -0,0 +1,2213 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html><head> + + + <meta name="generator" content="A human being"> + <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> + <link rel="stylesheet" type="text/css" href="indexing_suite_v2_files/boost.css"><title>Boost.Python - C++ Container Support</title></head><body> + <table summary="header" border="0" cellpadding="7" cellspacing="0" width="100%"> + <tbody><tr> + <td valign="top" width="300"> + <h3> + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/index.htm"><img alt="C++ Boost" src="indexing_suite_v2_files/cboost.gif" border="0" height="86" width="277"></a> + </h3> + </td> + <td valign="top"> + <h1 align="center"> + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/index.html">Boost.Python</a><br> + C++ Container Support + </h1> + </td> + </tr> + </tbody></table> + + <hr> + + <h2> + Contents + </h2> + + <dl class="page-index"> + <dt> + <a href="#introduction">Introduction</a> + </dt> + <dt> + <a href="#design_goals">Design goals</a> + </dt> + <dt> + <a href="#interface">Interface</a> + </dt> + <dd> + <dl class="page-index"> + <dt> + <a href="#container_suite">container_suite.hpp</a> + </dt> + <dt> + <a href="#specific">Container-specific headers</a> + </dt> + <dt> + <a href="#policies">Using policies</a> + </dt> + <dt> + <a href="#visitor_flags">Visitor flag values</a> + </dt> + <dt> + <a href="#extending">Extending and customizing</a> + </dt> + <dd> + <dl class="page-index"> + <dt> + <a href="#ValueTraits">ValueTraits</a> + </dt> + <dt> + <a href="#ContainerTraits">ContainerTraits</a> + </dt> + <dt> + <a href="#Algorithms">Algorithms</a> + </dt> + <dt> + <a href="#SliceHelper">SliceHelper</a> + </dt> + </dl> + </dd> + <dt> + <a href="#extending">Container adapters</a> + </dt> + <dd> + <dl class="page-index"> + <dt> + <a href="#container_proxy">container_proxy</a> + </dt> + <dt> + <a href="#iterator_range">iterator_range</a> + </dt> + </dl> + </dd> + <dt> + <a href="#workarounds">Compiler workarounds</a> + </dt> + <dt> + <a href="#limitations">Known limitations</a> + </dt> + </dl> + </dd> + <dt> + <a href="#references">References</a> + </dt> + <dt> + <a href="#acknoweldegments">Acknowledgements and Copyright</a> + </dt> + </dl> + + <h2><a name="introduction">Introduction</a></h2> + + The purpose of the container indexing suite is to allow Python + code to access C++ containers using regular Python + interfaces. Since each C++ container is different, it is + non-trivial to decide what Python methods can be emulated, and how + to map them to C++ function calls. The indexing suite provides a + framework for representing those decisions, as well as bindings + for the standard C++ container templates. The indexing headers are + in the Boost subdirectory + <i>boost/python/suite/indexing</i> and non-template + implementations are in + <i>libs/python/src/indexing</i>. Various tests, which can also + serve as examples are in <i>libs/python/test</i>. + + <h2><a name="design_goals">Design goals</a></h2> + + The primary design goals of the container indexing suite are as + follows. The suite should: + + <ul> + <li> + + Support instances of all useful standard container templates + + </li> + <li> + + Provide as much of the normal Python interface as is + reasonable for each container + + </li> + <li> + + Be extensible to user-defined container types + + </li> + <li> + + Support client-provided <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/CallPolicies.html">CallPolicies</a> + + </li> + </ul> + + Secondary design goals are as follows. The library should: + + <ul> + <li> + + Provide an emulation of Python reference semantics for + <i>values</i> in vector-like containers. + + </li> + <li> + + Provide an emulation of container semantics for iterator + ranges. + + </li> + </ul> + + <h2><a name="interface">Interface</a></h2> + + <p> + + The main iterface to the library is via the templated class + <code>container_suite</code>, an object of which adds a number + of Python functions to an extension class via a single + <code>def</code> call. Support is provided for all of the + standard container templates <a href="#Note1">[1]</a> via + container-specific header files, as shown in the following + example: + + </p> + +<pre>#include <boost/python/suite/indexing/container_suite.hpp> +#include <boost/python/suite/indexing/vector.hpp> +#include <boost/python/class.hpp> +#include <boost/python/module.hpp> +#include <vector> + +BOOST_PYTHON_MODULE(example) { + class_< std::vector<int> > ("vector_int") + .def (indexing::container_suite< std::vector<int> >()); +} +</pre> + + <p> + + The <code>container_suite</code> object achieves this using the + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/def_visitor.html">def_visitor interface</a>, which + provides a hook for the <code>def</code> function to install + multiple Python methods in one call. If the container element + type (<code>int</code> in the example above) is a user-defined + type, you would have to expose this type to Python via a + separate <code>class_</code> instance. + + </p> + <p> + + <a name="Note1">[1]</a> Automatic operation with the standard + containers works properly if your compiler supports partial + template specializations. Otherwise, refer to the <a href="#workarounds">compiler workarounds</a> section. + + </p> + + <h2><a name="container_suite">boost/python/suite/indexing/container_suite.hpp</a></h2> + + <p> + + The <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/boost/python/suite/indexing/container_suite.hpp"><code>container_suite.hpp</code></a> + header is summarized below: + + </p> + <p> +</p><pre>#include <boost/python/suite/indexing/algo_selector.hpp> +#include <boost/python/suite/indexing/visitor.hpp> + +#include <boost/python/return_by_value.hpp> +#include <boost/python/return_value_policy.hpp> + +namespace boost { namespace python { namespace indexing { + typedef return_value_policy<return_by_value> default_container_policies; + + template<class Container, + int Flags = 0, + class Algorithms = algo_selector<Container> > + struct container_suite + : public visitor<Algorithms, default_container_policies, Flags> + { + typedef Algorithms algorithms; + + template<typename Policy> + static visitor<Algorithms, Policy, Flags> + with_policies (Policy const &policy) + { + return visitor <Algorithms, Policy> (policy); + } + }; +} } } +</pre> + <p></p> + + <p> + + Some important points to note about <code>container_suite</code>: + + </p><ol> + <li> + + It does not include any of the container-specific headers + (like <code>vector.hpp</code> or <code>set.hpp</code>), so + these must be included separately to add support each type + of container. + + </li> + <li> + + It derives from the <code>indexing::visitor</code> + template, using a <code>return_by_value</code> return + policy. This is a reasonable default, and follows the + Boost.Python idiom of passing a default-constructed object + to the <code>def</code> function. + + </li> + <li> + + The <code>with_policies</code> static function template + generates different instances of the + <code>indexing::visitor</code> template, with + client-provided policies. + + </li> + <li> + + The template parameter <code>Flags</code> allows client code + to disable unneeded features in order to reduce code + size. Details are provided <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/visitor_flags">below</a>. + + </li> + </ol> + + <p></p> + + <h2><a name="specific">Container-specific headers</a></h2> + + <p> + + The container indexing suite includes support for many of the + standard C++ container templates, but note that the support code + for each is in a separate header file. These header files (in + the <i>boost/python/suite/indexing</i> subdirectory) are: + <code>vector.hpp</code>, <code>deque.hpp</code>, + <code>list.hpp</code>, <code>set.hpp</code> and + <code>map.hpp</code>. These correspond in the obvious way to the + standard headers <code>vector</code>, <code>deque</code>, + etc. The header files for the <a href="#container_proxy"><code>container_proxy</code></a> and <a href="#iterator_range"><code>iterator_range</code></a> templates + provide their own support implicitly. + + </p> + + <h2><a name="policies">Using policies</a></h2> + + You can select call policies using the + <code>container_suite</code> static member function + <code>with_policies</code> as in the following example: + +<pre> class_< std::list<heavy_class> > ("list_heavy_class") + .def (indexing::container_suite< std::list<heavy_class> > + ::with_policies (my_policies)); +</pre> + + <h3>Caution with policies</h3> + + <p> + + It can be tempting to use <code>return_internal_reference</code> + if the container elements are expensive to copy. However, this + can be quite dangerous, since references to the elements can + easily become invalid (e.g. if the element is deleted or + moved). The Boost.Python code for + <code>return_internal_reference</code> can only manage the + lifetime of the entire container object, and not those of the + elements actually being referenced. Various alternatives exist, + the best of which is to store the container elements indirectly, + using <code>boost::shared_ptr</code> or an equivalent. If this + is not possible, + <code><a href="#container_proxy">container_proxy</a></code> + may provide a + solution, at least for vector-like containers. + + </p> + + <h3>Internal policies detail</h3> + + <p> + + The <code>container_suite</code> object typically adds more than + one function to the Python class, and not all of those functions + can, or should, use exactly the same policies. For instance, the + Python <code>len</code> method, if provided, should always + return its result by value. The library actually uses up to + three different sets of policies derived from the one provided + to the <code>with_policies</code> function. These are: + + </p><ol> + <li> + + The supplied policies, unchanged + + </li> + <li> + + The supplied precall policy only, using <code>default_call_policies</code> for result conversion. + + </li> + <li> + + The supplied precall policies, and the supplied result + conversion policies applied to <i>each element</i> of a + returned list. + + </li> + </ol> + + Roughly speaking, methods returning a single container element + use the first option, while methods returning an integer value + (or <code>void</code>) use the second option. The third option + applies only to the slice version of <code>__getitem__</code>, + which generates a Python list by applying the return conversion + policies to each element in the list. + + <p></p> + + <h2><a name="visitor_flags">Visitor Flag values</a></h2> + + <p> + + The <code>container_suite</code> template has an optional + <code>Flags</code> parameter that allows client code to disable + various optional features of the suite. This can lead to + significant savings in the size of object files and executables + if features such as sorting or Python slice support are not + needed. The <code>Flags</code> parameter (an integer) can be any + bitwise combination of the following values (defined in the + <code>boost::python::indexing</code> namespace by <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/boost/python/suite/indexing/visitor.hpp"><code>visitor.hpp</code></a>): + + </p> + + <p> + + <table border="1"> + <tbody><tr> + <th>Flag</th> + <th>Effect</th> + </tr> + <tr> + + <td><code>disable_len</code></td> + + <td>omits the Python <code>__len__</code> method</td> + + </tr> + <tr> + + <td><code>disable_slices</code></td> + + <td>omits slice support code from <code>__getitem__</code>, + <code>__setitem__</code> and <code>__delitem__</code>.</td> + + </tr> + <tr> + + <td><code>disable_search</code></td> + + <td>omits the container search methods <code>count<code>, + </code>index</code> and <code>__contains__</code></td> + + </tr> + <tr> + + <td><code>disable_reorder</code></td> + + <td>omits the container reordering operations + <code>sort</code> and <code>reverse</code></td> + + </tr> + <tr> + + <td><code>disable_extend</code></td> + + <td>omits the <code>extend</code> method</td> + + </tr> + <tr> + + <td><code>disable_insert</code></td> + + <td>omits the <code>insert</code> method</td> + + </tr> + </tbody></table> + + </p> + + <p> + + Note that some containers don't support some of the optional + features at all, in which case the relevant flags are + ignored. The value <code>minimum_support</code> may be passed as + a flag value to disable all optional features. A simple example + is provided in <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/test/test_vector_disable.cpp"><code>test_vector_disable.cpp</code></a> + + </p> + + <h2><a name="extending">Extending and customizing</a></h2> + + <p> + + The <code>container_suite</code> template relies on seven main + support templates, five of which are suitable for specialization + or replacement by client code. The following diagram shows the + templates <a href="#Note2">[2]</a> and their dependencies, with + the replaceable ones highlighted in grey. For full details, + refer to the specific section on each component – what + follows here is an overview. + + </p> + + <table align="right"> + <tbody><tr> + <td> + + <img src="indexing_suite_v2_files/overview.png" alt="Dependencies between main templates" height="261" width="486"> + + </td> + </tr> + <tr> + <td><font size="-1"> + + Diagram 1. Overview of class dependencies + + </font></td> + </tr> + </tbody></table> + + <p> + + The <code>visitor</code> template, which implements the <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/def_visitor.html">def_visitor interface</a>, decides what + Python methods to provide for a container. It takes two template + parameters, <code>Algorithms</code> and <code>Policy</code> (the + <a href="http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/CallPolicies.html">CallPolicies</a> for the Python + methods on the container). The <code>Algorithms</code> argument + must provide implementations for the Python methods that the + container supports, as well as a matching + <code>ContainerTraits</code> type. This type provides various + compile-time constants that <code>visitor</code> uses to decide + what Python features the container provides. It also provides a + <code>value_traits</code> typedef, which has similar + compile-time constants related to the values stored in the + container. If the <code>visitor</code> instance decides to + provide Python slice support for the container, it instantiates + the <code>slice_handler</code> template, which also takes + <code>Algorithms</code> and <code>Policy</code> parameters. In + such cases, the <code>Algorithms</code> argument must supply a + <code>SliceHelper</code> type and factory function. + + </p> + <p> + + The high-level <code>container_suite</code> template uses the + <code>algo_selector</code> template to determine what types to + use in the instantiation of <code>visitor</code>. The + <code>algo_selector</code> template has partial specializations + for all of the STL container templates. + + </p> + + <p> + + <a name="Note2">[2]</a> Note that <code>Algorithms</code> and + <code>ContainerTraits</code> don't represent individual + templates in the diagram, but <i>groups</i> of related + templates. For instance, there are actually templates called + <code>list_algorithms</code> and <code>assoc_algorithms</code>, + among others. + + </p> + + + <h2><a name="ValueTraits">ValueTraits</a></h2> + + <p> + + A <code>ValueTraits</code> class provides simple information + about the type of value stored within a container that will be + exposed to Python via the <code>container_suite</code> + interface. It controls the provision of some operations that are + dependant on the operations supported by container elements (for + instance, <code>find</code> requires a comparison operator for + the elements). A <code>ValueTraits</code> class also provides a + hook called during initialization of the Python class, which can + be used for custom processing at this point. + + </p> + <p> + + The following table lists the static constants required in a + <code>ValueTraits</code> class: + + </p> + + <p> + <table border="1"> + <tbody><tr> + <th align="left"> + Static constant + </th> + <th align="center"> + Type + </th> + <th align="left"> + Meaning + </th> + </tr> + + <tr> + <td> + <code>equality_comparable</code> + </td> + <td> + bool + </td> + <td> + + Whether the value supports comparison via + <code>operator==</code>. + + </td> + </tr> + + <tr> + <td> + <code>lessthan_comparable</code> + </td> + <td> + bool + </td> + <td> + + Whether the value supports comparison via + <code>operator<</code>. + + </td> + </tr> + + </tbody></table> + </p> + + <p> + + A <code>ValueTraits</code> class should provide the following + member function template, which will be called during execution + of the <code>def</code> call for the container suite: + + </p> + + <p> + +</p><pre>template <typename PythonClass, typename Policy> +static void visitor_helper (PythonClass &, Policy const &); +</pre> + + <p></p> + + <h3>Usage notes for ValueTraits</h3> + + <p> + + In order to include a custom <code>ValueTraits</code> class into + the container suite, it is easiest to supply it as a + specialization of the template + <code>indexing::value_traits</code> for the container's element + type. The existing <code>ContainerTraits</code> classes all + make use of + <code>value_traits<container::value_type></code>, and so + will use a specialization for the value type if available. The + default, unspecialized, version of <code>value_traits</code> + sets both of the static constants to <code>true</code> and has + an empty implementation of <code>visitor_helper</code>. + + </p> + <p> + + As an example, if a user defined type does not have any + comparison operations, then there will probably be compile-time + errors caused by an attempt to provide the Python + <code>find</code> or <code>sort</code> methods. The solution is + to write a specialized version of + <code>indexing::value_traits</code> that disables the + appropriate features. For example: + + </p> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<> + struct value_traits<my_type> : public value_traits<int> + { + static bool const equality_comparable = false; + static bool const lessthan_comparable = false; + }; +} } } +</pre> + <p></p> + + <p> + + In this example, there is no need to perform any processing in + the <code>visitor_helper</code> function, and deriving from an + unspecialized version of the template (e.g. + <code>value_traits<int></code>) exposes an empty + <code>visitor_helper</code>. + + </p> + + <h3>Synopsis: boost/python/suite/indexing/value_traits.hpp</h3> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<typename T> + struct value_traits { + static bool const equality_comparable = true; + static bool const lessthan_comparable = true; + + template<typename PythonClass, typename Policy> + static void visitor_helper (PythonClass &, Policy const &) + { } + }; +} } } +</pre> + <p></p> + + <h2><a name="ContainerTraits">ContainerTraits</a></h2> + + <p> + + A <code>ContainerTraits</code> class serves three + purposes. Firstly, it identifies what facilities the container + supports in principle (i.e. either directly or via some support + code). Secondly, it identifies the types used to pass values + into and out of the supported operations. Thirdly, it provides a + hook for additional code to run during initialization of the + Python class (i.e. during the <code>def</code> call for the + suite). + + </p> + <p> + + Note that a <code>ContainerTraits</code> class can be any class, + derived from the existing implementations or not, as long as it + meets the requirements listed in the following sections. + + </p> + + <h3>Static constants for ContainerTraits</h3> + + The following table lists the static constants that a + <code>ContainerTraits</code> class should define. Note that these + must be <i>compile-time constants</i>, since parts of the library + use these constants to select between template specializations. + The constants must at least be convertible to the type shown in + the second column. + + <p> + <table border="1"> + <tbody><tr> + <th align="left"> + Static constant + </th> + <th align="center"> + Type + </th> + <th align="left"> + Meaning + </th> + <th align="left"> + Influence + </th> + </tr> + <tr> + <td> + <code>has_copyable_iter</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether copies of an iterator are independant <a href="#Note3">[3]</a> + + </td> + <td> + + Required for <code>len</code> and <code>__iter__</code> + + </td> + </tr> + + <tr> + <td> + <code>is_reorderable</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether it is possible to re-order the contents of the + container. + + </td> + <td> + + Required for <code>reverse</code> and <code>sort</code> + + </td> + </tr> + + <tr> + <td> + <code>has_mutable_ref</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + Whether container elements can be altered via a reference + </td> + <td> + Determines <code>is_reorderable</code> for most containers. + </td> + </tr> + + <tr> + <td> + <code>has_find</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether find is possible in principle (via member function + or otherwise) + + </td> + <td> + <code>__contains__</code>, + <code>index</code>, + <code>count</code>, + <code>has_key</code> + </td> + </tr> + + <tr> + <td> + <code>has_insert</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether it is possible to insert new elements into the container. + + </td> + <td> + <code>insert</code>, + <code>extend</code>, + slice version of <code>__setitem__</code> + </td> + </tr> + + <tr> + <td> + <code>has_erase</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether it is possible to erase elements from the container. + + </td> + <td> + <code>__delitem__</code>, + slice version of <code>__setitem__</code> + </td> + </tr> + + <tr> + <td> + <code>has_push_back</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether container supports insertion at the end. + + </td> + <td> + <code>append</code> + </td> + </tr> + + <tr> + <td> + <code>has_pop_back</code> + </td> + <td align="center"> + <code>bool</code> + </td> + <td> + + Whether container supports element deletion at the end. + + </td> + <td> + Currently unused + </td> + </tr> + + <tr> + <td> + <code>index_style</code> + </td> + <td align="center"> + <code>index_style_t</code> + </td> + <td> + + Type of indexing the container supports <a href="#Note4">[4]</a> + + </td> + <td> + <code>__getitem__</code>, + <code>__setitem__</code>, + <code>__delitem__</code>, + <code>__iter__</code>, + <code>extend</code>, + <code>index</code>, + <code>count</code>, + <code>has_key</code> + </td> + </tr> + </tbody></table> + </p> + + <p> + </p><h3>Notes</h3> + + <table> + <tbody><tr> + <td valign="top"> + <a name="Note3">[3]</a> + </td> + <td> + + For example, copies of stream iterators are <i>not</i> + independant. All iterator copies refer to the same stream, + which has only one read and one write position. + + </td> + </tr> + + <tr> + <td valign="top"> + <a name="Note4">[4]</a> + </td> + <td> + + <code>index_style_none</code>, no indexing at all + (e.g. <code>list</code>)<br> + + <code>index_style_linear</code>, continuous integer-like + index type (e.g. <code>vector</code>)<br> + + <code>index_style_nonlinear</code>, indexing via other + types (e.g. <code>map</code>). + + </td> + </tr> + </tbody></table> + + <p></p> + + <h3>Member types for ContainerTraits</h3> + + <p> + + The following table lists the type names that must be defined in + a compatible implementation of <code>ContainerTraits</code>. + The large number of types is supposed to provide flexibility for + containers with differing interfaces. For example, + <code>map</code> uses the same type for searching and "indexing" + (i.e. <code>find</code> and <code>operator[]</code>) so + <code>key_type</code> and <code>index_type</code> would have to + be the same. In contrast, searching a <code>vector</code> would + typically use a different type to that used for indexing into a + vector. + + </p> + + <p> + <table border="1"> + <tbody><tr> + <th align="left"> + Type name + </th> + <th align="left"> + Meaning + </th> + </tr> + + <tr> + <td> + <code>container</code> + </td> + <td> + The type of the C++ container. + </td> + </tr> + + <tr> + <td> + <code>size_type</code> + </td> + <td> + + The type used to represent the number of elements in the + container. + + </td> + </tr> + + <tr> + <td> + <code>iterator</code> + </td> + <td> + + The container's iterator type. This should be a non-const + iterator unless the container itself is const. + + </td> + </tr> + + <tr> + <td> + <code>index_type</code> + </td> + <td> + + The type used to represent indexes extracted from a + <code>__getitem__</code> call (and others). For + <code>index_style_linear</code>, this <i>should be a + signed type</i>, so that negative indices can be + processed. For <code>index_style_nonlinear</code>, this + will most likely be the same type as + <code>key_type</code>. + + </td> + </tr> + + <tr> + <td> + <code>index_param</code> + </td> + <td> + + The type to use when passing <code>index_type</code> into + a function. + + </td> + </tr> + + <tr> + <td> + <code>value_type</code> + </td> + <td> + + The type to use when copying a value into or out of the + container. + + </td> + </tr> + + <tr> + <td> + <code>value_param</code> + </td> + <td> + + The type to use when passing <code>value_type</code> into + a function. + + </td> + </tr> + + <tr> + <td> + <code>key_type</code> + </td> + <td> + + The type used for search operations like <code>find</code> + and <code>count</code>. + + </td> + </tr> + + <tr> + <td> + <code>key_param</code> + </td> + <td> + + The type to use when passing <code>key_type</code> into a + function. + + </td> + </tr> + + <tr> + <td> + <code>reference</code> + </td> + <td> + + The type to use when returning a reference to a container + element. + + </td> + </tr> + + <tr> + <td> + <code>value_traits_</code> + </td> + <td> + + Traits for the container elements. See <a href="#ValueTraits">the ValueTraits section</a> for + information about the requirements on this type. + + </td> + </tr> + + </tbody></table> + + </p> + + <h3>Member functions for ContainerTraits</h3> + + In order to support additional initialization code to run, a + <code>ContainerTraits</code> class should provide a static member + function template as follows: + + <p> +</p><pre>template <typename PythonClass, typename Policy> +static void visitor_helper (PythonClass &, Policy const &); +</pre> + <p></p> + + <p> + + Typically, the implementation would just forward the call to the + equivalent function in the <code>value_traits_</code> class. + + </p> + + <h3>Usage notes for ContainerTraits</h3> + + <p> + + It may be possible to mix your own <code>ContainerTraits</code> + class with one of the existing <code>Algorithms</code> + implementations, thus saving yourself a fair bit of work. The + easiest way to do this would be to specialize the + <code>algo_selector</code> template for your container type, + using public deriviation to get the implementation from one of + the existing <code>Algorithms</code> templates. For example, + assuming that <code>default_algorithms</code> is suitable for + your container: + + </p> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<> + struct algo_selector<my_container> + : public default_algorithms<my_container_traits> + { + }; +} } } +</pre> + <p></p> + <p> + + Alternatively, you could select the algorithms and traits using + the <code>visitor</code> template directly, as described in the + <a href="#workarounds">compiler workarounds</a> section. + + </p> + + <h3><a name="simple_ctraits">Simplistic ContainerTraits example</a></h3> + + <p> + + The following block of code shows a simplistic implementation of + <code>ContainerTraits</code> for the container + <code>std::map<std::string, int></code>. The actual + implementation used by the suite relies on template + metaprogramming techniques, whereas this example is designed to + show only the essential elements of a + <code>ContainerTraits</code> implementation. + + </p> + + <p> +</p><pre>#include <map> +#include <string> +#include <boost/python/suite/indexing/suite_utils.hpp> +// Include suite_utils to get index_style_t + +struct simple_map_traits { + // Traits information for std::map<std::string, int> + + typedef std::map<std::string, int> container; + typedef container::size_type size_type; + typedef container::iterator iterator; + + typedef int value_type; + typedef int & reference; + typedef std::string key_type; + typedef std::string index_type; + + typedef int value_param; + typedef std::string const & key_param; + typedef std::string const & index_param; + + static bool const has_copyable_iter = true; + static bool const has_mutable_ref = true; + static bool const has_find = true; + static bool const has_insert = true; + static bool const has_erase = true; + static bool const has_pop_back = false; + static bool const has_push_back = false; + static bool const is_reorderable = false; + + static boost::python::indexing::index_style_t const index_style + = boost::python::indexing::index_style_nonlinear; + + struct value_traits_ { + // Traits information for our value_type + static bool const equality_comparable = true; + static bool const lessthan_comparable = true; + }; + + template<typename PythonClass, typename Policy> + static void visitor_helper (PythonClass &, Policy const &) + { + // Empty + } +}; +</pre> + <p></p> + + <p> + + Example usage of the <code>simple_map_traits</code>: + + </p> + + <p> +</p><pre>#include "simple_map_traits.hpp" + +#include <boost/python/suite/indexing/container_suite.hpp> + +#include <boost/python/module.hpp> +#include <boost/python/class.hpp> + +BOOST_PYTHON_MODULE(test_simple) { + using namespace boost::python; + + typedef std::map<std::string, int> container_t; + typedef indexing::map_algorithms<simple_map_traits> algorithms_t; + + class_<container_t> ("map") + .def (indexing::container_suite<container_t, algorithms_t>()); +} +</pre> + <p></p> + + <h2><a name="Algorithms">Algorithms</a></h2> + + <p> + + The <code>Algorithms</code> requirements are designed to provide + a predictable interface to any container, so that the same + <code>visitor</code> code can expose any supported container to + Python. An implemention of <code>Algorithms</code> does this by + providing functions and typedefs with fixed names. The exact + interfaces to the functions can vary to some extent, since the + <code>def</code> function calls used internally by the + <code>visitor</code> deduce the function type + automatically. However, certain points should be confomed to: + + </p><ol> + <li> + + The functions should be static, with + <code>container &</code> as first parameter. + + </li> + + <li> + + The functions should <i>not</i> be overloaded – this + avoids problems with type deduction. + + </li> + <li> + + Generally, not all of the possible functions need to be + implemented, dependant on the static constants in the + <code>ContainerTraits</code>. + + </li> + </ol> + + <p></p> + + <p> + + The block of code below shows the definition of the + <code>default_algorithms</code> class template, which is the + basis for all current implementations of + <code>Algorithms</code>. The typedefs that it defines are + primarily for convenience within the implementation itself, + however <code>container</code>, <code>reference</code> and + <code>slice_helper</code> are also required by the + <code>slice_handler</code> template, if slices are + supported. Note that <code>default_algorithms</code> derives all + of the type information from its <code>ContainerTraits</code> + template argument, which allows the same implementation to be + used for various container types. + + </p> + + <h3>Partial boost/python/suite/indexing/algorithms.hpp</h3> + + <p> +</p><pre>namespace boost { namespace python { namespace indexing { + template<typename ContainerTraits, typename Ovr = detail::no_override> + class default_algorithms + { + typedef default_algorithms<ContainerTraits, Ovr> self_type; + + public: + typedef ContainerTraits container_traits; + + typedef typename ContainerTraits::container container; + typedef typename ContainerTraits::iterator iterator; + typedef typename ContainerTraits::reference reference; + typedef typename ContainerTraits::size_type size_type; + typedef typename ContainerTraits::value_type value_type; + typedef typename ContainerTraits::value_param value_param; + typedef typename ContainerTraits::index_param index_param; + typedef typename ContainerTraits::key_param key_param; + + typedef int_slice_helper<self_type, integer_slice> slice_helper; + + static size_type size (container &); + static iterator find (container &, key_param); + static size_type get_index (container &, key_param); + static size_type count (container &, key_param); + static bool contains (container &, key_param); + static void reverse (container &); + static reference get (container &, index_param); + static void assign (container &, index_param, value_param); + static void insert (container &, index_param, value_param); + static void erase_one (container &, index_param); + static void erase_range(container &, index_param, index_param); + static void push_back (container &, value_param); + static void sort (container &); + + static slice_helper make_slice_helper (container &c, slice const &); + + template<typename PythonClass, typename Policy> + static void visitor_helper (PythonClass &, Policy const &); + }; +} } } +</pre> + <p></p> + + <h3>Slice support</h3> + <p> + + For containers that support Python slices, the + <code>visitor</code> template will instantiate and use + internally the <code>slice_handler</code> template. This + template requires a type called <code>slice_helper</code> and a + factory function called <code>make_slice_helper</code> from its + <code>Algorithms</code> argument. More details are provided in + the section <a href="#SliceHelper">SliceHelper</a>. + + </p> + + <h3>Usage notes for Algorithms</h3> + + <p> + + The existing <code>indexing::algo_selector</code> template uses + partial specializations and public derivation to select an + <code>Algorithms</code> implementation suitable for any of the + standard container types. Exactly how it does this should be + considered an implementation detail, and uses some tricks to + reuse various existing <code>Algorithms</code> + implementations. In any case, client code can specialize the + <code>algo_selector</code> template for new container types, as + long as the specialized instances conform to the requirements + for <code>Algorithms</code> as already given. + + </p> + <p> + + A new implementation of <code>Algorithms</code> could derive + from any one of the existing implementation templates, or be + completely independant. The existing implementation templates + are listed in the following table. They each take one template + parameter, which should be a valid <code>ContainerTraits</code> + class, as specified in a <a href="#ContainerTraits">previous + section</a>. + + </p> + + <p> + <table border="1"> + <tbody><tr> + <th> + Template name + </th> + <th> + Description + </th> + </tr> + + <tr> + <td> + + <code>default_algorithms</code> + + </td> + <td> + + Uses standard iterator-based algorithms wherever + possible. Assumes that the container provides + <code>begin</code> and end <code>end</code> member + functions that return iterators, and some or all of + <code>size</code>, <code>insert</code>, <code>erase</code> + and <code>push_back</code>, depending on what functions get + instantiated. + + </td> + </tr> + + <tr> + <td> + + <code>list_algorithms</code> + + </td> + <td> + + Similar to the above (in fact, it derives from + <code>default_algorithms</code>) except that it uses + container member functions <code>reverse</code> and + <code>sort</code> instead of the iterator-based + versions. Defined in + <code>boost/python/suite/indexing/list.hpp</code>. + + </td> + </tr> + + <tr> + <td> + + <code>assoc_algorithms</code> + + </td> + <td> + + Also derived from <code>default_algorithms</code>, for use + with associative containers. Uses the container member + function <code>find</code> for indexing, and member + function <code>count</code> instead of iterator-based + implementations. + + </td> + </tr> + + <tr> + <td> + + <code>set_algorithms</code> + + </td> + <td> + + Derived from <code>assoc_algorithms</code> to handle + <code>set</code> insertion operations, which are slightly + different to the <code>map</code> versions. + + </td> + </tr> + + <tr> + <td> + + <code>map_algorithms</code> + + </td> + <td> + + Derived from <code>assoc_algorithms</code> to handle + <code>map</code> insertion and lookup, which are slightly + different to the <code>set</code> versions. + + </td> + </tr> + </tbody></table> + + </p> + <p> + + The <code>default_algorithms</code> template attempts to place + as few restrictions as possible on the container type, by using + iterators and standard algorithms in most of its functions. It + accepts an optional second template parameter, which can be used + via the curiously recurring template idiom to replace any of its + functions that it relies on internally. For instance, if you've + created an iterator-style interface to a container that is not + at all STL-like (let's call it <code>weird_container</code>), + you might be able to re-use most of + <code>default_algorithms</code> by replacing its basic functions + like this: + + </p> + <p> +</p><pre>namespace indexing = boost::python::indexing; + +struct my_algorithms + : public indexing::default_algorithms < + weird_container_traits, my_algorithms + > +{ + size_t size (weird_container const &c) { + return ...; + } + + my_iterator_t begin (weird_container &c) { + return ...; + } + + my_iterator_t end (weird_container &c) { + return ...; + } +}; +</pre> + <p></p> + + <h2><a name="SliceHelper">SliceHelper</a></h2> + + <p> + + Support code for Python slices is split into two portions, the + <code>slice_handler</code> template, and a "slice helper" that + can easily be replaced by client code via a typedef and factory + function in the <code>Algorithms</code> argument supplied to + <code>container_suite</code>. The slice helper object takes care + of reading and writing elements from a slice in a C++ container, + and optionally insertion and deletion. Effectively, the slice + helper object maintains a pointer to the current element of the + slice within the container, and provides a <code>next</code> + function to advance to the next element of the slice. The + container suite uses the following interface for slices: + + </p> + <p> + <table border="1"> + <tbody><tr> + <th> + + Expression + + </th> + <th> + + Return type + + </th> + <th> + + Notes + + </th> + </tr> + <tr> + <td> + + <code>Algorithms::</code> <code>make_slice_helper</code> + <code>(c, s)</code> + + </td> + <td> + + <code>Algorithms::</code> <code>slice_helper</code> + + </td> + <td> + + <code>c</code> is of type + <code>Algorithms::</code> <code>container &</code> and + <code>s</code> is of type <code>indexing::</code> + <code>slice const &</code>. + Returns a newly constructed <code>slice_helper</code> + object by value. + + </td> + </tr> + + <tr> + <td> + + <code>slice_helper.</code><code>next()</code> + + </td> + <td> + + <code>bool</code> + + </td> + <td> + + Advances the slice helper's current element pointer to the + next element of the slice. Returns true if such an element + exists, and false otherwise. The first time this function + is called, it should set the current pointer to the first + element of the slice (if any). + + </td> + </tr> + + <tr> + <td> + + <code>slice_helper.</code> <code>current()</code> + + </td> + <td> + + <code>Algorithms::</code> <code>reference</code> + + </td> + <td> + + Returns a reference to the current element of the + slice. This will only be called if the last call to + <code>next()</code> returned true. + + </td> + </tr> + <tr> + <td> + + <code>slice_helper.</code><code>write (v)</code> + + </td> + <td> + + <code>void</code> + + </td> + <td> + + The parameter <code>v</code> is of type + <code>Algorthims::value_param</code>. Advances to the + next element of the slice, as defined in + <code>next</code>, and writes the given value + <code>v</code> at the new location in the container.If the + slice is exhausted (i.e. <code>next</code> would return + false) then <code>write</code> <i>either</i> inserts the + value into the container at the next location (past the + end of the slice), <i>or</i> sets a Python exception and + throws. + + </td> + </tr> + <tr> + <td> + + <code>slice_helper.</code> <code>erase_remaining()</code> + + </td> + <td> + + <code>void</code> + + </td> + <td> + + <i>Either</i> erases any remaining elements in the slice + not already consumed by calls to <code>next</code> or + <code>write</code>, + <i>or</i> sets a Python exception and throws. + + </td> + </tr> + </tbody></table> + </p> + + <p> + + The container suite provides a generic implementation of the + <code>SliceHelper</code> requirements for containers that have + integer-like indexes. It is parameterized with a + <code>SliceType</code> parameter that allows t... [truncated message content] |
From: <rom...@us...> - 2006-07-20 07:01:23
|
Revision: 328 Author: roman_yakovenko Date: 2006-07-20 00:01:05 -0700 (Thu, 20 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=328&view=rev Log Message: ----------- moving tutorials to "documentation" directory Added Paths: ----------- pyplusplus_dev/docs/documentation/tutorials/ pyplusplus_dev/docs/documentation/tutorials/module_builder/ pyplusplus_dev/docs/documentation/tutorials/module_builder/generate_code.html pyplusplus_dev/docs/documentation/tutorials/module_builder/hello_world.html pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest pyplusplus_dev/docs/documentation/tutorials/module_builder/result.html pyplusplus_dev/docs/documentation/tutorials/module_builder/www_configuration.py pyplusplus_dev/docs/documentation/tutorials/pyplusplus_demo.png pyplusplus_dev/docs/documentation/tutorials/tutorials.rest pyplusplus_dev/docs/documentation/tutorials/www_configuration.py Removed Paths: ------------- pyplusplus_dev/docs/tutorials/ Added: pyplusplus_dev/docs/documentation/tutorials/module_builder/generate_code.html =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/generate_code.html (rev 0) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/generate_code.html 2006-07-20 07:01:05 UTC (rev 328) @@ -0,0 +1,101 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>generate_code.py</title> +<meta name="GENERATOR" content="SciTE - www.Scintilla.org" /> +<style type="text/css"> +.S0 { + color: #808080; + background: #FFFFFF; +} +.S1 { + font-family: 'Courier New'; + color: #007F00; + background: #FFFFFF; + font-size: 9pt; +} +.S4 { + font-family: 'Courier New'; + color: #7F007F; + background: #FFFFFF; + font-size: 10pt; +} +.S5 { + font-weight: bold; + color: #00007F; + background: #FFFFFF; +} +.S10 { + font-weight: bold; + color: #000000; + background: #FFFFFF; +} +.S12 { + color: #7F7F7F; + background: #FFFFFF; +} +span { + font-family: 'Courier New'; + color: #000000; + background: #FFFFFF; + font-size: 10pt; +} +</style> +</head> +<body bgcolor="#FFFFFF"> +<span><span class="S1">#! /usr/bin/python</span><br /> +<span class="S1"># Copyright 2004 Roman Yakovenko.</span><br /> +<span class="S1"># Distributed under the Boost Software License, Version 1.0. (See</span><br /> +<span class="S1"># accompanying file LICENSE_1_0.txt or copy at</span><br /> +<span class="S1"># http://www.boost.org/LICENSE_1_0.txt)</span><br /> +<br /> +<span class="S5">import</span><span class="S0"> </span>os<br /> +<span class="S5">import</span><span class="S0"> </span>sys<br /> +sys<span class="S10">.</span>path<span class="S10">.</span>append<span class="S10">(</span><span class="S0"> </span><span class="S4">'../..'</span><span class="S0"> </span><span class="S10">)</span><br /> +<span class="S5">from</span><span class="S0"> </span>environment<span class="S0"> </span><span class="S5">import</span><span class="S0"> </span>gccxml<br /> +<span class="S5">from</span><span class="S0"> </span>pyplusplus<span class="S0"> </span><span class="S5">import</span><span class="S0"> </span>module_builder<br /> +<br /> +mb<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>module_builder<span class="S10">.</span>module_builder_t<span class="S10">(</span><br /> +<span class="S0"> </span>files<span class="S10">=[</span><span class="S4">'hello_world.hpp'</span><span class="S10">]</span><br /> +<span class="S0"> </span><span class="S10">,</span><span class="S0"> </span>gccxml_path<span class="S10">=</span>gccxml<span class="S10">.</span>executable<span class="S0"> </span><span class="S10">)</span><span class="S0"> </span><span class="S1">#path to gccxml executable</span><br /> +<br /> +<span class="S1">#rename enum Color to color</span><br /> +Color<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>mb<span class="S10">.</span>enum<span class="S10">(</span><span class="S0"> </span><span class="S4">'color'</span><span class="S0"> </span><span class="S10">)</span><br /> +Color<span class="S10">.</span>rename<span class="S10">(</span><span class="S4">'Color'</span><span class="S10">)</span><br /> +<br /> +<span class="S1">#Set call policies to animal::get_name_ptr</span><br /> +animal<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>mb<span class="S10">.</span>class_<span class="S10">(</span><span class="S0"> </span><span class="S4">'animal'</span><span class="S0"> </span><span class="S10">)</span><br /> +get_name_ptr<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>animal<span class="S10">.</span>member_function<span class="S10">(</span><span class="S0"> </span><span class="S4">'get_name_ptr'</span><span class="S10">,</span><span class="S0"> </span>recursive<span class="S10">=</span>False<span class="S0"> </span><span class="S10">)</span><br /> +get_name_ptr<span class="S10">.</span>call_policies<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>module_builder<span class="S10">.</span>call_policies<span class="S10">.</span>return_internal_reference<span class="S10">()</span><br /> +<br /> +<span class="S1">#next code has same effect</span><br /> +get_name_ptr<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>mb<span class="S10">.</span>member_function<span class="S10">(</span><span class="S0"> </span><span class="S4">'get_name_ptr'</span><span class="S0"> </span><span class="S10">)</span><br /> +get_name_ptr<span class="S10">.</span>call_policies<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>module_builder<span class="S10">.</span>call_policies<span class="S10">.</span>return_internal_reference<span class="S10">()</span><br /> +<br /> +<span class="S1">#I want to exclude all classes with name starts with impl</span><br /> +impl_classes<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>mb<span class="S10">.</span>classes<span class="S10">(</span><span class="S0"> </span><span class="S5">lambda</span><span class="S0"> </span>decl<span class="S10">:</span><span class="S0"> </span>decl<span class="S10">.</span>name<span class="S10">.</span>startswith<span class="S10">(</span><span class="S0"> </span><span class="S4">'impl'</span><span class="S0"> </span><span class="S10">)</span><span class="S0"> </span><span class="S10">)</span><br /> +impl_classes<span class="S10">.</span>exclude<span class="S10">()</span><br /> +<br /> +<span class="S1">#I want to exclude all functions that returns pointer to int</span><br /> +ptr_to_int<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>mb<span class="S10">.</span>free_functions<span class="S10">(</span><span class="S0"> </span>return_type<span class="S10">=</span><span class="S4">'int *'</span><span class="S0"> </span><span class="S10">)</span><br /> +ptr_to_int<span class="S10">.</span>exclude<span class="S10">()</span><br /> +<br /> +<span class="S1">#I can print declarations to see what is going on</span><br /> +mb<span class="S10">.</span>print_declarations<span class="S10">()</span><br /> +<br /> +<span class="S1">#I can print single declaration</span><br /> +mb<span class="S10">.</span>print_declarations<span class="S10">(</span><span class="S0"> </span>animal<span class="S0"> </span><span class="S10">)</span><br /> +<br /> +<span class="S1">#Now it is the time to give a name to our module</span><br /> +mb<span class="S10">.</span>build_code_creator<span class="S10">(</span><span class="S0"> </span>module_name<span class="S10">=</span><span class="S4">'hw'</span><span class="S0"> </span><span class="S10">)</span><br /> +<br /> +<span class="S1">#It is common requirement in software world - each file should have license</span><br /> +mb<span class="S10">.</span>code_creator<span class="S10">.</span>license<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">'//Boost Software License( http://boost.org/more/license_info.html )'</span><br /> +<br /> +<span class="S1">#I don't want absolute includes within code</span><br /> +mb<span class="S10">.</span>code_creator<span class="S10">.</span>user_defined_directories<span class="S10">.</span>append<span class="S10">(</span><span class="S0"> </span>os<span class="S10">.</span>path<span class="S10">.</span>abspath<span class="S10">(</span><span class="S4">'.'</span><span class="S10">)</span><span class="S0"> </span><span class="S10">)</span><br /> +<br /> +<span class="S1">#And finally we can write code to the disk</span><br /> +mb<span class="S10">.</span>write_module<span class="S10">(</span><span class="S0"> </span>os<span class="S10">.</span>path<span class="S10">.</span>join<span class="S10">(</span><span class="S0"> </span>os<span class="S10">.</span>path<span class="S10">.</span>abspath<span class="S10">(</span><span class="S4">'.'</span><span class="S10">),</span><span class="S0"> </span><span class="S4">'hello_world.py.cpp'</span><span class="S0"> </span><span class="S10">)</span><span class="S0"> </span><span class="S10">)</span></span> +</body> +</html> Added: pyplusplus_dev/docs/documentation/tutorials/module_builder/hello_world.html =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/hello_world.html (rev 0) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/hello_world.html 2006-07-20 07:01:05 UTC (rev 328) @@ -0,0 +1,97 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>hello_world.hpp</title> +<meta name="GENERATOR" content="SciTE - www.Scintilla.org" /> +<style type="text/css"> +.S0 { + color: #808080; + background: #FFFFFF; +} +.S2 { + font-family: 'Courier New'; + color: #007F00; + background: #FFFFFF; + font-size: 9pt; +} +.S3 { + font-family: 'Courier New'; + color: #3F703F; + background: #FFFFFF; + font-size: 9pt; +} +.S4 { + color: #007F7F; + background: #FFFFFF; +} +.S5 { + font-weight: bold; + color: #00007F; + background: #FFFFFF; +} +.S6 { + color: #7F007F; + background: #FFFFFF; +} +.S9 { + color: #7F7F00; + background: #FFFFFF; +} +.S10 { + font-weight: bold; + color: #000000; + background: #FFFFFF; +} +span { + font-family: 'Courier New'; + color: #000000; + background: #FFFFFF; + font-size: 10pt; +} +</style> +</head> +<body bgcolor="#FFFFFF"> +<span><span class="S2">// Copyright 2004 Roman Yakovenko.</span><br /> +<span class="S2">// Distributed under the Boost Software License, Version 1.0. (See</span><br /> +<span class="S2">// accompanying file LICENSE_1_0.txt or copy at</span><br /> +<span class="S2">// http://www.boost.org/LICENSE_1_0.txt)</span><br /> +<br /> +<span class="S9">#ifndef __hello_world_hpp__</span><br /> +<span class="S9">#define __hello_world_hpp__</span><br /> +<br /> +<span class="S9">#include <string></span><br /> +<br /> +<span class="S2">//I want to rename color to Color</span><br /> +<span class="S5">enum</span><span class="S0"> </span>color<span class="S10">{</span><span class="S0"> </span>red<span class="S10">,</span><span class="S0"> </span>green<span class="S10">,</span><span class="S0"> </span>blue<span class="S0"> </span><span class="S10">};</span><br /> +<br /> +<span class="S5">struct</span><span class="S0"> </span>animal<span class="S10">{</span><br /> +<span class="S0"> </span><br /> +<span class="S0"> </span>animal<span class="S10">(</span><span class="S0"> </span><span class="S5">const</span><span class="S0"> </span>std<span class="S10">::</span>string<span class="S10">&</span><span class="S0"> </span>name<span class="S10">=</span><span class="S6">""</span><span class="S0"> </span><span class="S10">)</span><br /> +<span class="S0"> </span><span class="S10">:</span><span class="S0"> </span>m_name<span class="S10">(</span><span class="S0"> </span>name<span class="S0"> </span><span class="S10">)</span><br /> +<span class="S0"> </span><span class="S10">{}</span><br /> +<span class="S0"> </span><br /> +<span class="S0"> </span><span class="S2">//I need to set call policies to the function</span><br /> +<span class="S0"> </span><span class="S5">const</span><span class="S0"> </span>std<span class="S10">::</span>string<span class="S10">*</span><span class="S0"> </span>get_name_ptr<span class="S10">()</span><span class="S0"> </span><span class="S5">const</span><br /> +<span class="S0"> </span><span class="S10">{</span><span class="S0"> </span><span class="S5">return</span><span class="S0"> </span><span class="S10">&</span>m_name<span class="S10">;</span><span class="S0"> </span><span class="S10">}</span><br /> +<br /> +<span class="S0"> </span><span class="S5">const</span><span class="S0"> </span>std<span class="S10">::</span>string<span class="S10">&</span><span class="S0"> </span>name<span class="S10">()</span><span class="S0"> </span><span class="S5">const</span><br /> +<span class="S0"> </span><span class="S10">{</span><span class="S0"> </span><span class="S5">return</span><span class="S0"> </span>m_name<span class="S10">;</span><span class="S0"> </span><span class="S10">}</span><br /> +<span class="S0"> </span><br /> +<span class="S5">private</span><span class="S10">:</span><span class="S0"> </span><br /> +<span class="S0"> </span>std<span class="S10">::</span>string<span class="S0"> </span>m_name<span class="S10">;</span><br /> +<br /> +<span class="S10">};</span><br /> +<br /> +<span class="S2">//I want to exclude next declarations:</span><br /> +<span class="S5">struct</span><span class="S0"> </span>impl1<span class="S10">{};</span><br /> +<span class="S5">struct</span><span class="S0"> </span>impl2<span class="S10">{};</span><br /> +<br /> +<span class="S5">inline</span><span class="S0"> </span><span class="S5">int</span><span class="S10">*</span><span class="S0"> </span>get_int_ptr<span class="S10">(){</span><span class="S0"> </span><span class="S5">return</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;}</span><span class="S0"> </span><br /> +<span class="S5">inline</span><span class="S0"> </span><span class="S5">int</span><span class="S10">*</span><span class="S0"> </span>get_int_ptr<span class="S10">(</span><span class="S5">int</span><span class="S10">){</span><span class="S0"> </span><span class="S5">return</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;}</span><br /> +<span class="S5">inline</span><span class="S0"> </span><span class="S5">int</span><span class="S10">*</span><span class="S0"> </span>get_int_ptr<span class="S10">(</span><span class="S5">double</span><span class="S10">){</span><span class="S0"> </span><span class="S5">return</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;}</span><br /> +<span class="S0"> </span><br /> +<span class="S9">#endif</span><span class="S2">//__hello_world_hpp__</span><br /> +<br /> +<span class="S0"></span></span> +</body> +</html> Added: pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest (rev 0) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest 2006-07-20 07:01:05 UTC (rev 328) @@ -0,0 +1,167 @@ +==================== +pyplusplus tutorials +==================== + +.. contents:: Table of contents + +------------------- +What is pyplusplus? +------------------- + +.. include:: ./../../../definition.rest + +-------- +Preamble +-------- + +I guess you decided to try `pyplusplus`_ API. Good! Lets start. First of all, +please take a look on two files: + +* `hello_world.hpp`_ - C++ source code, that we want to export to Python + +* `generate_code.py`_ - Python code, that uses `pyplusplus`_ to export + declarations from the source file + +.. _`hello_world.hpp` : ./hello_world.html +.. _`generate_code.py` : ./generate_code.html + +---------------- +module_builder_t +---------------- + +`pyplusplus`_ is built from a few packages, but there is only one package, you +should really to be familiar with - ``module_builder``. This package is some kind +of facade to low level API. It provides simple and intuitive API. The main +class within this package is ``module_builder_t``. The instance of this class will +guide you through the whole process. Next few paragraphs will tell you more about +this class. + +------------------------- +module_builder_t.__init__ +------------------------- + +First of all, what is needed in order to create an instance of the class? + +``module_builder_t.__init__`` methods takes few arguments: + +1. ``files`` - list of all C++ source files, that declarations from them you want + to export. This is the only required parameter. + +2. ``gccxml_path`` - path to `GCC-XML`_ binary. If you don't supply this argument + `pygccxml`_ will look for it using your environment variable ``PATH``. + +There some other arguments: + +* additional include directories +* [un]defined symbols ( macros ) +* declarations cache +* ... + +Parsing of source files is done within this method. Post condition of this +method is - all declarations has been successfully extracted from the sources +files. + +-------------------------- +Declarations customization +-------------------------- +Not all declarations should be exported! Not every declaration could be exported +without human invocation! As you already saw from example, `pyplusplus`_ provides +simple and powerful declarations query interface. By default, only declarations +that belongs to files, you have asked to parse, and to files, that lies in the same +directories as parsed files, will be exported: +:: + + project_root/ + details/ + impl_a.h + impl_b.h + include/ + a.h //includes impl_a.h + b.h //includes impl_b.h + all.h //includes a.h and b.h + mb = module_builder( [ 'all.h' ] ) + +All declarations that belongs to ``include`` directory will be signed as included +to exporting. All other declarations will be ignored. + +You can change the set of exported declarations by calling ``exclude`` or +``include`` methods, on declarations. + +Basically, this is a second step of code generation process. During this step +you could/should/may change `pyplusplus`_ defaults: + +* to rename exposed declarations +* to include/exclude declarations +* to set call policies +* ... + +I think it is critical for beginers to see what is going on, right? +``module_builder_t`` class has ``print_declarations`` method. You can print whole +declarations tree or some specific declaration. Very convinient, very useful. + +----------------------------------- +module_builder_t.build_code_creator +----------------------------------- + +Now it is a time to create module code creator. Do you remember, in inroduction +to `pyplusplus`_, I told you that before writing code to disc, `pyplusplus`_ will +create some kind of `AST`_. Well this is done by calling +``module_builder_t.build_code_creator`` function. Right now, the only important +argument to the function is ``module_name``. Self explained, is it? + +What is the main value of code creators? Code creators allow you to modify +code before it has been written to disk. For example one common requirement for +open source projects it to have license text within every source file. You can +do it with one line of code only: +:: + + mb.code_creator.license = your license text + +After you call this function, I recommend you not to change declarations +configuration. In most cases the change will take effect, in some cases it will +not! + +This tutorials is not cover code creators and how you should work with them. +I will write an other tutorial. + +.. _`AST`: http://en.wikipedia.org/wiki/Abstract_syntax_tree + +----------------------------- +module_builder_t.write_module +----------------------------- +You have almost created your module. The last things left is to write module +code to file(s). You can do it with + +* ``module_builder_t.write_module`` - you should provide file name, the code + will be written in. + +* ``module_builder_t.split_module`` - you should provide directory name. + For big projects it is a must to minimize compilation time. So `pyplusplus`_ + splits your module source code to different files within the directory. + + +------ +Result +------ + +`View generated file`_ + +.. _`View generated file` : ./result.html + + +That's all. I hope you enjoyed. + +.. _`pyplusplus` : ./../../../pyplusplus.html +.. _`pygccxml` : ./../../../../pygccxml/pygccxml.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`SourceForge`: http://sourceforge.net/index.php +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/documentation/tutorials/module_builder/result.html =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/result.html (rev 0) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/result.html 2006-07-20 07:01:05 UTC (rev 328) @@ -0,0 +1,78 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>hello_world.py.cpp</title> +<meta name="GENERATOR" content="SciTE - www.Scintilla.org" /> +<style type="text/css"> +.S0 { + color: #808080; + background: #FFFFFF; +} +.S2 { + font-family: 'Courier New'; + color: #007F00; + background: #FFFFFF; + font-size: 9pt; +} +.S4 { + color: #007F7F; + background: #FFFFFF; +} +.S5 { + font-weight: bold; + color: #00007F; + background: #FFFFFF; +} +.S6 { + color: #7F007F; + background: #FFFFFF; +} +.S9 { + color: #7F7F00; + background: #FFFFFF; +} +.S10 { + font-weight: bold; + color: #000000; + background: #FFFFFF; +} +span { + font-family: 'Courier New'; + color: #000000; + background: #FFFFFF; + font-size: 10pt; +} +</style> +</head> +<body bgcolor="#FFFFFF"> +<span><span class="S2">// This file has been generated by pyplusplus.</span><br /> +<br /> +<span class="S2">//Boost Software License( http://boost.org/more/license_info.html )</span><br /> +<br /> +<span class="S9">#include "boost/python.hpp"</span><br /> +<br /> +<span class="S9">#include "hello_world.hpp"</span><br /> +<br /> +<span class="S5">namespace</span><span class="S0"> </span>bp<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>boost<span class="S10">::</span>python<span class="S10">;</span><br /> +<br /> +BOOST_PYTHON_MODULE<span class="S10">(</span>hw<span class="S10">){</span><br /> +<span class="S0"> </span>bp<span class="S10">::</span>enum_<span class="S10"><</span>color<span class="S10">>(</span><span class="S6">"Color"</span><span class="S10">)</span><br /> +<span class="S0"> </span><span class="S10">.</span>value<span class="S10">(</span><span class="S6">"blue"</span><span class="S10">,</span><span class="S0"> </span>blue<span class="S10">)</span><br /> +<span class="S0"> </span><span class="S10">.</span>value<span class="S10">(</span><span class="S6">"green"</span><span class="S10">,</span><span class="S0"> </span>green<span class="S10">)</span><br /> +<span class="S0"> </span><span class="S10">.</span>value<span class="S10">(</span><span class="S6">"red"</span><span class="S10">,</span><span class="S0"> </span>red<span class="S10">)</span><br /> +<span class="S0"> </span><span class="S10">.</span>export_values<span class="S10">()</span><br /> +<span class="S0"> </span><span class="S10">;</span><br /> +<br /> +<span class="S0"> </span>bp<span class="S10">::</span>class_<span class="S10"><</span><span class="S0"> </span>animal<span class="S10">,</span><span class="S0"> </span>boost<span class="S10">::</span>noncopyable<span class="S0"> </span><span class="S10">>(</span><span class="S0"> </span><span class="S6">"animal"</span><span class="S10">,</span><span class="S0"> </span>bp<span class="S10">::</span>init<span class="S10"><</span><span class="S0"> </span>bp<span class="S10">::</span>optional<span class="S10"><</span><span class="S0"> </span>std<span class="S10">::</span>string<span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S10">&</span><span class="S0"> </span><span class="S10">></span><span class="S0"> </span><span class="S10">>((</span><span class="S0"> </span>bp<span class="S10">::</span>arg<span class="S10">(</span><span class="S6">"name"</span><span class="S10">)=</span><span class="S6">""</span><span class="S0"> </span><span class="S10">))</span><span class="S0"> </span><span class="S10">)</span><span class="S0"> </span><br /> +<span class="S0"> </span><span class="S10">.</span>def<span class="S10">(</span><span class="S6">"get_name_ptr"</span><br /> +<span class="S0"> </span><span class="S10">,</span><span class="S0"> </span><span class="S10">&::</span>animal<span class="S10">::</span>get_name_ptr<br /> +<span class="S0"> </span><span class="S10">,</span><span class="S0"> </span>bp<span class="S10">::</span>return_internal_reference<span class="S10"><</span><span class="S0"> </span><span class="S4">1</span><span class="S10">,</span><span class="S0"> </span>bp<span class="S10">::</span>default_call_policies<span class="S0"> </span><span class="S10">>()</span><span class="S0"> </span><span class="S10">)</span><span class="S0"> </span><br /> +<span class="S0"> </span><span class="S10">.</span>def<span class="S10">(</span><span class="S6">"name"</span><br /> +<span class="S0"> </span><span class="S10">,</span><span class="S0"> </span><span class="S10">&::</span>animal<span class="S10">::</span>name<br /> +<span class="S0"> </span><span class="S10">,</span><span class="S0"> </span>bp<span class="S10">::</span>return_value_policy<span class="S10"><</span><span class="S0"> </span>bp<span class="S10">::</span>copy_const_reference<span class="S10">,</span><span class="S0"> </span>bp<span class="S10">::</span>default_call_policies<span class="S0"> </span><span class="S10">>()</span><span class="S0"> </span><span class="S10">);</span><br /> +<br /> +<span class="S0"> </span>bp<span class="S10">::</span>implicitly_convertible<span class="S10"><</span><span class="S0"> </span>std<span class="S10">::</span>string<span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S10">&,</span><span class="S0"> </span>animal<span class="S0"> </span><span class="S10">>();</span><br /> +<span class="S10">}</span><br /> +<span class="S0"></span></span> +</body> +</html> Added: pyplusplus_dev/docs/documentation/tutorials/module_builder/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/www_configuration.py 2006-07-20 07:01:05 UTC (rev 328) @@ -0,0 +1 @@ +name = 'module builder' \ No newline at end of file Added: pyplusplus_dev/docs/documentation/tutorials/pyplusplus_demo.png =================================================================== (Binary files differ) Property changes on: pyplusplus_dev/docs/documentation/tutorials/pyplusplus_demo.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: pyplusplus_dev/docs/documentation/tutorials/tutorials.rest =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/tutorials.rest (rev 0) +++ pyplusplus_dev/docs/documentation/tutorials/tutorials.rest 2006-07-20 07:01:05 UTC (rev 328) @@ -0,0 +1,64 @@ +========= +tutorials +========= + +.. contents:: Table of contents + +------------------- +What is pyplusplus? +------------------- + +.. include:: ./../definition.rest + +------------------- +Graphical interface +------------------- + +`pyplusplus`_ includes a `graphical interface`_. `Graphical interface`_ +is invoked with the ``pyplusplus_gui`` command, or with ``pyplusplus_gui.pyw`` +from the ``scripts`` subdirectory of the `Python`_ installation directory. + +My advise to you - start with `graphical interface`_, because: + * you don't have to learn new API + * few clicks with mouse and you have `boost.python`_ code for your file(s) + * it is very easy to evaluate `pyplusplus`_ using it + * you can check whether `GCC-XML`_ is able to compile your code or not + * you can use it as a guide to `boost.python`_ library + * it is able to generate `pyplusplus`_ code for you + +.. _`graphical interface` : ./pyplusplus_demo.png +.. _`Graphical interface` : ./pyplusplus_demo.png + +--------------- +Getting started +--------------- + +I suppose you decided to do some coding with `pyplusplus`_. `Module builder`_ +tutorials will help you. + +.. _`Module builder` : ./module_builder/module_builder.html + +-------- +Advanced +-------- + +To be written. I think I should cover here the usage of code creators and code +creator's tree. Meanwhile you can take a look on the content of +``examples/custom_code_creator`` directory. It contains example, that shows how +to create your own code creator. To be more specific, it exposes ``get*`` and +``set*`` methods as a single property. + +.. _`pyplusplus` : ./../../pyplusplus.html +.. _`pygccxml` : ./../....//pygccxml/pygccxml.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`SourceForge`: http://sourceforge.net/index.php +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/documentation/tutorials/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/documentation/tutorials/www_configuration.py 2006-07-20 07:01:05 UTC (rev 328) @@ -0,0 +1 @@ +name = 'tutorials' \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-08-01 15:13:23
|
Revision: 375 Author: roman_yakovenko Date: 2006-08-01 08:13:12 -0700 (Tue, 01 Aug 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=375&view=rev Log Message: ----------- updating documentation Modified Paths: -------------- pyplusplus_dev/docs/history/history.rest pyplusplus_dev/docs/pyplusplus.rest Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2006-08-01 13:25:55 UTC (rev 374) +++ pyplusplus_dev/docs/history/history.rest 2006-08-01 15:13:12 UTC (rev 375) @@ -24,7 +24,27 @@ 1. Georgiy Dernovoy contributed a patch, that allows `pyplusplus`_ GUI to save\load last used header file. - + +2. `pyplusplus`_ improved a lot functionality related to providing feedback to user: + + * every package has its own logger + + * only important user messages are written to ``stdout`` + + * user messages are clear + +3. Support for boost.python indexing suite version 2 was implemented. + +4. Every code creator class took ``parent`` argument in ``__init__`` method. + This argument was removed. ``adopt_creator`` and ``remove_creator`` will + set\unset reference to parent. + +5. Generated code for member and free functions was changed. This changed was + introduced to fix compilation errors on msvc 7.1 compiler. + +6. `pyplusplus`_ generates "stable" code. If header files were not changed, + `pyplusplus`_ will not change any file. + ------------- Version 0.8.0 ------------- Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2006-08-01 13:25:55 UTC (rev 374) +++ pyplusplus_dev/docs/pyplusplus.rest 2006-08-01 15:13:12 UTC (rev 375) @@ -14,9 +14,9 @@ Preamble -------- -This introduction will describe code generation process using `pyplusplus`_. +This introduction will describe code generation process using pyplusplus. I hope, that after you finished to read it, you will understand how powerful -`pyplusplus`_ is. +pyplusplus is. ----------------------- Code generation process @@ -24,20 +24,20 @@ `boost.python`_ library allows you to expose C++ code to `Python`_ in quick and elegant way. Almost the whole process of exposing declarations can be automated -by use of `pyplusplus`_. Code generation process, using `pyplusplus`_ consists +by use of pyplusplus. Code generation process, using pyplusplus consists from few steps. Next paragraphs will tell you more about every step. *"read declarations"* --------------------- -`pyplusplus`_ does not reinvent the wheel. `pyplusplus`_ uses `GCC C++ compiler`_ +pyplusplus does not reinvent the wheel. pyplusplus uses `GCC C++ compiler`_ to parse C++ source files. To be more precision, the tool chain looks like this: 1. source code is passed to `GCC-XML`_ 2. `GCC-XML`_ passes it to `GCC C++ compiler`_ 3. `GCC-XML`_ generates an XML description of a C++ program from GCC's internal representation. -4. `pyplusplus`_ uses `pygccxml`_ package to read `GCC-XML`_ generated file. +4. pyplusplus uses `pygccxml`_ package to read `GCC-XML`_ generated file. The bottom line - you can be sure, that all your declarations are read correctly. @@ -55,10 +55,10 @@ a question, what code should be written in order I get access from Python to that functionality -Of course, `pyplusplus`_ can not answer those question, but it provides maximum +Of course, pyplusplus can not answer those question, but it provides maximum help to implement an user requirements. -How can `pyplusplus`_ help you with first question? `pyplusplus`_ provides very +How can pyplusplus help you with first question? pyplusplus provides very powerful and simple query interface. For example in one line of code you can select all free functions that have @@ -88,16 +88,16 @@ the rules, that will continue to work even after exported C++ code was changed. It means that you don't have to change code generator source code every time. -So far, so good what about second question? Well, by default `pyplusplus`_ -generates a code that will satisfy almost all developers. `pyplusplus`_ relevant +So far, so good what about second question? Well, by default pyplusplus +generates a code that will satisfy almost all developers. pyplusplus relevant classes could be configured in many ways to satisfy your needs. But sometimes this is still not enough. There are use cases when you need full control over generated code. One of the biggest problems, with code generators in general, is modifying generated code and preserving changes. How many code generators did you use or know, that allow you to put your code any where or to reorder generated -code as you wish? `pyplusplus`_ allows you to do that. +code as you wish? pyplusplus allows you to do that. -`pyplusplus`_ introduces new concept: code creator and code creator's tree. +pyplusplus introduces new concept: code creator and code creator's tree. You can think about code creator's tree as some kind of `AST`_. The only difference is that code creator's tree has higher interface. For example ``include_t`` code creator is responsible to create C++ ``include`` directive code. You have full @@ -112,11 +112,11 @@ *"write code to files"* ----------------------- -During this step `pyplusplus`_ reads code creators tree and writes code to the +During this step pyplusplus reads code creators tree and writes code to the disc.The result of code generation process should not be different from the one, that would be achieved by human. For small project writing all code into single file is good approach, for big ones code should be written into multiple files. -`pyplusplus`_ implements both strategies. +pyplusplus implements both strategies. ------------- Features list This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-08-09 12:50:48
|
Revision: 389 Author: roman_yakovenko Date: 2006-08-09 05:50:32 -0700 (Wed, 09 Aug 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=389&view=rev Log Message: ----------- updating documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/architecture.rest pyplusplus_dev/docs/history/history.rest pyplusplus_dev/docs/links.rest Modified: pyplusplus_dev/docs/documentation/architecture.rest =================================================================== --- pyplusplus_dev/docs/documentation/architecture.rest 2006-08-09 06:06:50 UTC (rev 388) +++ pyplusplus_dev/docs/documentation/architecture.rest 2006-08-09 12:50:32 UTC (rev 389) @@ -168,7 +168,8 @@ ------------- Do you know how many ways exist to export member function? It is up to you to -find the answer to the question. Please consider next use cases: +find the answer to the question. Please consider next function properties and +mix of them: * function is non virtual, virtual or pure virtual @@ -178,20 +179,34 @@ * function could be an ``operator()`` or an ``operator[]`` -As you see, there are a lot of use cases. How does code creators solves the -problem? There is almost a direct mapping between code creators and use cases. -Code creator knows what code should be generated, in order to export this or that -declaration. That is the only job of code creators. For example: +* function could be overloaded -* ``code_creators.enum_t`` generates code, that will export named enum +As you see, there are a lot of use cases. How does ``code creator``s solves the +problem? There is almost a direct mapping between ``code creator``s and use cases. +``Code creator`` knows what code should be generated, in order to export a +declaration. That is the only job of ``code creator``s. For example: + +* ``code_creators.enum_t`` generates registration code for an enumeration -* ``code_creators.indexing_suite2_t`` generates code, that will export stl container +* ``code_creators.indexing_suite2_t`` generates registration code for an stl container -There are primary 2 kinds of code creators: declaration based and others. -Declaration based code creator creates code or part of it, that will export the -declaration. For example: in order to export virtual function, `pyplusplus`_ -creates 3 code creators: +* ``code_creators.mem_fun_pv_t`` generates registration code for public, pure + virtual function + +* ``code_creators.mem_fun_pv_wrapper_t`` generates declaration code for public, + pure virtual function + +* ``code_creators.include_t`` generates include directives +* ``code_creators.custom_text_t`` adds some custom( read user ) text\\code to + the generated code + +As you can see, there are primary 2 kinds of ``code creator``s: declaration based +and others. Declaration based creator generate code, that is needed to export the +declaration. There a lot of use cases, where in order to export a declaration, +`pyplusplus`_ builds more then one ``code creator``. For example: in order to +export virtual function 3 ``code creator``s are built: + ( I will reuse example from `boost.python`_ `tutorials`__.) .. __ : http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.virtual_functions_with_default_implementations @@ -202,7 +217,12 @@ 3. ``f`` registration code -Now when you understand, what code creator is, it is a time to move on - composite +Reminder: classes, defined in ``pyplusplus.decl_wrappers`` package, are used as +configuration to ``code creator``. So, ``code creator`` keeps reference to +declaration and when it is requested to generate code, it does this according +to declaration configuration. + +Now when you understand, what ``code creator`` is, it is a time to move on - composite code creator. Composite code creator is a creator, that contains other creators. For example: ``code_creators.class_t`` or ``code_creators.module_t``. They embed the code created by internal code creators within the code they create. Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2006-08-09 06:06:50 UTC (rev 388) +++ pyplusplus_dev/docs/history/history.rest 2006-08-09 12:50:32 UTC (rev 389) @@ -22,8 +22,8 @@ 0.8.1 ----- -1. Georgiy Dernovoy contributed a patch, that allows `pyplusplus`_ GUI to save\load - last used header file. +1. Georgiy Dernovoy contributed a patch, that allows `pyplusplus`_ GUI to + save\\load last used header file. 2. `pyplusplus`_ improved a lot functionality related to providing feedback to user: Modified: pyplusplus_dev/docs/links.rest =================================================================== --- pyplusplus_dev/docs/links.rest 2006-08-09 06:06:50 UTC (rev 388) +++ pyplusplus_dev/docs/links.rest 2006-08-09 12:50:32 UTC (rev 389) @@ -11,14 +11,20 @@ Thanks to Allen Bierbaum `pyplusplus`_ now has `wiki`_. We use it primary to discuss new features, that will be introduced in future versions. +.. _`wiki` : https://realityforge.vrsource.org/view/PyppApi/WebHome + ------- Reading ------- * `Building Hybrid Systems with Boost.Python`_ + .. _`Building Hybrid Systems with Boost.Python` : http://www.boost-consulting.com/writing/bpl.html + * `A rationale for semantically enhanced library languages`_ + .. _`A rationale for semantically enhanced library languages` : http://www.research.att.com/~bs/SELLrationale.pdf + ".. A Semantically Enhanced Library Language (a SEL language or a SELL) is a dialect created by supersetting a language using a library and then subsetting the result using a tool that `understands` the syntax and semantics of both @@ -28,14 +34,43 @@ * `Aspect oriented programming`_ - + + .. _`Aspect oriented programming` : http://en.wikipedia.org/wiki/Aspect-oriented_programming + `pyplusplus`_ borrowed few ideas from this programming paradigm. +-------------- +Help resources +-------------- -.. _`Aspect oriented programming` : http://en.wikipedia.org/wiki/Aspect-oriented_programming -.. _`A rationale for semantically enhanced library languages` : http://www.research.att.com/~bs/SELLrationale.pdf -.. _`Building Hybrid Systems with Boost.Python` : http://www.boost-consulting.com/writing/bpl.html -.. _`wiki` : https://realityforge.vrsource.org/view/PyppApi/WebHome +* http://www.google.com :-) + +* http://boost.org/libs/python/doc/index.html - tutorials, FAQs, reference + manuals + +* `boost.python wiki`_ + + .. _`boost.python wiki` : http://wiki.python.org/moin/boost%2epython?action=show&redirect=boost+2epython + +* http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/ - `boost.python`_ + unit tests. They could be very, very helpful. + +* http://svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/ - `pyplusplus`_ + unit tests. They could be even more helpful! + +------------- +Mailing lists +------------- + +* `C++-sig`_ - development of Python/C++ bindings + + .. _`C++-sig` : http://mail.python.org/mailman/listinfo/c++-sig/ + +* `pyplusplus mailing list`_ + + .. _`pyplusplus mailing list` : http://sourceforge.net/mail/?group_id=118209 + +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html .. _`pyplusplus` : ./pyplusplus.html .. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-08-14 19:47:32
|
Revision: 402 Author: roman_yakovenko Date: 2006-08-14 12:47:23 -0700 (Mon, 14 Aug 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=402&view=rev Log Message: ----------- updating docs Modified Paths: -------------- pyplusplus_dev/docs/documentation/architecture.rest pyplusplus_dev/docs/pyplusplus.rest Modified: pyplusplus_dev/docs/documentation/architecture.rest =================================================================== --- pyplusplus_dev/docs/documentation/architecture.rest 2006-08-14 12:47:13 UTC (rev 401) +++ pyplusplus_dev/docs/documentation/architecture.rest 2006-08-14 19:47:23 UTC (rev 402) @@ -16,9 +16,9 @@ C++ is very powerful programming language. The power brings complexity. It is not an easy task to parse C++ source files and to create in memory representation -of declarations tree. Lets say that I've managed to do it. It is not enough. -Declarations tree is worth nothing, if a user is not able to explorer it, to run -queries against it, to find out traits of a declaration or a type. +of declarations tree. Lets say that I've managed to do it. It is not enough. The +declarations tree is worth nothing, if a user is not able to explorer it, to run +queries against it or to find out traits of a declaration or a type. On the earlier stage of the development, I realized, that all this functionality does not belong to code generator and should be implemented out side of it. @@ -52,15 +52,16 @@ `Py++`_ uses different approaches to expose these services to the user. Parsing integration -------------------- -`Py++`_ provides it's own "API" to configure and run `pygccxml`_ parsing -services. The "API" I am talking about, is arguments to ``module_builder.__init__`` -method. The method takes all arguments, needed to envoke parsing services. It -has been done this way to simplify the usage of `Py++`_. +------------------- +`Py++`_ provides it's own "API" to configure `pygccxml`_ parsing services. The +"API" I am talking about, is arguments to ``module_builder.__init__`` method. +We think, that exposing those services via `Py++`_ simplifies its usage. + Declarations tree integration ----------------------------- + Declarations tree API consists from 3 parts: * interface definition: @@ -72,16 +73,14 @@ * type traits * query engine API + +The user should be familiar with these parts and relevant API. In my opinion, +wrapping\\hidding\\modifying the API will not provide an additonal value. The +interface of all those services is pretty simple and well polished. -The user should be familiar with these part and relevant API of `pygccxml`_ project. -The reason is simple: in my opinion, wrapping/hidding/modifying the API will not -provide an additonal value. The interface of all those services is pretty simple -and well polished. +Please take a look on next source code: -The question you should ask now is: how is this API integrated? Before I start to -explain, lets take a look on next source code: - :: mb = module_builder_t( ... ) @@ -106,9 +105,7 @@ What is the point of this example? From the user point of view it is perfectly good, it makes a lot of sence to configure the code generation engine, using -the declarations tree. Now, the desired solution is clear: we should use -declarations tree to configure the engine. So, let me to re-formulate the -question: how does `Py++`_ add missinig functionality to +the declarations tree. How does `Py++`_ add missinig functionality to ``pygccxml.declarations`` classes? There were few possible solutions to the problem. The next one was implemented: @@ -119,8 +116,8 @@ 2. ``pyplusplus.decl_wrappers`` package defines classes, that derive from ``pygccxml.declarations`` classes and defines the factory. -Also, this solution is not the simplest one, it provides an additional value to -the project: +The implemented solution is not the simplest one, it provides an additional value +to the project: * the code generation engine configuration and declarations tree are tightly coupled @@ -142,25 +139,19 @@ Code generation engine ---------------------- -Code generation for `Boost.Python`_ library is a difficult process. It is very -difficult to solve it as is. I prefer to apply `divide and conquer`_ paradigm. -There are 2 different problems the engine should solve: +Code generation for `Boost.Python`_ library is a difficult process. After small +analizes I understood, that there are 2 different problems the engine should solve: .. _`divide and conquer` : http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm * What code should be created in order to export a declaration? - I mean what `Boost.Python`_ code should be generated if you want to export this - or that declaration. - - Code creators is the solution to this problem. - * How it should be written to files? Remember, `Py++`_ is targeting big projects. It can not generate all code in one file - this will not work, not at all. - Code creators and file writers provides solution to this problem. +Code creators and file writers provides solution to both problems. Code creators @@ -182,7 +173,7 @@ As you see, there are a lot of use cases. How does ``code creator``'s solve the problem? There is almost a direct mapping between ``code creator``'s and use cases. -``Code creator`` knows what code should be generated, in order to export a +``Code creator`` knows what code should be created, in order to export a declaration. That is the only job of ``code creator``. For example: * ``code_creators.enum_t`` generates registration code for an enumeration @@ -211,16 +202,19 @@ .. __ : http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.virtual_functions_with_default_implementations -1. ``BaseWrap::f``, ``BaseWrap::default_f`` - ``code_creators.mem_fun_v_wrapper_t`` +1. ``BaseWrap::f``, ``BaseWrap::default_f`` - declaration code is created by + ``code_creators.mem_fun_v_wrapper_t`` -2. ``f`` registration code - ``code_creators.mem_fun_v_t`` - +2. ``f`` registration code is created by ``code_creators.mem_fun_v_t``. This + code creator also keeps reference to the relevant instance of + ``code_creators.mem_fun_v_wrapper_t`` class. -Reminder: classes, defined in ``pyplusplus.decl_wrappers`` package, are used as -configuration to ``code creator``. So, ``code creator`` keeps reference to -declaration and when it is requested to generate code, it does this according -to the declaration configuration. +Declaration based ``code creator`` keeps reference to the declaration ( +``pyplusplus.decl_wrapper.*`` class instance ). During code creation process, +``code creator`` reads its settings( the code generation engine instructions ) +from the declaration. + ``Code creator``'s are the only classes, that generate the code! Composite ``code creator`` is a creator, that contains other creators. Composite @@ -270,32 +264,31 @@ <free_function_t ...> <...> -I hope, now you understand the termine ``code creators tree``. +I hope, now you understand the termine ``code creators tree``. You can think +about code creator's tree as some kind of `AST`_. +.. _`AST`: http://en.wikipedia.org/wiki/Abstract_syntax_tree + Code creators tree construction ------------------------------- -``pygccxml.declarations`` package defines declarations visitor class. -``pyplusplus.module_creator.creator_t`` class derives from this class. Its main -job is to create ``code creators tree``. You can think about this class as a -big "switch-case" statement. This is the only class that fully "understands" -declarations and ``code creators``. It reads a declaration and then constructs -one or more ``code creator``'s and put them into the tree. +``pyplusplus.module_creator.creator_t`` class is responsible for the task. As +input it gets whole declarations tree. Extracts all declarations that should be +exported and sorts them. After this it constructs ``code creators tree``. -There is one interesting thing about this class you should know: this is the only -class that "sees" all declarations. It monitors all exported functions and -variables. Thus it knows that class ``X`` is used with ``boost::shared_ptr``, -so it will set ``class_<X>`` ``HeldType`` to be ``boost::shared_ptr`` or will -register its usage. Another interesting example is std containers. You don't have -to say to `Py++`_ to export them, it will do it by itself. You may ask -why this detail is so interesting? Because the user does not have to specify all -set of declarations he wants to export! Because, in near future, `Py++`_ -will analize declarations dependency graph of exported declarations. If some -declaration should be exported and it is not, then `Py++`_ will warn the -user. +Another responsibility of the class, is to analize declarations and their +dependency graphs. Today, only limited subset of the functionality is implemented: +* find out a class ``HeldType`` +* find out smart pointers conversion, that should be registered +* find out std containers, that should be exported + +Next functionality is still missing: if some declaration is not exported and +it used somewhere in exported declarations, `Py++`_ will warn user. + + File writers ------------ Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2006-08-14 12:47:13 UTC (rev 401) +++ pyplusplus_dev/docs/pyplusplus.rest 2006-08-14 19:47:23 UTC (rev 402) @@ -97,9 +97,9 @@ you use or know, that allow you to put your code any where or to reorder generated code as you wish? Py++ allows you to do that. -Py++ introduces new concept: code creator and code creator's tree. -You can think about code creator's tree as some kind of `AST`_. The only difference -is that code creator's tree has higher interface. For example ``include_t`` code +Py++ introduces new concept: code creator and code creators tree. You can think +about code creators tree as some kind of `AST`_. The only difference is that code +creators tree provides more specific functionality. For example ``include_t`` code creator is responsible to create C++ ``include`` directive code. You have full control over code creators tree, before it is written to disc. Here you can find UML diagram of almost all code creators: `class diagram`_. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-08-16 08:44:39
|
Revision: 411 Author: roman_yakovenko Date: 2006-08-16 01:44:16 -0700 (Wed, 16 Aug 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=411&view=rev Log Message: ----------- updating docs - removing white spaces, inserted by MS Word Modified Paths: -------------- pyplusplus_dev/docs/documentation/how_to.rest pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest pyplusplus_dev/docs/documentation/tutorials/tutorials.rest pyplusplus_dev/docs/examples/examples.rest pyplusplus_dev/docs/history/history.rest pyplusplus_dev/docs/peps/peps_index.rest pyplusplus_dev/docs/pyplusplus.rest pyplusplus_dev/docs/quotes.rest Removed Paths: ------------- pyplusplus_dev/docs/peps/indexing_suite.rest Modified: pyplusplus_dev/docs/documentation/how_to.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/documentation/how_to.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -110,9 +110,9 @@ That's all. ------------------------------------------------------------- +------------------------------------------------------------- Fatal error C1204:Compiler limit: internal structure overflow ------------------------------------------------------------- +------------------------------------------------------------- If you get this error, that the generated file is too big. You will have to split it to few files. Well, not you but `Py++`_ you will only have to tell that Modified: pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -8,18 +8,20 @@ What is Py++? ------------- -.. include:: ./../../../definition.rest +.. include:: ./../../../definition.rest -------- Preamble -------- I guess you decided to try `Py++`_ API. Good! Lets start. First of all, -please take a look on two files: +please take a look on two files: + * `hello_world.hpp`_ - C++ source code, that we want to export to Python - -* `generate_code.py`_ - Python code, that uses `Py++`_ to export + + +* `generate_code.py`_ - Python code, that uses `Py++`_ to export declarations from the source file .. _`hello_world.hpp` : ./hello_world.html @@ -30,10 +32,10 @@ ---------------- `Py++`_ is built from a few packages, but there is only one package, you -should really to be familiar with - ``module_builder``. This package is some kind -of facade to low level API. It provides simple and intuitive API. The main -class within this package is ``module_builder_t``. The instance of this class will -guide you through the whole process. Next few paragraphs will tell you more about +should really to be familiar with - ``module_builder``. This package is some kind +of facade to low level API. It provides simple and intuitive API. The main +class within this package is ``module_builder_t``. The instance of this class will +guide you through the whole process. Next few paragraphs will tell you more about this class. ------------------------- @@ -46,18 +48,18 @@ 1. ``files`` - list of all C++ source files, that declarations from them, you want to expose. This is the only required parameter. - + 2. ``gccxml_path`` - path to `GCC-XML`_ binary. If you don't supply this argument `pygccxml`_ will look for it using your environment variable ``PATH``. - -There are some other arguments: +There are some other arguments: + * additional include directories * [un]defined symbols ( macros ) * declarations cache * ... -Parsing of source files is done within this method. Post condition of this +Parsing of source files is done within this method. Post condition of this method is - all declarations has been successfully extracted from the sources files. @@ -67,7 +69,7 @@ Not all declarations should be exported! Not every declaration could be exported without human invocation! As you already saw from example, `Py++`_ provides simple and powerful declarations query interface. By default, only declarations -that belongs to files, you have asked to parse, and to files, that lies in the same +that belongs to files, you have asked to parse, and to files, that lies in the same directories as parsed files, will be exported: :: @@ -76,11 +78,11 @@ impl_a.h impl_b.h include/ - a.h //includes impl_a.h + a.h //includes impl_a.h b.h //includes impl_b.h all.h //includes a.h and b.h mb = module_builder( [ 'all.h' ] ) - + All declarations that belongs to ``include`` directory will be signed as included to exporting. All other declarations will be ignored. @@ -94,63 +96,65 @@ * to include/exclude declarations * to set call policies * ... - -I think it is critical for beginners to see what is going on, right? -``module_builder_t`` class has ``print_declarations`` method. You can print whole -declarations tree or some specific declaration. Very convenient, very useful. - + + +I think it is critical for beginners to see what is going on, right? +``module_builder_t`` class has ``print_declarations`` method. You can print whole +declarations tree or some specific declaration. Very convenient, very useful. + ----------------------------------- module_builder_t.build_code_creator ----------------------------------- -Now it is a time to create module code creator. Do you remember, in introduction -to `Py++`_, I told you that before writing code to disc, `Py++`_ will -create some kind of `AST`_. Well this is done by calling -``module_builder_t.build_code_creator`` function. Right now, the only important -argument to the function is ``module_name``. Self explained, is it? - -What is the main value of code creators? Code creators allow you to modify -code before it has been written to disk. For example one common requirement for -open source projects it to have license text within every source file. You can -do it with one line of code only: -:: - - mb.code_creator.license = your license text - -After you call this function, I recommend you not to change declarations -configuration. In most cases the change will take effect, in some cases it will -not! - -This tutorial is not cover code creators and how you should work with them. -I will write another tutorial. - -.. _`AST`: http://en.wikipedia.org/wiki/Abstract_syntax_tree - ------------------------------ -module_builder_t.write_module ------------------------------ -You have almost created your module. The last things left is to write module -code to file(s). You can do it with - -* ``module_builder_t.write_module`` - you should provide file name, the code - will be written in. - -* ``module_builder_t.split_module`` - you should provide directory name. - For big projects it is a must to minimize compilation time. So `Py++`_ - splits your module source code to different files within the directory. - - ------- -Result ------- - -`View generated file`_ - -.. _`View generated file` : ./result.html - - -That's all. I hope you enjoyed. +Now it is a time to create module code creator. Do you remember, in introduction +to `Py++`_, I told you that before writing code to disc, `Py++`_ will create some +kind of `AST`_. Well this is done by calling ``module_builder_t.build_code_creator`` +function. Right now, the only important argument to the function is ``module_name``. +Self explained, is it? + +What is the main value of code creators? Code creators allow you to modify +code before it has been written to disk. For example one common requirement for +open source projects it to have license text within every source file. You can +do it with one line of code only: + +:: + + mb.code_creator.license = your license text + +After you call this function, I recommend you not to change declarations +configuration. In most cases the change will take effect, in some cases it will +not! + +This tutorial is not cover code creators and how you should work with them. +I will write another tutorial. + +.. _`AST`: http://en.wikipedia.org/wiki/Abstract_syntax_tree + +----------------------------- +module_builder_t.write_module +----------------------------- + +You have almost created your module. The last things left is to write module +code to file(s). You can do it with + +* ``module_builder_t.write_module`` - you should provide file name, the code + will be written in. + +* ``module_builder_t.split_module`` - you should provide directory name. + For big projects it is a must to minimize compilation time. So `Py++`_ + splits your module source code to different files within the directory. + +------ +Result +------ + +`View generated file`_ + +.. _`View generated file` : ./result.html + +That's all. I hope you enjoyed. + .. _`Py++` : ./../../../pyplusplus.html .. _`pygccxml` : ./../../../../pygccxml/pygccxml.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html Modified: pyplusplus_dev/docs/documentation/tutorials/tutorials.rest =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/tutorials.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/documentation/tutorials/tutorials.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -3,51 +3,57 @@ ========= .. contents:: Table of contents - + ------------- What is Py++? ------------- -.. include:: ./../../definition.rest - -------------------- -Graphical interface -------------------- - -`Py++`_ includes a `graphical interface`_. `Graphical interface`_ -is invoked with the ``pyplusplus_gui`` command, or with ``pyplusplus_gui.pyw`` -from the ``scripts`` subdirectory, of the `Python`_ installation directory. - -My advise to you - start with `graphical interface`_, because: - * you don't have to learn new API - * few clicks with mouse and you have `Boost.Python`_ code for your file(s) - * it is very easy to evaluate `Py++`_ using it - * you can check whether `GCC-XML`_ is able to compile your code or not - * you can use it as a guide to `Boost.Python`_ library - * it is able to generate `Py++`_ code for you - -.. _`graphical interface` : ./pyplusplus_demo.png -.. _`Graphical interface` : ./pyplusplus_demo.png - ---------------- -Getting started ---------------- - -I suppose you decided to do some coding with `Py++`_. `Module builder`_ -tutorials will help you. - -.. _`Module builder` : ./module_builder/module_builder.html - --------- -Advanced --------- - -To be written. I think I should cover here the usage of code creators and code -creators tree. Meanwhile you can take a look on the content of -``examples/custom_code_creator`` directory. It contains example, which shows how -to create your own code creator. To be more specific, it exposes ``get*`` and -``set*`` methods as a single property. +.. include:: ./../../definition.rest +------------------- +Graphical interface +------------------- +`Py++`_ includes a `graphical interface`_. `Graphical interface`_ is invoked +with the ``pyplusplus_gui`` command, or with ``pyplusplus_gui.pyw`` from the +``scripts`` subdirectory, of the `Python`_ installation directory. + +My advise to you - start with `graphical interface`_, because: + + * you don't have to learn new API + + * few clicks with mouse and you have `Boost.Python`_ code for your file(s) + + * it is very easy to evaluate `Py++`_ using it + + * you can check whether `GCC-XML`_ is able to compile your code or not + + * you can use it as a guide to `Boost.Python`_ library + + * it is able to generate `Py++`_ code for you + +.. _`graphical interface` : ./pyplusplus_demo.png +.. _`Graphical interface` : ./pyplusplus_demo.png + +--------------- +Getting started +--------------- + +I suppose you decided to do some coding with `Py++`_. `Module builder`_ +tutorials will help you. + +.. _`Module builder` : ./module_builder/module_builder.html + +-------- +Advanced +-------- + +To be written. I think I should cover here the usage of code creators and code +creators tree. Meanwhile you can take a look on the content of +``examples/custom_code_creator`` directory. It contains example, which shows how +to create your own code creator. To be more specific, it exposes ``get*`` and +``set*`` methods as a single property. + + .. _`Py++` : ./../../pyplusplus.html .. _`pygccxml` : ./../....//pygccxml/pygccxml.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html Modified: pyplusplus_dev/docs/examples/examples.rest =================================================================== --- pyplusplus_dev/docs/examples/examples.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/examples/examples.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -7,8 +7,9 @@ ------------------- Graphical interface ------------------- - -`Py++`_ has nice, small and simple `graphical interface`_. Please, read + + +`Py++`_ has nice, small and simple `graphical interface`_. Please, read `tutorials`_ for more information. .. _`graphical interface` : ./../tutorials/pyplusplus_demo.png @@ -16,34 +17,33 @@ --------- pyeasybmp ---------- - -`EasyBMP`_ is a small cross-platform library that provide you functionality -needed to work with Windows bitmap (BMP) image files. I took me only few minutes -to create Python bindings for the library. Read more `here`__. - -.. __ : ./easybmp/easybmp.html - ---------------- -boost libraries ---------------- - -Boost provides free peer-reviewed portable C++ source libraries. +--------- -Using `Py++`_ I created Python bindings for few libraries: +`EasyBMP`_ is a small cross-platform library that provide you functionality +needed to work with Windows bitmap (BMP) image files. I took me only few minutes +to create Python bindings for the library. Read more `here`__. +.. __ : ./easybmp/easybmp.html + +--------------- +boost libraries +--------------- + +Boost provides free peer-reviewed portable C++ source libraries. Using `Py++`_ I +created Python bindings for few libraries: + * `Boost.Date_Time`_ * `Boost.CRC`_ * `Boost.Rational`_ * `Boost.Random`_ -This is not "just another example". I went father and created new package: +This is not "just another example". I went father and created new package: `pyboost`_. This is fully working Python package, with almost all unit test from -the libraries ported to Python. For more information please read `pyboost`_ +the libraries ported to Python. For more information please read `pyboost`_ package documentation. .. _`pyboost` : ./boost/boost.html - + .. _`boost.date_time` : http://boost.org/doc/html/date_time.html .. _`boost.crc` : http://boost.org/libs/crc/index.html .. _`boost.rational` : http://boost.org/libs/rational/index.html Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/history/history.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -4,7 +4,6 @@ .. contents:: Table of contents - ------------ Contributors ------------ @@ -15,48 +14,61 @@ * John Pallister * Matthias Baas * Allen Bierbaum - * Lakin Wecker + * Lakin Wecker + * Georgiy Dernovoy - ------ -0.8.1 ------ - -1. Georgiy Dernovoy contributed a patch, which allows `Py++`_ GUI to - save\\load last used header file. - -2. `Py++`_ improved a lot functionality related to providing feedback to user: - - * every package has its own logger - - * only important user messages are written to ``stdout`` - - * user messages are clear - -3. Support for Boost.Python indexing suite version 2 was implemented. - -4. Every code creator class took ``parent`` argument in ``__init__`` method. - This argument was removed. ``adopt_creator`` and ``remove_creator`` will - set\unset reference to parent. - -5. Generated code for member and free functions was changed. This changed was - introduced to fix compilation errors on msvc 7.1 compiler. - -6. `Py++`_ generates "stable" code. If header files were not changed, - `Py++`_ will not change any file. - -7. Support for huge classes was added. `Py++`_ is able to split registration - code for the class to multiple cpp files. - -8. User code could be added almost anywhere, without use of low level API. - -9. Generated source files include only header files you passes as an argument - to module builder. - -10. Bug fixes. - -11. Documentation was improved.. - + +------------ +Project name +------------ + +In version 0.8.1 project has been renamed from "pyplusplus" to "Py++". +There were few reasons to this: + +1. I like "Py++" more then "pyplusplus". + +2. "Py++" was the original name of the project: http://mail.python.org/pipermail/c++-sig/2005-July/009280.html + +3. Users always changed the name of the projects. I saw at least 6 different names. + + +----- +0.8.1 +----- + +1. Georgiy Dernovoy contributed a patch, which allows `Py++`_ GUI to + save\\load last used header file. + +2. `Py++`_ improved a lot functionality related to providing feedback to user: + + * every package has its own logger + * only important user messages are written to ``stdout`` + * user messages are clear + +3. Support for Boost.Python indexing suite version 2 was implemented. + +4. Every code creator class took ``parent`` argument in ``__init__`` method. + This argument was removed. ``adopt_creator`` and ``remove_creator`` will + set\unset reference to parent. + +5. Generated code for member and free functions was changed. This changed was + introduced to fix compilation errors on msvc 7.1 compiler. + +6. `Py++`_ generates "stable" code. If header files were not changed, + `Py++`_ will not change any file. + +7. Support for huge classes was added. `Py++`_ is able to split registration + code for the class to multiple cpp files. + +8. User code could be added almost anywhere, without use of low level API. + +9. Generated source files include only header files you passes as an argument + to module builder. + +10. Bug fixes. + +11. Documentation was improved.. + ------------- Version 0.8.0 ------------- Deleted: pyplusplus_dev/docs/peps/indexing_suite.rest =================================================================== --- pyplusplus_dev/docs/peps/indexing_suite.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/peps/indexing_suite.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -1,99 +0,0 @@ -====================== -Indexing suite support -====================== - -.. contents:: Table of contents - -------------------- -What is useful for? -------------------- - -http://boost.org/libs/python/doc/v2/indexing.html - -------------- -The way to go -------------- -The generated code should work, even if it contains usage of STD containers -classes. There are few ways to implement indexing suite support within `Py++`_. -I will describe, how I think it should be implemented and used by user. - -Generated code --------------- -All generated code will have next form: -:: - - class_< container, other class parameters >(name) - .def( concrete indexing suite class< container, proxy, derived policies >() ) - ; - -Usage example -------------- -C++ code: -:: - - #include <map> - #include <vector> - -:: - - std::vector<string> get_options(){...} - -:: - - struct my_data{...}; - std::map< int, my_data > get_data(); - -Assumption: user wants to use ``get_options`` and ``get_data`` functions. Next -steps will describe what `Py++`_ will do in this case: - -1. `Py++`_ will analyze functions return type and arguments. - -2. It will understand that ``std::vector< std::string >`` and ``std::map< int, my_data >`` - classes should be exported too. - -3. It will understand that those classes should be exported using indexing suite - functionality provided by `Boost.Python`_ library or `Py++`_ - ``code repository``. - -4. It will generate the code, which will use that functionality. - -So far, so good. Sometimes, there are use cases, when user has to change default -values, for example ``NoProxy`` or ``DerivedPolicies``. What interface `Py++`_ -will provide in order to change the defaults? Well, ``std::vector< std::string >`` -is the class that could be found in declarations tree, right? User can find the -class and change the defaults: -:: - - mb = module_builder_t( ... ) - #the next line will not work, because the real name of std::vector< std::string > - #is platform dependent and much longer. It is there for simplicity. - vector_of_strings = mb.class_( "std::vector< std::string >" ) - vector_of_strings.alias = "StringVector" - vector_of_strings.held_type = ... - vector_of_strings.indexing_suite.no_proxy = False - - -Please, pay attention to the next line: -:: - - vector_of_strings.indexing_suite.no_proxy = False - -Every class, which represents instantiation of some STD container will have -class variable ``indexing_suite``, that will be initialized with relevant -indexing suite class. - - - -.. _`Py++` : ./../pyplusplus.html -.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html -.. _`Python`: http://www.python.org -.. _`GCC-XML`: http://www.gccxml.org - -.. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - End: - Modified: pyplusplus_dev/docs/peps/peps_index.rest =================================================================== --- pyplusplus_dev/docs/peps/peps_index.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/peps/peps_index.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -6,55 +6,52 @@ ----------- Description ------------ - -This page is an official `Py++`_ "TODO" page. - -For small features, the description of the feature and it's implementation will -be written here. Big features will get their own page. - ---------------- -Unnamed classes ---------------- -There is no technical reason why unnamed classes/structs/unions are not exported -by `Py++`_: -:: - - class Foo{ - union { - struct { - float r,g,b,a; - }; - float val[4]; - }; - }; - -Implementation details ----------------------- -As it seems to me, the only code that should be changed is -"pyplusplus/module_creator/creator.py" file. To be more specific: all code creators, -for declarations in unnamed classes, should be created under named class. - -The coding itself should take something like 4 - 5 hours, including unit test. - ---------------------- -Call wrapper policies ---------------------- - -Not all functions could be exposed to Python as is. This `document`__ will -explain how `Py++`_ will help users to create wrappers around those functions. - -.. __ : ./call_wrapper_policies.html - --------------- -Indexing suite --------------- - -`Py++`_ will expose C++ STD containers. This `document`__ will describe -how it will work. +----------- -.. __ : ./indexing_suite.html +This page is an official `Py++`_ "TODO" page. +For small features, the description of the feature and it's implementation will +be written here. Big features will get their own page. + +--------------- +Unnamed classes +--------------- + +There is no technical reason why unnamed classes/structs/unions are not exported + +by `Py++`_: + +:: + + class Foo{ + union { + struct { + float r,g,b,a; + }; + float val[4]; + }; + }; + + +Implementation details +---------------------- + +As it seems to me, the only code that should be changed is +"pyplusplus/module_creator/creator.py" file. To be more specific: all code creators, +for declarations in unnamed classes, should be created under named class. + +The coding itself should take something like 4 - 5 hours, including unit test. + +--------------------- +Call wrapper policies +--------------------- + +Not all functions could be exposed to Python as is. This `document`__ will +explain how `Py++`_ will help users to create wrappers around those functions. + +.. __ : ./call_wrapper_policies.html + + .. _`Py++` : ./../pyplusplus.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html .. _`Python`: http://www.python.org Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/pyplusplus.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -8,69 +8,72 @@ What is Py++? ------------- -.. include:: ./definition.rest +.. include:: ./definition.rest -------- Preamble -------- -This introduction will describe code generation process using Py++. +This introduction will describe code generation process using Py++. I hope, that after you finished to read it, you will understand how powerful -Py++ is. +Py++ is. ----------------------- Code generation process ----------------------- -`Boost.Python`_ library allows you to expose C++ code to `Python`_ in quick and -elegant way. Almost the whole process of exposing declarations can be automated -by use of Py++. Code generation process, using Py++ consists -from few steps. Next paragraphs will tell you more about every step. +`Boost.Python`_ library allows you to expose C++ code to `Python`_ in quick and +elegant way. Almost the whole process of exposing declarations can be automated +by use of Py++. Code generation process, using Py++ consists +from few steps. Next paragraphs will tell you more about every step. + *"read declarations"* ---------------------- +--------------------- -Py++ does not reinvent the wheel. It uses `GCC C++ compiler`_ to parse C++ -source files. To be more precise, the tool chain looks like this: - -1. source code is passed to `GCC-XML`_ -2. `GCC-XML`_ passes it to `GCC C++ compiler`_ -3. `GCC-XML`_ generates an XML description of a C++ program from GCC's internal - representation. -4. Py++ uses `pygccxml`_ package to read `GCC-XML`_ generated file. - -The bottom line - you can be sure, that all your declarations are read correctly. - -.. _`GCC C++ compiler` : http://www.gnu.org/software/gcc +Py++ does not reinvent the wheel. It uses `GCC C++ compiler`_ to parse C++ +source files. To be more precise, the tool chain looks like this: +1. source code is passed to `GCC-XML`_ + +2. `GCC-XML`_ passes it to `GCC C++ compiler`_ + +3. `GCC-XML`_ generates an XML description of a C++ program from GCC's internal + representation. + +4. Py++ uses `pygccxml`_ package to read `GCC-XML`_ generated file. + +The bottom line - you can be sure, that all your declarations are read correctly. + +.. _`GCC C++ compiler` : http://www.gnu.org/software/gcc + + *"build module"* ----------------- -Only very small and simple projects could be exported as is. Most of the projects -still require human invocation. Basically there are 2 questions that you should +Only very small and simple projects could be exported as is. Most of the projects +still require human invocation. Basically there are 2 questions that you should answer: - 1. which declarations should be exported - 2. how this specific declaration should be exported or, if I change a little - a question, what code should be written in order I get access from Python + 1. which declarations should be exported + 2. how this specific declaration should be exported or, if I change a little + a question, what code should be written in order I get access from Python to that functionality -Of course, Py++ cannot answer those question, but it provides maximum -help to implement an user requirements. - -How can Py++ help you with first question? Py++ provides very -powerful and simple query interface. +Of course, Py++ cannot answer those question, but it provides maximum help to +implement an user requirements. -For example in one line of code you can select all free functions that have -two arguments, where the first argument has type ``int &`` and the type of the -second argument is any: +How can Py++ help you with first question? Py++ provides very powerful and +simple query interface. For example in one line of code you can select all free +functions that have two arguments, where the first argument has type ``int &`` +and the type of the second argument is any: :: mb = module_builder_t( ... ) #module_builder_t is the main class that #will help you with code generation process mb.free_functions( arg_types=[ 'int &', None ] ) -An other example - the developer wants to exclude all protected functions from +An other example - the developer wants to exclude all protected functions from being exported: :: @@ -83,109 +86,110 @@ mb = module_builder_t( ... ) mb.decls( lambda decl: 'impl' in decl.name ).exclude() - -Please, note the way queries were built. You can think about those queries as -the rules, which will continue to work even after exported C++ code was changed. -It means that you don't have to change code generator source code every time. -So far, so good what about second question? Well, by default Py++ -generates a code that will satisfy almost all developers. Py++ relevant -classes could be configured in many ways to satisfy your needs. But sometimes -this is still not enough. There are use cases when you need full control over -generated code. One of the biggest problems, with code generators in general, is -modifying generated code and preserving changes. How many code generators did -you use or know, that allow you to put your code anywhere or to reorder generated -code as you wish? Py++ allows you to do that. -Py++ introduces new concept: code creator and code creators tree. You can think -about code creators tree as some kind of `AST`_. The only difference is that code -creators tree provides more specific functionality. For example ``include_t`` code -creator is responsible to create C++ ``include`` directive code. You have full -control over code creators tree, before it is written to disc. Here you +Please, note the way queries were built. You can think about those queries as +the rules, which will continue to work even after exported C++ code was changed. +It means that you don't have to change code generator source code every time. + +So far, so good what about second question? Well, by default Py++ generates a +code that will satisfy almost all developers. Py++ relevant classes could be +configured in many ways to satisfy your needs. But sometimes this is still not +enough. There are use cases when you need full control over generated code. One +of the biggest problems, with code generators in general, is modifying generated +code and preserving changes. How many code generators did you use or know, that +allow you to put your code anywhere or to reorder generated code as you wish? +Py++ allows you to do that. + +Py++ introduces new concept: code creator and code creators tree. You can think +about code creators tree as some kind of `AST`_. The only difference is that code +creators tree provides more specific functionality. For example ``include_t`` code +creator is responsible to create C++ ``include`` directive code. You have full +control over code creators tree, before it is written to disc. Here you can find UML diagram of almost all code creators: `class diagram`_. - + .. _`AST`: http://en.wikipedia.org/wiki/Abstract_syntax_tree .. _`class diagram`: ./code_creators_uml.png -At the end of this step you have code creators tree, which is ready to be written +At the end of this step you have code creators tree, which is ready to be written to disc. -*"write code to files"* +*"write code to files"* ----------------------- -During this step Py++ reads code creators tree and writes code to the -disc. The result of code generation process should not be different from the one, -that would be achieved by human. For small project writing all code into single +During this step Py++ reads code creators tree and writes code to the +disc. The result of code generation process should not be different from the one, +that would be achieved by human. For small project writing all code into single file is good approach, for big ones code should be written into multiple files. -Py++ implements both strategies. +Py++ implements both strategies. ------------- Features list ------------- * classes - + * class wrappers - + * two modes of code generation: - + * using scope - better error messages location from compiler - + * no scope - + * automatic detection of held type - + * nested classes - + * implicit conversion * functions - + * virtual methods - + * protected method, even non-virtual ones can be accessed from `Python`_. - + * overloading - + * two modes of code generation: - - * with function type - good for exporting template instantiated + + * with function type - good for exporting template instantiated functions and overloaded ones. - + * without function type - + * static methods - + * code generated for wrapped methods takes into account types of arguments - + * operators, both free and member ones - + * call policies resolver - - * enumerations + * enumerations + * variables, bit fields * namespace aliasing and using - + * writing multiple files - + * user code could be inserted almost any where * write code into file if there were changes - * user license is written at the top of every file - + * user license is written at the top of every file + * extracting documentation from source files and integrating it with generated source code - + * ... ------- License ------- -`Boost Software License`_. - +`Boost Software License`_. + .. _`Py++` : ./pyplusplus.html .. _`pygccxml` : ./../pygccxml/pygccxml.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html Modified: pyplusplus_dev/docs/quotes.rest =================================================================== --- pyplusplus_dev/docs/quotes.rest 2006-08-16 08:43:25 UTC (rev 410) +++ pyplusplus_dev/docs/quotes.rest 2006-08-16 08:44:16 UTC (rev 411) @@ -1,78 +1,76 @@ -========================= -What they say about Py++? -========================= +========================= +What they say about Py++? +========================= .. contents:: Table of contents ----------------- What do they say? ----------------- - -"... If you can, use pyplusplus over pyste. I say that for ALL users of -pyste, pyplusplus is now mature enough to be useful as well as being -actively developed. It can also do quite a few tricks pyste cannot. " - - Niall Douglas, the author of `TnFOX`_ library - -"... On a related note, I highly suggest that any users out there that have -tried/used Pyste but have found it to be too lacking in power should -really give pyplusplus a try. It has allowed me to do everything I -ever wanted to do with Pyste and couldn't and then some. It is really -a great tool and I can't thank Roman enough for taking the time to -create it and make it available. " - +"... If you can, use pyplusplus over pyste. I say that for ALL users of +pyste, pyplusplus is now mature enough to be useful as well as being +actively developed. It can also do quite a few tricks pyste cannot. " + + Niall Douglas, the author of `TnFOX`_ library + + +"... On a related note, I highly suggest that any users out there that have +tried/used Pyste but have found it to be too lacking in power should +really give pyplusplus a try. It has allowed me to do everything I +ever wanted to do with Pyste and couldn't and then some. It is really +a great tool and I can't thank Roman enough for taking the time to +create it and make it available. " + Allen Bierbaum, the author of `PyOpenSG`_ library - -"... This rule based approach is amazing for maintenance, as it reduces the -turnaround for binding new code. If the new Ogre API's follow similar rules and -standards as previously defined, the same set of rules will appropriately bind -the new API without any effort on the part of the maintainers. " - -" ... In general, I've really liked working with pyplusplus. I've probably spent -20-30 hours working on these bindings, and they are very close to being equivalent -to the PyOgre bindings (when I last used them). " - - Lakin Wecker, the author of `Python-OGRE`_ project - + +"... This rule based approach is amazing for maintenance, as it reduces the +turnaround for binding new code. If the new Ogre API's follow similar rules and +standards as previously defined, the same set of rules will appropriately bind +the new API without any effort on the part of the maintainers. " + +" ... In general, I've really liked working with pyplusplus. I've probably spent +20-30 hours working on these bindings, and they are very close to being equivalent +to the PyOgre bindings (when I last used them). " + + Lakin Wecker, the author of `Python-OGRE`_ project + ------------------ Who is using Py++? ------------------ -* Matthias Baas, the author of `Python Computer Graphics Kit`_ project, is using - `Py++`_ to create Python bindings for `Maya C++ SDK`__. - +* Matthias Baas, the author of `Python Computer Graphics Kit`_ project, is using + `Py++`_ to create Python bindings for `Maya C++ SDK`__. .. __ : http://www.highend3d.com/maya - -* Lakin Wecker, the author of `Python-OGRE`_ project, is using `Py++`_ to - create Python bindings for `OGRE`_. - +* Lakin Wecker, the author of `Python-OGRE`_ project, is using `Py++`_ to + create Python bindings for `OGRE`_. + * I am :-). I created Python bindings for next libraries: - + * `Boost.Date_Time`_ * `Boost.CRC`_ * `Boost.Rational`_ * `Boost.Random`_ -.. _`boost.date_time` : http://boost.org/doc/html/date_time.html -.. _`boost.crc` : http://boost.org/libs/crc/index.html -.. _`boost.rational` : http://boost.org/libs/rational/index.html -.. _`boost.random` : http://boost.org/libs/random/index.html + .. _`boost.date_time` : http://boost.org/doc/html/date_time.html + .. _`boost.crc` : http://boost.org/libs/crc/index.html + .. _`boost.rational` : http://boost.org/libs/rational/index.html + .. _`boost.random` : http://boost.org/libs/random/index.html You can download the bindings from https://sourceforge.net/project/showfiles.php?group_id=118209 . .. _`Py++` : ./pyplusplus.html -.. _`Python Computer Graphics Kit` : http://cgkit.sourceforge.net/ -.. _`TnFOX`: http://www.nedprod.com/TnFOX/ -.. _`PyOpenSG`: https://realityforge.vrsource.org/view/PyOpenSG/WebHome -.. _`Python-OGRE` : http://lakin.weckers.net/index_ogre_python.html -.. _`OGRE` : http://www.ogre3d.org/index.php?option=com_content&task=view&id=19&Itemid=79 -.. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - End: +.. _`Python Computer Graphics Kit` : http://cgkit.sourceforge.net/ +.. _`TnFOX`: http://www.nedprod.com/TnFOX/ +.. _`PyOpenSG`: https://realityforge.vrsource.org/view/PyOpenSG/WebHome +.. _`Python-OGRE` : http://lakin.weckers.net/index_ogre_python.html +.. _`OGRE` : http://www.ogre3d.org/index.php?option=com_content&task=view&id=19&Itemid=79 +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-10-10 13:18:37
|
Revision: 638 http://svn.sourceforge.net/pygccxml/?rev=638&view=rev Author: roman_yakovenko Date: 2006-10-10 06:18:29 -0700 (Tue, 10 Oct 2006) Log Message: ----------- adding new directory that will contain ready-to-learn solutions Added Paths: ----------- pyplusplus_dev/docs/bpl_lessons_learned/ pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py Added: pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest 2006-10-10 13:18:29 UTC (rev 638) @@ -0,0 +1,38 @@ +============================== +Boost.Python - lessons learned +============================== + +.. contents:: Table of contents + +-------- +Preamble +-------- + +Software development is an interactrive process. During `Py++`_ development +I see many interesting problems and even more interesting solutions. + +On this page you will find my collection of the solutions to some of the problems. + + +`Custom smart pointer class`_ + + There are projects, which use custom smart pointer(s). For majority of the + projects, it is not an option to switch to ``boost::shared_ptr``. The + solution contains source code and comprehensive unit test for the problem. + + +.. _`Custom smart pointer class` : ./smart_ptr/smart_ptr.html + + +.. _`Py++` : ./../pyplusplus.html +.. _`pygccxml` : http://www.language-binding.net/pygccxml/pygccxml.html +.. _`SourceForge`: http://sourceforge.net/index.php + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: + Added: pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py 2006-10-10 13:18:29 UTC (rev 638) @@ -0,0 +1,3 @@ +name = 'Boost.Python - lessons learned' +main_html_file = 'lessons_learned.html' +names = { 'lessons_learned' : 'Boost.Python - lessons learned' } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-10-11 10:44:22
|
Revision: 644 http://svn.sourceforge.net/pygccxml/?rev=644&view=rev Author: roman_yakovenko Date: 2006-10-11 03:43:41 -0700 (Wed, 11 Oct 2006) Log Message: ----------- switching from :: ( rest preformated block ) to .. code-block:: Modified Paths: -------------- pygccxml_dev/docs/design.rest pygccxml_dev/docs/history/history.rest pygccxml_dev/docs/pygccxml.rest pygccxml_dev/docs/query_interface.rest pyplusplus_dev/docs/comparisons/pyste.rest pyplusplus_dev/docs/documentation/architecture.rest pyplusplus_dev/docs/documentation/best_practices.rest pyplusplus_dev/docs/documentation/containers.rest pyplusplus_dev/docs/documentation/doc_string.rest pyplusplus_dev/docs/documentation/feedback.rest pyplusplus_dev/docs/documentation/hints.rest pyplusplus_dev/docs/documentation/how_to.rest pyplusplus_dev/docs/documentation/inserting_code.rest pyplusplus_dev/docs/documentation/properties.rest pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest pyplusplus_dev/docs/examples/boost/boost.rest pyplusplus_dev/docs/history/history.rest pyplusplus_dev/docs/peps/dsl_challenge.rest pyplusplus_dev/docs/peps/function_transformation.rest pyplusplus_dev/docs/peps/peps_index.rest pyplusplus_dev/docs/pyplusplus.rest Modified: pygccxml_dev/docs/design.rest =================================================================== --- pygccxml_dev/docs/design.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pygccxml_dev/docs/design.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -255,12 +255,15 @@ -------- Well, `GCC-XML`_ has few bugs, which could not be fixed from it. For example -:: +.. code-block:: C++ + namespace ns1{ namespace ns2{ enum fruit{ apple, orange }; } } +.. code-block:: C++ + void fix_enum( ns1::ns2::fruit arg=ns1::ns2::apple ); `GCC-XML`_ will report the default value of ``arg`` as ``apple``. Obviously Modified: pygccxml_dev/docs/history/history.rest =================================================================== --- pygccxml_dev/docs/history/history.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pygccxml_dev/docs/history/history.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -122,8 +122,9 @@ This has been done in order to provide stable order of enumeration values. 4. Now you can pass operator symbol, as a name to query functions: - :: + .. code-block:: Python + cls = global_namespace.class_( 'my_class' ) op = cls.operator( '<' ) #instead of @@ -154,8 +155,9 @@ of the same name in the decl interface from ``declarations.scopedef_t`` class. So for example: - :: + .. code-block:: Python + classes = ns.decls("class") classes.decls("method") Modified: pygccxml_dev/docs/pygccxml.rest =================================================================== --- pygccxml_dev/docs/pygccxml.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pygccxml_dev/docs/pygccxml.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -89,8 +89,9 @@ try to give small example, that will prove my point. If you want to know more about provided API please read `query interface`__ document or API documentation. Examples: -:: +.. code-block:: Python + #global_ns is the reference to declarations that describes C++ namespace. #In our case, instance of that declarations describes global ( :: ) namespace. global_ns.free_functions( "do_smth", return_type='void', arg_types=[None,'int'] ) @@ -98,14 +99,15 @@ Small explanation. Assume that ``None`` means "any type". Now the code is pretty readable: + :: - select all free functions - where - name equal to "do_smth" - return type is void - function has two arguments - second argument type is int + select all free functions from the project + where + name equal to "do_smth" + return type is void + function has two arguments + second argument type is int .. __: ./query_interface.html Modified: pygccxml_dev/docs/query_interface.rest =================================================================== --- pygccxml_dev/docs/query_interface.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pygccxml_dev/docs/query_interface.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -15,7 +15,7 @@ I don't care about first argument type, but I do want second argument type to be a reference to an integer. More over, I want those functions names to end with "impl" string and they should be protected or private. -:: +.. code-block:: Python #global_ns is the reference to an instance of namespace_t object, that #represents global namespace @@ -26,7 +26,7 @@ The example is complex, but still readable. In many cases you will find your self looking for one or many declarations using one or two properties of that declaration(s). For example: -:: +.. code-block:: Python global_ns.namespaces( 'details' ) @@ -53,7 +53,7 @@ I will explain the usage of ``member_function`` and ``member_functions`` methods. The usage of other methods is very similar to them. Here is definition of those methods: -:: +.. code-block:: Python def member_function( self, name=None, @@ -81,8 +81,9 @@ * ``name`` Python string, that contains member function name or full name. - :: + .. code-block:: Python + do_smth = my_class.member_function( 'do_smth' ) do_smth = my_class.member_function( 'my_namespace::my_class::do_smth' ) @@ -91,8 +92,9 @@ Python callable object. You would use this functionality, if you need to build custom query. This object will be called with one argument - declaration, and it should return ``True`` or ``False``. - :: + .. code-block:: Python + impls = my_class.member_functions( lambda decl: decl.name.endswith( 'impl' ) ) ``impls`` will contain all member functions, that their name ends with "impl". @@ -101,8 +103,9 @@ Function return type. This argument can be Python string or an object that describes C++ type. - :: + .. code-block:: Python + mem_funcs = my_class.member_functions( return_type='int' ) i = declarations.int_t() @@ -117,8 +120,9 @@ type. Size of list says how many arguments function should have. If you want to skip some argument type from within comparison, you put ``None``, into relevant position within the list. - :: + .. code-block:: Python + mem_funcs = my_class.member_functions( arg_types=[ None, 'int'] ) ``mem_funcs`` will contain all member functions, that have two arguments @@ -178,13 +182,16 @@ objects at once. I will give an example from another project - `Py++`_. In order to help `Boost.Python`_ to manage objects life time, all functions should have `call policies`_. For example: -:: +.. code-block:: C++ + struct A{ A* clone() const { return new A(); } ... }; +.. code-block:: C++ + struct B{ B* clone() const { return new B(); } ... @@ -193,8 +200,9 @@ `Call policies`_ of the member function ``clone`` is ``return_value_policy<manage_new_object>()``. Next code applies `call policies`_ on all ``clone`` member functions within the project. -:: +.. code-block:: Python + #global_ns - instance of namespace_t class, that contains reference to global namespace clone = global_ns.member_functions( 'clone' ) clone.call_policies = return_value_policy( manage_new_object ) @@ -210,7 +218,7 @@ class you don't have to write loops. If will do it for you. Also if you insist to write loops, ``mdecl_wrapper_t`` class implements ``__len__``, ``__getitem__`` and ``__iter__`` methods. So you can write next code: -:: +.. code-block:: Python for clone in global_ns.member_functions( 'clone' ): print clone.parent.name Modified: pyplusplus_dev/docs/comparisons/pyste.rest =================================================================== --- pyplusplus_dev/docs/comparisons/pyste.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/comparisons/pyste.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -185,12 +185,17 @@ * identify "call policies" algorithm * code creator that generates body of "overridden" virtual functions: - :: + .. code-block:: C++ + struct expensive_to_copy{...}; + .. code-block:: C++ + void do_smth( expensive_to_copy* x, const expensive_to_copy& y ){...} + .. code-block:: C++ + void do_smth(expensive_to_copy* x, const expensive_to_copy& y){ //Pyste generates next code @@ -326,16 +331,18 @@ those directories into account. * To define namespace alias. - :: + .. code-block:: C++ + namespace dt = boost::date_time; All code, which is generated after this statement, will use ``dt`` instead of ``boost::date_time``. This allows `Py++`_ to create user-friendly code. * Classes and functions support 2 modes of code generation. Example: - :: + .. code-block:: C++ + struct world{ void set(std::string msg) { this->msg = msg; } std::string greet() { return msg; } @@ -343,8 +350,9 @@ }; First mode: - :: + .. code-block:: C++ + class_<world>("world") .def("greet", &world::greet) .def("set", &world::set) @@ -352,8 +360,9 @@ Second mode: - :: + .. code-block:: C++ + if( true ){ typedef class_<world> world_exposer_t; world_exposer_t world_exposer; Modified: pyplusplus_dev/docs/documentation/architecture.rest =================================================================== --- pyplusplus_dev/docs/documentation/architecture.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/architecture.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -85,16 +85,16 @@ Before I explain how these services are integrated, take a look on next source code: -:: +.. code-block:: Python mb = module_builder_t( ... ) -:: +.. code-block:: Python details = mb.namespace( 'details' ) details.exclude() -:: +.. code-block:: Python my_class = mb.class_( 'my_class' ) my_class.rename("MyClass") @@ -229,7 +229,7 @@ Here is "cut & paste" of the relevant code from the source file: - :: + .. code-block:: Python def _create_impl(self): result = [] Modified: pyplusplus_dev/docs/documentation/best_practices.rest =================================================================== --- pyplusplus_dev/docs/documentation/best_practices.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/best_practices.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -41,7 +41,7 @@ ``module_builder_t.__init__`` methods takes reference to an instance of cache class or ``None``: - :: + .. code-block:: Python from module_builder import * mb = module_builder_t( ..., cache=file_cache_t( path to project cache file ), ... ) @@ -60,13 +60,12 @@ implemented an initial version of the functionality. After small discussion, we agreed on next interface: - :: + .. code-block:: Python class module_builder_t( ... ): ... def split_module( self, directory_path, huge_classes=None, precompiled_header=None ): ... - ... ``precompiled_header`` argument could be ``None`` or string, that contains name of precompiled header file, which will be created in the directory. @@ -78,7 +77,7 @@ `this error`_. `Py++`_ will automatically split generated code for the huge classes to few files: - :: + .. code-block:: Python mb = module_builder_t( ... ) ... Modified: pyplusplus_dev/docs/documentation/containers.rest =================================================================== --- pyplusplus_dev/docs/documentation/containers.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/containers.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -77,8 +77,9 @@ By default, `Py++`_ works with built-in indexing suite. If you want to use next version of indexing suite, you should tell this to the ``module_builder_t.__init__`` method: -:: +.. code-block:: Python + mb = module_builder_t( ..., indexing_suite_version=2 ) Every declared class has ``indexing_suite`` property. If the class is an @@ -121,8 +122,9 @@ In this case there is no single place, where you can configure exported container functionality. Please take a look on next C++ code: -:: +.. code-block:: C++ + struct item{ ... private: Modified: pyplusplus_dev/docs/documentation/doc_string.rest =================================================================== --- pyplusplus_dev/docs/documentation/doc_string.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/doc_string.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -15,7 +15,7 @@ API description --------------- -:: +.. code-block:: Python mb = module_builder_t( ... ) my_class = mb.class_( 'my_class' ) @@ -37,7 +37,7 @@ ``doc_extractor`` is a callable object, which takes one argument - reference to declaration. -:: +.. code-block:: Python def doc_extractor( decl ): ... Modified: pyplusplus_dev/docs/documentation/feedback.rest =================================================================== --- pyplusplus_dev/docs/documentation/feedback.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/feedback.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -24,27 +24,27 @@ them and in some cases provide hints about how to resolve the problem. Few examples: * - :: + .. code-block:: C++ - struct Y{ ... }; - + struct Y{ ... }; + + .. code-block:: C++ + struct X{ ... virtual Y& do_smth(); - ... }; Member function ``do_smth`` can not be overridden in Python because... [FILL IN HERE]. * - :: + .. code-block:: C++ struct window{ ... void get_size( int& heght, int& widht ) const; - ... }; - + Member function ``get_size`` can be exposed to Python, but it will not be callable because [FILL IN HERE]. * In order to expose free/member function that takes more than 10 arguments user @@ -80,12 +80,12 @@ 1. If you simply want to change the logging message level: - :: + .. code-block:: Python import logging from pyplusplus import module_builder - :: + .. code-block:: Python module_builder.set_logger_level( logging.DEBUG ) @@ -101,20 +101,15 @@ Both packages define a ``loggers`` class. Those classes keep references to different loggers. The ``loggers`` classes look very similar to the next class: - :: + .. code-block:: Python import logging #standard Python package - - :: - + def _create_logger_( name ): logger = logging.getLogger(name) ... return logger - - - :: - + class loggers: file_writer = _create_logger_( 'pyplusplus.file_writer' ) declarations = _create_logger_( 'pyplusplus.declarations' ) Modified: pyplusplus_dev/docs/documentation/hints.rest =================================================================== --- pyplusplus_dev/docs/documentation/hints.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/hints.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -12,23 +12,18 @@ template, than `Py++`_ will use it as a `Python`_ class name. For example: -:: - #include <vector> +.. code-block:: C++ -:: - + #include <vector> typedef std::vector< int > numbers; - -:: - numbers generate_n(){ ... } `Py++`_ will use "numbers" as Python class name: -:: +.. code-block:: C++ using boost::python; class_< std::vector< int > >( "numbers" ) Modified: pyplusplus_dev/docs/documentation/how_to.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/how_to.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -7,17 +7,17 @@ ---------------------------------------- How to add custom exception translation? ---------------------------------------- -:: +.. code-block:: C++ + struct my_exception{ ... const std::string& error() const; - ... } First of all lets define ``translate`` function: -:: +.. code-block:: Python translate_code = \ """ @@ -26,14 +26,14 @@ } """ -:: +.. code-block:: Python mb.add_declaration_code( translate_code ) Now we should register it: -:: +.. code-block:: Python registration_code = "boost::python::register_exception_translator<my_exception>(&translate);" mb.add_registration_code( registration_code ) @@ -43,7 +43,7 @@ `Py++`_ allows you to define a query that will return you all exception classes: -:: +.. code-block:: Python mb = module_builder_t( ... ) exception_classes = mb.decls( lambda decl: decl.name.endswith( 'exception' ) ) @@ -56,25 +56,25 @@ ------------------------------------------------------- How to expose function, which has hand-written wrapper? ------------------------------------------------------- -:: +.. code-block:: C++ struct window_t{ ... void get_size( int& height, int& widht ) const; - ... }; You can not expose ``get_size`` function as is - ``int`` is immutable type in Python. So, we need to create a wrapper to the function: -:: +.. code-block:: C++ + boost::python::tuple get_size_wrapper( const window_t& win ){ int height(0), width( 0 ); win.get_size( height, widht ); return boost::python::make_tuple( height, width ); } -:: +.. code-block:: C++ class_<window_t>( ... ) .def( "get_size", &get_size_wrapper ) @@ -84,9 +84,8 @@ Now, after you know how this problem is solved. I will show how this solution could be integrated with `Py++`_. +.. code-block:: Python -:: - wrapper_code = \ """ static boost::python::tuple get_size( const window_t& win ){ @@ -96,11 +95,11 @@ } """ -:: +.. code-block:: Python registration_code = 'def( "get_size", &%s::get_size )' % window.wrapper_alias -:: +.. code-block:: Python mb = module_builder_t( ... ) window = mb.class_( "window_t" ) @@ -132,33 +131,21 @@ ------------------------------------------------------ Lets say you have next C++ function: -:: - //file point.h +.. code-block:: C++ -:: - + // file point.h namespace geometry{ - -:: - - template< class T> - struct point_t{ - T x, y; - }; - -:: - - template <class T> - double distance( const point_t<T>& point ){ - return sqrt( point.x * point.x + point.y*point.y ); - } - -:: - + template< class T> + struct point_t{ + T x, y; + }; + template <class T> + double distance( const point_t<T>& point ){ + return sqrt( point.x * point.x + point.y*point.y ); + } } //namespace geometry - You should understand, that you can not export template itself, but only its instantiations. The solution is built using next facts: @@ -174,11 +161,11 @@ Open your favorite editor and create a header file with the content: -:: +.. code-block:: C++ #include "point.h" -:: +.. code-block:: C++ namespace py_details{ inline void instantiate(){ @@ -194,7 +181,7 @@ ``module_builder_t.__init__`` method and excludes the ``py_details`` namespace declarations from being exported: -:: +.. code-block:: Python mb = module_builder_t( [..., just created file ], ... ) mb.namespace( 'py_details' ).exclude() @@ -207,20 +194,20 @@ The solution is to build your own code generator, which will generate code similar to the one, in the previous paragraph. -:: +.. code-block:: Python from module_builder import module_builder_t, create_text_fc -:: +.. code-block:: Python def generate_instantiations_string( ... ): ... -:: +.. code-block:: Python code = generate_instantiations_string( ... ) -:: +.. code-block:: Python mb = module_builder_t( [ ..., create_text_fc( code ) ], ... ) mb.namespace( 'py_details' ).exclude() @@ -246,7 +233,7 @@ --------------------------------------------------- How to deal with template on return type functions? --------------------------------------------------- -:: +.. code-block:: C++ struct environment_t{ ... @@ -269,8 +256,9 @@ Otherwise, you will discover the errors while testing the bindings. Generated code: -:: +.. code-block:: C++ + bp::class_< environment_t >( "environment_t" ) ... .def( "get_value" @@ -279,8 +267,9 @@ , (::std::string ( ::environment_t::* )( ::std::string const & ) )( &::environment_t::get_value ) ); The correct code: -:: +.. code-block:: C++ + bp::class_< environment_t >( "environment_t" ) .def( "get_value" , (int ( ::environment_t::* )( ::std::string const & ) )( &::environment_t::get_value< int > ) ) @@ -290,8 +279,9 @@ //------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^ The perfect one: -:: +.. code-block:: C++ + bp::class_< environment_t >( "environment_t" ) ... .def( "get_value", &::environment_t::get_value< int > ) @@ -299,7 +289,7 @@ Solution -------- -:: +.. code-block:: Python mb = module_builder_t( ..., optimize_queries=False, ... ) environment = mb.class_( "environment_t" ) Modified: pyplusplus_dev/docs/documentation/inserting_code.rest =================================================================== --- pyplusplus_dev/docs/documentation/inserting_code.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/inserting_code.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -18,7 +18,7 @@ Almost every ``Boost.Python`` module has next structure: -:: +.. code-block:: C++ //declarations code ... @@ -45,7 +45,7 @@ Example ------- -:: +.. code-block:: Python mb = module_builder_t( ... ) mb.build_code_creator( ... ) @@ -60,7 +60,7 @@ ``class_t`` declaration defines few methods, which add user code to the generated one. Lets take a look on next use case: -:: +.. code-block:: C++ struct window_t{ ... @@ -74,7 +74,7 @@ In the near future `Py++`_ will eliminate the need of creating hand written wrapper for this use case. -:: +.. code-block:: C++ boost::python::tuple get_window_size( const window_t& win ){ int h(0), w(0); @@ -84,7 +84,7 @@ Now you have to register it: -:: +.. code-block:: C++ using boost::python; class_< window_t >( ... ) @@ -112,15 +112,17 @@ What is ``works_on_instance`` argument for? In our case, we added new method to the class. The first argument of the call will be ``self``. - :: + .. code-block:: Python + #From Python user can call this method like this: win = window_t( ) height, width = win.get_size() If you will pass ``works_on_instance=False`` next code will be generated: - :: + .. code-block:: C++ + { class_< window_t > window_exporter( "window_t" ); scope window_scope( window_exporter ); @@ -129,16 +131,17 @@ } And in this case, user will be forced to pass reference to ``window_t`` object: - - :: + .. code-block:: C++ + win = window_t() height, width = window_t.get_size( win ) Example ------- -:: +.. code-block:: Python + mb = module_builder_t( ... ) window = mb.class_( 'window_t' ) window.add_declaration_code( get_window_size definition ) @@ -174,7 +177,7 @@ Solution -------- -:: +.. code-block:: Python def inject_code( cls ): constructors = cls.constructors() @@ -184,9 +187,9 @@ cls.add_wrapper_code( destructor declaration and definition code ) cls.add_wrapper_code( the new class variable definition code ) - -:: +.. code-block:: Python + mb = module_builder_t( ... ) for cls in mb.classes( relevant classes only ): inject_code( cls ) Modified: pyplusplus_dev/docs/documentation/properties.rest =================================================================== --- pyplusplus_dev/docs/documentation/properties.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/properties.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -18,8 +18,9 @@ ------------- Usage example ------------- -:: +.. code-block:: C++ + struct number{ ... float value() const; @@ -29,7 +30,7 @@ float m_value; } -:: +.. code-block:: Python mb = module_builder_t( ... ) number = mb.class_( 'number' ) @@ -41,8 +42,9 @@ This is rather the hard way to add properties to the class. `Py++`_ comes with built-in algorithm, which automaticly recognizes properties and adds them to the class: -:: +.. code-block:: Python + mb = module_builder_t( ... ) number = mb.class_( 'number' ) number.add_properties( exclude_accessors=False ) #accessors will be exposed @@ -61,10 +63,12 @@ Consider next use case: -:: +.. code-block:: C++ struct nested{ ... }; +.. code-block:: C++ + struct data{ ... const nested& get_nested() const @@ -78,7 +82,7 @@ `call policies`_. Same precondition holds for exposing member function as property: -:: +.. code-block:: Python mb = module_builder_t( ... ) get_nested = mb.member_function( 'get_nested' ) Modified: pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -118,7 +118,7 @@ open source projects it to have license text within every source file. You can do it with one line of code only: -:: +.. code-block:: Python mb.code_creator.license = your license text Modified: pyplusplus_dev/docs/examples/boost/boost.rest =================================================================== --- pyplusplus_dev/docs/examples/boost/boost.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/examples/boost/boost.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -85,19 +85,15 @@ * Python code: - :: + .. code-block:: Python import time from pyboost import boost_random - - :: - + rng = boost_random.mt19937( int( time.time() ) ) #setting initial seed six = boost_random.uniform_int(1,6) die = boost_random.variate_generator( rng, six ) - - :: - + print die() date_time @@ -107,7 +103,7 @@ * Python code: - :: + .. code-block:: Python import os from pyboost import date_time @@ -115,75 +111,53 @@ from pyboost.date_time import posix_time from pyboost.date_time import local_time from pyboost.date_time import to_simple_string - - :: - - # + #Date programming - # + weekstart = gregorian.date(2002, date_time.Feb,1) print 'weekstart: ', to_simple_string( weekstart ) - - :: - + weekend = weekstart + gregorian.weeks(1) print 'weekend: ', to_simple_string( weekend ) - - :: - + today = gregorian.day_clock.local_day() d2 = weekstart + gregorian.days(5) if d2 >= today: #comparison operator pass - - :: - + thisWeek = gregorian.date_period(today,d2) if thisWeek.contains(today): pass - - :: - + #date generator functions + d5 = gregorian.next_weekday(today, date_time.Sunday); #calculate Sunday following d4 print 'd5: ', to_simple_string( d5 ) - - :: - + #US labor day is first Monday in Sept first = gregorian.nth_day_of_the_week_in_month.first labor_day = gregorian.nth_day_of_the_week_in_month(first, date_time.Monday, date_time.Sep) #calculate a specific date for 2004 from functor print 'labor day 2004: ', to_simple_string( labor_day.get_date(2004) ) - - :: - - # + #Time programming: - # + d = gregorian.date(2002,date_time.Feb,1)#an arbitrary date t1 = posix_time.ptime(d, posix_time.hours(5) + posix_time.millisec(100)); #date + time of day offset print 't1: ', to_simple_string( t1 ) - - :: - + t2 = t1 - posix_time.minutes(4) + posix_time.seconds(2) print 't2: ', to_simple_string( t2 ) - - :: - + now = posix_time.second_clock.local_time(); #use the clock print 'now: ', to_simple_string( now ) today = now.date() #Get the date part out of the time print 'today: ', to_simple_string( today ) tomorrow = today + gregorian.date_duration(1) print 'tomorrow: ', to_simple_string( tomorrow ) - - :: - - # + #Local time programming: - # + #setup some timezones for creating and adjusting times #first time zone uses the time zone file for regional timezone definitions tz_db = local_time.time_zone_database() @@ -191,9 +165,7 @@ nyc_tz = tz_db.time_zone_from_region("America/New_York") #This timezone uses a posix time zone string definition to create a time zone phx_tz = local_time.posix_time_zone("MST-07:00:00") - - :: - + #local departure time in phoenix is 11 pm on April 2 2005 #Note that New York changes to daylight savings on Apr 3 at 2 am) phx_departure = local_time.local_date_time( @@ -201,16 +173,13 @@ , posix_time.hours(23) , phx_tz , local_time.local_date_time.NOT_DATE_TIME_ON_ERROR) - - :: - + flight_length = posix_time.hours(4) + posix_time.minutes(30) phx_arrival = phx_departure + flight_length #convert the phx time to a nyz time nyc_arrival = phx_arrival.local_time_in(nyc_tz, posix_time.time_duration() ) print "New York arrival: ", nyc_arrival.to_string() #//2005-Apr-03 06:30:00 EDT - rational ~~~~~~~~ @@ -218,33 +187,26 @@ * Python code: - :: + .. code-block:: Python import unittest from pyboost import rational - - :: - + half = rational.rational( 1, 2 ) one = rational.rational( 1 ) two = rational.rational( 2 ) - - :: - + #Some basic checks assert half.numerator() == 1 assert half.denominator() == 2 assert float(half) == 0.5 - - :: - + #Arithmetic assert half + half == one == 1 assert one - half == half assert two * half == one == 1 assert one / half == two == 2 - crc ~~~ @@ -252,20 +214,18 @@ * Python code: - :: + .. code-block:: Python import os import sys from pyboost import crc - - :: - + if __name__ == '__main__': if sys.argv: files = sys.argv else: files = [ sys.executable ] - + try: result = crc.crc_32_type() for file_name in files: Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/history/history.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -198,16 +198,17 @@ a default argument. 8. `Py++`_ now generates correct code for hierarchy of abstract classes: - :: + .. code-block:: C++ + struct abstract1{ virtual void do_smth() = 0; } - + struct abstract2 : public abstract1{ virtual void do_smth_else() = 0; } - + struct concrete : public abstract2{ virtual void do_smth(){}; virtual void do_smth_else(){}; Modified: pyplusplus_dev/docs/peps/dsl_challenge.rest =================================================================== --- pyplusplus_dev/docs/peps/dsl_challenge.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/peps/dsl_challenge.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -16,7 +16,7 @@ I will use next C++ code as an example: -:: +.. code-block:: C++ namespace geometry{ struct Point{ @@ -40,8 +40,9 @@ 3. to rename ``x`` and ``y`` to ``X`` and ``Y`` Today, in order to configure this class, the user has to write next code: -:: +.. code-block:: Python + mb = module_builder_t( ... ) Point = mb.class_( 'Point' ) Point.member_function( 'create_new' ).call_policies = ... @@ -54,8 +55,9 @@ If class ``Point`` is not unique, than user will have to write a little bit different code: -:: +.. code-block:: Python + Point = mb.global_ns.namespace('geometry').class( 'Point' ) The current approach is pretty readable and simple. The drawbacks of this approach @@ -68,8 +70,9 @@ --------------------------- Better user interface (BUI) --------------------------- -:: +.. code-block:: Python + mb = module_builder_t( ... ) Point = mb.module.geometry.Point Point.create_new.call_policies = ... @@ -102,27 +105,29 @@ BUI does not work for template instantiated classes and functions. If we change class ``Point`` to be template, the special syntax should be introduced: - :: + .. code-block:: C++ template < class Numeric > struct Point{ ... }; - :: +.. code-block:: Python PointTmpl = mb.module.template('Point') Point = PointTmpl( 'int' ) This is a trivial example, that is why it looks grate. Consider next class: - :: +. code-block:: C++ + template< class String, class Allocator > class regex{ ... } The code the user will need to write is: - :: + .. code-block:: Python + regex_tmpl = mb.module.geometry.template( 'regex' ) #white spaces and scope resolution( :: ) are important regex_std_string = regex_tmpl( @@ -131,11 +136,12 @@ Using current `Py++`_ interface the user can get reference to the class instantiation in one line of code: - :: - regex_std_string = mb.class_( - lambda decl: decl.name.startswith( 'regex' ) and 'wchar_t' not in decl.name ) +.. code-block:: Python + regex_std_string = mb.class_( + lambda decl: decl.name.startswith( 'regex' ) and 'wchar_t' not in decl.name ) + * overloaded functions resolution There are use cases, when overloaded functions should be treated differently. @@ -158,8 +164,9 @@ Using BUI the user is forced to write full declaration name, otherwise he faces next problem: -:: +.. code-block:: Python + Point = mb.module.Point Lets analyze what the ``Point`` value: @@ -173,7 +180,7 @@ There are a lot of use cases, when the user has to add some code to the class: - :: + .. code-block:: Python Point.add_registration_code( ... ) Modified: pyplusplus_dev/docs/peps/function_transformation.rest =================================================================== --- pyplusplus_dev/docs/peps/function_transformation.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/peps/function_transformation.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -46,8 +46,9 @@ ft = int get_last_error(); The definition of ``ft`` could look like: -:: +.. code-block:: C++ + int get_last_error_transformed(){ int error(0); get_last_error( error ); @@ -92,29 +93,37 @@ In an ideal world we would have 2 classes, one class - one responsibility. In `Py++`_ it means that we would have ``transformation_t`` class: -:: +.. code-block:: Python + class transformation_t( object ): def __init__( self ): pass +.. code-block:: Python + def check( self, function ): "checks whether the transformation could be applied on the function or not" raise NotImplementedError() +.. code-block:: Python + def signature_changes( self, function ): "returns a list of changes that should be done on function signature" raise NotImplementedError() The class logically belongs to the ``decl_wrappers`` package. The ``transformer_t`` is the second class, which logically belongs to ``code_creators`` package: -:: +.. code-block:: Python + class transformer_t( ast_visitor_t ): def __init__( self, function, transformation ): function is a reference to the declaration we want to apply transformation on transformation is an instance of "concrete" transformation +.. code-block:: Python + def apply( self, function_body_as_tree ): "integrates transformation code to function body" raise NotImplementedError() @@ -146,21 +155,28 @@ Small re-factoring is needed. I don't expect changes in the user code. Proposed class: -:: +.. code-block:: Python + class transformer_t( object ): "base class for all transformation classes" def __init__( self ): pass +.. code-block:: Python + def check( self, function ): "checks whether the transformation could be applied on the function or not" raise NotImplementedError() +.. code-block:: Python + def signature_changes( self, function ): "returns a list of changes that should be done on function signature" raise NotImplementedError() +.. code-block:: Python + def apply( self, sm ): #sm is an instance of the substitution manager "integrates transformation code into function transformation body" raise NotImplementedError() @@ -197,12 +213,15 @@ ------------------------------------- output_arg transformation example ------------------------------------- -:: +.. code-block:: Python + class output_arg_t( transformer_t ): def __init__( self, ordinal ): self.ordinal = ordinal +.. code-block:: Python + def check( self, decl ): if len( decl.arguments ) <= self.ordinal: return user message @@ -210,11 +229,15 @@ if not reference to immutable type: raise user message +.. code-block:: Python + def signature_changes( self, decl ): assert not self.check( decl ) return [ remove_arg( self.ordinal ) , add_var_to_return_value( decl.arguments[ self.ordinal ].name ] - + +.. code-block:: Python + def apply( self, sm ): if sm is wrapper around C++ function: sm. add declaration of variable type = decl.arguments[ self.ordinal ].type @@ -223,6 +246,8 @@ else: #sm is a wrapper around Python function sm. extract value from the tuple and assign it to the argument +.. code-block:: Python + def output_arg( ordinal ): return output_arg_t( ordinal ) @@ -237,8 +262,9 @@ I am going to change a little an example, from `Boost.Python`_ tutorials: http://www.boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies -:: +.. code-block:: C++ + //C++ code struct Y { @@ -246,12 +272,16 @@ int z_value() { return z->value(); } }; +.. code-block:: C++ + X& f(Y& y, Z* z, int& error) { y.z = z; return y.x; } +.. code-block:: C++ + //Boost.Python code def("f", f, return_internal_reference<1, with_custodian_and_ward<1, 2> >() ); @@ -265,8 +295,9 @@ 1. May be it is possible with `Boost.Python`_ library to set call policies on the part of the return value? - :: + .. code-block:: C++ + boost::tuple f_wrapper( Y& y, Z* z ){ int error(0); X& x = f( y, z, error ); @@ -277,8 +308,9 @@ 2. May be it is possible to create Boost.Python ``object`` with life-time management hint? - :: + .. code-block:: C++ + boost::python::tuple f_wrapper( Y& y, Z* z ){ int error(0); X& x = f( y, z, error ); Modified: pyplusplus_dev/docs/peps/peps_index.rest =================================================================== --- pyplusplus_dev/docs/peps/peps_index.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/peps/peps_index.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -21,7 +21,7 @@ by `Py++`_: -:: +.. code-block:: C++ class Foo{ union { Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2006-10-10 22:06:12 UTC (rev 643) +++ pyplusplus_dev/docs/pyplusplus.rest 2006-10-11 10:43:41 UTC (rev 644) @@ -67,27 +67,29 @@ simple query interface. For example in one line of code you can select all free functions that have two arguments, where the first argument has type ``int &`` and the type of the second argument is any: -:: +.. code-block:: Python + mb = module_builder_t( ... ) #module_builder_t is the main class that #will help you with code generation process mb.free_functions( arg_types=[ 'int &', None ] ) An other example - the developer wants to exclude all protected functions from being exported: -:: +.. code-block:: Python + mb = module_builder_t( ... ) mb.calldefs( access_type_matcher_t( 'protected' ) ).exclude() The developer can create custom criteria, for example exclude all declarations that have 'impl' ( implementation ) string within the name. -:: +.. code-block:: Python + mb = module_builder_t( ... ) mb.decls( lambda decl: 'impl' in decl.name ).exclude() - Please, note the way queries were built. You can think about those queries as the rules, which will continue to work even after exported C++ code was changed. It means that you don't have to change code generator source code every time. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-10-12 11:38:49
|
Revision: 659 http://svn.sourceforge.net/pygccxml/?rev=659&view=rev Author: roman_yakovenko Date: 2006-10-12 04:38:31 -0700 (Thu, 12 Oct 2006) Log Message: ----------- fixing broken links, reported by linkchekcer Modified Paths: -------------- developer_scripts/check_links.bat pyplusplus_dev/docs/comparisons/pyste.rest pyplusplus_dev/docs/documentation/best_practices.rest pyplusplus_dev/docs/examples/examples.rest pyplusplus_dev/docs/peps/peps_index.rest Modified: developer_scripts/check_links.bat =================================================================== --- developer_scripts/check_links.bat 2006-10-12 09:57:05 UTC (rev 658) +++ developer_scripts/check_links.bat 2006-10-12 11:38:31 UTC (rev 659) @@ -1 +1 @@ -e:\python24\python.exe e:\python24\Scripts\linkchecker ..\..\language-binding\production\www\index.html +E:\Python24\Scripts\linkchecker.bat ..\..\language-binding\production\www\index.html Modified: pyplusplus_dev/docs/comparisons/pyste.rest =================================================================== --- pyplusplus_dev/docs/comparisons/pyste.rest 2006-10-12 09:57:05 UTC (rev 658) +++ pyplusplus_dev/docs/comparisons/pyste.rest 2006-10-12 11:38:31 UTC (rev 659) @@ -424,7 +424,7 @@ thought about them, long before I created `Py++`_. But unfortunately, lack of time and motivation prevents him to work on `Pyste`_. -.. _`screenshot` : ./../tutorials/pyplusplus_demo.png +.. _`screenshot` : ./../documentation/tutorials/pyplusplus_demo.png .. _`Py++` : ./../pyplusplus.html .. _`pygccxml` : ./../../pygccxml/pygccxml.html .. _`Pyste`: http://www.boost.org/libs/python/doc/index.html Modified: pyplusplus_dev/docs/documentation/best_practices.rest =================================================================== --- pyplusplus_dev/docs/documentation/best_practices.rest 2006-10-12 09:57:05 UTC (rev 658) +++ pyplusplus_dev/docs/documentation/best_practices.rest 2006-10-12 11:38:31 UTC (rev 659) @@ -23,7 +23,7 @@ few hundred of header files. `Py++`_ was born to create `Python`_ bindings for such projects. If you take a look `here`__ you will find few such projects. -.. __ : ./../../pygccxml/quotes.html +.. __ : ./../../pyplusplus/quotes.html Tips ---- Modified: pyplusplus_dev/docs/examples/examples.rest =================================================================== --- pyplusplus_dev/docs/examples/examples.rest 2006-10-12 09:57:05 UTC (rev 658) +++ pyplusplus_dev/docs/examples/examples.rest 2006-10-12 11:38:31 UTC (rev 659) @@ -12,8 +12,8 @@ `Py++`_ has nice, small and simple `graphical interface`_. Please, read `tutorials`_ for more information. -.. _`graphical interface` : ./../tutorials/pyplusplus_demo.png -.. _`tutorials` : ./../tutorials/tutorials.html +.. _`graphical interface` : ./../documentation/tutorials/pyplusplus_gui.html +.. _`tutorials` : ./../documentation/tutorials/tutorials.html --------- pyeasybmp Modified: pyplusplus_dev/docs/peps/peps_index.rest =================================================================== --- pyplusplus_dev/docs/peps/peps_index.rest 2006-10-12 09:57:05 UTC (rev 658) +++ pyplusplus_dev/docs/peps/peps_index.rest 2006-10-12 11:38:31 UTC (rev 659) @@ -49,7 +49,7 @@ Not all functions could be exposed to Python as is. This `document`__ will explain how `Py++`_ will help users to create wrappers around those functions. -.. __ : ./call_wrapper_policies.html +.. __ : ./function_transformation.html ------------------------------------------ Domain Specific Language ( DSL ) challenge This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-10-17 15:04:21
|
Revision: 666 http://svn.sourceforge.net/pygccxml/?rev=666&view=rev Author: roman_yakovenko Date: 2006-10-17 08:03:57 -0700 (Tue, 17 Oct 2006) Log Message: ----------- updating documentation Modified Paths: -------------- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/sconstruct pyplusplus_dev/docs/documentation/functions/call_policies.rest pyplusplus_dev/docs/documentation/functions/default_args.rest pyplusplus_dev/docs/documentation/functions/functions.rest pyplusplus_dev/docs/documentation/functions/overloading.rest Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp 2006-10-16 21:24:52 UTC (rev 665) +++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/bindings.cpp 2006-10-17 15:03:57 UTC (rev 666) @@ -1,8 +1,3 @@ -// Copyright 2004 Roman Yakovenko. -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - #include "boost/python.hpp" #include "classes.hpp" @@ -11,11 +6,13 @@ namespace boost{ namespace python{ //We need to tell Boost.Python how to work with your smart pointer. + //Short explanation: + // "get_pointer" extracts the pointer to the object it manages. + // "pointee" extracts the type of the object, smart pointer manages. + //You can read more about this functionality in the reference manual: //http://boost.org/libs/python/doc/v2/pointee.html . - //In general - // get_pointer extracts the pointer to the object it manages. - // pointee extracts the type of the object smart pointer manages. + template<class T> inline T * get_pointer(smart_ptr_t<T> const& p){ return p.get(); @@ -86,8 +83,9 @@ //Register implicit conversion between smart pointers. Boost.Python library //can not discover relationship between classes.This will allow Boost.Python - //to treat right functions, which expect to get as argument smart_ptr_t< base_i > - //class instance. + //to treat right the functions, which expect to get as argument + //smart_ptr_t< base_i > class instance, when smart_ptr_t< derived from base_i > + //class instance is passed. //For more information about implicitly_convertible see the documentation: //http://boost.org/libs/python/doc/v2/implicit.html . bp::implicitly_convertible< smart_ptr_t< base_wrapper_t >, smart_ptr_t< base_i > >(); @@ -103,7 +101,7 @@ //in Python, which derive from the derived_t class. .def( "get_value", &derived_t::get_value, &derived_wrapper_t::default_get_value ); - //Nothing special, just registering all existing conversion. + //Now register all existing conversion: bp::implicitly_convertible< smart_ptr_t< derived_wrapper_t >, smart_ptr_t< derived_t > >(); bp::implicitly_convertible< smart_ptr_t< derived_t >, smart_ptr_t< base_i > >(); bp::implicitly_convertible< derived_ptr_t, smart_ptr_t< derived_t > >(); Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp 2006-10-16 21:24:52 UTC (rev 665) +++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/classes.hpp 2006-10-17 15:03:57 UTC (rev 666) @@ -1,7 +1,6 @@ #ifndef classes_11_11_2006 #define classes_11_11_2006 - #include "smart_ptr.h" struct base_i{ @@ -68,14 +67,16 @@ } -//Next function could be exposed, but it could not be solved +//Next function could be exposed, but it could not be called from Python, when +//the argument is instance of derived class. +// //This is the explanation David Abrahams gave: -//Naturally; there is no instance of smart_ptr_t<base_i> anywhere in the -//Python object for the reference to bind to. The rules are the same as in C++: +// Naturally; there is no instance of smart_ptr_t<base_i> anywhere in the +// Python object for the reference to bind to. The rules are the same as in C++: // -// int f(smart_ptr_t<base>& x) { return 0; } +// int f(smart_ptr_t<base>& x); // smart_ptr_t<derived> y; -// int z = f(y); // fails to compile +// int z = f(y); // fails to compile inline int ref_get_value( smart_ptr_t< base_i >& a ){ Modified: pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/sconstruct =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/sconstruct 2006-10-16 21:24:52 UTC (rev 665) +++ pyplusplus_dev/docs/bpl_lessons_learned/smart_ptrs/sconstruct 2006-10-17 15:03:57 UTC (rev 666) @@ -1,3 +1,4 @@ +#scons build script SharedLibrary( target=r'custom_sptr' , source=[ r'bindings.cpp' ] , LIBS=[ r"boost_python" ] @@ -3,5 +4,4 @@ , LIBPATH=[ r"/home/roman/boost_cvs/bin",r"" ] , CPPPATH=[ r"/home/roman/boost_cvs",r"/usr/include/python2.4" ] - , CCFLAGS=[ '-DBOOST_PYTHON_TRACE_REGISTRY' ] , SHLIBPREFIX='' , SHLIBSUFFIX='.so' Modified: pyplusplus_dev/docs/documentation/functions/call_policies.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/call_policies.rest 2006-10-16 21:24:52 UTC (rev 665) +++ pyplusplus_dev/docs/documentation/functions/call_policies.rest 2006-10-17 15:03:57 UTC (rev 666) @@ -8,11 +8,11 @@ Introduction ------------ -`Boost.Python`_ has a `nice introduction`__ in the tutorials about call policies. -Also you can find more formal definition - `CallPolicies Concept`_ . +`Boost.Python`_ has a `nice introduction`__ to call policies. `"Call policies concept"`_ +document will provide you with formal definition. .. __ : http://boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies -.. _`CallPolicies Concept` : http://boost.org/libs/python/doc/v2/CallPolicies.html#CallPolicies-concept +.. _`"Call policies concept"` : http://boost.org/libs/python/doc/v2/CallPolicies.html#CallPolicies-concept ------ Syntax @@ -60,51 +60,54 @@ mb = module_builder.module_builder_t( ... ) mb.free_function( 'return_second_arg' ).call_policies = call_policies.return_arg( 2 ) + #---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mb.member_function( 'do_smth' ).call_policies = call_policies.return_self() + #-------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - mb.calldef( 'get_opaque' ).call_policies \ + mb.calldef( 'get_opaque' ).call_policies = call_policies.return_value_policy( call_policies.return_opaque_pointer ) -------- Defaults -------- -`Py++`_ is able to "guess" few call policies, base on analysis of return type: +`Py++`_ is able to "guess" few call policies, base on analysis of return type +and\\or operator name: * ``default_call_policies``: - * `Python`_ immutable type by value: C++ fundamental types, ``std::string``, enumerations + * `Python`_ immutable type returned by value: C++ fundamental types, ``std::string``, enumerations - * user defined type ( class ) by value + * user-defined type ( class ) returned by value - * ``const char*`` + * return type is ``const char*`` * ``return_value_policy`` * ``return_opaque_pointer`` - * ``void*`` + * return type is ``void*`` - * ``const void*`` + * return type is ``const void*`` * ``copy_const_reference`` - * ``const T&`` + * return type is ``const T&`` * for member ``operator[]`` that returns const reference to immutable type * ``return_by_value`` - * ``const wchar_t*`` + * return type is ``const wchar_t*`` * ``copy_non_const_reference`` - * ``T&``, for member ``operator[]`` that returns reference to immutable type + * return type is ``T&``, for member ``operator[]`` that returns reference to immutable type * ``return_internal_reference`` - * ``T&``, for member ``operator[]`` + * return type is ``T&``, for member ``operator[]`` --------------------- Missing call policies @@ -131,9 +134,9 @@ ------------ ``return_value_policy( return_opaque_pointer )`` is a special policy for `Boost.Python`_. -In this case, it requieres from an user to define specializations for the +In this case, it requieres from you to define specialization for the ``boost::python::type_id`` function on the type pointed to by returned pointer. -`Py++`_ will generate the requiered code. +`Py++`_ will generate the required code. For more information about the call policy please refer to `Boost.Python`_ `documentation`_. @@ -141,8 +144,6 @@ .. _`documentation` : http://boost.org/libs/python/doc/v2/return_opaque_pointer.html - - .. _`Py++` : ./../pyplusplus.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html .. _`Python`: http://www.python.org Modified: pyplusplus_dev/docs/documentation/functions/default_args.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/default_args.rest 2006-10-16 21:24:52 UTC (rev 665) +++ pyplusplus_dev/docs/documentation/functions/default_args.rest 2006-10-17 15:03:57 UTC (rev 666) @@ -39,8 +39,8 @@ , ( bp::arg("a")=(int)(12) ) ); } -This approach brings another additional value: keyword arguments. Your users -will be able to call function ``f`` like this: +The additional value of the approach is keyword arguments. You will be able to +call function ``f`` like this: .. code-block:: Python @@ -52,17 +52,24 @@ ---------------------------- ``BOOST_PYTHON_FUNCTION_OVERLOADS`` and ``BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS`` -macros help to deal with default values. You can turn ``use_overload_macro`` -to ``True`` as shown in `overloading`_ document. +macros can help to deal with default values too. You can turn ``use_overload_macro`` +to ``True``: -.. _`overloading` : ./overloading.html +.. code-block:: Python + import module_builder + + mb = module_builder.module_builder_t( ... ) + x = mb.class_( "X" ) + x.member_function( "f" ).use_overload_macro = True + #------------------------^^^^^^^^^^^^^^^^^^^^^^^^^ + -------------------------- Registration order problem -------------------------- -There are different trades-off between these approaches. In general you should -use the first one, untill you have "registration order" problem: +There is different trades-off between these approaches. In general you should +use the first one, until you have "registration order" problem: .. code-block:: C++ @@ -88,30 +95,51 @@ } -These module could not be loaded, because the expression ``arg("s1")=S1()`` -requieres ``S1`` struct to be registered. `GCC-XML`_ reports default arguments -as strings. `Py++`_ doesn't have enough information to generate code with the -right class registration order. +The good news is that it is very easy to identify the problem: the module could +not be loaded. The main reason is that expression ``arg("s1")=S1()`` requires +``S1`` struct to be registered. `GCC-XML`_ reports default arguments as strings. +`Py++`_ doesn't have enough information to generate code with the right class +registration order. In this case you have to instruct `Py++`_ to use macros: +.. code-block:: Python -Unfortunatelly these macros have some limitations: + import module_builde + + mb = module_builder.module_builder_t( ... ) + s2 = mb.class_( "S2" ) + s2.member_function( "do_smth" ).use_overload_macro = True -1. The overloaded functions must have a common sequence of initial arguments. +When you switch to macros, than: -2. You will not be able to override virtual functions in `Python`_. +* You will not be able to override virtual functions in `Python`_. -3. You will not be able to use "named" arguments. +* You will not be able to use "named" arguments. -4. You will not be able to set the functions documentation. +* You will not be able to set the functions documentation. -Nevertheless these limitations the macros becomes very useful when you have -"registration order" problem with default arguments. +Special case +------------ +Class constructors are special case: +.. code-block:: C++ + struct S1; + struct S2; + + struct S1{ + S1( S2* s2=0 ); + }; + + struct S2{ + S2( S1 s1=S1() ); + }; -`Py++`_ needs your help to generate right code: +You cannot use same work around and `Py++`_ ( version 0.8.2 ) could not help you. +The use case presented here is a little bit esoteric. If you have such use case +and you cannot change the source code, consider contacting `Py++`_ developers. +I am sure we will be able to help you. .. _`Py++` : ./../pyplusplus.html Modified: pyplusplus_dev/docs/documentation/functions/functions.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/functions.rest 2006-10-16 21:24:52 UTC (rev 665) +++ pyplusplus_dev/docs/documentation/functions/functions.rest 2006-10-17 15:03:57 UTC (rev 666) @@ -10,7 +10,7 @@ `Boost.Python`_ provides very rich interface to expose functions and operators. This section of documentation will explain how to configure `Py++`_ in order -to export your code using desired `Boost.Python`_ functionality. +to export your functions, using desired `Boost.Python`_ functionality. .. _`Py++` : ./../pyplusplus.html Modified: pyplusplus_dev/docs/documentation/functions/overloading.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/overloading.rest 2006-10-16 21:24:52 UTC (rev 665) +++ pyplusplus_dev/docs/documentation/functions/overloading.rest 2006-10-17 15:03:57 UTC (rev 666) @@ -8,7 +8,7 @@ Introduction ------------ -Things get a little bit complex, when you should export overloaded functions. +Things get a little bit complex, when you have to export overloaded functions. In general the solution is to explicitly say to compiler what function you want to export, by specifying its type. Before we proceed, please take a look on next class: @@ -37,7 +37,7 @@ .. __ : http://boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.overloading -There are few approaches, which you can use in order to exort the functions. +There are few approaches, which you can use in order to export the functions. ------------------- Do nothing approach @@ -66,9 +66,6 @@ , ( bp::arg("a"), bp::arg("b"), bp::arg("c") ) ); } -From my experience, this approach works pretty well and in most cases the only -customization you should do on exported function is to setup right call policies. - -------------------------------- "create_with_signature" approach -------------------------------- @@ -79,15 +76,12 @@ Overloaded template function ---------------------------- -I am sure you already know next facts, but still I want to remind them: +I am sure you already know next fact, but still I want to remind it: -1. `GCC-XML`_ doesn't report about uninstantiated templates +* `GCC-XML`_ doesn't report about un-instantiated templates -2. `Boost.Python`_ is able to export only template instantiation +It is very important to understand it. Lets take a look on next source code: -It is very important to understand the first fact. Lets take a look on next source -code: - .. code-block:: C++ struct Y{ @@ -101,7 +95,7 @@ If you didn't instantiate( use ) ``do_smth`` member function, than `GCC-XML`_ will not report it. As a result, `Py++`_ will not be aware of the fact that -``do_smth`` is an overloaded function. To make the long story short the generated +``do_smth`` is an overloaded function. To make the long story short, the generated code will not compile. You have to instruct `Py++`_ to generate code, which contains function type: @@ -125,11 +119,19 @@ Code modification - the weakness of the "do nothing" approach. We live in the dynamic world. You can create bindings for a project, but a month letter, the project developers will add a new function to the exported class. Lets assume -that the function will introduce overloading. If ``create_with_signature`` has -``False`` as a value, than the previously generated code will not compile. My -advise to you: explicitly set ``create_with_signature`` to ``True``. It will -save your time in future. +that the new function will introduce overloading. If ``create_with_signature`` +has ``False`` as a value, than the previously generated code will not compile +and you will have to run code generator one more time. +Consider to explicitly set ``create_with_signature`` to ``True``. It will save +your and your users time in future. + +.. code-block:: Python + + mb = module_builder_t( ... ) + mb.calldefs().create_with_signature = True + + ------------------------ Overloading using macros ------------------------ @@ -141,7 +143,7 @@ * ``BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS`` -`Boost.Python`_ tutorials contains an `explanation`_ about this macros. +`Boost.Python`_ tutorials contain an `explanation`_ about this macros. .. _`explanation` : http://boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.auto_overloading This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-19 12:20:31
|
Revision: 734 http://svn.sourceforge.net/pygccxml/?rev=734&view=rev Author: roman_yakovenko Date: 2006-11-19 04:20:30 -0800 (Sun, 19 Nov 2006) Log Message: ----------- updating documentation Modified Paths: -------------- pyplusplus_dev/docs/peps/dsl_challenge.rest pyplusplus_dev/docs/quotes.rest Modified: pyplusplus_dev/docs/peps/dsl_challenge.rest =================================================================== --- pyplusplus_dev/docs/peps/dsl_challenge.rest 2006-11-18 19:20:05 UTC (rev 733) +++ pyplusplus_dev/docs/peps/dsl_challenge.rest 2006-11-19 12:20:30 UTC (rev 734) @@ -105,42 +105,42 @@ BUI does not work for template instantiated classes and functions. If we change class ``Point`` to be template, the special syntax should be introduced: - .. code-block:: C++ + .. code-block:: C++ - template < class Numeric > - struct Point{ - ... - }; + template < class Numeric > + struct Point{ + ... + }; -.. code-block:: Python + .. code-block:: Python - PointTmpl = mb.module.template('Point') - Point = PointTmpl( 'int' ) + PointTmpl = mb.module.template('Point') + Point = PointTmpl( 'int' ) - This is a trivial example, that is why it looks grate. Consider next class: + This is a trivial example, that is why it looks grate. Consider next class: -. code-block:: C++ + .. code-block:: C++ - template< class String, class Allocator > - class regex{ ... } + template< class String, class Allocator > + class regex{ ... } - The code the user will need to write is: + The code the user will need to write is: - .. code-block:: Python + .. code-block:: Python - regex_tmpl = mb.module.geometry.template( 'regex' ) - #white spaces and scope resolution( :: ) are important - regex_std_string = regex_tmpl( - '::std::basic_string<char,std::char_traits<char>,std::allocator<char> >' - , '::std::allocator<char>' ) + regex_tmpl = mb.module.geometry.template( 'regex' ) + #white spaces and scope resolution( :: ) are important + regex_std_string = regex_tmpl( + '::std::basic_string<char,std::char_traits<char>,std::allocator<char> >' + , '::std::allocator<char>' ) - Using current `Py++`_ interface the user can get reference to the class - instantiation in one line of code: + Using current `Py++`_ interface the user can get reference to the class + instantiation in one line of code: -.. code-block:: Python + .. code-block:: Python - regex_std_string = mb.class_( - lambda decl: decl.name.startswith( 'regex' ) and 'wchar_t' not in decl.name ) + regex_std_string = mb.class_( + lambda decl: decl.name.startswith( 'regex' ) and 'wchar_t' not in decl.name ) * overloaded functions resolution @@ -165,9 +165,9 @@ Using BUI the user is forced to write full declaration name, otherwise he faces next problem: -.. code-block:: Python + .. code-block:: Python - Point = mb.module.Point + Point = mb.module.Point Lets analyze what the ``Point`` value: @@ -182,7 +182,7 @@ .. code-block:: Python - Point.add_registration_code( ... ) + Point.add_registration_code( ... ) Constructor declaration does not define ``add_registration_code`` method. According to Python rules: "Errors should never pass silently", exception Modified: pyplusplus_dev/docs/quotes.rest =================================================================== --- pyplusplus_dev/docs/quotes.rest 2006-11-18 19:20:05 UTC (rev 733) +++ pyplusplus_dev/docs/quotes.rest 2006-11-19 12:20:30 UTC (rev 734) @@ -45,8 +45,41 @@ .. __ : http://www.highend3d.com/maya * Lakin Wecker, the author of `Python-OGRE`_ project, is using `Py++`_ to - create Python bindings for `OGRE`_. + create Python bindings for `OGRE`_. + + `OGRE`_ - is a scene-oriented, flexible 3D engine written in C++ designed to + make it easier and more intuitive for developers to produce applications + utilising hardware-accelerated 3D graphics. +* Andy Miller, another developer of `Python-OGRE`_ project, is using `Py++`_ to + create Python bindings for: + + * `CEGUI`_ - a free library providing windowing and widgets for graphics + APIs / engines where such functionality is not natively available, or + severely lacking. + + .. _`CEGUI` : http://www.cegui.org.uk/wiki/index.php/Main_Page + + * `Newton`_ - Newton Game Dynamics, a closed source (but free) physics and + collisions library. + + .. _`Newton` : http://www.newtondynamics.com/apache2-default/ + + * `ODE`_ - an open source, high performance library for simulating rigid body + dynamics. + + .. _`ODE` : http://www.ode.org/ + + * `OIS`_ - an object oriented input system. + + .. _`OIS` : http://www.wreckedgames.com/wiki/index.php/WreckedLibs:OIS + +* Nicolas Tessore is using `Py++`_ to create Python bindings for `NifTools`_ + project. You can read in his `blog`_ what he thinks about `Py++`_. + + .. _`NifTools` : http://www.niftools.org/wiki/index.php/NIF_File_Format_Library_and_Tools + .. _`blog` : http://ni-te.de/blog/?p=10 + * I am :-). I created Python bindings for next libraries: * `Boost.Date_Time`_ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-12-11 07:07:44
|
Revision: 794 http://svn.sourceforge.net/pygccxml/?rev=794&view=rev Author: roman_yakovenko Date: 2006-12-10 23:07:41 -0800 (Sun, 10 Dec 2006) Log Message: ----------- updating documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest pyplusplus_dev/docs/documentation/functions/transformation/terminology.rest pyplusplus_dev/docs/peps/peps_index.rest pyplusplus_dev/docs/pyplusplus.rest Added Paths: ----------- pyplusplus_dev/docs/documentation/functions/transformation/custom/ pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest pyplusplus_dev/docs/documentation/functions/transformation/custom/www_configuration.py Removed Paths: ------------- pyplusplus_dev/docs/peps/function_transformation.rest Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest 2006-12-10 20:42:12 UTC (rev 793) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest 2006-12-11 07:07:41 UTC (rev 794) @@ -16,24 +16,29 @@ * ``inout`` -* ``input_array`` +* ``input_static_array`` -* ``output_array`` +* ``output_static_array`` The set doesn't cover all common use cases, but it will grow with every new version of `Py++`_. If you created your own transformer consider to contribute it to the project. -I suggest you to start reading ``output`` transformer. It is pretty simple and +I suggest you to start reading `output`_ transformer. It is pretty simple and well explained. +.. _`output` : ./output.html + All built-in transformers could be applied on any function, except constructors. The support for constructors will be added in future releases. You don't have to warry about call policies. You can set the call policy and -`Py++`_ will generate correct code. +`Py++`_ will generate the correct code. +You don't have to warry about the number of arguments, transformers or return +value. `Py++`_ handles pretty well such use cases. + .. _`Py++` : ./../pyplusplus.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html .. _`Python`: http://www.python.org Added: pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest (rev 0) +++ pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest 2006-12-11 07:07:41 UTC (rev 794) @@ -0,0 +1,40 @@ +========================= +User defined transformers +========================= + +.. contents:: Table of contents + +---- +KISS +---- + +KISS - Keep It Simple Stupid! + +The main goal of the feature: to provide relatively simple way to implement +custom transformers. More over, all `built-in transformers`_ implemented as is +they were custom transformers. + +----------- +How to ...? +----------- + +Unfortunatelly I don't have enough time to write a complete documentation :-(. +Meanwhile fill free to `contact me`_. You also can take a look on `built-in transformers`_ +implementation. + +.. _`contact me` : ../../../../links.html#id5 +.. _`built-in transformers` : ../built_in/built_in.html + + +.. _`Py++` : ./../pyplusplus.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Added: pyplusplus_dev/docs/documentation/functions/transformation/custom/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/custom/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/documentation/functions/transformation/custom/www_configuration.py 2006-12-11 07:07:41 UTC (rev 794) @@ -0,0 +1,4 @@ +name = 'custom transformers' +#main_html_file = 'index.html' + +names = { } Modified: pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest 2006-12-10 20:42:12 UTC (rev 793) +++ pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest 2006-12-11 07:07:41 UTC (rev 794) @@ -59,7 +59,9 @@ function The good news - they will not be changed between different runs of the code -generator. If you are exposing an overloaded function, than `Py++`_ uses the ugly +generator. + +If you are exposing an overloaded function, in that case `Py++`_ uses the ugly function-wrapper name as an alias. It is up to you to change the alias: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/terminology.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/terminology.rest 2006-12-10 20:42:12 UTC (rev 793) +++ pyplusplus_dev/docs/documentation/functions/transformation/terminology.rest 2006-12-11 07:07:41 UTC (rev 794) @@ -4,7 +4,7 @@ .. contents:: Table of contents -* Function transformation +**Function transformation** `Py++`_ sub-system\\framework, which allows you to create function wrappers and to keep smile. @@ -12,21 +12,21 @@ The operation of changing one function into another in accordance with some rules. Especially: a change of return type and\\or arguments and their mapping to the original ones. - -* Function wrapper ( or just wrapper ) +**Function wrapper** ( or just wrapper ) + C++ function, which calls some other function. -* Immutable type +**Immutable type** An instance of this type could not be modified after construction -* Transformer +**Transformer** An object that applies predefined set of rules on a function, during function-wrapper construction process. -* Function alias ( or just alias ) +**Function alias** ( or just alias ) Name under which `Python`_ users see the exposed function Deleted: pyplusplus_dev/docs/peps/function_transformation.rest =================================================================== --- pyplusplus_dev/docs/peps/function_transformation.rest 2006-12-10 20:42:12 UTC (rev 793) +++ pyplusplus_dev/docs/peps/function_transformation.rest 2006-12-11 07:07:41 UTC (rev 794) @@ -1,333 +0,0 @@ -======================== -Function transformation -======================== - -.. contents:: Table of contents - -------------------- -What is useful for? -------------------- - -https://realityforge.vrsource.org/view/PyppApi/CodeInserter gives a nice introduction -and the problem description. Please read it. - ------------ -Terminology ------------ - -Lets say that we have a function ``f``: - -:: - - f = R f( A0 a0, ..., AN an ) - -``R`` and ``A*`` represent an arbitrary C++ types. What we want is to create -another function ``ft`` (transformed): - -:: - - ft = RT ft( AT0 at0, ..., ATM atm ) - -such that will do an additional work before and after ``f`` call. - -Definitions ------------ - -*Transformation* - process that defines how to create transformed function from the -original one. - -For example - ``make function argument to be return value``: -:: - - f = void get_last_error( int& error ); - -:: - - ft = int get_last_error(); - -The definition of ``ft`` could look like: - -.. code-block:: C++ - - int get_last_error_transformed(){ - int error(0); - get_last_error( error ); - return error; - } - -I modified ``f`` signature and added some code before and after ``f`` call. - -*Function transformation* - group of transformations that should be applied at once -on a function. - -For example a function could have two immutable arguments, passed by reference. -Function transformation aggregates two transformations. - -A user will be able to define few function transformations for a single function. - ------------------------ -Design & implementation ------------------------ - -In the previous paragraph I introduced two new concepts: "transformation" and -"function transformation". These concepts should be presented in the solution. - - -Transformation --------------- - -Transformation class has two responsibilities: - -1. to modify function signature: - - * remove argument - * change argument type - * join arguments - * change return type - -2. to implement the transformation - -It is important to distinct between the responsibilities. Function signature -defines "interface" for a lot of services provided by `Py++`_. While the second -one is "implementation details" and should be "hidden" from the rest of the world. - -In an ideal world we would have 2 classes, one class - one responsibility. -In `Py++`_ it means that we would have ``transformation_t`` class: - -.. code-block:: Python - - class transformation_t( object ): - def __init__( self ): - pass - -.. code-block:: Python - - def check( self, function ): - "checks whether the transformation could be applied on the function or not" - raise NotImplementedError() - -.. code-block:: Python - - def signature_changes( self, function ): - "returns a list of changes that should be done on function signature" - raise NotImplementedError() - -The class logically belongs to the ``decl_wrappers`` package. The ``transformer_t`` -is the second class, which logically belongs to ``code_creators`` package: - -.. code-block:: Python - - class transformer_t( ast_visitor_t ): - def __init__( self, function, transformation ): - function is a reference to the declaration we want to apply transformation on - transformation is an instance of "concrete" transformation - -.. code-block:: Python - - def apply( self, function_body_as_tree ): - "integrates transformation code to function body" - raise NotImplementedError() - -What is ``ast_visitor_t`` and ``function_body_as_tree``. In an ideal world -concrete instance of ``transformer_t`` class would work with some kind of AST -( Abstract Syntax Tree ). Thus transformer would travel on the tree and modify it. - -Get the job done! ------------------ - -The previously described solution will not work in our, `Py++`_ developers and -users, world. There are mainly two reasons: - -1. AST approach is tooooooo complex. We don't have time to develop an AST for - representing, even limited subset of C++ expressions. Users will not have - time to learn how to use it. - -2. Class separation approach will not work too. In order to introduce new - transformation, user will have to understand the whole design of the `Py++`_ - package. - -Matthias Baas provided a "real world" solution for both problems. At first I did -not understand it, but now I appreciate it very much. It does not meant that I -agree with the his implementation. As for me he did not stress enough the -concepts within the code and more over he mixed them in different classes. - -I am going to propose another solution, which will be based on existing code. -Small re-factoring is needed. I don't expect changes in the user code. - -Proposed class: - -.. code-block:: Python - - class transformer_t( object ): - "base class for all transformation classes" - def __init__( self ): - pass - -.. code-block:: Python - - def check( self, function ): - "checks whether the transformation could be applied on the function or not" - raise NotImplementedError() - -.. code-block:: Python - - def signature_changes( self, function ): - "returns a list of changes that should be done on function signature" - raise NotImplementedError() - -.. code-block:: Python - - def apply( self, sm ): #sm is an instance of the substitution manager - "integrates transformation code into function transformation body" - raise NotImplementedError() - -Comments: - -1. ``substituion_manager_t`` class allows us to achieve same result as with AST. - he way it does it is pretty simple to explain and understand - string - substitution. - -2. ``transformer_t`` class allows user to introduce new transformations, without - understanding the whole `Py++`_ package. - -Function trasformation -~~~~~~~~~~~~~~~~~~~~~~ - -What is responcibility of the ``function_transformation_t`` class? - -1. To keep reference to transformations defined by the user. - -2. To apply every transformation on the function body. For this purpose this - class will keep instance of ``substituion_manager_t`` class. - -3. To provide interface for ``mem_fun_v_transformed_t`` and - ``mem_fun_v_transformed_wrapper_t`` code creators classes. - -4. [Nice to have]To check, whether the transformation defined by user is - applicable or not. - -Somewhere we should put "function transformation" factory. This factory will -create or give a hint to the user what transformation could\\should be applied -on the function. - -------------------------------------- -output_arg transformation example -------------------------------------- - -.. code-block:: Python - - class output_arg_t( transformer_t ): - def __init__( self, ordinal ): - self.ordinal = ordinal - -.. code-block:: Python - - def check( self, decl ): - if len( decl.arguments ) <= self.ordinal: - return user message - type_ = decl.arguments[self.ordinal].type - if not reference to immutable type: - raise user message - -.. code-block:: Python - - def signature_changes( self, decl ): - assert not self.check( decl ) - return [ remove_arg( self.ordinal ) - , add_var_to_return_value( decl.arguments[ self.ordinal ].name ] - -.. code-block:: Python - - def apply( self, sm ): - if sm is wrapper around C++ function: - sm. add declaration of variable type = decl.arguments[ self.ordinal ].type - and name = decl.arguments[ self.ordinal ].type and initial value - sm. add variable to return expression. - else: #sm is a wrapper around Python function - sm. extract value from the tuple and assign it to the argument - -.. code-block:: Python - - def output_arg( ordinal ): - return output_arg_t( ordinal ) - ------------------ -Problems to solve ------------------ - -I don't have any solution to the next problems. - -Call policies -------------- - -I am going to change a little an example, from `Boost.Python`_ tutorials: -http://www.boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies - -.. code-block:: C++ - - //C++ code - struct Y - { - X x; Z* z; - int z_value() { return z->value(); } - }; - -.. code-block:: C++ - - X& f(Y& y, Z* z, int& error) - { - y.z = z; - return y.x; - } - -.. code-block:: C++ - - //Boost.Python code - def("f", f, return_internal_reference<1, with_custodian_and_ward<1, 2> >() ); - -What is the difference? Function ``f`` now takes 3rd argument - ``int&``. This -function could not be called from `Python`_. (Hint: numbers are immutable -objects in `Python`_ ). So in order to expose function ``f`` to `Python`_, -an user need to create a wrapper. And now he has a problem: how to wrap the function? - -I see only one solution user have to change signature of function ``f``. -Now some speculations: - -1. May be it is possible with `Boost.Python`_ library to set call policies on the - part of the return value? - - .. code-block:: C++ - - boost::tuple f_wrapper( Y& y, Z* z ){ - int error(0); - X& x = f( y, z, error ); - return boost::tuple<X&, int>( x, error ); - } - - def("f", f_wrapper, smart call policies that will work only on first element within the tuple ); - -2. May be it is possible to create Boost.Python ``object`` with life-time management - hint? - - .. code-block:: C++ - - boost::python::tuple f_wrapper( Y& y, Z* z ){ - int error(0); - X& x = f( y, z, error ); - boost::python::object x_obj( x, x is internal reference of y ); - return boost::python::make_tuple( x_obj, error ); - } - -.. _`Py++` : ./../pyplusplus.html -.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html -.. _`Python`: http://www.python.org -.. _`GCC-XML`: http://www.gccxml.org - -.. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - End: - Modified: pyplusplus_dev/docs/peps/peps_index.rest =================================================================== --- pyplusplus_dev/docs/peps/peps_index.rest 2006-12-10 20:42:12 UTC (rev 793) +++ pyplusplus_dev/docs/peps/peps_index.rest 2006-12-11 07:07:41 UTC (rev 794) @@ -42,15 +42,6 @@ The coding itself should take something like 4 - 5 hours, including unit test. ---------------------- -Call wrapper policies ---------------------- - -Not all functions could be exposed to Python as is. This `document`__ will -explain how `Py++`_ will help users to create wrappers around those functions. - -.. __ : ./function_transformation.html - ------------------------------------------ Domain Specific Language ( DSL ) challenge ------------------------------------------ Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2006-12-10 20:42:12 UTC (rev 793) +++ pyplusplus_dev/docs/pyplusplus.rest 2006-12-11 07:07:41 UTC (rev 794) @@ -127,9 +127,11 @@ ------------- * `Py++`_ support almost all features found in `Boost.Python`_ library + * `Py++`_ generates code, which will help you to understand compiler generated error messages + * `Py++`_ has few modes of writing code into files: @@ -148,13 +150,13 @@ * Your license is written at the top of every file * `Py++`_ will check the "completeness" of the bindings. It will check for you - that exposed declarations don't have references to unexposed ones. + that the exposed declarations don't have references to unexposed ones. * `Py++`_ provides enough functionality to extract source code documentation and write it as Python documentation string -* `Py++`_ provides simple and powerful framework to create wraper for functions, - which could not be exposed as is to `Python`_. +* `Py++`_ provides simple and powerful framework to create a wrapper for + functions, which could not be exposed as is to `Python`_. * ... This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-12-13 22:12:03
|
Revision: 797 http://svn.sourceforge.net/pygccxml/?rev=797&view=rev Author: roman_yakovenko Date: 2006-12-13 14:12:02 -0800 (Wed, 13 Dec 2006) Log Message: ----------- fixing spelling errors Modified Paths: -------------- pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest pyplusplus_dev/docs/documentation/architecture.rest pyplusplus_dev/docs/documentation/best_practices.rest pyplusplus_dev/docs/documentation/containers.rest pyplusplus_dev/docs/documentation/feedback.rest pyplusplus_dev/docs/documentation/functions/call_policies.rest pyplusplus_dev/docs/documentation/functions/default_args.rest pyplusplus_dev/docs/documentation/functions/overloading.rest pyplusplus_dev/docs/documentation/functions/registration_order.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/inout.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/input.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/output.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest pyplusplus_dev/docs/documentation/how_to.rest pyplusplus_dev/docs/documentation/index.rest pyplusplus_dev/docs/documentation/inserting_code.rest pyplusplus_dev/docs/documentation/properties.rest pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest pyplusplus_dev/docs/download.rest pyplusplus_dev/docs/examples/easybmp/easybmp.rest pyplusplus_dev/docs/history/history.rest pyplusplus_dev/docs/links.rest pyplusplus_dev/docs/peps/dsl_challenge.rest pyplusplus_dev/docs/peps/peps_index.rest pyplusplus_dev/docs/pyplusplus.rest pyplusplus_dev/docs/quotes.rest Modified: pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/bpl_lessons_learned/lessons_learned.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -25,7 +25,7 @@ .. include:: ./shared_ptr/definition.rest .. _`boost::shared_ptr< const T>` : ./shared_ptr/shared_ptr.html - + .. _`Py++` : ./../pyplusplus.html .. _`pygccxml` : http://www.language-binding.net/pygccxml/pygccxml.html .. _`SourceForge`: http://sourceforge.net/index.php Modified: pyplusplus_dev/docs/documentation/architecture.rest =================================================================== --- pyplusplus_dev/docs/documentation/architecture.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/architecture.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -8,7 +8,7 @@ Introduction ------------ -This document will describe an architecture behind `Py++`_. +This document will describe an architecture behind `Py++`_. --------------------------- Py++ & pygccxml integration @@ -17,18 +17,18 @@ C++ --- -C++ is very powerful programming language. The power brings complexity. It is -not an easy task to parse C++ source files and to create in memory representation -of declarations tree. The declarations tree is worth nothing, if a user is not -able to explorer it, to run queries against it or to find out traits of a +C++ is very powerful programming language. The power brings complexity. It is +not an easy task to parse C++ source files and to create in memory representation +of declarations tree. The declarations tree is worth nothing, if a user is not +able to explorer it, to run queries against it or to find out traits of a declaration or a type. -On the earlier stage of the development, I realized, that all this functionality -does not belong to code generator and should be implemented out side of it. -`pygccxml`_ project was born. `pygccxml`_ made the code generator to be smaller +On the earlier stage of the development, I realized, that all this functionality +does not belong to code generator and should be implemented out side of it. +`pygccxml`_ project was born. `pygccxml`_ made the code generator to be smaller and C++ parser independent. It provides next services: -* definition of classes, that describe C++ declaration and types, and their +* definition of classes, that describe C++ declaration and types, and their analyzers ( type traits ) * C++ source files parsing and caching functionality @@ -45,7 +45,7 @@ * indexing suite parameters * generate warnings/hints - + * ... @@ -57,8 +57,8 @@ Parsing integration ~~~~~~~~~~~~~~~~~~~ -`Py++`_ provides it's own "API" to configure `pygccxml`_ parsing services. The -"API" I am talking about, is arguments to ``module_builder.__init__`` method. +`Py++`_ provides it's own "API" to configure `pygccxml`_ parsing services. The +"API" I am talking about, is arguments to ``module_builder.__init__`` method. We think, that exposing those services via `Py++`_ simplifies its usage. @@ -78,11 +78,11 @@ * query engine API -The user should be familiar with these parts and relevant API. In my opinion, -wrapping or hiding the API will not provide an additional value. The interface +The user should be familiar with these parts and relevant API. In my opinion, +wrapping or hiding the API will not provide an additional value. The interface of all those services is pretty simple and well polished. -Before I explain how these services are integrated, take a look on next source +Before I explain how these services are integrated, take a look on next source code: .. code-block:: Python @@ -100,43 +100,43 @@ my_class.rename("MyClass") -What you see here, is a common pattern, that will appear in all projects, that +What you see here, is a common pattern, that will appear in all projects, that use `Py++`_: * find the declaration(s) * give the instruction(s) to the code generator engine -What is the point of this example? From the user point of view it is perfectly -good, it makes a lot of sense to configure the code generation engine, using -the declarations tree. How does `Py++`_ add missing functionality to -``pygccxml.declarations`` classes? There were few possible solutions to the +What is the point of this example? From the user point of view it is perfectly +good, it makes a lot of sense to configure the code generation engine, using +the declarations tree. How does `Py++`_ add missing functionality to +``pygccxml.declarations`` classes? There were few possible solutions to the problem. The next one was implemented: 1. ``pygccxml.parser`` package interface was extended. Instead of creating - a concrete instance of declaration classes, ``pygccxml.parser`` package uses + a concrete instance of declaration classes, ``pygccxml.parser`` package uses a factory. - + 2. ``pyplusplus.decl_wrappers`` package defines classes, which derive from ``pygccxml.declarations`` classes and defines the factory. -The implemented solution is not the simplest one, but it provides an additional +The implemented solution is not the simplest one, but it provides an additional value to the project: -* the code generation engine configuration and declarations tree are tightly +* the code generation engine configuration and declarations tree are tightly coupled * the functionality provided by ``pygccxml.declarations`` and ``pygccxml.parser`` packages is available for ``pyplusplus.decl_wrappers`` classes -* classes defined in ``pyplusplus.decl_wrappers`` package implement next +* classes defined in ``pyplusplus.decl_wrappers`` package implement next functionality: - - * setting reasonable defaults for the code generation engine( call policies, + + * setting reasonable defaults for the code generation engine( call policies, indexing suite, ... ) - + * provides user with additional information( warnings and hints ) - + * as a bonus, `pygccxml`_ remained to be stand-alone project ---------------------- @@ -160,7 +160,7 @@ ``Code creators`` ----------------- -Do you know how many ways exist to export member function? If you will try to +Do you know how many ways exist to export member function? If you will try to answer the question, consider next function characteristics and their mix: * virtuality( non virtual, virtual or pure virtual ) @@ -171,59 +171,59 @@ * overloads -As you see, there are a lot of use cases. How do ``code creators`` solve the problem? +As you see, there are a lot of use cases. How do ``code creators`` solve the problem? Definition ~~~~~~~~~~ ``Code creator`` is an in-memory fragment of a C++ code. -Also, ``code creator`` can represent an arbitrary C++ code, in practice it -represents logically complete block. +Also, ``code creator`` can represent an arbitrary C++ code, in practice it +represents logically complete block. Example of ``code creators``: * ``code_creators.enum_t`` generates registration code for an enumeration - -* ``code_creators.mem_fun_pv_t`` generates registration code for public, pure + +* ``code_creators.mem_fun_pv_t`` generates registration code for public, pure virtual function - -* ``code_creators.mem_fun_pv_wrapper_t`` generates declaration code for public, + +* ``code_creators.mem_fun_pv_wrapper_t`` generates declaration code for public, pure virtual function - + * ``code_creators.include_t`` generates include directives -* ``code_creators.custom_text_t`` adds some custom( read user ) text\\code to +* ``code_creators.custom_text_t`` adds some custom( read user ) text\\code to the generated code -There are primary two groups of ``code creators``: declaration based and others. +There are primary two groups of ``code creators``: declaration based and others. Declaration based ``code creator`` keeps reference to the declaration ( ``pyplusplus.decl_wrapper.*`` class instance ). During code generation process, -it reads its settings( the code generation engine instructions ) from the -declaration. Declaration based ``code creators`` also divided into two groups. -The first group creates registration code, where the second one creates +it reads its settings( the code generation engine instructions ) from the +declaration. Declaration based ``code creators`` also divided into two groups. +The first group creates registration code, where the second one creates wrapper\\helper declaration code. I will reuse `this example`__, from `Boost.Python`_ tutorials. .. __ : http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.virtual_functions_with_default_implementations -1. ``BaseWrap::f``, ``BaseWrap::default_f`` - declaration code is created by +1. ``BaseWrap::f``, ``BaseWrap::default_f`` - declaration code is created by ``code_creators.mem_fun_v_wrapper_t`` 2. ``f`` registration code is created by ``code_creators.mem_fun_v_t``. This - code creator also keeps reference to the relevant instance of + code creator also keeps reference to the relevant instance of ``code_creators.mem_fun_v_wrapper_t`` class. -Composite ``code creator`` is a creator, which contains other creators. Composite -``code creator`` embeds the code, created by internal ``code creators``, within +Composite ``code creator`` is a creator, which contains other creators. Composite +``code creator`` embeds the code, created by internal ``code creators``, within the code it creates. For example: * ``code_creators.class_t``: - First of all it creates class registration code ( ``class_<...>`` ), after - this it appends to it code generated by internal creators. + First of all it creates class registration code ( ``class_<...>`` ), after + this it appends to it code generated by internal creators. * ``code_creators.module_body_t``: @@ -242,7 +242,7 @@ ``Code creators tree`` ~~~~~~~~~~~~~~~~~~~~~~ -``code_creators.module_t`` class is a top level ``code creator``. Take a look on +``code_creators.module_t`` class is a top level ``code creator``. Take a look on next possible "snapshot" of the ``code creators tree``: :: @@ -262,7 +262,7 @@ <free_function_t ...> <...> -You can think about ``code creators tree`` as some kind of `AST`_. +You can think about ``code creators tree`` as some kind of `AST`_. .. _`AST`: http://en.wikipedia.org/wiki/Abstract_syntax_tree @@ -270,7 +270,7 @@ ----------------------------------- ``pyplusplus.module_creator`` package is responsible for the tree construction. -``pyplusplus.module_creator.creator_t`` is the main class of the package. It +``pyplusplus.module_creator.creator_t`` is the main class of the package. It creates the tree in few steps: 1. It builds set of exposed declarations. @@ -279,7 +279,7 @@ 3. It creates ``code creators`` and put them into the right place within the tree. 4. If a declaration describes C++ class, it applies these steps to it. -Another responsibility of ``creator_t`` class, is to analyze declarations and +Another responsibility of ``creator_t`` class, is to analyze declarations and their dependency graphs. As a result, this class can: * find out a class ``HeldType`` @@ -288,15 +288,15 @@ * find out STD containers, which should be exported -* warn user, if some declaration is not exported and it used somewhere in +* warn user, if some declaration is not exported and it used somewhere in exported declarations ( **not implemented** ) ``File writers`` ---------------- -``File writers`` classes are responsible for writing ``code creators tree`` into -the files. `Py++`_ implements next strategies of writing ``code creators tree`` +``File writers`` classes are responsible for writing ``code creators tree`` into +the files. `Py++`_ implements next strategies of writing ``code creators tree`` into files: * single file @@ -307,7 +307,7 @@ * multiple files, with huge classes are written into multiple files - provides a solution for `compiler limit`_ problem. - + .. _`compiler limit` : http://www.boost.org/libs/python/doc/v2/faq.html#c1204 The more sophisticated approach, the better understanding of ``code creators`` Modified: pyplusplus_dev/docs/documentation/best_practices.rest =================================================================== --- pyplusplus_dev/docs/documentation/best_practices.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/best_practices.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -115,7 +115,7 @@ for those declarations that are actually used within your library). In the ``pygccxml`` package you can set the value for the ``-fxml-start`` - option using the ``start_with_declarations`` attribute of the + option using the ``start_with_declarations`` attribute of the ``pygccxml.parser.config_t`` object that you are passing to the parser. Modified: pyplusplus_dev/docs/documentation/containers.rest =================================================================== --- pyplusplus_dev/docs/documentation/containers.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/containers.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -25,7 +25,7 @@ * multiset * hash_multiset -It is not a trivial task to expose C++ container to Python. Boost.Python has +It is not a trivial task to expose C++ container to Python. Boost.Python has a functionality that will help you to expose some of STL containers to `Python`_. This functionality called - "indexing suite". If you want, you can read more about indexing suite `here`__. @@ -33,15 +33,15 @@ .. __ : http://boost.org/libs/python/doc/v2/indexing.html Boost.Python, out of the box, supports only ``vector``, ``map`` and ``hash_map`` -containers. In October 2003, Raoul Gough implemented support for the rest of -containers. Well, actually he did much more - he implemented new framework. -This framework provides support for almost all C++ containers and also an easy -way to add support for custom ones. You'd better read his `post`_ to +containers. In October 2003, Raoul Gough implemented support for the rest of +containers. Well, actually he did much more - he implemented new framework. +This framework provides support for almost all C++ containers and also an easy +way to add support for custom ones. You'd better read his `post`_ to `Boost.Python`_ mailing list or `documentation`_ for the new indexing suite. Now, I am sure you have next question: if this suite is so good, why it is not -in the main branch? The short answer is that this suite has some problems on +in the main branch? The short answer is that this suite has some problems on MSVC 6.0 compiler and there are few users, that still use that compiler. The long answer is here: @@ -57,10 +57,10 @@ Py++ and indexing suites ------------------------ -`Py++`_ implements support for both indexing suites. More over, you can +`Py++`_ implements support for both indexing suites. More over, you can freely mix indexing suites. For example you can expose ``std::vector<int>`` using `Boost.Python`_ built-in indexing suite and ``std::map< int, std::string>`` using -Raoul Gough's indexing suite. +Raoul Gough's indexing suite. ----------------- How does it work? @@ -69,7 +69,7 @@ In both cases, `Py++`_ provides almost "hands free" solution. `Py++`_ keeps track of all exported functions and variables, and if it sees that there is a usage of stl container, it exports the container. In both cases, `Py++`_ -analyzes the container ``value_type`` ( or in case of mapping container +analyzes the container ``value_type`` ( or in case of mapping container ``mapped_type`` ), in order to set reasonable defaults, when it generates the code. ------------------- @@ -84,16 +84,16 @@ mb = module_builder_t( ..., indexing_suite_version=2 ) -Every declared class has ``indexing_suite`` property. If the class is an +Every declared class has ``indexing_suite`` property. If the class is an instantiation of STL container, this property contains reference to an instance -of ``indexing_suite1_t`` or ``indexing_suite2_t`` class. +of ``indexing_suite1_t`` or ``indexing_suite2_t`` class. -How does `Py++`_ know, that a class represents STL container instantiation? -Well, it uses ``pygccxml.declarations.container_traits`` to find out this. -``pygccxml.declarations.container_traits`` class, provides all functionality +How does `Py++`_ know, that a class represents STL container instantiation? +Well, it uses ``pygccxml.declarations.container_traits`` to find out this. +``pygccxml.declarations.container_traits`` class, provides all functionality needed to identify container and to find out its ``value_type`` -( ``mapped_type`` ). +( ``mapped_type`` ). Built-in indexing suite API @@ -105,13 +105,13 @@ * ``no_proxy`` - a boolean, if ``value_type`` is one of the next types * fundamental type - + * enumeration * std::string or std::wstring * boost::shared_ptr<?> - + then, ``no_proxy`` will be set to ``True``, otherwise to ``False``. * ``derived_policies`` - a string, that will be added as is to generated code @@ -128,28 +128,28 @@ .. code-block:: C++ struct item{ - ... + ... private: bool operator==( const item& ) const; bool operator<( const item& ) const; }; - + struct my_data{ std::vector<item> items; std::map< std::string, item > name2item_mapping; }; -`Py++`_ declarations tree will contains ``item``, ``my_data``, -``vector<item>`` and ``map<string,item>`` class declarations. +`Py++`_ declarations tree will contains ``item``, ``my_data``, +``vector<item>`` and ``map<string,item>`` class declarations. -If ``value_type`` does not support "equal" or "less than" functionality, sort +If ``value_type`` does not support "equal" or "less than" functionality, sort and search functionality could not be exported. -`Py++`_ class declaration has two properties: ``equality_comparable`` and -``less_than_comparable``. The value of those properties is calculated on first -invocation. If `Py++`_ can find ``operator==``, that works on ``value_type``, -then, ``equality_comparable`` property value will be set to ``True``, otherwise +`Py++`_ class declaration has two properties: ``equality_comparable`` and +``less_than_comparable``. The value of those properties is calculated on first +invocation. If `Py++`_ can find ``operator==``, that works on ``value_type``, +then, ``equality_comparable`` property value will be set to ``True``, otherwise to ``False``. Same process is applied on ``less_than_comparable`` property. In our case, `Py++`_ will set both properties to ``False``, thus sort and @@ -159,36 +159,36 @@ * ``container_class`` - read only property, returns reference to container class declaration - + * ``container_traits`` - read only property, returns reference to the relevant - container traits class. Container traits classes are defined in + container traits class. Container traits classes are defined in ``pygccxml.declarations`` package. - + * ``element_type`` - is a reference to container ``value_type`` or ``mapped_type``. -* ``call_policies`` - read/write property, in near future I will add code to - `Py++`_ that will analize container ``value_type`` and will decide about +* ``call_policies`` - read/write property, in near future I will add code to + `Py++`_ that will analyze container ``value_type`` and will decide about default call policies. Just an example: for non-copy constructable classes - ``call_policies`` should be set to ``return_internal_reference``. - -* ``[disable|enable]_method`` - new indexing suite, allows to configure + ``call_policies`` should be set to ``return_internal_reference``. + +* ``[disable|enable]_method`` - new indexing suite, allows to configure functionality exported to Python, using simple bitwise operations on predefined flags. `Py++`_ allows you to specify what methods you want to disable or enable. ``indexing_suite2_t.METHODS`` contains names of all supported methods. - + * ``[disable|enable]_methods_group`` - almost same as above, but allows you - to specify what group of methods you want to disable or enable. + to specify what group of methods you want to disable or enable. ``indexing_suite2_t.METHOD_GROUPS`` contains names of all supported groups. Small tips/hints ---------------- 1. If you set ``equality_comparable`` or ``less_than_comparable`` to ``False``. - The indexing suite will disable relevant functionality. You don't have + The indexing suite will disable relevant functionality. You don't have explicitly to disable method or mothods group. -2. The documentation of new indexing suite contains few small mistakes. - I hope, I will have time to fix them. Any way, `Py++`_ generates +2. The documentation of new indexing suite contains few small mistakes. + I hope, I will have time to fix them. Any way, `Py++`_ generates correct code. Modified: pyplusplus_dev/docs/documentation/feedback.rest =================================================================== --- pyplusplus_dev/docs/documentation/feedback.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/feedback.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -19,8 +19,8 @@ Those goals all have something in common. In order to achieve them, `Py++`_ must -give useful feedback to the user. Because `Py++`_ understands the -declarations it exports, it can scan declarations for potential problems, report +give useful feedback to the user. Because `Py++`_ understands the +declarations it exports, it can scan declarations for potential problems, report them and in some cases provide hints about how to resolve the problem. Few examples: * @@ -42,11 +42,11 @@ struct window{ ... - void get_size( int& heght, int& widht ) const; + void get_size( int& height, int& width ) const; }; Member function ``get_size`` can be exposed to Python, but it will not be callable because [FILL IN HERE]. - + * In order to expose free/member function that takes more than 10 arguments user should define ``BOOST_PYTHON_MAX_ARITY`` macro. @@ -56,12 +56,12 @@ struct X{ ... }; - + void do_smth( X x ); - + If you expose ``do_smth`` function and don't expose struct ``X``, `Py++`_ will tell you that struct ``X`` is used in exported declaration, but was not - exposed. + exposed. For these problems and many other `Py++`_ gives a nice explanation and sometimes a link to the relevant information on the Internet. @@ -78,7 +78,7 @@ important messages to ``stdout``. More over it prints them only for declarations that are going to be exported. -`Py++`_ uses the python `logging`_ package to write all user messages. By +`Py++`_ uses the python `logging`_ package to write all user messages. By default, messages with ``DEBUG`` level will be skipped, all other messages will be reported. @@ -99,7 +99,7 @@ * warning unique identifier: "W1020" -* short explanation of the problem: "Py++ will generate class wrapper - hand +* short explanation of the problem: "Py++ will generate class wrapper - hand written code should be added to the wrapper class" --------------- @@ -109,20 +109,20 @@ How to disable warning(s)? -------------------------- -Every warning has unique identifier. In the example I gave it was ``W1020``. +Every warning has unique identifier. In the example I gave it was ``W1020``. .. code-block:: Python from pyplusplus import messages from pyplusplus import module_builder - + mb = module_builder.module_builder_t( ... ) xyz = mb.class_( XYZ ) xyz.disable_warnings( messages.W1020 ) It is also possible to disable warnings for all declarations. ``pyplusplus.messages`` package defines ``DISABLE_MESSAGES`` variable. This variable( ``list`` ) keeps -all warnings, which should not be reported. Use ``messages.disable`` function to +all warnings, which should not be reported. Use ``messages.disable`` function to edit it: .. code-block:: Python @@ -134,7 +134,7 @@ ----------- If you are here, it probably means that you are not pleased with default configuration -and want to change it, right? +and want to change it, right? 1. If you simply want to change the logging message level: @@ -149,38 +149,38 @@ 2. But what if you want to disable some messages and leave others? This is also possible. - `Py++`_ and `pygccxml`_ do not use a single logger. Almost every internal + `Py++`_ and `pygccxml`_ do not use a single logger. Almost every internal package has its own logger. So you can enable one logger and disable another one. - + The `pygccxml`_ package defines all loggers in the ``pygccxml.utils`` package. - + The `Py++`_ package defines all loggers in the ``pyplusplus._logging_`` package. - - Both packages define a ``loggers`` class. Those classes keep references to + + Both packages define a ``loggers`` class. Those classes keep references to different loggers. The ``loggers`` classes look very similar to the next class: .. code-block:: Python import logging #standard Python package - + def _create_logger_( name ): logger = logging.getLogger(name) ... return logger - + class loggers: file_writer = _create_logger_( 'pyplusplus.file_writer' ) declarations = _create_logger_( 'pyplusplus.declarations' ) - module_builder = _create_logger_( 'pyplusplus.module_builder' ) + module_builder = _create_logger_( 'pyplusplus.module_builder' ) root = logging.getLogger( 'pyplusplus' ) all = [ root, file_writer, module_builder, declarations ] You can use these references in the ``logging`` package to complete your task of adjusting individual loggers. - - One more thing, `Py++`_ automatically splits long message, where line + + One more thing, `Py++`_ automatically splits long message, where line length defaults to 70 characters. Thus it is very convenient to read them on your screen. - If you want to use different tools to monitor those messages, consider to use + If you want to use different tools to monitor those messages, consider to use standard `Formatter`_ class, instead of ``multi_line_formatter_t`` one. @@ -191,17 +191,17 @@ * ``why_not_exportable( self )`` - This method explains why a declaration could not be exported. The return value + This method explains why a declaration could not be exported. The return value is a string or ``None``. ``None`` is returned if the declaration is exportable. - Property ``exportable`` will be set to ``True`` if declaration is exportable, - and to ``False`` otherwise. + Property ``exportable`` will be set to ``True`` if declaration is exportable, + and to ``False`` otherwise. * ``readme( self )`` This method gives you access to all tips/hints/warnings `Py++`_ has about - the declaration. This methods returns a list of strings. If the declaration is - not exportable, than first message within the list is an explanation, why it + the declaration. This methods returns a list of strings. If the declaration is + not exportable, than first message within the list is an explanation, why it is not exportable. Modified: pyplusplus_dev/docs/documentation/functions/call_policies.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/call_policies.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/call_policies.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -18,7 +18,7 @@ Syntax ------ -The call policies in `Py++`_ are named exactly as in `Boost.Python`_, only the +The call policies in `Py++`_ are named exactly as in `Boost.Python`_, only the syntax is slightly different. For instance, this call policy: .. code-block:: C++ @@ -37,7 +37,7 @@ Usage example ------------- -Every "callable" object in `Py++`_ has ``call_policies`` property. +Every "callable" object in `Py++`_ has ``call_policies`` property. C++ code: @@ -45,9 +45,9 @@ struct data{...}; const data& do_smth( const data& d, int x ); - + void return_second_arg( int x, int y ); - + typedef struct opaque_ *opaque_pointer; opaque_pointer get_opaque(); @@ -57,15 +57,15 @@ from pyplusplus import module_builder from pyplusplus.module_builder import call_policies - + mb = module_builder.module_builder_t( ... ) mb.free_function( 'return_second_arg' ).call_policies = call_policies.return_arg( 2 ) #---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - + mb.member_function( 'do_smth' ).call_policies = call_policies.return_self() #-------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - mb.calldef( 'get_opaque' ).call_policies + + mb.calldef( 'get_opaque' ).call_policies = call_policies.return_value_policy( call_policies.return_opaque_pointer ) -------- @@ -78,41 +78,41 @@ * ``default_call_policies``: * `Python`_ immutable type returned by value: C++ fundamental types, ``std::string``, enumerations - + * user-defined type ( class ) returned by value - + * return type is ``const char*`` * ``return_value_policy`` - + * ``return_opaque_pointer`` - - * return type is ``void*`` - + + * return type is ``void*`` + * return type is ``const void*`` - + * return type is ``T*`` and ``T`` is a user defined opaque type - - ``class_t`` and ``class_declaration_t`` classes have ``opaque`` property. - You have to set it to ``True``, if you want `Py++`_ to create this call - policy automaticly for all functions, that use ``T*`` as return type. - + + ``class_t`` and ``class_declaration_t`` classes have ``opaque`` property. + You have to set it to ``True``, if you want `Py++`_ to create this call + policy automatically for all functions, that use ``T*`` as return type. + * ``copy_const_reference`` * return type is ``const T&`` - + * for member ``operator[]`` that returns const reference to immutable type - + * ``return_by_value`` * return type is ``const wchar_t*`` - + * ``copy_non_const_reference`` - + * return type is ``T&``, for member ``operator[]`` that returns reference to immutable type - + * ``return_internal_reference`` - + * return type is ``T&``, for member ``operator[]`` --------------------- @@ -124,13 +124,13 @@ * `Py++`_ prints a warning message -* `Py++`_ generates code with - +* `Py++`_ generates code with + .. code-block:: C++ - + /* undefined call policies */ - - comment, in place of call policy. If `Py++`_ was wrong and function doesn't + + comment, in place of call policy. If `Py++`_ was wrong and function doesn't need call policy the generate code will compile fine, otherwise you will get a compilation error. @@ -142,13 +142,13 @@ Before you read this paragraph consider to read `Boost.Python`_ `return_opaque_pointer documentation`_. ``return_value_policy( return_opaque_pointer )`` is a special policy for `Boost.Python`_. -In this case, it requieres from you to define specialization for the -``boost::python::type_id`` function on the type pointed to by returned pointer. -`Py++`_ will generate the required code. +In this case, it requires from you to define specialization for the +``boost::python::type_id`` function on the type pointed to by returned pointer. +`Py++`_ will generate the required code. Actually you should define ``boost::python::type_id`` specialization also in case -a function takes the opaque type as an argument. `Py++`_ can do it for you, all +a function takes the opaque type as an argument. `Py++`_ can do it for you, all you need is to say to mark a declaration as opaque. Example: @@ -157,13 +157,13 @@ struct identity_impl_t{}; typedef identity_impl_t* identity; - + struct world_t{ - + world_t( identity id ); - + identity get_id() const; - + ... }; @@ -175,7 +175,7 @@ mb.class_( 'identity_impl_t' ).opaque = True -.. _`return_opaque_pointer documentation` : http://boost.org/libs/python/doc/v2/return_opaque_pointer.html +.. _`return_opaque_pointer documentation` : http://boost.org/libs/python/doc/v2/return_opaque_pointer.html -------------------------- Py++ defined call policies @@ -184,7 +184,7 @@ return_pointee_value -------------------- -Class ``return_pointee_value`` is a model of `ResultConverterGenerator`_ which +Class ``return_pointee_value`` is a model of `ResultConverterGenerator`_ which can be used to wrap C++ functions returning any pointer, such that the pointee of return value is copied into a new Python object. @@ -197,11 +197,11 @@ static float value = 0.5; return &value; } - + float* get_null_value(){ return (float*)( 0 ); } - + namespace bpl = boost::python; BOOST_PYTHON_MODULE(my_module){ def( "get_value" @@ -217,7 +217,7 @@ from pyplusplus import module_builder from pyplusplus.module_builder import call_policies - + mb = module_builder.module_builder_t( ... ) mb.free_function( return_type='float *' ).call_policies \ = call_policies.return_value_policy( call_policies.return_pointee_value ) @@ -227,7 +227,7 @@ .. code-block:: Python import my_module - + assert 0.5 == my_module.get_value() assert None is my_module.get_null_value() Modified: pyplusplus_dev/docs/documentation/functions/default_args.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/default_args.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/default_args.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -8,7 +8,7 @@ Introduction ------------ -There is more than one way to export function with default arguments. Before we +There is more than one way to export function with default arguments. Before we proceed, please take a look on next class: .. code-block:: C++ @@ -18,7 +18,7 @@ bool f(int a=12) { return true; - } + } }; ------------------- @@ -30,16 +30,16 @@ .. code-block:: C++ namespace bp = boost::python; - + BOOST_PYTHON_MODULE(pyplusplus){ - bp::class_< X >( "X" ) - .def( + bp::class_< X >( "X" ) + .def( "f" , &::X::f - , ( bp::arg("a")=(int)(12) ) ); + , ( bp::arg("a")=(int)(12) ) ); } -The additional value of the approach is keyword arguments. You will be able to +The additional value of the approach is keyword arguments. You will be able to call function ``f`` like this: .. code-block:: Python @@ -58,7 +58,7 @@ .. code-block:: Python import module_builder - + mb = module_builder.module_builder_t( ... ) x = mb.class_( "X" ) x.member_function( "f" ).use_overload_macro = True @@ -75,36 +75,36 @@ struct S1; struct S2; - + struct S1{ void do_smth( S2* s2=0 ); }; - + struct S2{ void do_smth( S1 s1=S1() ); }; - + BOOST_PYTHON_MODULE( ... ){ using namespace boost::python; - + class_< S2 >( "S2" ) .def( "do_smth", &S2::do_smth, ( arg("s1")=S1() ) ); - + class_< S1 >( "S1" ) .def( "do_smth", &S1::do_smth, ( arg("s2")=object() ) ); - + } -The good news is that it is very easy to identify the problem: the module could -not be loaded. The main reason is that expression ``arg("s1")=S1()`` requires -``S1`` struct to be registered. `GCC-XML`_ reports default arguments as strings. -`Py++`_ doesn't have enough information to generate code with the right class +The good news is that it is very easy to identify the problem: the module could +not be loaded. The main reason is that expression ``arg("s1")=S1()`` requires +``S1`` struct to be registered. `GCC-XML`_ reports default arguments as strings. +`Py++`_ doesn't have enough information to generate code with the right class registration order. In this case you have to instruct `Py++`_ to use macros: .. code-block:: Python - import module_builde - + import module_builder + mb = module_builder.module_builder_t( ... ) s2 = mb.class_( "S2" ) s2.member_function( "do_smth" ).use_overload_macro = True @@ -126,11 +126,11 @@ struct S1; struct S2; - + struct S1{ S1( S2* s2=0 ); }; - + struct S2{ S2( S1 s1=S1() ); }; Modified: pyplusplus_dev/docs/documentation/functions/overloading.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/overloading.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/overloading.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -21,12 +21,12 @@ { return true; } - + bool f(int a, double b) { return true; } - + bool f(int a, double b, char c) { return true; @@ -49,18 +49,18 @@ .. code-block:: C++ namespace bp = boost::python; - + BOOST_PYTHON_MODULE(pyplusplus){ - bp::class_< X >( "X" ) - .def( + bp::class_< X >( "X" ) + .def( "f" , (bool ( ::X::* )( int ) )( &::X::f ) - , ( bp::arg("a") ) ) - .def( + , ( bp::arg("a") ) ) + .def( "f" , (bool ( ::X::* )( int,double ) )( &::X::f ) - , ( bp::arg("a"), bp::arg("b") ) ) - .def( + , ( bp::arg("a"), bp::arg("b") ) ) + .def( "f" , (bool ( ::X::* )( int,double,char ) )( &::X::f ) , ( bp::arg("a"), bp::arg("b"), bp::arg("c") ) ); @@ -85,45 +85,45 @@ .. code-block:: C++ struct Y{ - + void do_smth( int ); - + template< class T> void do_smth( T t ); - + }; If you didn't instantiate( use ) ``do_smth`` member function, than `GCC-XML`_ -will not report it. As a result, `Py++`_ will not be aware of the fact that +will not report it. As a result, `Py++`_ will not be aware of the fact that ``do_smth`` is an overloaded function. To make the long story short, the generated -code will not compile. You have to instruct `Py++`_ to generate code, which +code will not compile. You have to instruct `Py++`_ to generate code, which contains function type: .. code-block:: Python from pyplusplus import module_builder - + mb = module_builder.module_builder_t( ... ) y = mb.class_( 'Y' ) y.member_function( 'do_smth' ).create_with_signature = True #------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Every `Py++`_ class, which describes C++ function\\operator has ``create_with_signature`` -property. You have to set it to ``True``. Default value of the property is +property. You have to set it to ``True``. Default value of the property is computed. If the exported function is overloaded, then its value is ``True`` otherwise it will be ``False``. Do nothing approach weakness ---------------------------- -Code modification - the weakness of the "do nothing" approach. We live in the -dynamic world. You can create bindings for a project, but a month letter, the -project developers will add a new function to the exported class. Lets assume -that the new function will introduce overloading. If ``create_with_signature`` -has ``False`` as a value, than the previously generated code will not compile -and you will have to run code generator one more time. +Code modification - the weakness of the "do nothing" approach. We live in the +dynamic world. You can create bindings for a project, but a month letter, the +project developers will add a new function to the exported class. Lets assume +that the new function will introduce overloading. If ``create_with_signature`` +has ``False`` as a value, than the previously generated code will not compile +and you will have to run code generator one more time. -Consider to explicitly set ``create_with_signature`` to ``True``. It will save +Consider to explicitly set ``create_with_signature`` to ``True``. It will save your and your users time in future. .. code-block:: Python @@ -136,7 +136,7 @@ Overloading using macros ------------------------ -`Boost.Python`_ provides two macros, which help you to deal with overloaded +`Boost.Python`_ provides two macros, which help you to deal with overloaded functions: * ``BOOST_PYTHON_FUNCTION_OVERLOADS`` @@ -152,12 +152,12 @@ .. code-block:: Python import module_builder - + mb = module_builder.module_builder_t( ... ) x = mb.class_( "X" ) x.member_functions( "f" ).use_overload_macro = True #-------------------------^^^^^^^^^^^^^^^^^^^^^^^^^ - + Member and free functions declaration classes have ``use_overload_macro`` property. The default value of the property is ``False``. Modified: pyplusplus_dev/docs/documentation/functions/registration_order.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/registration_order.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/registration_order.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -8,10 +8,10 @@ Introduction ------------ -"... I would very much like to pass bools from Python to C++ and have them -accepted as bools. However I cannot seem to do this. ..." +"... I would very much like to pass booleans from Python to C++ and have them +accepted as boils. However I cannot seem to do this. ..." -"... My class has 2 "append" functions. The first one, has single argument with +"... My class has 2 "append" functions. The first one, has single argument with type "const char*", the second one also has single argument with type "char". It seems, that I am not able to call the first function. ..." @@ -26,30 +26,30 @@ struct tester_t{ tester_t() {} - + const char* append(const char*) { return "append(const char *)"; } - + const char* append(const char) { return "append(const char)"; } - + const char* do_smth( bool ) { return "do_smth( bool )"; } - + const char* do_smth( int ) { return "do_smth( int )"; } }; -`Py++`_ generates code, that register functions in the order they apper in the +`Py++`_ generates code, that register functions in the order they appear in the source code: .. code-block:: C++ namespace bp = boost::python; - + BOOST_PYTHON_MODULE(my_module){ - bp::class_< tester_t >( "tester_t" ) - .def( bp::init< >() ) + bp::class_< tester_t >( "tester_t" ) + .def( bp::init< >() ) .def( "append" , (char const * ( ::tester_t::* )( char const * ) )( &::tester_t::append ) ) .def( "append" @@ -73,7 +73,7 @@ print tester.do_smth( True ) print tester.do_smth( 10 ) print tester.append( "Hello world!" ) - + ? The output is: @@ -84,8 +84,8 @@ append(const char) -Unexpected, right? The registration order of exposed overloaded functions is -important. `Boost.Python`_ tries overloads in reverse order of definition. +Unexpected, right? The registration order of exposed overloaded functions is +important. `Boost.Python`_ tries overloads in reverse order of definition. If I understand right, `Boost.Python`_ tries to match in reverse order the overloaded functions, if it can convert `Python`_ arguments to C++ ones, it does @@ -94,7 +94,7 @@ Now, when you understand the behaviour, it should be pretty simple to provide a correct functionality: -1. You can change alias of the function, by mangling the type of the argument +1. You can change alias of the function, by mangling the type of the argument into it: .. code-block:: Python @@ -105,38 +105,38 @@ 2. You can reorder the declarations within the source file. -3. You can ask `Py++`_ to generate code, which takes into account the order of +3. You can ask `Py++`_ to generate code, which takes into account the order of declarations: - + .. code-block:: Python - + from pyplusplus.module_creator import sort_algorithms - + sort_algorithms.USE_CALLDEF_ORGANIZER = True # The functionality is available from version 0.8.3 - + 4. The last and the perfect solution. `Py++`_ will let you know, when your code - has such problem. The functionality is available from version 0.8.3. After - this you can change the aliases of the functions. The third step is to create + has such problem. The functionality is available from version 0.8.3. After + this you can change the aliases of the functions. The third step is to create small "dispatch" function in Python: - + .. code-block:: Python - + import my_module - + def tester_t_do_smth( self, value ): if isinstance( value, bool ): self.do_smth_bool( value ): else: self.do_smth_int( value ) - + tester_t.do_smth = tester_t_do_smth - The tehnique showen here described pretty good in `Boost.Python`_ + The technique shown here described pretty good in `Boost.Python`_ `Extending Wrapped Objects in Python tutorials`_ . May be in future, `Py++`_ will generate this code for you. Anyway, if you have - a lot of use cases like this consider to generate `Python`_ code and not to + a lot of use cases like this consider to generate `Python`_ code and not to write it manually. .. _`Extending Wrapped Objects in Python tutorials` : http://boost.org/libs/python/doc/tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/built_in.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -20,11 +20,11 @@ * ``output_static_array`` -The set doesn't cover all common use cases, but it will grow with every new -version of `Py++`_. If you created your own transformer consider to contribute +The set doesn't cover all common use cases, but it will grow with every new +version of `Py++`_. If you created your own transformer consider to contribute it to the project. -I suggest you to start reading `output`_ transformer. It is pretty simple and +I suggest you to start reading `output`_ transformer. It is pretty simple and well explained. .. _`output` : ./output.html @@ -32,10 +32,10 @@ All built-in transformers could be applied on any function, except constructors and pure virtual functions. The support for them be added in future releases. -You don't have to warry about call policies. You can set the call policy and +You don't have to worry about call policies. You can set the call policy and `Py++`_ will generate the correct code. -You don't have to warry about the number of arguments, transformers or return +You don't have to worry about the number of arguments, transformers or return value. `Py++`_ handles pretty well such use cases. Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/inout.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/inout.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/inout.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -9,8 +9,8 @@ ---------- ``inout`` transformer is a combination of `input`_ and `output`_ transformers. -It removes a "reference" type from the function argument and then adds the -"returned", by the original function, value to the return statement of the +It removes a "reference" type from the function argument and then adds the +"returned", by the original function, value to the return statement of the function-wrapper. ``inout`` transformer takes as argument name or index of the original function @@ -27,20 +27,20 @@ .. code-block:: C++ #include <string> - + inline void hello_world( std::string& hw ){ hw = "hello world!"; } Lets say that you need to expose ``hello_world`` function. As you know -``std::string`` is mapped to `Python`_ string, which is immutable type, so you +``std::string`` is mapped to `Python`_ string, which is immutable type, so you have to create small wrapper for the function. Next `Py++`_ code does it for you: .. code-block:: Python from pyplusplus import module_builder from pyplusplus import function_transformers as FT - + mb = module_builder.module_builder_t( ... ) hw = mb.mem_fun( 'hello_world' ) hw.add_transformation( FT.inout(0) ) @@ -50,11 +50,11 @@ .. code-block:: C++ namespace bp = boost::python; - + static boost::python::object hello_world_a3478182294a057b61508c30b1361318( ::std::string hw ){ ::hello_world(hw); return bp::object( hw ); - } + } BOOST_PYTHON_MODULE(...){ ... Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/input.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/input.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/input.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -21,20 +21,20 @@ .. code-block:: C++ #include <string> - + inline void hello_world( std::string& hw ){ hw = "hello world!"; } Lets say that you need to expose ``hello_world`` function. As you know -``std::string`` is mapped to `Python`_ string, which is immutable type, so you +``std::string`` is mapped to `Python`_ string, which is immutable type, so you have to create small wrapper for the function. Next `Py++`_ code does it for you: .. code-block:: Python from pyplusplus import module_builder from pyplusplus import function_transformers as FT - + mb = module_builder.module_builder_t( ... ) hw = mb.mem_fun( 'hello_world' ) hw.add_transformation( FT.input(0) ) @@ -44,7 +44,7 @@ .. code-block:: C++ namespace bp = boost::python; - + static void hello_world_a3478182294a057b61508c30b1361318( ::std::string hw ){ ::hello_world(hw); } Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -8,12 +8,12 @@ Definition ---------- -"input_static_array" transformer works on native static arrays. It handles the -translation between `Python`_ object, passed as argument that represent a sequence, +"input_static_array" transformer works on native static arrays. It handles the +translation between `Python`_ object, passed as argument that represent a sequence, and the array. Size of array should be predefined. -"input_static_array" transformer takes as first argument name or index of the -original function argument. The argument should have "array" or "pointer" type. +"input_static_array" transformer takes as first argument name or index of the +original function argument. The argument should have "array" or "pointer" type. The second argument should an integer value, that represents array size. ------- @@ -23,13 +23,13 @@ .. code-block:: C++ struct vector3{ - + void init( int values[3] ){ x = values[0]; y = values[1]; z = values[2]; } - + int x,y,z; }; @@ -40,7 +40,7 @@ from pyplusplus import module_builder from pyplusplus import function_transformers as FT - + mb = module_builder.module_builder_t( ... ) v3 = mb.class_( 'vector3' ) v3.mem_fun( 'init' ).add_transformation( FT.input_static_array( 0, 3 ) ) @@ -50,24 +50,24 @@ .. code-block:: C++ #include "__convenience.pypp.hpp" //Py++ header file, which contains few convenience function - + namespace bp = boost::python; - + static void init_418e52f4a347efa6b7e123b96f32a73c( ::ft::vector3 & inst, boost::python::object values ){ int native_values[3]; pyplus_conv::ensure_uniform_sequence< int >( values, 3 ); pyplus_conv::copy_sequence( values, pyplus_conv::array_inserter( native_values, 3 ) ); inst.init(native_values); } - + BOOST_PYTHON_MODULE(...){ ... - bp::class_< ft::vector3 >( "vector3", "documentation" ) + bp::class_< ft::vector3 >( "vector3", "documentation" ) .def( "init" , &init_418e52f4a347efa6b7e123b96f32a73c , ( bp::arg("inst"), bp::arg("values") ) ) - .def_readwrite( "x", &ft::vector3::x ) - .def_readwrite( "y", &ft::vector3::y ) + .def_readwrite( "x", &ft::vector3::x ) + .def_readwrite( "y", &ft::vector3::y ) .def_readwrite( "z", &ft::vector3::z ); } Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/output.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/output.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/output.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -9,7 +9,7 @@ ---------- "output" transformer removes an argument from the function definition and adds -the "returned", by the original function, value to the return statement of the +the "returned", by the original function, value to the return statement of the function-wrapper. "output" transformer takes as argument name or index of the original function @@ -23,20 +23,20 @@ .. code-block:: C++ #include <string> - + inline void hello_world( std::string& hw ){ hw = "hello world!"; } Lets say that you need to expose ``hello_world`` function. As you know -``std::string`` is mapped to `Python`_ string, which is immutable type, so you +``std::string`` is mapped to `Python`_ string, which is immutable type, so you have to create small wrapper for the function. Next `Py++`_ code does it for you: .. code-block:: Python from pyplusplus import module_builder from pyplusplus import function_transformers as FT - + mb = module_builder.module_builder_t( ... ) hw = mb.mem_fun( 'hello_world' ) hw.add_transformation( FT.output(0) ) @@ -46,13 +46,13 @@ .. code-block:: C++ namespace bp = boost::python; - + static boost::python::object hello_world_a3478182294a057b61508c30b1361318( ){ std::string hw2; ::hello_world(hw2); return bp::object( hw2 ); } - + BOOST_PYTHON_MODULE(...){ ... bp::def( "hello_world", &hello_world_a3478182294a057b61508c30b1361318 ); Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest 2006-12-13 08:16:21 UTC (rev 796) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest 2006-12-13 22:12:02 UTC (rev 797) @@ -8,11 +8,11 @@ Definition ---------- -"output_static_array" transformer works on native static arrays. It handles the +"output_static_array" transformer works on native static arrays. It handles the translation between array and `Python`_ list object. Size of array should be predefined. -"output_static_array" transformer takes as first argument name or index of the -original function argument. The argument should have "array" or "pointer" type. +"output_static_array" transformer takes as first argument name or index of the +original function argument. The argument should have "array" or "pointer" type. The second argument should an integer value, that represents array size. ------- @@ -22,13 +22,13 @@ .. code-block:: C++ struct vector3{ - + void get_values( int values[3] ){ values[0] = x; values[1] = y; values[2] = z; - } - + } + int x,y,z; }; @@ -39,7 +39,7 @@ from pyplusplus import module_builder from pyplusplus import function_transformers as FT - + mb = module_builder.module_builder_t( ... ) v3 = mb.class_( 'vector3' ) v3.mem_fun( 'get_values' ).add_transformation( FT.output_static_array( 0, 3 ) ) @@ -49,9 +49,9 @@ .. code-block:: C++ #include "__convenience.pypp.hpp" //Py++ header file, which contains few convenience function - + namespace bp = boost::python; - + static boost::python::object get_values_22786c66e5973b70f714e7662e2aecd2( ::ft::vector3 & inst ){ int native_values[3]; boost::python::list py_values; @@ -59,15 +59,15 @@ pyplus_conv::copy_container( native_values, native_values + 3, pyplus_conv::list_inserter( py_values ) ); return bp::object( py_values ); } - + ... [truncated message content] |
From: <rom...@us...> - 2007-01-03 21:19:45
|
Revision: 841 http://svn.sourceforge.net/pygccxml/?rev=841&view=rev Author: roman_yakovenko Date: 2007-01-03 13:19:39 -0800 (Wed, 03 Jan 2007) Log Message: ----------- small improvment Modified Paths: -------------- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/pointer_holder.hpp.patch.rest pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py Added Paths: ----------- pyplusplus_dev/docs/tutorials.rest Modified: pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/pointer_holder.hpp.patch.rest =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/pointer_holder.hpp.patch.rest 2007-01-03 18:15:11 UTC (rev 840) +++ pyplusplus_dev/docs/bpl_lessons_learned/shared_ptr/pointer_holder.hpp.patch.rest 2007-01-03 21:19:39 UTC (rev 841) @@ -1,3 +1,7 @@ +Download: `pointer_holder.hpp.patch`_ + +.. _`pointer_holder.hpp.patch` : pointer_holder.hpp.patch + .. code-block:: :language: diff :source-file: ./pointer_holder.hpp.patch Modified: pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py =================================================================== --- pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py 2007-01-03 18:15:11 UTC (rev 840) +++ pyplusplus_dev/docs/bpl_lessons_learned/www_configuration.py 2007-01-03 21:19:39 UTC (rev 841) @@ -1,3 +1,3 @@ -name = 'Boost.Python - lessons learned' +name = 'Boost.Python - troubleshooting guide' main_html_file = 'lessons_learned.html' names = { 'lessons_learned' : 'Boost.Python - lessons learned' } Added: pyplusplus_dev/docs/tutorials.rest =================================================================== --- pyplusplus_dev/docs/tutorials.rest (rev 0) +++ pyplusplus_dev/docs/tutorials.rest 2007-01-03 21:19:39 UTC (rev 841) @@ -0,0 +1,7 @@ +.. raw:: html + + <head><meta http-equiv="refresh" content="0; URL=./documentation/tutorials/tutorials.html"/></head> + <body> + Automatic redirection failed, please go to + <a href="./documentation/tutorials/tutorials.html">./documentation/tutorials/tutorials.html</a> + </body> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-04 20:10:17
|
Revision: 845 http://svn.sourceforge.net/pygccxml/?rev=845&view=rev Author: roman_yakovenko Date: 2007-01-04 12:10:16 -0800 (Thu, 04 Jan 2007) Log Message: ----------- rename dir from bpl_lessons_learned to troubleshooting_guide Added Paths: ----------- pyplusplus_dev/docs/troubleshooting_guide/ Removed Paths: ------------- pyplusplus_dev/docs/bpl_lessons_learned/ Copied: pyplusplus_dev/docs/troubleshooting_guide (from rev 843, pyplusplus_dev/docs/bpl_lessons_learned) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-03-01 14:19:22
|
Revision: 942 http://svn.sourceforge.net/pygccxml/?rev=942&view=rev Author: roman_yakovenko Date: 2007-03-01 06:19:19 -0800 (Thu, 01 Mar 2007) Log Message: ----------- updating documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/www_configuration.py pyplusplus_dev/docs/history/history.rest Added Paths: ----------- pyplusplus_dev/docs/documentation/multi_module_development.rest Added: pyplusplus_dev/docs/documentation/multi_module_development.rest =================================================================== --- pyplusplus_dev/docs/documentation/multi_module_development.rest (rev 0) +++ pyplusplus_dev/docs/documentation/multi_module_development.rest 2007-03-01 14:19:19 UTC (rev 942) @@ -0,0 +1,92 @@ +======================== +Multi-module development +======================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +It is a common practices to construct final program or just a library\\package +from few different dependent\\independent packages\\libraries. Many time these +libraries reuse classes\\functions defined in another one. I think this is a must +requirement from a code generator to be able to expose these libraries to `Python`_ , +without "re-exposing" the class\\functions definition twise. + + +Please take a look on `Creating Packages`_ example, in `Boost.Python`_ tutorials. +The example introduces slightly different use case, but it is good enough for us. + +Lets assume ``sounds::core`` namespace defines interface (base class) for all +filter classes. ``sounds::filters`` namespace defines few "filter" classes. + +The question now is how to expose the classes to Python, while preserving their +logical location using `Py++`_? + +.. _`Creating Packages` : http://boost.org/libs/python/doc/tutorial/doc/html/python/techniques.html#python.creating_packages + +------------------- +``already_exposed`` +------------------- + +`Py++`_ declaration + +.. code-block:: C++ + + //file sounds/core/filter_interface.h + + namespace sounds{ namespace core{ + + struct filter_i{ + ... + virtual void apply() = 0; + }; + } } //sounds::core + + +.. code-block:: C++ + + //file sounds/filters/ogg.h + + #include "sounds/core/filter_interface.h" + + namespace sounds{ namespace ogg{ + + struct noise_cleaner_t : public core::filter_i{ + ... + }; + + } } //sound::ogg + +.. code-block:: Python + + #generate_code.py script + + mb_core = module_builder_t( ... ) + mb_core.class_( 'filter_i' ).include() + + mb_filters = module_builder_t( ... ) + mb_filters.class_( '::sounds::core::filter_i' ).already_exposed = True + + #----------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^ + #This will tell to Py++ that "filter_i" class is already exposed + +`Py++`_ will generate right code for both modules: + + + + +.. _`Py++` : ./../pyplusplus.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: + Modified: pyplusplus_dev/docs/documentation/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/www_configuration.py 2007-03-01 10:51:10 UTC (rev 941) +++ pyplusplus_dev/docs/documentation/www_configuration.py 2007-03-01 14:19:19 UTC (rev 942) @@ -6,4 +6,5 @@ , 'doc_string' : 'documentation string' , 'inserting_code' : 'inserting code' , 'best_practices' : 'best practices' -} \ No newline at end of file + , 'multi_module_development' : 'multi-module development' +} Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2007-03-01 10:51:10 UTC (rev 941) +++ pyplusplus_dev/docs/history/history.rest 2007-03-01 14:19:19 UTC (rev 942) @@ -46,7 +46,7 @@ .. line-separator -2. Added exposing of copy constructors and "operator=". "operator=" is exposed +2. Added exposing of copy constructor and ``operator=``. ``operator=`` is exposed under "assign" name. .. line-separator @@ -55,7 +55,8 @@ .. _`as_tuple` : ../documentation/functions/call_policies.html#as-tuple -4. Added initial support for multi-module development. +4. Added initial support for multi-module development. Now you can mark you declaration + as ``already_exposed``. "Py++" will not create code for it, but will .. line-separator This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-03-07 09:55:51
|
Revision: 950 http://svn.sourceforge.net/pygccxml/?rev=950&view=rev Author: roman_yakovenko Date: 2007-03-07 01:55:51 -0800 (Wed, 07 Mar 2007) Log Message: ----------- updating documentation Modified Paths: -------------- pyplusplus_dev/docs/comparisons/compare_to.rest pyplusplus_dev/docs/quotes.rest Modified: pyplusplus_dev/docs/comparisons/compare_to.rest =================================================================== --- pyplusplus_dev/docs/comparisons/compare_to.rest 2007-03-07 07:29:32 UTC (rev 949) +++ pyplusplus_dev/docs/comparisons/compare_to.rest 2007-03-07 09:55:51 UTC (rev 950) @@ -28,8 +28,27 @@ The impression of Lakin Wecker, after spending 30 hours working working with `Py++`_: http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=1478&sid=4d77585146aabbc54f4b31ec50874d86 - .. _`Python-OGRE` : http://lakin.weckers.net/index_ogre_python.html + `Python-OGRE`_ project is reached the state, when it has all functionality + provided by similar one - `PyOgre`_. `PyOgre`_ is developed using SWIG. + I suggest you to compare the amount of code, written by `Python-Ogre`_ + developers and `PyOgre`_ ones: + + * `PyOgre`_ sources: http://svn.berlios.de/viewcvs/pyogre/trunk/pyogre/ogre/ + + * `Python-Ogre`_ sources: + + http://python-ogre.python-hosting.com/browser/trunk/python-ogre/code_generators/ogre/ + + http://python-ogre.python-hosting.com/browser/trunk/python-ogre/code_generators/common_utils/ + + Pay attention: functionality defined in "common_utils" package is used by + other scripts too. + + .. _`Python-OGRE` : http://python-ogre.python-hosting.com/ + .. _`PyOgre` : http://www.ogre3d.org/wiki/index.php/PyOgre + + Some other links, that compare Boost.Python, SWIG, SIP and other tools: * `Evaluation of Python/C++ interfacing packages`_ Modified: pyplusplus_dev/docs/quotes.rest =================================================================== --- pyplusplus_dev/docs/quotes.rest 2007-03-07 07:29:32 UTC (rev 949) +++ pyplusplus_dev/docs/quotes.rest 2007-03-07 09:55:51 UTC (rev 950) @@ -104,7 +104,7 @@ .. _`Python Computer Graphics Kit` : http://cgkit.sourceforge.net/ .. _`TnFOX`: http://www.nedprod.com/TnFOX/ .. _`PyOpenSG`: https://realityforge.vrsource.org/view/PyOpenSG/WebHome -.. _`Python-OGRE` : http://lakin.weckers.net/index_ogre_python.html +.. _`Python-OGRE` : http://python-ogre.python-hosting.com/ .. _`OGRE` : http://www.ogre3d.org/index.php?option=com_content&task=view&id=19&Itemid=79 .. Local Variables: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-04-25 05:15:36
|
Revision: 1019 http://svn.sourceforge.net/pygccxml/?rev=1019&view=rev Author: roman_yakovenko Date: 2007-04-24 22:15:33 -0700 (Tue, 24 Apr 2007) Log Message: ----------- fixing spelling errors Modified Paths: -------------- pygccxml_dev/docs/design.rest pygccxml_dev/docs/query_interface.rest pyplusplus_dev/docs/comparisons/compare_to.rest pyplusplus_dev/docs/comparisons/pyste.rest pyplusplus_dev/docs/documentation/best_practices.rest pyplusplus_dev/docs/documentation/containers.rest pyplusplus_dev/docs/documentation/functions/registration_order.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/modify_type.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest pyplusplus_dev/docs/documentation/functions/transformation/built_in/transfer_ownership.rest pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest pyplusplus_dev/docs/documentation/how_to.rest pyplusplus_dev/docs/documentation/index.rest pyplusplus_dev/docs/documentation/inserting_code.rest pyplusplus_dev/docs/documentation/multi_module_development.rest pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest pyplusplus_dev/docs/documentation/warnings.rest pyplusplus_dev/docs/history/history.rest pyplusplus_dev/docs/peps/dsl_challenge.rest pyplusplus_dev/docs/peps/peps_index.rest pyplusplus_dev/docs/pyplusplus.rest pyplusplus_dev/docs/quotes.rest pyplusplus_dev/docs/troubleshooting_guide/lessons_learned.rest pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest Modified: pygccxml_dev/docs/design.rest =================================================================== --- pygccxml_dev/docs/design.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pygccxml_dev/docs/design.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -137,7 +137,7 @@ * cache - classes, those one will help you to eliminate unnecessary parsing -* patchers - classes, that fix `GCC-XML`_ generated declarations. ( Yes, sometimes +* patchers - classes, which fix `GCC-XML`_ generated declarations. ( Yes, sometimes GCC-XML generates wrong description of C++ declaration. ) Parser classes @@ -227,9 +227,8 @@ There are few cache classes, which implements different cache strategies. -1. ``file_configuration_t`` class, that keeps pass to C++ source file and path to - `GCC-XML`_ generated XML file. This class is not a cache class, but it also - allows you to save your time. +1. ``file_configuration_t`` class, that keeps path to C++ source file and path to + `GCC-XML`_ generated XML file. 2. ``file_cache_t`` class, will save all declarations from all files within single binary file. @@ -277,7 +276,7 @@ Summary ------- -Thats all. I hope I was clear, at least I tried. Any way, `pygccxml`_ is an open +That's all. I hope I was clear, at least I tried. Any way, `pygccxml`_ is an open source project. You always can take a look on the source code. If you need more information please read API documentation. Modified: pygccxml_dev/docs/query_interface.rest =================================================================== --- pygccxml_dev/docs/query_interface.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pygccxml_dev/docs/query_interface.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -24,8 +24,8 @@ query = query & ~declarations.access_type_matcher_t( 'public' ) global_ns.member_functions( function=query, arg_types=[None, 'int &'] ) -The example is complex, but still readable. In many cases you will find your -self looking for one or many declarations using one or two properties of that +The example is complex, but still readable. In many cases you will find +yourself looking for one or many declarations using one or two properties of that declaration(s). For example: .. code-block:: Python @@ -105,8 +105,8 @@ * ``return_type`` - Function return type. This argument can be Python string or an object that - describes C++ type. + the function return type. This argument can be string or an object that describes + C++ type. .. code-block:: Python @@ -129,7 +129,7 @@ mem_funcs = my_class.member_functions( arg_types=[ None, 'int'] ) - ``mem_funcs`` will contain all member functions, that have two arguments + ``mem_funcs`` will contain all member functions, which have two arguments and type of second argument is ``int``. * ``header_dir`` Modified: pyplusplus_dev/docs/comparisons/compare_to.rest =================================================================== --- pyplusplus_dev/docs/comparisons/compare_to.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/comparisons/compare_to.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -49,7 +49,7 @@ .. _`PyOgre` : http://www.ogre3d.org/wiki/index.php/PyOgre -Some other links, that compare Boost.Python, SWIG, SIP and other tools: +Some other links, which compares Boost.Python, SWIG, SIP and other tools: * `Evaluation of Python/C++ interfacing packages`_ Modified: pyplusplus_dev/docs/comparisons/pyste.rest =================================================================== --- pyplusplus_dev/docs/comparisons/pyste.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/comparisons/pyste.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -44,7 +44,7 @@ analyzes. If you identify one, please report it. I will try to fix it, as quick as possible. In the past, I created bindings to few projects using `Pyste`_. Code, generated by `Pyste`_, was pretty good and gave me a good start both with -my projects and with `Boost.Python`_ library. As for me, there are 2 main +my projects and with `Boost.Python`_ library. As for me, there are two main problems with `Pyste`_: 1. It is time-consuming operation to maintain `Pyste`_ scripts in a big, @@ -116,7 +116,7 @@ code. 2. Module creator package. This is code creators factory. Classes in this - package analyze C++ declarations and creates relevant code creators. + package, analyze C++ declarations and creates relevant code creators. 3. File writers package. This package contains classes that write generated code to file(s). @@ -167,7 +167,7 @@ * few parsing strategies: - + all files will be parsed as it was one file that include all them + + all files will be parsed as it was one file that includes all them + every file will be parsed alone, after this, duplicated declarations and types will be removed @@ -375,7 +375,7 @@ 1. It is easier to understand compilation error. - 2. If in future a developer decide to create overload to some function, + 2. If in future a developer decides to create overload to some function, this code will continue to compile. * `Py++`_ has small nice future - "license". User can specify the Modified: pyplusplus_dev/docs/documentation/best_practices.rest =================================================================== --- pyplusplus_dev/docs/documentation/best_practices.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/best_practices.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -38,7 +38,7 @@ couple minutes with a reasonable cache size. You can read more about different caches supported by `pygccxml`_ `here`__. - ``module_builder_t.__init__`` methods takes reference to an instance of cache + ``module_builder_t.__init__`` method takes reference to an instance of cache class or ``None``: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/containers.rest =================================================================== --- pyplusplus_dev/docs/documentation/containers.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/containers.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -185,7 +185,7 @@ 1. If you set ``equality_comparable`` or ``less_than_comparable`` to ``False``. The indexing suite will disable relevant functionality. You don't have - explicitly to disable method or mothods group. + explicitly to disable method or methods group. 2. The documentation of new indexing suite contains few small mistakes. I hope, I will have time to fix them. Any way, `Py++`_ generates Modified: pyplusplus_dev/docs/documentation/functions/registration_order.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/registration_order.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/functions/registration_order.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -91,7 +91,7 @@ overloaded functions, if it can convert `Python`_ arguments to C++ ones, it does this and calls the function. -Now, when you understand the behaviour, it should be pretty simple to provide +Now, when you understand the behavior, it should be pretty simple to provide a correct functionality: 1. You can change alias of the function, by mangling the type of the argument Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/input_static_array.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -14,7 +14,7 @@ "input_static_array" transformer takes as first argument name or index of the original function argument. The argument should have "array" or "pointer" type. -The second argument should an integer value, that represents array size. +The second argument should an integer value, which represents array size. ------- Example Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/modify_type.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/modify_type.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/modify_type.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -16,7 +16,7 @@ 2. a callable, which takes as argument reference to type and returns new type -New in version grater than 0.8.5. +New in version greater than 0.8.5. Pay attention! -------------- Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/output_static_array.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -13,7 +13,7 @@ "output_static_array" transformer takes as first argument name or index of the original function argument. The argument should have "array" or "pointer" type. -The second argument should an integer value, that represents array size. +The second argument should an integer value, which represents array size. ------- Example Modified: pyplusplus_dev/docs/documentation/functions/transformation/built_in/transfer_ownership.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/built_in/transfer_ownership.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/functions/transformation/built_in/transfer_ownership.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -18,7 +18,7 @@ "transfer_ownership" transformer takes one argument, name or index of the original function argument. The argument type should be "pointer". -New in version grater than 0.8.5. +New in version greater than 0.8.5. ------- Example Modified: pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/functions/transformation/custom/custom.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -18,8 +18,8 @@ How to ...? ----------- -Unfortunately I don't have enough time to write a complete documentation :-(. -Meanwhile fill free to `contact me`_. You also can take a look on `built-in transformers`_ +Unfortunately I don't have enough time to write a complete documentation :-(, +fill free to `contact me`_. You also can take a look on `built-in transformers`_ implementation. .. _`contact me` : ../../../../links.html#id5 Modified: pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -75,7 +75,7 @@ Thanks to --------- -Thanks goes to Matthias Baas for his efforts and hard work. He did a research, +A thanks goes to Matthias Baas for his efforts and hard work. He did a research, implemented the initial working version and wrote a lot of documentation. .. _`Py++` : ./../pyplusplus.html Modified: pyplusplus_dev/docs/documentation/how_to.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/how_to.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -348,7 +348,7 @@ .. _`constraints` : http://www.python.org/doc/current/ref/identifiers.html -There are few pretty good reasons for this behaviour: +There are few pretty good reasons for this behavior: * when you just start to work on `Python`_ bindings concentrate your attention on really important things Modified: pyplusplus_dev/docs/documentation/index.rest =================================================================== --- pyplusplus_dev/docs/documentation/index.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/index.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -14,7 +14,7 @@ How can you help? * Lets face it: today it is not possible to use `Py++`_ without eventually - looking into source code. `Py++`_ uses `Epydoc`_ to generate documentation + looking into source code. `Py++`_ uses `epydoc`_ to generate documentation from source files. So, if you found some undocumented piece of code and you understand what it does, please write documentation string. @@ -48,7 +48,7 @@ .. _`best practices`: ./best_practices.html -* `documentation string`_ - explains how to automaticly extract a documentation +* `documentation string`_ - explains how to automatically extract a documentation from the source files and put it as Python documentation string .. _`documentation string` : ./doc_string.html @@ -56,7 +56,7 @@ * `warnings`_ - `Py++`_ could be used as some kind of validator. It checks the exposed declarations and reports the potential errors. Thus you are able to create high quality Python bindings from the beginning. This document also - describes how to supress the errors\\warnings. + describes how to suppress the errors\\warnings. .. _`warnings` : ./warnings.html @@ -65,7 +65,7 @@ .. _`functions & operators` : ../functions/functions.html -* `hints`_ - describes few techinques, which will help you with exposing template +* `hints`_ - describes few techniques, which will help you with exposing template instantiations .. _`hints`: ./hints.html @@ -94,7 +94,7 @@ .. _`tutorials` : ./tutorials/tutorials.html -.. _`Epydoc` : http://epydoc.sourceforge.net/ +.. _`epydoc` : http://epydoc.sourceforge.net/ .. _`Py++` : ./../pyplusplus.html .. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html .. _`Python`: http://www.python.org Modified: pyplusplus_dev/docs/documentation/inserting_code.rest =================================================================== --- pyplusplus_dev/docs/documentation/inserting_code.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/inserting_code.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -100,7 +100,7 @@ This method will add the code to the declaration section within the module. If you split your module to few files, `Py++`_ will add this code to the - cpp file, class registration code will be written in. + "cpp" file, class registration code will be written in. Attention: there is no defined order between wrapper code and declaration section code. If you have dependencies between code from declaration section and class Modified: pyplusplus_dev/docs/documentation/multi_module_development.rest =================================================================== --- pyplusplus_dev/docs/documentation/multi_module_development.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/multi_module_development.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -8,7 +8,7 @@ Introduction ------------ -It is a common practises to construct final program or a package from few +It is a common practices to construct final program or a package from few different dependent or independent C++ libraries. Many time these libraries reuse classes\\functions defined in some other library. I think this is a must requirement from a code generator to be able to expose these libraries to `Python`_ , Modified: pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest =================================================================== --- pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/tutorials/module_builder/module_builder.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -114,8 +114,8 @@ Now it is a time to create module code creator. Do you remember, in introduction to `Py++`_, I told you that before writing code to disc, `Py++`_ will create some -kind of `AST`_. Well this is done by calling ``module_builder_t.build_code_creator`` -function. Right now, the only important argument to the function is ``module_name``. +kind of `AST`_. Well calling module_builder_t.build_code_creator function does this. +Right now, the only important argument to the function is ``module_name``. Self explained, is it? Modified: pyplusplus_dev/docs/documentation/warnings.rest =================================================================== --- pyplusplus_dev/docs/documentation/warnings.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/documentation/warnings.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -35,7 +35,7 @@ virtual Y& do_smth(); }; - Member function ``do_smth`` can not be overridden in Python because... [FILL IN HERE]. + Member function ``do_smth`` cannot be overridden in Python because ... . * .. code-block:: C++ @@ -45,7 +45,7 @@ void get_size( int& height, int& width ) const; }; - Member function ``get_size`` can be exposed to Python, but it will not be callable because [FILL IN HERE]. + Member function ``get_size`` can be exposed to Python, but it will not be callable because ... . * In order to expose free/member function that takes more than 10 arguments user should define ``BOOST_PYTHON_MAX_ARITY`` macro. @@ -75,8 +75,8 @@ In previous paragraph, I described some pretty useful functionality but what should you do to enable it? - *Nothing!* By default, `Py++`_ only prints the -important messages to ``stdout``. More over it prints them only for declarations -that are going to be exported. +important messages to ``stdout``. More over, it prints them only for to be exposed +declarations. `Py++`_ uses the python `logging`_ package to write all user messages. By default, messages with ``DEBUG`` level will be skipped, all other messages will Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/history/history.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -81,7 +81,7 @@ 6. Added ability to control generated "include" directives. Now you can ask `Py++`_ to include a header file, when it generates code for some declaration. For more - information refer to `inserting code guide`_. + information refers to `inserting code guide`_. .. _`inserting code guide` : ../documentation/inserting_code.html#header-files @@ -95,7 +95,7 @@ .. line-separator -9. Added ability to add code before overriden and default function calls. +9. Added ability to add code before overridden and default function calls. For more information refer to `member function API documentation`_. .. _`member function API documentation` : ../documentation/apidocs/pyplusplus.decl_wrappers.calldef_wrapper.member_function_t-class.html Modified: pyplusplus_dev/docs/peps/dsl_challenge.rest =================================================================== --- pyplusplus_dev/docs/peps/dsl_challenge.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/peps/dsl_challenge.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -117,7 +117,7 @@ PointTmpl = mb.module.template('Point') Point = PointTmpl( 'int' ) - This is a trivial example, that is why it looks grate. Consider next class: + This is a trivial example, which is why it looks grate. Consider next class: .. code-block:: C++ Modified: pyplusplus_dev/docs/peps/peps_index.rest =================================================================== --- pyplusplus_dev/docs/peps/peps_index.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/peps/peps_index.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -60,13 +60,13 @@ In version 0.8.1 `Py++`_ introduced nice feature: automatic extraction and integration of documentation strings. I estimated wrong the influence of the feature on the project. First user, who actually tried it, was Gottfried Ganssauge. -He asked me to add support for documentation string that contains unicode characters. +He asked me to add support for documentation string that contains Unicode characters. These days I understand the influence. I should convert all strings in the whole -project to be unicode strings, with encoding specified by the user. This is a +project to be Unicode strings, with encoding specified by the user. This is a lot of work, but I think this is really important. So this is high priority "TODO". http://www.joelonsoftware.com/articles/Unicode.html - a nice article, which -explains what is unicode, encoding and character sets. +explains what is Unicode, encoding and character sets. .. _`Py++` : ./../pyplusplus.html Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/pyplusplus.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -81,7 +81,7 @@ mb.calldefs( access_type_matcher_t( 'protected' ) ).exclude() The developer can create custom criteria, for example exclude all declarations -that have 'impl' ( implementation ) string within the name. +with 'impl' ( implementation ) string within the name. .. code-block:: Python @@ -118,7 +118,7 @@ ----------------------- During this step Py++ reads code creators tree and writes code to the disc. The result of code generation process should not be different from the one, -that would be achieved by human. For small project writing all code into single +which would be achieved by human. For small project writing all code into single file is good approach, for big ones code should be written into multiple files. Py++ implements both strategies. Modified: pyplusplus_dev/docs/quotes.rest =================================================================== --- pyplusplus_dev/docs/quotes.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/quotes.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -36,7 +36,7 @@ Lakin Wecker, the author of `Python-OGRE`_ project "... Py++ allows the wrappers to be "automagically" created, which means it's much -easier to keep things up to date (the maintainence on the Py++ based wrapper is +easier to keep things up to date (the maintenance on the Py++ based wrapper is tiny compared to any other system I've used). It also allows us to wrap other libraries fairly easily. " Modified: pyplusplus_dev/docs/troubleshooting_guide/lessons_learned.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/lessons_learned.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/troubleshooting_guide/lessons_learned.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -8,7 +8,7 @@ Preamble -------- -Software development is an interactrive process. During `Py++`_ development +Software development is an interactive process. During `Py++`_ development I see many interesting problems and even more interesting solutions. On this page you will find my collection of the solutions to some of the problems. Modified: pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest 2007-04-25 04:10:48 UTC (rev 1018) +++ pyplusplus_dev/docs/troubleshooting_guide/shared_ptr/shared_ptr.rest 2007-04-25 05:15:33 UTC (rev 1019) @@ -16,7 +16,7 @@ There are two possible solutions to the problem. The first one is to fix Boost.Python library: `pointer_holder.hpp.patch`_ . The patch was contributed -to the library ( 8-December-2006 ) and some day it will be commited to the CVS. +to the library ( 8-December-2006 ) and some day it will be committed to the CVS. It is also possible to solve the problem, without changing Boost.Python library: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-11-13 07:24:30
|
Revision: 1147 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1147&view=rev Author: roman_yakovenko Date: 2007-11-12 23:24:34 -0800 (Mon, 12 Nov 2007) Log Message: ----------- updating links to python-ogre Modified Paths: -------------- pyplusplus_dev/docs/comparisons/compare_to.rest pyplusplus_dev/docs/quotes.rest Modified: pyplusplus_dev/docs/comparisons/compare_to.rest =================================================================== --- pyplusplus_dev/docs/comparisons/compare_to.rest 2007-11-12 22:16:36 UTC (rev 1146) +++ pyplusplus_dev/docs/comparisons/compare_to.rest 2007-11-13 07:24:34 UTC (rev 1147) @@ -37,14 +37,14 @@ * `Python-Ogre`_ sources: - http://python-ogre.python-hosting.com/browser/trunk/python-ogre/code_generators/ogre/ + http://python-ogre.svn.sourceforge.net/viewvc/python-ogre/trunk/python-ogre/code_generators/ogre/ - http://python-ogre.python-hosting.com/browser/trunk/python-ogre/code_generators/common_utils/ + http://python-ogre.svn.sourceforge.net/viewvc/python-ogre/trunk/python-ogre/code_generators/common_utils/ Pay attention: functionality defined in "common_utils" package is used by other scripts too. - .. _`Python-OGRE` : http://python-ogre.python-hosting.com/ + .. _`Python-OGRE` : http://www.python-ogre.org .. _`PyOgre` : http://www.ogre3d.org/wiki/index.php/PyOgre Modified: pyplusplus_dev/docs/quotes.rest =================================================================== --- pyplusplus_dev/docs/quotes.rest 2007-11-12 22:16:36 UTC (rev 1146) +++ pyplusplus_dev/docs/quotes.rest 2007-11-13 07:24:34 UTC (rev 1147) @@ -116,7 +116,7 @@ .. _`Python Computer Graphics Kit` : http://cgkit.sourceforge.net/ .. _`TnFOX`: http://www.nedprod.com/TnFOX/ .. _`PyOpenSG`: https://realityforge.vrsource.org/view/PyOpenSG/WebHome -.. _`Python-OGRE` : http://python-ogre.python-hosting.com/ +.. _`Python-OGRE` : http://www.python-ogre.org .. _`OGRE` : http://www.ogre3d.org/index.php?option=com_content&task=view&id=19&Itemid=79 .. Local Variables: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |