Re: Parsing a UTF-16LE file line by line, BUG?

2017-01-26 Thread Jack Applegame via Digitalmars-d-learn

On Monday, 16 January 2017 at 14:47:23 UTC, Era Scarecrow wrote:
static char[1024*4] buffer;  //4k reusable buffer, NOT 
thread safe


Maybe I'm wrong, but I think it's thread safe. Because static 
mutable non-shared variables are stored in TLS.




Re: D idom for removing array elements

2017-01-26 Thread Stefan Koch via Digitalmars-d-learn

On Thursday, 26 January 2017 at 23:10:02 UTC, albert-j wrote:

On Thursday, 26 January 2017 at 13:21:38 UTC, Dukc wrote:


import std.stdio, std.algorithm, std.range, std.array;
int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto sortedB = sort(b.dup);
auto c = a
.   filter!(i => !sortedB.contains(i))
.   array
;
assert(c == [1, 2, 5, 7]);

If arrays get large, this should be more efficient since it 
performs O(n * n.log) instead of O(n * n).


It does look much faster than my solution. Will it also work 
correctly and fast for arrays of custom objects? How should 
opCmp() be defined if objects don't have a meaningful ordering? 
The order of elements in the original array does not matter.


To me it looks rather slow.
please benchmark!


Re: Parsing a UTF-16LE file line by line, BUG?

2017-01-26 Thread Era Scarecrow via Digitalmars-d-learn

On Tuesday, 17 January 2017 at 11:40:15 UTC, Nestor wrote:
Thanks, but unfortunately this function does not produce proper 
UTF8 strings, as a matter of fact the output even starts with 
the BOM. Also it doesn't handle CRLF, and even for LF 
terminated lines it doesn't seem to work for lines other than 
the first.


 I thought you wanted to get line by line of contents, which 
would then remain as UTF-16. Translating between the two types 
shouldn't be hard, probably to!string or a foreach with appending 
to code-units on chars would convert to UTF-8.


 Skipping the BOM is just a matter of skipping the first two 
bytes identifying it...


I guess I have to code encoding detection, buffered read, and 
transcoding by hand, the only problem is that the result could 
be sub-optimal, which is why I was looking for a built-in 
solution.


 Maybe. Honestly I'm not nearly as familiar with the library or 
functions as I would love to be, so often home-made solutions 
seem more prevalent until I learn the lingo. A disadvantage of 
being self taught.


Re: D idom for removing array elements

2017-01-26 Thread albert-j via Digitalmars-d-learn

On Thursday, 26 January 2017 at 13:21:38 UTC, Dukc wrote:


import std.stdio, std.algorithm, std.range, std.array;
int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto sortedB = sort(b.dup);
auto c = a
.   filter!(i => !sortedB.contains(i))
.   array
;
assert(c == [1, 2, 5, 7]);

If arrays get large, this should be more efficient since it 
performs O(n * n.log) instead of O(n * n).


It does look much faster than my solution. Will it also work 
correctly and fast for arrays of custom objects? How should 
opCmp() be defined if objects don't have a meaningful ordering? 
The order of elements in the original array does not matter.


Re: When I should create structures with new keywords?

2017-01-26 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 26 January 2017 at 19:30:54 UTC, Suliman wrote:
But I still not understand where the data is location in first 
variant?


It is stored in the file itself. The File struct is pretty small, 
it just provides access to the contents of the file, it doesn't 
actually hold that content itself.





When I should create structures with new keywords?

2017-01-26 Thread Suliman via Digitalmars-d-learn
In the past I asked Adam about when I should use keyword `new` 
with structures and got next answer:


"The File in the first one is put on the stack as a reference 
counted
local object whereas the second one would be on the garbage 
collected
heap, which often isn't what you want for files since you want to 
close

them when you're done.

Generally, D's structs often work best without the `new` keyword 
since

they can be made in place."

But I have read that stack size is very limited I tried to test 
two variants of reading big (20MB) text file:


auto file = File("test.txt", "r");
and
auto file = new File("test.txt", "r");

Tests does not show any significant difference in performance. 
But I still not understand where the data is location in first 
variant?


