www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Testing for RandomAccessRange on strings

reply Etienne <etcimon globecsys.com> writes:
I'm trying to make a memory controller that has a cache and works only 
with malloc allocations (no GC). My problem is that I need to be able to 
copy ranges of bytes like this

target[] = mem[]

basically, it works for char[], dchar[], ubyte[] etc.

I can't really decide myself on what should be the generic test here 
because RandomAccessRange doesn't work, opIndex doesn't exist, and I'd 
want my memory controller to be able to accept classes that look like this:

class CombinedMemoryElement {
	string name;
	uint accessed;
	size_t hash;
	ubyte opIndex(size_t pos);
	ubyte[] opSlice(size_t start, size_t end);
...opDollar...
}

With data serialization in opIndex / opSlice.

So I thought of something like

static if (__traits(compiles, T.init[$]));

Where T would be CombinedMemoryElement[] in

but it looks too much like a hack. Did we end up with a concept in D 
that defines this specific purpose of ranges?
Jan 18 2014
parent Etienne <etcimon globecsys.com> writes:
On 2014-01-18 14:23, Etienne wrote:
 I'm trying to make a memory controller that has a cache and works only
 with malloc allocations (no GC). My problem is that I need to be able to
 copy ranges of bytes like this

 target[] = mem[]

 basically, it works for char[], dchar[], ubyte[] etc.

 I can't really decide myself on what should be the generic test here
 because RandomAccessRange doesn't work, opIndex doesn't exist, and I'd
 want my memory controller to be able to accept classes that look like this:

 class CombinedMemoryElement {
      string name;
      uint accessed;
      size_t hash;
      ubyte opIndex(size_t pos);
      ubyte[] opSlice(size_t start, size_t end);
 ...opDollar...
 }

 With data serialization in opIndex / opSlice.

 So I thought of something like

 static if (__traits(compiles, T.init[$]));

 Where T would be CombinedMemoryElement[] in

 but it looks too much like a hack. Did we end up with a concept in D
 that defines this specific purpose of ranges?

I ended up defining Serializable!(T, Serializer, Deserializer) which takes any object with members and makes the boilerplate for opIndex, opSlice, this(ubyte[]), opAssign(ubyte[]), etc. with a immutable(ubyte)[] serialized return type. This way, Serializable! simulates a basic char array, which enables ubyte[] copy = serializable[] even if serializable has many fields. I can populate raw memory allocations with it or send it over the network and restore it easily. I can then check isSerializable! in the generic templates that would have only taken raw byte arrays. isSerializable returns true for basic char arrays too. Since this is an object, instead of ElementType, the range trait is called SerializableElementType, which returns char for char[] or immutable(ubyte) for any Serializable!(T,...) This makes things a lot more consistent for generic programming (well, for me at least). I hope it's of any use to others.
Jan 18 2014