How to avoid code duplication?
The situation is next: I have got the function that get arrays of lognames and logfullname: void loginsert(string [] lognames, string [] logfullname) { if(logfullname[i].endsWith("txt")) { auto file = File(logfullname[i], "r"); foreach (line; file.byLine) { // long manupulation with strings } } } But now need add supporting passing to function not only txt files, but also zip archives. The problem that now I see only one way to do adding zip -- add block: if(logfullname[i].endsWith("zip")) And in it do everything with unpacking content of archive like: foreach(ArchiveMember am; zip.directory) { string file = cast(string)zip.expand(am); foreach (line; file.lineSplitter()) { } } and put inside it some same content that I am doing in "long manupulation with strings". Maybe there is any better way? But I really can't understand it because auto file = File(logfullname[i], "r"); can't read unpacked content of archive.
Re: How to avoid code duplication?
Maybe there is way to access of element of archive in the same way as to txt file? I looked, but it's seems that constructor accept only path to file. But I can't understand how to set path to unpacked element of archive.
Re: How to avoid code duplication?
On 1/04/2015 6:15 p.m., Suliman wrote: The situation is next: I have got the function that get arrays of lognames and logfullname: void loginsert(string [] lognames, string [] logfullname) { if(logfullname[i].endsWith("txt")) { auto file = File(logfullname[i], "r"); foreach (line; file.byLine) { // long manupulation with strings } } } But now need add supporting passing to function not only txt files, but also zip archives. The problem that now I see only one way to do adding zip -- add block: if(logfullname[i].endsWith("zip")) And in it do everything with unpacking content of archive like: foreach(ArchiveMember am; zip.directory) { string file = cast(string)zip.expand(am); foreach (line; file.lineSplitter()) { } } and put inside it some same content that I am doing in "long manupulation with strings". Maybe there is any better way? But I really can't understand it because auto file = File(logfullname[i], "r"); can't read unpacked content of archive. Use InputRange!string aka an input range which gives you elements. It can wrap up the behavior for getting the values.
Re: How to avoid code duplication?
Rikki, could you explain? I did not understand where it can help me
Re: How to avoid code duplication?
On 1/04/2015 7:19 p.m., Suliman wrote: Rikki, could you explain? I did not understand where it can help me Here is some example code. While I've only implemented one InputRange!string instance. You would probably have one, for just zip's and another raw text files. Keep in mind it returns only a single line from standard input. In other words, let the range handle reading a line from a file. import std.range; import std.stdio; class Range : InputRange!string { private { string buffer; } this() { popFront; } @property { string front() { return buffer; } bool empty() { return false; } } void popFront() { buffer = readln(); } string moveFront() { string ret = front(); popFront(); return ret; } int opApply(int delegate(string) del) { int result; while(!empty()) { result = del(moveFront()); if (result) break; } return result; } int opApply(int delegate(size_t, string) del) { int result; size_t offset; while(!empty()) { result = del(offset, moveFront()); if (result) break; offset++; } return result; } } void myfunc(InputRange!string input) { foreach(line; input) { writeln("GOT [line]: ", line); } } void main() { InputRange!string theRange = new Range(); myfunc(theRange); }
How to avoid code duplication in static if branches?
import std.stdio; void check() { writeln("check"); } struct Foo { bool isTrue = true; } struct Bar { } void test(T)(T t) { static if (is(T == Foo)) { if (t.isTrue) check(); } else { check(); } } void main() { Foo foo; Bar bar; test(foo); test(bar); } I want to avoid writing "check()" twice. I only have to statically check a field of a member if it's of a certain type (Foo). One solution would be to use a boolean: void test(T)(T t) { bool isTrue = true; static if (is(T == Foo)) isTrue = t.isTrue; if (isTrue) check(); } But that kind of defeats the purpose of static if (avoiding runtime overhead). Does anyone have a trick up their sleeve for these types of situations? :)
Re: How to avoid code duplication in static if branches?
04.03.2012 3:42, Andrej Mitrovic пишет: [...code...] I want to avoid writing "check()" twice. I only have to statically check a field of a member if it's of a certain type (Foo). One solution would be to use a boolean: void test(T)(T t) { bool isTrue = true; static if (is(T == Foo)) isTrue = t.isTrue; if (isTrue) check(); } But that kind of defeats the purpose of static if (avoiding runtime overhead). Does anyone have a trick up their sleeve for these types of situations? :) Alias maybe? void test(T)( T t ) { enum TRUE = true; static if( is(T == Foo) ) { alias t.isTrue isTrue; } else { alias TRUE isTrue; } if( isTrue ) { check(); } } This will still insert a redundant check for one of instantiations, but compiler should be able to deal with 'if(true)' checks.
Re: How to avoid code duplication in static if branches?
"Andrej Mitrovic" wrote in message news:mailman.364.1330825349.24984.digitalmars-d-le...@puremagic.com... > import std.stdio; > void check() { writeln("check"); } > > struct Foo { bool isTrue = true; } > struct Bar { } > > void test(T)(T t) > { >static if (is(T == Foo)) >{ >if (t.isTrue) >check(); >} >else >{ >check(); >} > } > > void main() > { >Foo foo; >Bar bar; >test(foo); >test(bar); > } > > I want to avoid writing "check()" twice. I only have to statically > check a field of a member if it's of a certain type (Foo). > > One solution would be to use a boolean: > void test(T)(T t) > { >bool isTrue = true; >static if (is(T == Foo)) >isTrue = t.isTrue; > >if (isTrue) >check(); > } > > But that kind of defeats the purpose of static if (avoiding runtime > overhead). Does anyone have a trick up their sleeve for these types of > situations? :) Have you checked the generated code? When the static if check fails, it should be reduced to: > void test(T)(T t) > { >bool isTrue = true; > >if (isTrue) >check(); > } And the compiler should be able to tell that isTrue is always true. Otherwise, void test(T)(T t) { enum doCheck = is(T == Foo); bool isTrue = true; static if (is(T == Foo)) auto isTrue = t.isTrue; if (!doCheck || isTrue) check(); } The compiler takes care of it because doCheck is known at compile time.
Re: How to avoid code duplication in static if branches?
You're right it should be able do that dead-code elimination thing. Slipped my mind. :) On 3/4/12, Daniel Murphy wrote: > "Andrej Mitrovic" wrote in message > news:mailman.364.1330825349.24984.digitalmars-d-le...@puremagic.com... >> import std.stdio; >> void check() { writeln("check"); } >> >> struct Foo { bool isTrue = true; } >> struct Bar { } >> >> void test(T)(T t) >> { >>static if (is(T == Foo)) >>{ >>if (t.isTrue) >>check(); >>} >>else >>{ >>check(); >>} >> } >> >> void main() >> { >>Foo foo; >>Bar bar; >>test(foo); >>test(bar); >> } >> >> I want to avoid writing "check()" twice. I only have to statically >> check a field of a member if it's of a certain type (Foo). >> >> One solution would be to use a boolean: >> void test(T)(T t) >> { >>bool isTrue = true; >>static if (is(T == Foo)) >>isTrue = t.isTrue; >> >>if (isTrue) >>check(); >> } >> >> But that kind of defeats the purpose of static if (avoiding runtime >> overhead). Does anyone have a trick up their sleeve for these types of >> situations? :) > > Have you checked the generated code? When the static if check fails, it > should be reduced to: >> void test(T)(T t) >> { >>bool isTrue = true; >> >>if (isTrue) >>check(); >> } > > And the compiler should be able to tell that isTrue is always true. > > Otherwise, > > void test(T)(T t) > { > enum doCheck = is(T == Foo); > bool isTrue = true; > static if (is(T == Foo)) > auto isTrue = t.isTrue; > if (!doCheck || isTrue) > check(); > } > > The compiler takes care of it because doCheck is known at compile time. > > >
Re: How to avoid code duplication in static if branches?
Andrej Mitrovic wrote: > ...snip... > I want to avoid writing "check()" twice. I only have to statically > check a field of a member if it's of a certain type (Foo). > > One solution would be to use a boolean: > void test(T)(T t) > { > bool isTrue = true; > static if (is(T == Foo)) > isTrue = t.isTrue; > > if (isTrue) > check(); > } > > But that kind of defeats the purpose of static if (avoiding runtime > overhead). Does anyone have a trick up their sleeve for these types of > situations? :) There's always this: void test(T)(T t) { static if (is (T == Foo)) if (!t.isTrue) return; check(); } Jerome -- mailto:jeber...@free.fr http://jeberger.free.fr Jabber: jeber...@jabber.fr signature.asc Description: OpenPGP digital signature