1 module fileinput; 2 import std.stdio; 3 import std.conv; 4 import std.string; 5 6 /// implements a custom range that loops over the lines of files 7 struct FileInputRange 8 { 9 public: 10 /// constructor 11 this(in string[] args) 12 { 13 if (args.length==1) { // when no args, read stdin 14 file=std.stdio.stdin; 15 } 16 else { 17 files=args; 18 curfileidx = 1; 19 file = File(files[curfileidx]); 20 } 21 } 22 /// disable default constructor 23 @disable this(); 24 /// in the range Interface this signal the end of data 25 bool empty = false; 26 27 // Peeks at the first element 28 string front() const @property 29 { 30 return curline; 31 } 32 /// consume the first element 33 void popFront() 34 { 35 if (file.readln(buf)) 36 { 37 curline = to!string(buf); 38 } else { 39 file.close(); // next file 40 curfileidx++; 41 if (curfileidx >= files.length) { 42 empty = true; 43 } else { 44 file=File(files[curfileidx]); 45 } 46 } 47 } 48 49 private: 50 const string[] files; 51 string curline; 52 char[] buf; 53 File file; 54 size_t curfileidx; 55 } 56 57 FileInputRange input(in string[] args) 58 { 59 return FileInputRange(args); 60 }