How to avoid code duplication?

2015-03-31 Thread Suliman via Digitalmars-d-learn


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?

2015-03-31 Thread Suliman via Digitalmars-d-learn
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?

2015-03-31 Thread Rikki Cattermole via Digitalmars-d-learn

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?

2015-03-31 Thread Suliman via Digitalmars-d-learn
Rikki, could you explain? I did not understand where it can help 
me


Re: How to avoid code duplication?

2015-03-31 Thread Rikki Cattermole via Digitalmars-d-learn

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?

2012-03-03 Thread Andrej Mitrovic
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?

2012-03-03 Thread Mantis

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?

2012-03-03 Thread Daniel Murphy
"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?

2012-03-03 Thread Andrej Mitrovic
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?

2012-03-03 Thread Jérôme M. Berger
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