commit 28860abd2f58cc39bac3a723eec071f2c7620220
parent d149e28676da2eac0adaf5dcb882c2f9c92bf6c7
Author: Dominik Schmidt <das1993@hotmail.com>
Date: Sun, 9 Aug 2015 15:14:06 +0200
Introduce Cookie-struct.
This replaces the primary string-range with Cookie-ranges, which allows to
to neat stuff like ```Fortune d; d.filter!"a.size<300";```
The range can be mapped with d.strings(Range) or just d.strings() to the actual
texts again.
Diffstat:
dfortune.d | | | 62 | +++++++++++++++++++++++++++++++++++++++++--------------------- |
1 file changed, 41 insertions(+), 21 deletions(-)
diff --git a/dfortune.d b/dfortune.d
@@ -5,10 +5,15 @@ import std.bitmanip;
import std.encoding;
import std.range;
import std.random;
+import std.algorithm;
import core.exception;
-class Fortune : RandomAccessFinite!(string){
+static struct Cookie{
+ uint pos;
+ uint size;
+}
+class Fortune : RandomAccessFinite!(Cookie){
static struct Header{
uint version_;
uint numstr;
@@ -41,6 +46,13 @@ class Fortune : RandomAccessFinite!(string){
uint pos,end;
+ auto @property strings(){
+ return this.map!(a=>read(a));
+ }
+ auto strings(T)(T r) if(isInputRange!(T) && is(ElementType!T == Cookie)){
+ return r.map!(a=>read(a));
+ }
+
this(string file){
basename=file;
src=EncodingScheme.create("UTF-8");
@@ -105,6 +117,14 @@ class Fortune : RandomAccessFinite!(string){
uint end=getOffset(i+1)-3; //-3 to exclude \n%\n
return sliceFile(pos,end);
}
+ public Cookie getCookie(uint i){
+ uint pos=getOffset(i);
+ uint end=getOffset(i+1)-3; //-3 to exclude \n%\n
+ return Cookie(pos, end-pos);
+ }
+ public string read(in ref Cookie c){
+ return sliceFile(c.pos,c.pos+c.size);
+ }
public void close(){
table.close();
@@ -132,16 +152,16 @@ class Fortune : RandomAccessFinite!(string){
c.end=cast(uint)b;
return c;
}
- @property string back(){
- return read(end);
+ @property Cookie back(){
+ return getCookie(end);
}
- string moveBack(){
+ Cookie moveBack(){
return back;
}
void popBack(){
end--;
}
- int opApply(int delegate(string)f){
+ int opApply(int delegate(Cookie)f){
int ret;
while(!empty()){
ret=f(front());
@@ -152,19 +172,19 @@ class Fortune : RandomAccessFinite!(string){
}
return ret;
}
- string moveFront(){
- return read(pos);
+ Cookie moveFront(){
+ return getCookie(pos);
}
@property bool empty() const{
return (pos>end);
}
- @property string front(){
+ @property Cookie front(){
return moveFront();
}
void popFront(){
pos++;
}
- int opApply(int delegate(size_t,string)f){
+ int opApply(int delegate(size_t,Cookie)f){
int ret;
size_t cnt=0;
while(!empty()){
@@ -176,12 +196,12 @@ class Fortune : RandomAccessFinite!(string){
}
return ret;
}
- string moveAt(size_t i){
+ Cookie moveAt(size_t i){
pos=cast(uint)i;
- return read(pos);
+ return getCookie(pos);
}
- string opIndex(size_t i){
- return read(cast(uint)i);
+ Cookie opIndex(size_t i){
+ return getCookie(cast(uint)i);
}
@property Fortune save(){
@@ -212,7 +232,7 @@ struct Fortunes{
r.popFront();
}
}
- string opIndex(size_t i){
+ Cookie opIndex(size_t i){
foreach(Fortune f; fortunes.save){
if(i>=f.length){
i-=f.length;
@@ -229,13 +249,13 @@ struct Fortunes{
size+=f.length;
return size;
}
- @property string front(){
+ @property Cookie front(){
return opIndex(pos);
}
- @property string back(){
+ @property Cookie back(){
return opIndex(end);
}
- string moveAt(size_t i){
+ Cookie moveAt(size_t i){
pos=i;
return opIndex(pos);
}
@@ -245,16 +265,16 @@ struct Fortunes{
@property Fortunes save(){
return Fortunes(fortunes, pos, end);
}
- string moveFront(){
+ Cookie moveFront(){
return front();
}
- string moveBack(){
+ Cookie moveBack(){
return back();
}
void popBack(){
end--;
}
- int opApply(int delegate(string)f){
+ int opApply(int delegate(Cookie)f){
int ret;
while(!empty()){
ret=f(moveFront());
@@ -265,7 +285,7 @@ struct Fortunes{
}
return ret;
}
- int opApply(int delegate(size_t,string)f){
+ int opApply(int delegate(size_t,Cookie)f){
int ret;
size_t i;
while(!empty()){