port C++ to D - copy constness

Timon Gehr via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 2 03:09:26 PDT 2014


On 06/02/2014 09:06 AM, dennis luehring wrote:
> i want to port this C++ code to good/clean D and have no real idea how
> to start
>
> contains 2 templates - a slice like and a binary reader for an slice
> main idea was to copy the immutablity of the slice data to the reader
>
> http://pastebin.com/XX2yhm8D
>
> the example compiles fine with http://gcc.godbolt.org/, clang version
> 3.4.1 and compiler-options: -O2 -std=c++11
>
> the slice_T template - could be maybe reduce down to an normal D slice
> but i want to control the slice (im)mutability - so maybe there is still
> a need for the slice_T thing
>
> i don't know if the binary reader read_ref method should be written
> totaly different in D
>
> any tips, ideas?
>

If the following is not already what you were looking for, it should get 
you started. (But note that the interface provided by BinaryReader is 
unsafe: It may invent pointers. You might want to add template 
constraints that would at least allow the implementation to be @trusted.)

template CopyQualifiers(S,T){
     import std.traits;
     static if(is(S==const)) alias T1=const(Unqual!T);
     else alias T1=Unqual!T;
     static if(is(S==immutable)) alias T2=immutable(T1);
     else alias T2=T1;
     static if(is(S==inout)) alias T3=inout(T2);
     else alias T3=T2;
     static if(is(S==shared)) alias CopyQualifiers=shared(T3);
     else alias CopyQualifiers=T3;
}

struct BinaryReader(T){
     @disable this();
     this(T[] slice){ this.slice=slice; }
     size_t left()const{ return slice.length - offset; }
     bool enoughSpaceLeft(size_t size)const{ return size <= left(); }
     ref readRef(V)(){
         if(!enoughSpaceLeft(V.sizeof)) throw new Exception("1");
         auto off=offset;
         offset+=V.sizeof;
         return *cast(CopyQualifiers!(T,V)*)(slice.ptr+off);
     }
     auto readValue(V)(){ return readRef!V(); }
private:
     T[] slice;
     size_t offset=0;
}

auto binaryReader(T)(T[] slice){ return BinaryReader!T(slice); }

void main(){
     import std.stdio;
     try{
         auto testData = "THIS IS BINARY TEST DATA"; // no comment
         auto stream = binaryReader(testData);
         static assert(is(typeof(stream.readRef!uint())==immutable));
         (ref ref_){
             auto value = stream.readValue!uint();
         }(stream.readRef!uint());
     }catch(Exception e){
         writeln("exception error: ",e.msg);
     }catch{
         writeln("exception unknown");
     }
}




More information about the Digitalmars-d-learn mailing list