December 06, 2019
Learning all the ins and outs of the std library is fun. But there are soo many hidden gems that its hard to tell when to keep looking and when to just write something. I was working on a split function with some particulars:

Split but keep exactly one delimiter at the beginning of each section
so if splitting on B:
AAAABADSFBBBBDER ==> AAAA BADSF BDER
BBBBURPBURGER ==> BURP BURGER
BBBABBLEB ==> BA BLE B

Below is my attempt (As far as I know it works)
'''D
import std;

auto splitB(T)(T irange, T isplitter)
     if (isInputRange!T){
    struct SplitB(T) {
        private T _str;
        private T _splitter;
        private size_t cnt;

        this(T instr,T splitter){
            _str=instr;
            _splitter=splitter;
        }
        bool empty() const{
            return _str.length==0;
        }

        ref auto front(){
            auto tmp = _str.until!"a!=b"(_splitter);
            auto tmp2 = _str.drop(tmp.count).until(_splitter,Yes.openRight);
            cnt = tmp.count + tmp2.count;
            return chain(tmp.takeOne,tmp2);
        }

        void popFront(){
            _str = _str.drop(cnt);
        }
    }
 	return SplitB!T( irange,isplitter);
}


void main()
{
    "BBAAABSDFSDFBBBAFFA".splitB("A").writeln;
}
'''

I guess there are two reasons for this post.
1. There are probably much easier ways to do this, I would like to hear about that.
2. This is one of my first complete range setups. Any coding tips / critical comments would be helpful.