www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - port C++ to D - copy constness

reply dennis luehring <dl.soluz gmx.net> writes:
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?
Jun 02 2014
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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"); } }
Jun 02 2014
parent dennis luehring <dl.soluz gmx.net> writes:
Am 02.06.2014 12:09, schrieb Timon Gehr:
 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"); } }
seems to be a good start - how would you implement such slice/reader thing in idiomatic D style - the same?
Jun 02 2014