#include <iostream>

using namespace std;

const char * msgHello = "helloWorld!!\n";
const char * msgFuck = " Fucking ";
const char * msgDamn = "god damn shit ass";

struct funk
{
    int len;
    friend ostream& operator<<(ostream& output, const funk& p);
	virtual char operator() (int)
	{
		return 0;
	}
	char operator[] (int i)
	{
        return operator()(i);
    }
};

ostream& operator<<(ostream& output, funk& p) {
    int i=1;
    char c=p(0);
    while (c != 0)
    {
        output << c;
        c = p(i);
        i++;
    }
    return output;  // for multiple << operators.
}

struct fstr:funk
{
	const char * arg;
	fstr(const char * _arg, int _len)
	{
		arg = _arg;
		len = _len;
	}
	fstr(const char * _arg)
	{
        arg = _arg;
        len = 0;
        while(*(_arg+len)!=0)
            len++;
    }
	char operator() (int i=0)
	{
		if (i >= len || i < 0)
			return 0;
		else if (arg)
			return *(arg+i);
		return 0;
	}
};

struct fins:funk
{
	funk * back;
	funk * arg;
	int start;
    fins(funk * _back, int _start, int _len, funk * _arg)
	{
		back = _back;
		arg = _arg;
		start = _start;
		len = _len;
	}
	fins(funk * _back, int _start, funk *_arg)
	{
        back = _back;
        arg = _arg;
        start = _start;
        len = 0;
    }
	char operator() (int i)
	{
		if (i < start)
			return (*back)(i);
		else if ((*arg)(i-start)==0)
			return (*back)(i+len-(arg->len));
		else
			return (*arg)(i-start);
	}
};

struct ffind:funk
{
    funk * back;
    char startW;
    char endW;
    int start;
    ffind(funk * _back,char _startW, char _endW)
    {
        startW = _startW;
        endW = _endW;
        back = _back;
        start = 0;
        while ((*back)(start) != startW)
            start++;
        len = 0;
        while ((*back)(start+len) != endW)
            len++;
    }
    char operator() (int i)
    {
        if (i < len && i >= 0)
        {
            return (*back)(start+i);
        }
        return 0;
    }
};

int main()
{
	fstr hello(msgHello);
	fstr fuck(msgFuck);
	fstr damn(msgDamn);
	fins fd(&hello,5,&fuck);
    fins gd(&fd,6,7,&damn);
    ffind ffd(&gd,'g','W');

	for (int i=0;i<40;i++)
		cout << gd[i];
	cout << endl;


    cout << ffd << endl;

	return 0;
}