February 14, 2015
On Saturday, 14 February 2015 at 18:04:50 UTC, Andrei Alexandrescu wrote:
> On 2/13/15 4:23 AM, Guillaume Chatelet wrote:
>> * In the video Walter posted recently (3), he states that one should use
>> a class to represent a std::string or std::vector in D because most of
>> the time we want to have reference semantic. I find this a bit counter
>> intuitive for people coming from C++ since they are clearly value
>> semantic. std::string and std::vector should behave the same in C++ and
>> D to confirm the principle of least astonishment.
>
> Yah, this is still a bit in the air. The point here is that the simplest route to getting std::vector working in D is to avoid the many little difference between C++ copy ctors and D's postblit. As such, we say: pass std::vector by reference from/to C++, and never construct or copy one on the D side.

I think we can do with 'never copy' but never create seems a bit rough.
If you want to call a C++ function that takes a vector you'd need to allocate it somehow. And struct would make allocation predictable by default.

> I think that's a usable policy - most of the time containers are not supposed to be copied and people must carefully pass them by reference everywhere. The annoying part is having one as a member in a D type.
>
> Clearly we need to think this through carefully.

Definitely. I think I'll do two implementations and see how far I can go with both (class vs struct).
My understanding is that if we go with struct we can allocate on the D side and we have value semantic (for what I tested copy does work and does not leak memory).

>> I did a few tests. Using a class doesn't work because of the added vptr.
>> The data would be managed at the same time on the D and the C++ side.
>
> That should work. You don't need any layout information at all for std::vector on the D side; all you do is pass a pointer to std::vector around D code, and when you want to mess with it you pass the pointer to "this" appropriately. It all works; there's no need for D to know the layout, only the correct pointer and method signatures.

I agree but I see several potential issues :
- you can't control the object lifetime on the D side (can't allocate on D side  without a C++ helper function, can't delete the object)
- using scoped!std_string will crash.

> I think a gating issue right now is handling C++ exceptions in D code. C++ stdlib types are not really usable without exceptions.

For string and vector a lot of the functions are nothrow, so those would be safe to use at least.
February 14, 2015
"Guillaume Chatelet"  wrote in message news:fzxoskcrswitmsdsztso@forum.dlang.org...

> I did a few tests. Using a class doesn't work because of the added vptr.

This is a bug, D currently adds a vptr even if there are no members.  It's just one that doesn't happen to affect ddmd so I never got around to fixing it.

> struct std_string {
>    void[8] _ = void; // to match sizeof(std::string) and pad the object correctly.
> }
>
> The padding will be left untouched on the D side because of void initializer and will be managed entirely on the C++ side.

Just remember to be careful that any C++ structs don't rely on interior pointers.

> - name mangling on linux (bug reported in my first message)

Is this in bugzilla?

> - name mangling on Windows at least (name would be mangled as a struct instead of class)

We can probably use pragma(mangle) to fix this or add a new pragma for it. eg pragma(cpp_class/cpp_struct);

> - disabled default constructor.

Yeeeeah I've always felt like we're going to have to add default struct ctors to D eventually. 

February 14, 2015
On Saturday, 14 February 2015 at 19:54:53 UTC, Daniel Murphy wrote:
>> - name mangling on linux (bug reported in my first message)
>
> Is this in bugzilla?

I just created it
https://issues.dlang.org/show_bug.cgi?id=14178
February 15, 2015
I updated https://github.com/gchatelet/dlang_cpp_std to provide a struct and class implementation of string.
Also added a README to weigh the pros and cons of each, list bugs I encountered  and other things we need to think about.
February 15, 2015
On Sunday, 15 February 2015 at 14:42:46 UTC, Guillaume Chatelet wrote:
> I updated https://github.com/gchatelet/dlang_cpp_std to provide a struct and class implementation of string.
> Also added a README to weigh the pros and cons of each, list bugs I encountered  and other things we need to think about.

That's a great work.
Guillaume, I'll try to ask this question again.

I'm wrapping the C++ API of OpenCV [1], and it works great.
I'm using a D struct for std::string instead of D class, because I agree with your findings that's more convenient.

But, in case I would like to use a D class for std::string, how to call a C++ function that takes a std::string&? It's feasible right now?

I think we need more control over the mangle in extern(C++)...

[1] http://docs.opencv.org/trunk/modules/refman.html
February 15, 2015
On Sunday, 15 February 2015 at 15:37:33 UTC, Paolo Invernizzi wrote:
> That's a great work.

