#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <utility>

using StrView = std::pair<const char*, size_t>;

StrView makeStrView(const char *str, size_t size) {
	return std::make_pair(str, size);
}

struct compareStrView {
	bool operator()(const StrView &lhs, const StrView &rhs) const {
		if (lhs.second == rhs.second)
			return (std::char_traits<char>::compare(lhs.first, rhs.first, lhs.second) < 0);
		return (lhs.second < rhs.second);
	}
};

std::ostream& operator<<(std::ostream &os, const StrView &rhs) {
	return os.write(rhs.first, rhs.second);
}

int main() {
    std::string str("0=My,1=comma,2=separated,3=string,0=with,3=repeated,7=IDs");
    std::vector<StrView> out0;
    std::map<StrView, StrView, compareStrView> out;

    size_t startPos = 0, delimPos, nameStart, nameEnd, valueStart, valueEnd;

    // loop over the string, collecting "key=value" pairs
    while (startPos < str.size()){
        nameStart = startPos;
        delimPos = str.find_first_of("=,", startPos, 2);
        if (delimPos == std::string::npos) {
            nameEnd = valueStart = valueEnd = str.size();
        }
        else {
            nameEnd = delimPos;
            if (str[delimPos] == '=') {
                valueStart = nameEnd + 1;
                valueEnd = str.find(',', valueStart);
                if (valueEnd == std::string::npos) {
                    valueEnd = str.size();
                }
            }
            else {
                valueStart = valueEnd = nameEnd;
            }
        }

        // TODO: if needed, adjust nameStart/End and valueStartEnd to
        // ignore leading/trailing whitespace around the name and value
        // substrings...

        if (str.compare(nameStart, nameEnd - nameStart, "0", 1) == 0) {
            out0.push_back(makeStrView(&str[valueStart], valueEnd - valueStart));
        } else {
            out[makeStrView(&str[nameStart], nameEnd - nameStart)] = makeStrView(&str[valueStart], valueEnd - valueStart);
		}

        startPos = valueEnd + 1;
    }

    // print out the data structures
    std::cout << "out0:";
    for (auto& entry : out0) {
        std::cout << ' ' << entry;
	}
    std::cout << std::endl;

    std::cout << "out:";
    for (auto &it : out) {
        std::cout << ' ' << it.first << '=' << it.second;
    }
}