static CharT decode_octal (state &state_)
    {
        std::size_t accumulator_ = 0;
        CharT ch_ = *state_._curr;
        unsigned short count_ = 3;
        bool eos_ = false;

        for (;;)
        {
            accumulator_ *= 8;
            accumulator_ += ch_ - '0';
            --count_;
            state_.increment ();
            eos_ = state_.eos ();

            if (!count_ || eos_) break;

            ch_ = *state_._curr;

            // Don't consume invalid chars!
            if (ch_ < '0' || ch_ > '7')
            {
                break;
            }
        }

        return static_cast<CharT> (accumulator_);
    }
    static CharT decode_control_char (state &state_)
    {
        // Skip over 'c'
        state_.increment ();

        CharT ch_ = 0;
        bool eos_ = state_.next (ch_);

        if (eos_)
        {
            // Pointless returning index if at end of string
            throw runtime_error ("Unexpected end of regex following \\c.");
        }
        else
        {
            if (ch_ >= 'a' && ch_ <= 'z')
            {
                ch_ -= 'a' - 1;
            }
            else if (ch_ >= 'A' && ch_ <= 'Z')
            {
                ch_ -= 'A' - 1;
            }
            else if (ch_ == '@')
            {
                // Apparently...
                ch_ = 0;
            }
            else
            {
                std::ostringstream ss_;

                ss_ << "Invalid control char at index " <<
                    state_.index () - 1 << '.';
                throw runtime_error (ss_.str ().c_str ());
            }
        }

        return ch_;
    }
    static CharT decode_hex (state &state_)
    {
        // Skip over 'x'
        state_.increment ();

        CharT ch_ = 0;
        bool eos_ = state_.next (ch_);

        if (eos_)
        {
            // Pointless returning index if at end of string
            throw runtime_error ("Unexpected end of regex following \\x.");
        }

        if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') ||
            (ch_ >= 'A' && ch_ <= 'F')))
        {
            std::ostringstream ss_;

            ss_ << "Illegal char following \\x at index " <<
                state_.index () - 1 << '.';
            throw runtime_error (ss_.str ().c_str ());
        }

        std::size_t hex_ = 0;

        do
        {
            hex_ *= 16;

            if (ch_ >= '0' && ch_ <= '9')
            {
                hex_ += ch_ - '0';
            }
            else if (ch_ >= 'a' && ch_ <= 'f')
            {
                hex_ += 10 + (ch_ - 'a');
            }
            else
            {
                hex_ += 10 + (ch_ - 'A');
            }

            eos_ = state_.eos ();

            if (!eos_)
            {
                ch_ = *state_._curr;

                // Don't consume invalid chars!
                if (((ch_ >= '0' && ch_ <= '9') ||
                    (ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F')))
                {
                    state_.increment ();
                }
                else
                {
                    eos_ = true;
                }
            }
        } while (!eos_);

        return static_cast<CharT> (hex_);
    }
    static CharT chr (state &state_)
    {
        CharT ch_ = 0;

        // eos_ has already been checked for.
        switch (*state_._curr)
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
                ch_ = decode_octal (state_);
                break;
            case 'a':
                ch_ = '\a';
                state_.increment ();
                break;
            case 'b':
                ch_ = '\b';
                state_.increment ();
                break;
            case 'c':
                ch_ = decode_control_char (state_);
                break;
            case 'e':
                ch_ = 27; // '\e' not recognised by compiler
                state_.increment ();
                break;
            case 'f':
                ch_ = '\f';
                state_.increment ();
                break;
            case 'n':
                ch_ = '\n';
                state_.increment ();
                break;
            case 'r':
                ch_ = '\r';
                state_.increment ();
                break;
            case 't':
                ch_ = '\t';
                state_.increment ();
                break;
            case 'v':
                ch_ = '\v';
                state_.increment ();
                break;
            case 'x':
                ch_ = decode_hex (state_);
                break;
            default:
                ch_ = *state_._curr;
                state_.increment ();
                break;
        }

        return ch_;
    }