Re: D idom for removing array elements

2017-01-26 Thread Jordan Wilson via Digitalmars-d-learn

On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote:
What is the D idiom for removing array elements that are 
present in another array?


Is this the right/fastest way?

int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto c = a.remove!(x => b.canFind(x));
assert(c == [1, 2, 5, 7]);


If you don't care about array a being mutated, then I think what 
you have is best (although I would suggest that if you don't care 
about a being mutated, just reassign the results back to a again).


Otherwise, I think you need to allocate a new array, so the other 
answers using filter are good.


Re: dub subpackage output to shared lib not working

2017-01-26 Thread Tofu Ninja via Digitalmars-d-learn

On Thursday, 26 January 2017 at 19:01:41 UTC, Tofu Ninja wrote:
Actually.. if I do dub describe on the root package it lists 
both the exe and the lib as targets but the build settings for 
the lib has "targetType": 6 which according to 
dub/source/dub/compilers/buildsettings.d is staticLibrary... is 
this a bug or what?


omfg I should have read the build output more closely...right 
at the top "Dynamic libraries are not yet supported as 
dependencies - building as static library."... welp guess I give 
up then, 4 days waisted.


Re: dub subpackage output to shared lib not working

2017-01-26 Thread Tofu Ninja via Digitalmars-d-learn

On Thursday, 26 January 2017 at 18:26:27 UTC, Tofu Ninja wrote:

On Thursday, 26 January 2017 at 18:10:12 UTC, Tofu Ninja wrote:

On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote:

Is this not doable?


I guess an alternative question, is there any way to have 
multiple binaries(an executable and a bunch of shared libs) 
built from a single dub package? Or should I just give up on 
trying to use dub for this...


