[C++-sig] boost python class member getter/setter same name different only by constness

2014-10-03 Thread MM
Hi

class C {
public:
  const std::string& name() const;
  std::string& name();
private:
  std::string name_;
};

given this class C, how would I expose it to python with the class property
name?

class_("C").
  .add_property("name",   &C::name, &C::name);

or do I use 2 mem function pointers to distinguish the 2 names, and pass
those 2 pointers?

MM
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] boost python class member getter/setter same name different only by constness

2014-10-03 Thread MM
yes i did that.

class C {
> public:
>   const std::string& get_name() const;
>   void set_name(const std::string&);
> private:
>   std::string name_;
> };
>


> class_("C").
>   .add_property("name",   &C::get_name, &C::set_name);


this fails to compile because of unspecified call policies about the string
refs.


The following, on the other hand, compiles.

> class C {
> public:
>   const std::string get_name() const;
>   void set_name(const std::string);
> 
> class_("C").
>   .add_property("name",   &C::get_name, &C::set_name);


Which policy do I specify? and how do I set it in add_property?

MM

On 3 October 2014 17:50, Stefan Seefeld  wrote:

> On 2014-10-02 16:09, MM wrote:
> > Hi
> >
> > class C {
> > public:
> >   const std::string& name() const;
> >   std::string& name();
> > private:
> >   std::string name_;
> > };
> >
> > given this class C, how would I expose it to python with the class
> > property name?
> >
> > class_("C").
> >   .add_property("name",   &C::name, &C::name);
> >
> > or do I use 2 mem function pointers to distinguish the 2 names, and
> > pass those 2 pointers?
>
> You need to disambiguate the two overloads. The cleanest way to do that
> is to introduce two (local) variables of the appropriate
> pointer-to-member-function types, then pass those variables to the
> 'add_property' call.
> In addition, I believe boost.python expects a different signature for
> the setter (a function taking a value-type argument), so you may have to
> provide a wrapper function for that, unless you want to modify the 'C'
> class in-place.
>
> HTH,
> Stefan
>
>
>
> --
>
>   ...ich hab' noch einen Koffer in Berlin...
>
> ___
> Cplusplus-sig mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/cplusplus-sig
>
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] boost python class member getter/setter same name different only by constness

2014-10-03 Thread MM
On 3 October 2014 18:23, Jim Bosch  wrote:

> On Fri, Oct 3, 2014 at 1:15 PM, Stefan Seefeld 
> wrote:
>
>> On 2014-10-03 12:56, MM wrote:
>> > yes i did that.
>> >
>> > class C {
>> > public:
>> >   const std::string& get_name() const;
>> >   void set_name(const std::string&);
>> > private:
>> >   std::string name_;
>> > };
>> >
>> >
>> >
>> > class_("C").
>> >   .add_property("name",   &C::get_name, &C::set_name);
>> >
>> >
>> > this fails to compile because of unspecified call policies about the
>> > string refs.
>> >
>> >
>> > The following, on the other hand, compiles.
>> >
>> > class C {
>> > public:
>> >   const std::string get_name() const;
>> >   void set_name(const std::string);
>> > 
>> > class_("C").
>> >   .add_property("name",   &C::get_name, &C::set_name);
>> >
>> >
>> > Which policy do I specify? and how do I set it in add_property?
>>
>> Good question. The policy you want is likely pass-by-value (In Python
>> strings are immutable anyhow), however I have no idea how to express
>> that with the add_property() call.
>> As a quick hack I suggest adding a wrapper function that returns the
>> result by-value:
>>
>>   std::string get_name(C &c) { return c.get_name();}
>>
>> and use that. That's neither elegant nor efficient (if you call it a
>> lot), but it may unblock you until you find a real fix.
>>
>>
> To use a call policy here, I *think* you'd pass
> return_value_policy() as the fourth argument to
> add_property, but it may be some slight modification of that.  In any case,
> I suspect that's no more efficient than Stefan's solution in this case.
>
>
> Jim
>
> Not quite. get_property's 4th argument is just a docstring.
It seems only def has a policy argument.

Actually this is a problem because the next 2 properties of the class are
big vectors.

I am gonna go with just defs of getter/setter instead as add_property
doesn't help (i looked at class.hpp inside boost.python)

MM
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

[C++-sig] express pointer ownership

2015-08-13 Thread MM
I have the following class:

class T {
};
// T has been exposed to python with class_

and free function:

void add_T( T* );

Ownership of the T* is taken by this C++ function.


If I create an instance of the python version of T, how do I "def" the
add_T function?

def("add_T", add_T)

fails to compile.
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] express pointer ownership

2015-08-13 Thread MM
On 13 August 2015 at 10:24, MM  wrote:

