#include <iostream>
#include <sstream>
#include <string>

    struct Text : std::string { using std::string::string; };

    std::istream& operator>>(std::istream& is, Text& t)
    {
        if (is.flags() & is.skipws) is >> std::skipws;
        for (char c: t)
        {
            if (is.peek() != c)
            {
                is.setstate(std::ios::failbit);
                break;
            }
            is.get();
        }
        return is;
    }

    struct Until_Delim {
    	Until_Delim(std::string& s, std::string delim) : s_(s), delim_(delim) { }
    	std::string& s_;
    	std::string delim_;
    };

    std::istream& operator>>(std::istream& is, const Until_Delim& ud)
    {
        std::istream::sentry sentry(is);
        size_t in_delim = 0;
        for (char c = is.get(); is; c = is.get())
        {
            if (c == ud.delim_[in_delim])
            {
                if (++in_delim == ud.delim_.size())
                    break;
                continue;
            }
            else if (in_delim) // was part-way into delimiter match...
            {
                ud.s_.append(ud.delim_, 0, in_delim);
                in_delim = 0;
            }
            ud.s_ += c;
        }
        // may need to trim trailing whitespace...
        if (is.flags() & std::ios_base::skipws)
            while (!ud.s_.empty() && std::isspace(ud.s_.back()))
                ud.s_.pop_back();
        return is;
    }
    
    int main()
    {
    	Text t{"ignore"};
    	std::istringstream iss("ignore3.14ignore Some ignorable Text ignore 2.718");
    	
    	double pi, e;
    	std::string a_string;
    	if (iss >> t >> pi >> t >> Until_Delim(a_string, "ignore") >> e)
    	    std::cout << "pi " << pi << ", a_string '" << a_string << "', e " << e << '\n';
    }