Re: D move semantics

2017-07-30 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 30 July 2017 at 16:12:41 UTC, piotrekg2 wrote:

What is the idiomatic D code equivalent to this c++ code?


There's no direct equivalent of all your code to D using only 
druntime+phobos AFAIK.




class Block
{
[...]
};


Since you don't seem to be using reference type semantics or 
polymorphism this should be mapped to a struct, such as


---
import std.experimental.allocator;
import std.experimental.allocator.mallocator;

struct Block
{
public:
static Block create()
{
Block obj;
obj.data_ = Mallocator.instance.makeArray!char(4096);
return obj;
}

~this() nothrow
{
if (data_ !is null) {
Mallocator.instance.dispose(data_);
data_ = null;
}
}

@disable this(this); // Forbid copying
private:
char[] data_;
}
---



// What is the equivalent of std::vector, the closest thing I 
could find is

// std.container.array
std::vector blocks;

for (int i = 0; i < 100; ++i) {
  // NOTE: blocks are moved when relocation happens
  // because of move-ctor and move-assign-operator marked 
noexcept

  blocks.emplace_back();
}


That's the closest one in Phobos AFAIK. There are custom 
container implementations out there such as the emsi containers 
[1]. If you use one of them, the above should be as simple as


---
Array!Block blocks;

foreach (i; 0..100)
{
blocks ~= Block.create();
}
---

I've added your example as a unittest to my own dynamic array 
implementation, should you wish to have a look [2].


A little bit of background:

Classes are reference types, structs are value types i.e there's 
no copy/move mechanics for classes w.r.t. your code. The one for 
structs is roughly like this: Whenever the compiler sees a struct 
object `obj` being assigned a new value `other`, it will run the 
destructor for `obj` (should one exist), then copy `other` over 
`obj`, followed by calling the postblit constructor `this(this) { 
... }` (should it exist) on `obj`.


In some instances (such as return from function, or first 
assignment in constructor, i.e. initialization) the compiler may 
automatically optimize the copy to a move.
Assuming the compiler tries to do a copy, it will only work if 
`typeof(obj)` is copyable (doesn't have the postblit disabled via 
`@disable this(this)`), if it isn't, the compiler will error out;
you can force a move by using `std.algorithm : move`. There's 
also `std.algorithm : moveEmplace` in case you don't wish the 
target to be destroyed.


[1] https://github.com/economicmodeling/containers
[2] 
https://github.com/Calrama/libds/blob/83211c5d7cb866a942dc9dd8ba1c622573611ccd/src/ds/dynamicarray.d#L351


D move semantics

2017-07-30 Thread piotrekg2 via Digitalmars-d-learn

What is the idiomatic D code equivalent to this c++ code?

class Block
{
public:
  Block()
: data_(new char[4096])
  {}

  ...

  // NOTE: both members marked noexcept
  Block(Block &&rhs) noexcept = default;
  Block& operator=(Block &&rhs) noexcept = default;

  ...

private:
  std::unique_ptr data_;
};

// What is the equivalent of std::vector, the closest thing I 
could find is

// std.container.array
std::vector blocks;

for (int i = 0; i < 100; ++i) {
  // NOTE: blocks are moved when relocation happens
  // because of move-ctor and move-assign-operator marked noexcept
  blocks.emplace_back();
}