Thx :)

> Guillaume, I'll try to ask this question again.
>
> I'm wrapping the C++ API of OpenCV [1], and it works great.
> I'm using a D struct for std::string instead of D class, because I agree with your findings that's more convenient.
>
> But, in case I would like to use a D class for std::string, how to call a C++ function that takes a std::string&? It's feasible right now?
>
> I think we need more control over the mangle in extern(C++)...
>
> [1] http://docs.opencv.org/trunk/modules/refman.html

I just pushed a new commit which shows how to do it with classes as well:
https://github.com/gchatelet/dlang_cpp_std/commit/892a736386ecd84516b7330fef4ee75f1b4d2ad3

This requires to pervert the type system though so it's pretty unsafe.
I added the two following helper functions to reinterpret a D reference semantic as a C++ value semantic :
const (basic_string*) c_ptr() const { return cast(const std_string*)(this); }
ref const(basic_string) c_ref() const { return *cast(const std_string*)(this); }

You can then call the C++ function :
getStringSize(s.c_ref);

This is cumbersome and unsafe but workable.

Because the C++ function contains a const ref to string we have to provide the correct mangling manually anyways because of mangling bug https://issues.dlang.org/show_bug.cgi?id=14178
February 15, 2015
On 2/15/15 6:42 AM, Guillaume Chatelet wrote:
> I updated https://github.com/gchatelet/dlang_cpp_std to provide a struct
> and class implementation of string.
> Also added a README to weigh the pros and cons of each, list bugs I
> encountered  and other things we need to think about.

Awesome work, thanks. After further thinking of this, Walter and I concluded we should make std::string, std::vector etc. be structs in D code as well lest we confuse the heck out of people.

Please file bugs for any constructor/destructor issues you find (I notice you filed one already). Walter is up to the task and of course I'm counting on others, too.

Let's aim for passable support for 2.068.


Thanks,

Andrei

February 15, 2015
On Sunday, 15 February 2015 at 19:44:39 UTC, Guillaume Chatelet wrote:
> On Sunday, 15 February 2015 at 15:37:33 UTC, Paolo Invernizzi wrote:
>> That's a great work.
>
> Thx :)
>
>> Guillaume, I'll try to ask this question again.
>>
>> I'm wrapping the C++ API of OpenCV [1], and it works great.
>> I'm using a D struct for std::string instead of D class, because I agree with your findings that's more convenient.
>>
>> But, in case I would like to use a D class for std::string, how to call a C++ function that takes a std::string&? It's feasible right now?
>>
>> I think we need more control over the mangle in extern(C++)...
>>
>> [1] http://docs.opencv.org/trunk/modules/refman.html
>
> I just pushed a new commit which shows how to do it with classes as well:
> https://github.com/gchatelet/dlang_cpp_std/commit/892a736386ecd84516b7330fef4ee75f1b4d2ad3
>
> This requires to pervert the type system though so it's pretty unsafe.
> I added the two following helper functions to reinterpret a D reference semantic as a C++ value semantic :
> const (basic_string*) c_ptr() const { return cast(const std_string*)(this); }
> ref const(basic_string) c_ref() const { return *cast(const std_string*)(this); }
>
> You can then call the C++ function :
> getStringSize(s.c_ref);
>
> This is cumbersome and unsafe but workable.
>
> Because the C++ function contains a const ref to string we have to provide the correct mangling manually anyways because of mangling bug https://issues.dlang.org/show_bug.cgi?id=14178

Thanks for sharing!
---
/P

February 17, 2015
On Sunday, 15 February 2015 at 19:49:28 UTC, Andrei Alexandrescu wrote:
> Please file bugs for any constructor/destructor issues you find (I notice you filed one already). Walter is up to the task and of course I'm counting on others, too.

ctor/dtor C++ naming : https://issues.dlang.org/show_bug.cgi?id=14086
invalid stl manlging : https://issues.dlang.org/show_bug.cgi?id=14178

Questions :
+ Shall I add one more to allow default ctor for struct when they are extern C++ ? (ie. no @disable)
+ I guess this C++ STL binding will end up in phobos. Any idea of where this should be put ?
February 17, 2015
We'll also have to provide a new pragma to allow correct mangling of types on Windows. Maybe something like :

extern(C++, std) {

pragma(mangleAs, "class")
struct basic_string()
{
...
}

}