constness for arrays
xs0
xs0 at xs0.com
Tue Jul 18 04:00:05 PDT 2006
As has been discussed, the lack of something like C++ const hurts most
when using arrays, as you can't code around it like with classes,
structs or primitives (with the latter two you can just pass by value,
for classes you can make readonly versions). The fact that inbuilt
strings are also arrays makes the problem occur often.
I was wondering whether the following would resolve that issue:
- the top bit of arrays' .length becomes an indicator of the
readonlyness of the array reference
- type of .length is changed from uint to int (just to indicate the
proper maximum value; it still can't be negative (from the user's POV))
- arrays get a .isReadonly property which tests the top bit
- arrays get a .lock() method that sets it to 1
- .dup clears it (obviously :)
- reading .length masks the bit out
- setting .length sets the bit to zero if reallocation occurs, and
leaves it intact otherwise
- arrays get a .readonly property which returns a copy of the array
reference with the bit set
- optionally, arrays get a .needToWrite() method which does the
following: { if (arr.isReadonly) arr=arr.dup; } (yes, the name sucks)
Now this has the following (imho) neat properties:
- initial implementation should be quite trivial, I bet Walter could do
it in a few hours; eventually, debug builds could prevent you from
writing to a readonly array, but that's even not that important
- losing that one bit has no real effect on anything
- it can be tested for at runtime
- it has practically negligible impact on efficiency:
- reading .length needs one instruction more (AND with 0x7fffffff)
- setting .length needs about three instructions more
- reading and writing to the array has no additional cost
- moving the reference around also costs the same
- new operations are quite trivial as well
- fits with COW perfectly
- there's no const-pollution and no need to write two versions of functions
A quick example of the possibilities:
char[] toUpper(char[] txt)
{
for (int i=0; i<txt.length; i++) {
char c = s[i];
if ('a'<=c && c<='z') {
txt.needToWrite();
txt[i] = c-(cast(char)'a'-'A');
}
}
}
char[] FOO = toUpper("foo"); // constants are readonly, so COW is made
char[] bibi = getBibi(); // who owns it? I can finally know if it's me
char[] BIBI = toUpper(bibi); // write into bibi, if owned
char[] BIBI = toUpper(bibi.readonly); // leave bibi alone, as I need it
What y'all think?
xs0
PS:
Credits: the idea is not all mine, I got it from the discussion with
Reiner Pope on D.learn
I'm also sorry if this was already suggested, but I don't remember
anything of the sorts discussed..
More information about the Digitalmars-d
mailing list