> I have the following class:
>
> class T {
> };
> // T has been exposed to python with class_
>
> and free function:
>
> void add_T( T* );
>
> Ownership of the T* is taken by this C++ function.
>
>
> If I create an instance of the python version of T, how do I "def" the
> add_T function?
>
> def("add_T", add_T)
>
> fails to compile.
>

Apologies. This compiled correctly.

This function:

const T* get_T( const std::string& name );

failed to compile.

so the T pointer is owner by a container in the c++ world, it gets stored
there by add_T,
then the get_T  returns a raw pointer to it. I want to tell python to let
c++ manage it.
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] express pointer ownership

2015-08-13 Thread MM
On 13 August 2015 at 12:01, Stefan Seefeld  wrote:

> On 13/08/15 06:58 AM, MM wrote:
> > On 13 August 2015 at 10:24, MM  > <mailto:[email protected]>> wrote:
> >
> > I have the following class:
> >
> > class T {
> > };
> > // T has been exposed to python with class_
> >
> > and free function:
> >
> > void add_T( T* );
> >
> > Ownership of the T* is taken by this C++ function.
> >
> >
> > If I create an instance of the python version of T, how do I "def"
> > the add_T function?
> >
> > def("add_T", add_T)
> >
> > fails to compile.
> >
> >
> > Apologies. This compiled correctly.
> >
> > This function:
> >
> > const T* get_T( const std::string& name );
> >
> > failed to compile.
> >
> > so the T pointer is owner by a container in the c++ world, it gets
> > stored there by add_T,
> > then the get_T  returns a raw pointer to it. I want to tell python to
> > let c++ manage it.
>
> Sounds like you want to use the "return_internal_reference" call policy
> (see
>
> http://boostorg.github.io/python/doc/html/tutorial/tutorial/functions.html#tutorial.functions.call_policies
> ).
>
> Stefan
>
>
That policy says:

"Ties lifetime of one argument to that of result"

The argument of my function is just the string Really its lifetime
doesn't matter
In the context of a call from python:

t = get_T( 'name1' )

At some point, a std::string temporary must be constructed, holding
'name1'?  and then get_T uses it for lookup.
Once get_T returns   the const T*, it doesn't care about it anymore.

What I want to express is:

The t returned by the python function should refer to object T held in c++
memory, and for instance

del t

should not delete the actual T object in c++ memory

Should I still use "return_internal_reference"  ?
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

[C++-sig] register c++ std::pair and std::pair

2015-08-28 Thread MM
I expose the return type of a C++ function that is a pair of strings with
the following snippet:

to_python_converter<
std::pair,
Converter>();

Later, I have a unrelated C++ range type:

typedef std::pair range_t;

which I export as:

class_("range")
.def("__iter__" , range(..., ...));
scope().attr("allitems") = object(ptr(&R));

where R is of type range_t

in python, allitems can be iterated over.

The only issue is I get the following warning:

/usr/lib64/python3.4/importlib/_bootstrap.py:321: RuntimeWarning:
to-Python converter for std::pair already registered; second conversion method ignored.

Is there a way to avoid this warning?

MM
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] register c++ std::pair and std::pair

2015-08-28 Thread MM
On 28 August 2015 at 13:41, Stefan Seefeld  wrote:

> On 28/08/15 07:49 AM, MM wrote:
> >
> > I expose the return type of a C++ function that is a pair of strings
> > with the following snippet:
> >
> > |to_python_converter,Converter>();|
> >
> > Later, I have a unrelated C++ range type:
> >
> > |typedef std::pairrange_t;|
> >
> > which I export as:
> >
> >
> |class_("range").def("__iter__",range(...,...));scope().attr("allitems")=object(ptr(&R));|
> >
> > where R is of type range_t
> >
> > in python, allitems can be iterated over.
> >
> > The only issue is I get the following warning:
> >
> >
> |/usr/lib64/python3.4/importlib/_bootstrap.py:321:RuntimeWarning:to-Pythonconverter
> > forstd::pairalready
> > registered;second conversion method ignored.|
> >
> > Is there a way to avoid this warning?
> >
>
> Why do you need the explicit converter if you also define a
> class_ ? Wouldn't everything work just fine without it ?
>
> Stefan
>
This is in too separate modules.
The converter is registered in module1, and the class_ in module 2.
I import 1 then 2, then it happens

