biotagging as a simple stateful filter

monkyyy crazymonkyyy at gmail.com
Tue Jul 28 08:12:41 UTC 2026


```d
enum biotag{outside,inside,begin};

auto biomap(alias F,alias G,R)(R r){
	struct map{
		R r;
		biotag state=biotag.outside;
		auto front()=>r.front;
		void popFront(){
			r.popFront;
			if( ! r.empty){
				state=state ? G(r.front) : cast(biotag)(F(r.front)*2);
		}}
		bool empty()=>r.empty;
	}
	return map(r);
}
bool isdigit(dchar c)=>iota('0',':').canFind(c);
static assert('9'.isdigit);
biotag isdigitorsymbol(dchar c){
	if(c.isdigit||c==','||c=='.'){
		return biotag.inside;
	}
	return biotag.outside;
}
unittest{
	auto r="hello, you. 
123,456.789!".biomap!(isdigit,isdigitorsymbol);
	while( ! r.empty){
		writeln(r.front,':',r.state);
		r.popFront;
}}
auto takeextra(alias F,R)(R r,int i){
	struct take{
		R r;
		int i;
		auto front()=>r.front;
		void popFront(){
			if(i>0){i--;}
			r.popFront;
		}
		static if(__traits(compiles,F(r))){
			bool empty()=> r.empty || i==0 && ! F(r);
		} else {
			bool empty()=> r.empty || i==0 && ! F(r.front);
		}
	}
	return take(r,i);
}
unittest{
	auto r=[1,2,5,6,2];
	r.takeextra!(a=>a>3)(2).writeln;
	r.takeextra!(a=>a.sum>10)(1).writeln;
}
auto find(alias F,R)(R r){
	while( ! r.empty && ! F(r)){
		r.popFront;
	}
	return r;
}
auto biosplit(alias F,alias G,R)(R r){
	auto r_=r.biomap!(F,G);
	struct split{
		typeof(r_) r;
		//auto 
front()=>chain(r.take(1),r.drop(1).until!(a=>a.state!=biotag.inside));
		auto front()=>r.takeextra!(a=>a.state==biotag.inside)(1);
		void popFront(){
			r.popFront;
			while( ! r.empty && r.state!=biotag.begin){
				r.popFront;
		}}
		bool empty()=>r.empty;
	}
	return split(r_.find!(r=>r.state==biotag.begin));
}
unittest{
	"hello, im john the 3rd. I made 4$, and 100,000.01euros"
		.biosplit!(isdigit,isdigitorsymbol)
		.each!writeln;
}
```

Im not entire sure this is correct; and I had to fight phoboes 
overly constrained type theory; but for future reference


More information about the Digitalmars-d mailing list