digitalmars.D - Using non-copyable types
- Yuxuan Shui (8/8) May 23 2019 When I try to use non-copyable types, I just get all sorts of
- H. S. Teoh (13/24) May 23 2019 Wrap them in a reference. I.e., instead of passing the range itself,
- Yuxuan Shui (4/18) May 23 2019 What about Tuple?
- H. S. Teoh (27/45) May 23 2019 Probably have to create a new Tuple that references the uncopyable
- Yuxuan Shui (18/43) May 23 2019 Somehow this trick doesn't work with fold:
- Kagamin (1/1) May 24 2019 That's because foreach doesn't support pointer ranges.
- H. S. Teoh (5/6) May 24 2019 Aha, so that's where a wrapper reference range struct comes in handy.
When I try to use non-copyable types, I just get all sorts of resistance from the standard library. For example, most of the std.range functions assume the range is copyable. std.typecons.Tuple assume all of its types are copyable. I tried to use the new copy constructor feature to make a wrapper that moves by default. But apparently copy constructors are ignored when postblit is disabled. How can we make using non-copyable types easier?
May 23 2019
On Thu, May 23, 2019 at 06:05:41PM +0000, Yuxuan Shui via Digitalmars-d wrote:When I try to use non-copyable types, I just get all sorts of resistance from the standard library. For example, most of the std.range functions assume the range is copyable. std.typecons.Tuple assume all of its types are copyable. I tried to use the new copy constructor feature to make a wrapper that moves by default. But apparently copy constructors are ignored when postblit is disabled. How can we make using non-copyable types easier?Wrap them in a reference. I.e., instead of passing the range itself, pass a pointer to the range. Or use a suitable wrapper struct with reference semantics. Thanks to D unifying member invocation via object and via pointer to object, this should be mostly transparent to Phobos algorithms. This gets around the complications with postblits / copy ctors and Phobos assumptions about copyability. NonCopyableRange r = ...; auto rp = &r; result = rp.map!(...).filter!(...).joiner; // etc. T -- When solving a problem, take care that you do not become part of the problem.
May 23 2019
On Thursday, 23 May 2019 at 18:18:02 UTC, H. S. Teoh wrote:On Thu, May 23, 2019 at 06:05:41PM +0000, Yuxuan Shui via Digitalmars-d wrote:What about Tuple? These are probably not the best examples, I just sense there is a general lack of consideration of non-copyable types in phobos.[...]Wrap them in a reference. I.e., instead of passing the range itself, pass a pointer to the range. Or use a suitable wrapper struct with reference semantics. Thanks to D unifying member invocation via object and via pointer to object, this should be mostly transparent to Phobos algorithms. This gets around the complications with postblits / copy ctors and Phobos assumptions about copyability. NonCopyableRange r = ...; auto rp = &r; result = rp.map!(...).filter!(...).joiner; // etc. T
May 23 2019
On Thu, May 23, 2019 at 06:33:04PM +0000, Yuxuan Shui via Digitalmars-d wrote:On Thursday, 23 May 2019 at 18:18:02 UTC, H. S. Teoh wrote:[...]On Thu, May 23, 2019 at 06:05:41PM +0000, Yuxuan Shui via Digitalmars-d wrote:[...]Wrap them in a reference. I.e., instead of passing the range itself, pass a pointer to the range. Or use a suitable wrapper struct with reference semantics. Thanks to D unifying member invocation via object and via pointer to object, this should be mostly transparent to Phobos algorithms. This gets around the complications with postblits / copy ctors and Phobos assumptions about copyability. NonCopyableRange r = ...; auto rp = &r; result = rp.map!(...).filter!(...).joiner; // etc.What about Tuple?Probably have to create a new Tuple that references the uncopyable object in the original.These are probably not the best examples, I just sense there is a general lack of consideration of non-copyable types in phobos.Certainly, because non-copyable types were added to the language after the fact. Like so many additions that people clamor for, they add many complications and unexpected interactions with existing language features, and also break assumptions Phobos was originally predicated upon, thereby introducing subtle bugs and/or corner cases that didn't exist when the code was written. Basically, Phobos was written assuming that ranges are mutable and assignable, and that .init exists and is valid. When one or more of these is false, you'll get a lot of unexpected behaviours. The .init stuff may have been fixed by now, but I wouldn't be surprised if there are still places where this assumption is still being made. The assignable part may have been mostly fixed, but there are still a lot of places where this is assumed. This is probably part of the reason W&A have very high standards when it comes to adding new features. Most of the time the people clamoring for the new feature fail to realize the full implications of adding it to the language. Breaking Phobos assumptions is one of the things people rarely think about, and it's particularly pernicious because the breakage is silent and nobody is aware until long after the new feature has been merged and stabilized, and it's too late to back out. T -- INTEL = Only half of "intelligence".
May 23 2019
On Thursday, 23 May 2019 at 18:18:02 UTC, H. S. Teoh wrote:On Thu, May 23, 2019 at 06:05:41PM +0000, Yuxuan Shui via Digitalmars-d wrote:Somehow this trick doesn't work with fold: struct A { bool empty = false; int count = 0; int front = 1; void popFront() { count++; if (count > 100) empty = true; } } void main() { import std.range, std.stdio, std.array, std.algorithm; A range; auto x = (&range).fold!"a+b"(4); // doesn't work // auto x = range.fold!"a+b"(4); // works writeln(x); writeln(range.count); }When I try to use non-copyable types, I just get all sorts of resistance from the standard library. For example, most of the std.range functions assume the range is copyable. std.typecons.Tuple assume all of its types are copyable. I tried to use the new copy constructor feature to make a wrapper that moves by default. But apparently copy constructors are ignored when postblit is disabled. How can we make using non-copyable types easier?Wrap them in a reference. I.e., instead of passing the range itself, pass a pointer to the range. Or use a suitable wrapper struct with reference semantics. Thanks to D unifying member invocation via object and via pointer to object, this should be mostly transparent to Phobos algorithms. This gets around the complications with postblits / copy ctors and Phobos assumptions about copyability. NonCopyableRange r = ...; auto rp = &r; result = rp.map!(...).filter!(...).joiner; // etc. T
May 23 2019
On Fri, May 24, 2019 at 07:47:28AM +0000, Kagamin via Digitalmars-d wrote:That's because foreach doesn't support pointer ranges.Aha, so that's where a wrapper reference range struct comes in handy. T -- First Rule of History: History doesn't repeat itself -- historians merely repeat each other.
May 24 2019