Also the intents are different. THe pair is to be considered
as a (str1,str2) tuple of 2 values.
The pair is the [begin, end[ iterators into an array with
value_type string
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] register c++ std::pair and std::pair

2015-08-28 Thread MM
On 28 August 2015 at 15:01, Stefan Seefeld  wrote:

> On 28/08/15 09:26 AM, MM wrote:
> > This is in too separate modules.
> > The converter is registered in module1, and the class_ in
> > module 2.
> > I import 1 then 2, then it happens
> >
> > Also the intents are different. THe pair is to be
> > considered as a (str1,str2) tuple of 2 values.
> > The pair is the [begin, end[ iterators into an array
> > with value_type string
>
>
> Oups, sorry, I hadn't noticed that they had different types. Can you
> please post a minimal bug self-contained test case ? I'd like to debug
> this a bit to better understand what is going on. I believe this should
> work as there is no reason the two types should be confused. (It
> obviously depends on your "Converter" type, which you haven't shown.)
>
> Thanks,
> Stefan
>
>
Well, there's something about the fact that pointer types somehow change to
the types pointed to I don't understand it well

I tried to strip it down here:

/// header file
template 
struct stdpair_to_python_tuple
{
  static PyObject* convert(const std::pair&pr)
  {
return incref( make_tuple(pr.first, pr.second).ptr() );
  }
};

/// module1.cpp
BOOST_PYTHON_MODULE(libmodule1)
{
  to_python_converter<
  std::pair,
  stdpair_to_python_tuple>();
}

/// module2.cpp
typedef std::pair range_t;
range_t range;

BOOST_PYTHON_MODULE(libmodule2)
{
  using namespace boost::python;

  class_("range")
.def("__iter__",
  range(&range_t::first, &range_t::second))
;

  scope().attr("allitems") = object(ptr(&range));
}


Load 1 then 2 it should trigger the warning.
Apologies for missing the includes.

Thanks
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] register c++ std::pair and std::pair

2015-08-28 Thread MM
On 28 August 2015 at 16:05, Stefan Seefeld  wrote:

> On 28/08/15 10:15 AM, MM wrote:
> >
> > Load 1 then 2 it should trigger the warning.
> > Apologies for missing the includes.
>
> I had to modify your code a bit as it triggers errors when compiled
> as-is. And with those modifications it didn't see any warning.
> Could you please post code that I can compile without any modifications ?
>
> Thanks,
> Stefan
>

Apologies, I also didn't get any warnings.

I was actually registering an identical   std::pair as an iterator with a different name in a prior module, ie I had
another class_("range2")

and range2_t is identical to ranget_t :-)

Thanks for helping to spot this:-)
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

[C++-sig] boost python exposing const*

2015-09-05 Thread MM
I have a c++ class T that I succesfully expose via:

class_ ...


later on, I have

struct S {
  const T* underlying;
};

class_("S").
.def_readonly("underlying", &S::underlying)
;

>From python, when I call:

s.underlying

where s is a python instance of S, i get the following error:

TypeError: No to_python (by-value) converter found for C++ type: T const*

Do I need another converter for T const* in particular? or for both T* and
T const*?
Does the class_ above only expose T itself, not pointers to it?

Thanks
MM
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

[C++-sig] Why isn't python-exposed boost::gregorian::date available everywhere?

2015-09-07 Thread MM
I thought I'd post this SO question here as well, thanks:

I exposed boost::gregorian::date with the following:

date_from_python_date{};
to_python_converter{};

where *date_to_python_date* is a struct with the right convert function: it
converts it to a python datetime.date. Some c++ functions return date and
calling them from python works.

At a later stage, I have a c++ class

class F {/// public:
boost::gregorian::date start;};

which I register with:

class_>("F")
  .def_readwrite("start", &F::start, "FTD");

I do this after having python-registered date. I then obtain an instance f
of the F wrapper. But then, when I print

f.start

The error is:

No Python class registered for C++ class boost::gregorian::date
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig

[C++-sig] map_indexing_suite for boost::container::flat_map, std::map, std::unordered_amp

2018-07-08 Thread MM
Hello,

I've tried to adapt

using myfm = boost::container::flat_map;

with boost::python::map_indexing_suite

  class_< myfm, myfm*  >("myfm")
.def( map_indexing_suite{} )
  ;

I get a compile errors:


/usr/include/boost/python/detail/invoke.hpp:75:14: error: no match for call
> to ‘(const
> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning T*>) (const T*)’
> ...
> Caller = boost::python::detail::caller V>&), default_call_policies ...>

I would suspect that there is some function that returns the key_type of
the flat_map and takes a single argument of the value_type, but I can't
find any.

If there's one, I would need pick a return value policy for it.

As a matter of fact, I've switched to std::unordered_map and std::map, and
I am encountering the same problem

MM
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig


[C++-sig] boost python PR 315

2021-06-08 Thread MM
https://github.com/boostorg/python/pull/315

Hello
Is there some further testing required for this to be merged to be
candidate to make it in the next release?

rds,
___
Cplusplus-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cplusplus-sig