This [https://github.com/dlang/dub/issues/665] seems to be 
somewhat related to what I am trying to do, not sure if this 
got addressed at all though.


Actually.. if I do dub describe on the root package it lists both 
the exe and the lib as targets but the build settings for the lib 
has "targetType": 6 which according to 
dub/source/dub/compilers/buildsettings.d is staticLibrary... is 
this a bug or what?


Re: Bug in documentation or misunderstanding it?

2017-01-26 Thread Suliman via Digitalmars-d-learn

On Thursday, 26 January 2017 at 18:42:29 UTC, Suliman wrote:

On Thursday, 26 January 2017 at 17:52:24 UTC, H. S. Teoh wrote:
On Thu, Jan 26, 2017 at 05:38:59PM +, Suliman via 
Digitalmars-d-learn wrote:
I read docs and can't understand what's wrong. Or I am do not 
understand it, or there is come mistake.


Let's look at function 
https://dlang.org/phobos/std_stdio.html#.File.byLine


auto byLine(Terminator = char, Char = char)(KeepTerminator 
keepTerminator =

No.keepTerminator, Terminator terminator = '\x0a')

what does mean first groups of scope: (Terminator = char, 
Char = char) ?


Those are compile-time parameters. You specify them in a 
compile-time argument list using the !(...) construct, for 
example:


auto lines = File("myfile.txt")
.byLine!(dchar, char)(Yes.keepTerminator, '\u263a');


T


So I am right about others items about for example that `=` is 
optional?


Why this code is work: `file.byLine(KeepTerminator.no, 'm')`


Re: Bug in documentation or misunderstanding it?

2017-01-26 Thread Suliman via Digitalmars-d-learn

On Thursday, 26 January 2017 at 17:52:24 UTC, H. S. Teoh wrote:
On Thu, Jan 26, 2017 at 05:38:59PM +, Suliman via 
Digitalmars-d-learn wrote:
I read docs and can't understand what's wrong. Or I am do not 
understand it, or there is come mistake.


Let's look at function 
https://dlang.org/phobos/std_stdio.html#.File.byLine


auto byLine(Terminator = char, Char = char)(KeepTerminator 
keepTerminator =

No.keepTerminator, Terminator terminator = '\x0a')

what does mean first groups of scope: (Terminator = char, Char 
= char) ?


Those are compile-time parameters. You specify them in a 
compile-time argument list using the !(...) construct, for 
example:


auto lines = File("myfile.txt")
.byLine!(dchar, char)(Yes.keepTerminator, '\u263a');


T


So I am right about others items about for example that `=` is 
optional?


Re: dub subpackage output to shared lib not working

2017-01-26 Thread Tofu Ninja via Digitalmars-d-learn

On Thursday, 26 January 2017 at 18:10:12 UTC, Tofu Ninja wrote:

On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote:

Is this not doable?


I guess an alternative question, is there any way to have 
multiple binaries(an executable and a bunch of shared libs) 
built from a single dub package? Or should I just give up on 
trying to use dub for this...


This [https://github.com/dlang/dub/issues/665] seems to be 
somewhat related to what I am trying to do, not sure if this got 
addressed at all though.


Re: dub subpackage output to shared lib not working

2017-01-26 Thread Tofu Ninja via Digitalmars-d-learn

On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote:

Is this not doable?


I guess an alternative question, is there any way to have 
multiple binaries(an executable and a bunch of shared libs) built 
from a single dub package? Or should I just give up on trying to 
use dub for this...


Re: dub subpackage output to shared lib not working

2017-01-26 Thread Tofu Ninja via Digitalmars-d-learn

On Sunday, 22 January 2017 at 08:16:49 UTC, Tofu Ninja wrote:
Trying to get a dub sub package to output as a shared lib but 
for some reason I can only get it to output as a static lib.


dub.json
---
{
"name": "tofueng",
"targetType": "executable",
"targetPath" : "game",
"sourcePaths": ["eng"],
"importPaths": ["eng"],

"dependencies": {
"tofueng:test": "*",
},
"subPackages": [
{
"name": "test",
"targetType": "dynamicLibrary",
"targetPath" : "game/libs",
"sourcePaths": ["com/test"],
"importPaths": ["com/test"]
}
]
}
---

Get tofueng_test.lib instead of tofueng_test.dll. If I try to 
build the sub package directly it builds the dll. What am I 
doing wrong?


Is this not doable?


Re: Bug in documentation or misunderstanding it?

2017-01-26 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 26, 2017 at 05:38:59PM +, Suliman via Digitalmars-d-learn wrote:
> I read docs and can't understand what's wrong. Or I am do not understand it,
> or there is come mistake.
> 
> Let's look at function https://dlang.org/phobos/std_stdio.html#.File.byLine
> 
> auto byLine(Terminator = char, Char = char)(KeepTerminator keepTerminator =
> No.keepTerminator, Terminator terminator = '\x0a')
> 
> what does mean first groups of scope: (Terminator = char, Char = char) ?

Those are compile-time parameters. You specify them in a compile-time
argument list using the !(...) construct, for example:

auto lines = File("myfile.txt")
.byLine!(dchar, char)(Yes.keepTerminator, '\u263a');


T

-- 
If lightning were to ever strike an orchestra, it'd always hit the conductor 
first.


Re: Bug in documentation or misunderstanding it?

2017-01-26 Thread Stefan Koch via Digitalmars-d-learn

On Thursday, 26 January 2017 at 17:38:59 UTC, Suliman wrote:
I read docs and can't understand what's wrong. Or I am do not 
understand it, or there is come mistake.


[...]


You have to import typecons.


Re: D idom for removing array elements

2017-01-26 Thread Stefan Koch via Digitalmars-d-learn
On Thursday, 26 January 2017 at 11:44:27 UTC, Nicholas Wilson 
wrote:

On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote:
What is the D idiom for removing array elements that are 
present in another array?


Is this the right/fastest way?

int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto c = a.remove!(x => b.canFind(x));
assert(c == [1, 2, 5, 7]);


filter.

auto c = a.filter!(x => !b.canFind(x)).array;


He wanted to remove elements.
This will allocate a freaking new array.
And do N function calls to build it.
This is WORSE!



Bug in documentation or misunderstanding it?

2017-01-26 Thread Suliman via Digitalmars-d-learn
I read docs and can't understand what's wrong. Or I am do not 
understand it, or there is come mistake.


Let's look at function 
https://dlang.org/phobos/std_stdio.html#.File.byLine


auto byLine(Terminator = char, Char = char)(KeepTerminator 
keepTerminator = No.keepTerminator, Terminator terminator = 
'\x0a')


what does mean first groups of scope: (Terminator = char, Char = 
char) ?


The second one as I understand it's options symbol `=` mean that 
there is some default values, so if I will call function I can do 
not set them, so predefined values will be used.


Am I right? And If I do not want predefined I can pass my own 
like:

`byLine(No.keepTerminator, 'SomeLetter')`

for example: `file.byLine(No.keepTerminator, 'a')`

But when I compile simple example I am getting compilation error: 
`undefined identifier 'No'`


Where I am wrong?




Re: D idom for removing array elements

2017-01-26 Thread Dukc via Digitalmars-d-learn

On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote:
What is the D idiom for removing array elements that are 
present in another array?


Is this the right/fastest way?

int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto c = a.remove!(x => b.canFind(x));
assert(c == [1, 2, 5, 7]);


import std.stdio, std.algorithm, std.range, std.array;
int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto sortedB = sort(b.dup);
auto c = a
.   filter!(i => !sortedB.contains(i))
.   array
;
assert(c == [1, 2, 5, 7]);

If arrays get large, this should be more efficient since it 
performs O(n * n.log) instead of O(n * n).


On the other hand you could also just use assumeSorted if b is 
already sorted, as in this case. But if you do, I still recommend 
adding an assert to check the range truly is sorted when 
debugging.


It can be made to perform O(n) by sorting both a and b, but then 
you need to figure a way to return a back to normal order after 
filtering. I tried, and found it to be so hard I didn't bother.


Re: Trying to understand multidimensional arrays in D

2017-01-26 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 26 January 2017 at 05:20:07 UTC, Profile Anaysis 
wrote:
(On the contrary, declarations in C or C++ looks rather 
unintuitive from this perspective: `T a[4][5][6]` is means 
that `a` is an array of 4 arrays of 5 arrays of 6 arrays of 
`T`.  Note how we have to read left-to-right but then wrap 
around the string to get the meaning.)


lol, I don' tknow what the last sentence means. wrap around the 
string? Do you mean look at the variable?


For me the interpretation above is the most logical because it 
is a sequential operation in my mind, if you will. x of y of z 
and the chain can be cut off anywhere and the interpretation 
still be the same.


This means that in `T a[4][5][6]`, the type `T[4][5][6]` is 
spread on both sides of the variable name `a`.  In the 
interpretation,

"`a` is an array of 4 arrays of 5 arrays of 6 arrays of `T`",
note that 4, 5 and 6 are from the right side but T is from the 
left side.  That's what I meant by wrap around.


Re: D idom for removing array elements

2017-01-26 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote:
What is the D idiom for removing array elements that are 
present in another array?


Is this the right/fastest way?

int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto c = a.remove!(x => b.canFind(x));
assert(c == [1, 2, 5, 7]);


filter.

auto c = a.filter!(x => !b.canFind(x)).array;




Re: Trying to understand multidimensional arrays in D

2017-01-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, January 26, 2017 05:44:04 Profile Anaysis via Digitalmars-d-
learn wrote:
> I am using static arrays because the size of the matrix is fixed.
> I need to allocate them though because that is what my
> matrix_history contains.

If I understood correctly, you want a dynamic array of static arrays where
the static array is therefore an entry in your "matrix history." That does
not require that you allocate a static array. It just requires that you
allocate the dynamic array of static arrays. For instance, if you had an
integer instead of a matrix, you would have something like

int[] arr;

and when you appended to it, you would just append the value. e.g.

arr ~= 42;
arr ~= 77;
arr ~= 9;

No allocation of the values is required. The dynamic array may very well do
some reallocating to fit the new values (depending on its current capacity),
but the values themselves are not allocated. So, if you have a dynamic array
of static arrays

int[4][4][] arr;

then you just append each static array. e.g.

int[4][4] value;
// fill in value...

arr ~= value;

or

arr ~= [[9, 9, 9, 9], [7, 7, 7, 7], [2, 2, 2, 2], [3, 3, 3, 3]];

Again. You're not allocating the values that you're appending at all. At
most, the dynamic array ends up being reallocated to make room for more
elements.

- Jonathan M Davis



Re: Trying to understand multidimensional arrays in D

2017-01-26 Thread Mike Parker via Digitalmars-d-learn
Sorry. I mistyped some of my examples. Obviously dropped some 
news:


auto a = new int[](4);
auto b = new int[][](4);

And the static arrays should be:
int[4] c;
int[][4] d;

And I would also like managed to overlook there is no static 
array in sight here:


auto y = new int[1][2][][](3,4);

The 1 and 2 are not creating static arrays. They are dynamic 
arrays. The following are exactly the same:


auto a1 = new int[](2);
auto a2 = new int[2];

The syntax in a2 is the original syntax for allocating space for 
dynamic arrays. The () was added later.


The point I made about changing the declaration of x remains.


Re: Trying to understand multidimensional arrays in D

2017-01-26 Thread Mike Parker via Digitalmars-d-learn
On Thursday, 26 January 2017 at 05:50:03 UTC, Profile Anaysis 
wrote:


It is inconsistent with dynamic arrays and mixing them creates 
a mess in the order of indices.


I best someone was asleep at the wheel when programming the 
code for static arrays. (probably someone different than who 
programmed the dynamic arrays)


This is a bug IMO.(unfortunately one that can't be fixed ;/)


No, there's no inconsistence and there's no bug. Shorten things 
down a bit:


```
auto x = new int[][](3,4);
auto y = new int[3][](4);
writefln("%s, %s", x[0].length, y[0].length);
```
This will print 4, 3. Why?

auto a = int[](4);

In this case, a is an array of int. The allocation makes space 
for 4 values of type int.


auto b = int[][](4);

Here, b is an array of int[]. The allocation makes space for 
values of type int[].


The following are the equivalent declarations for static arrays:

auto c = int[4];
auto d = int[][4];

In other words  int[][4] is the static equivalent of new 
int[][](4).


Following from that:

auto e = new int[][](4, 3);

This creates an array of 4 values of type int[], each of which is 
an array that holds 3 values of type int. The static equivalent:


auto f = int[3][4];

So based on that, you should be able to see that the problem is 
not in the implementation of static arrays in D, but a mismatch 
in your declarations.


auto x = new int[][][][](1,2,3,4);
auto y = new int[1][2][][](3,4); // Does not match declaration of 
x


To get what you want, change the declaration of x:

auto x = new int[][][][](4, 3, 2, 1);


Re: Min, max of enum

2017-01-26 Thread Biotronic via Digitalmars-d-learn
On Thursday, 26 January 2017 at 05:58:26 UTC, Profile Anaysis 
wrote:
Since we do not have attributes for enums, I use _ in front of 
the names for meta values.


I need to get the non-meta values for the enum so I can iterate 
over it and use it properly.


enum myEnum
{
_Meta1 = 0,
A,B,C,
_Meta3 = 43,
D = 3,
}

The num, for all practical purposes does not contain _Meta1, 
and_Meta3. But in code I use to!myEnum(intI) and having the 
meta values complicate things(simple shifting may or may not 
work).


I also need to create array indexers based on myEnum that don't 
include the meta characters.


What I do a lot is convert integers in to fields of the enum.

If I do not include any Meta, then it is straight forward 
to!myEnum(i), but with them it is not, so doing things like


int[myEnum] x;

x[to!myEnum(i))] is difficult because the conversion will be 
invalid for meta. I'd have to do some work on i to get the 0-n 
representation to map properly in to the enum... basically 
avoiding the meta fields.


This would all be solved with attributes for enums, but that, I 
suppose is a pipe dream.


Any ideas how I can make this easy?


Like Stefan said, __traits(allMembers, myEnum) lets you iterate 
over the elements of the enum. For a to!myEnum that ignores _Meta 
fields, you could do something like this:


T toEnum(T)(int n) {
foreach (element; __traits(allMembers, myEnum)) {
static if (element[0] != '_') {
if (n == cast(int)__traits(getMember, myEnum, 
element))

return __traits(getMember, myEnum, element);
}
}
assert(false);
}

Looking at your code though, I wonder if the problem you want 
solved is a different one. Especially this part:


I'd have to do some work on i to get the 0-n representation to 
map properly in to the enum... basically avoiding the meta 
fields.


If I understand you correctly, you want this:

enum myEnum
{
_Meta1 = 0,
A,B,C,
_Meta3 = 43,
D = 3,
}

to become this:

enum myEnum
{
A = 0,
B = 1,
C = 2,
D = 3
}

That's a taller order, especially given that the original is 
equivalent to this:


enum myEnum
{
A = 1,
B = 2,
C = 3,
D = 3
// And some meta members, but not relevant here.
}

One option would look somewhat like this:

alias myEnum = Enum!q{
_Meta1 = 0,
A, B, C,
_Meta2 = 43,
D
};

template Enum(string enumBody) {
mixin(generateEnum!enumBody);
}

string generateEnum(string enumBody)() {
import std.conv;
string result;
mixin("enum members {"~enumBody~"}");

foreach (element; __traits(allMembers, members)) {
if (element[0] != '_') {
result ~= element ~ ",";
}
}

return "@MetaData!\""~enumBody~"\" enum Enum {"~result~"}";
}

template MetaData(string enumBody) {
mixin(generateMeta!enumBody);
}

string generateMeta(string enumBody)() {
import std.conv;
string result;
mixin("enum members {"~enumBody~"}");

foreach (element; __traits(allMembers, members)) {
if (element[0] == '_') {
result ~= element ~ " = " ~ 
(cast(int)__traits(getMember, members, element)).to!string ~ ",";

}
}

return "enum MetaData {"~result~"}";
}



template meta(T) if (is(T == enum)) {
import std.typetuple;
alias meta = AliasSeq!(__traits(getAttributes, T))[0];
}

void main() {
import std.stdio;
import std.conv;
import std.typetuple;

writeln(myEnum.A, ": ", cast(int)myEnum.A);
writeln(myEnum.B, ": ", cast(int)myEnum.B);
writeln(myEnum.C, ": ", cast(int)myEnum.C);
writeln(myEnum.D, ": ", cast(int)myEnum.D);

writeln(meta!myEnum._Meta1, ":", cast(int)meta!myEnum._Meta1);
writeln(meta!myEnum._Meta2, ":", cast(int)meta!myEnum._Meta2);
}

This lets you define the enum with a somewhat familiar syntax:

alias myEnum = Enum!q{
_Meta1 = 0,
A, B, C,
_Meta2 = 43,
D
};

and generates from that the equivalent of this:

@myEnum_Meta
enum myEnum {
A, B, C, D
}

enum myEnum_Meta {
_Meta1 = 0,
_Meta2 = 43
}




D idom for removing array elements

2017-01-26 Thread albert-j via Digitalmars-d-learn
What is the D idiom for removing array elements that are present 
in another array?


Is this the right/fastest way?

int[] a = [1, 2, 3, 4, 5, 6, 7, 4];
int[] b = [3, 4, 6];
auto c = a.remove!(x => b.canFind(x));
assert(c == [1, 2, 5, 7]);


Re: Why is &array[0] @safer than array.ptr?

2017-01-26 Thread Dukc via Digitalmars-d-learn
On Wednesday, 25 January 2017 at 22:59:55 UTC, Jonathan M Davis 
wrote:
So, yes, if all you're planning to do is look at the pointer to 
the first element in the array, then &arr[0] is safer, but odds 
are quite low that that's actually what you're going to do, and 
in all of the other cases, you might as well just use .ptr. So, 
telling folks to go use &arr[0] instead of .ptr doesn't seem 
very helpful to me.



Pehaps it should say something like: arr.ptr is deprecated in 
@safe code. Use &arr[0] for checked access or remove the @safe 
attribute.


That would make it clear that .ptr is not an issue, only .ptr in 
@safe.