#include <iostream>
#include <list>
#include <utility>
using namespace std;
typedef list<pair<string, string> > KeyVal;
struct Header { string name; string value; Header(string name, string value) : name(name), value(value) {}; };
struct Param { string name; string value; Param(string name, string value) : name(name), value(value) {}; };
/* Something that contains headers */
template<typename T> class WithHeaders {
KeyVal headers;
public:
virtual T &operator <<(const Header &h) {
headers.push_back(pair<string, string>(h.name, h.value));
return static_cast<T&> (*this);
}
};
/* Something that contains query params */
template<class T> class WithQuery {
KeyVal query_params;
public:
virtual T &operator <<(const Param &q) {
query_params.push_back(pair<string, string>(q.name, q.value));
return static_cast<T&> (*this);
}
const KeyVal &get_query() const {return query_params;}
};
/* Http Request has both headers and query parameters */
class Request: public WithQuery<Request>, public WithHeaders<Request> {
public:
using WithHeaders<Request>::operator<<;
using WithQuery<Request>::operator<<;
};
int main() {
Request rq;
rq << Header("a", "b");
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bGlzdD4KI2luY2x1ZGUgPHV0aWxpdHk+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdHlwZWRlZiBsaXN0PHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gS2V5VmFsOwpzdHJ1Y3QgSGVhZGVyIHsgc3RyaW5nIG5hbWU7IHN0cmluZyB2YWx1ZTsgSGVhZGVyKHN0cmluZyBuYW1lLCBzdHJpbmcgdmFsdWUpIDogbmFtZShuYW1lKSwgdmFsdWUodmFsdWUpIHt9OyB9OwpzdHJ1Y3QgUGFyYW0geyBzdHJpbmcgbmFtZTsgc3RyaW5nIHZhbHVlOyBQYXJhbShzdHJpbmcgbmFtZSwgc3RyaW5nIHZhbHVlKSA6IG5hbWUobmFtZSksIHZhbHVlKHZhbHVlKSB7fTsgfTsKCi8qIFNvbWV0aGluZyB0aGF0IGNvbnRhaW5zIGhlYWRlcnMgKi8KdGVtcGxhdGU8dHlwZW5hbWUgVD4gY2xhc3MgV2l0aEhlYWRlcnMgewogIEtleVZhbCBoZWFkZXJzOwpwdWJsaWM6CiAgdmlydHVhbCBUICZvcGVyYXRvciA8PChjb25zdCBIZWFkZXIgJmgpIHsKICAgIGhlYWRlcnMucHVzaF9iYWNrKHBhaXI8c3RyaW5nLCBzdHJpbmc+KGgubmFtZSwgaC52YWx1ZSkpOwogICAgcmV0dXJuIHN0YXRpY19jYXN0PFQmPiAoKnRoaXMpOwogIH0KfTsKCi8qIFNvbWV0aGluZyB0aGF0IGNvbnRhaW5zIHF1ZXJ5IHBhcmFtcyAqLwp0ZW1wbGF0ZTxjbGFzcyBUPiBjbGFzcyBXaXRoUXVlcnkgewogICAgS2V5VmFsIHF1ZXJ5X3BhcmFtczsKCnB1YmxpYzoKICAgIHZpcnR1YWwgVCAmb3BlcmF0b3IgPDwoY29uc3QgUGFyYW0gJnEpIHsKICAgICAgcXVlcnlfcGFyYW1zLnB1c2hfYmFjayhwYWlyPHN0cmluZywgc3RyaW5nPihxLm5hbWUsIHEudmFsdWUpKTsKICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQmPiAoKnRoaXMpOwogICAgfQoKICAgIGNvbnN0IEtleVZhbCAmZ2V0X3F1ZXJ5KCkgY29uc3Qge3JldHVybiBxdWVyeV9wYXJhbXM7fQp9OwoKLyogSHR0cCBSZXF1ZXN0IGhhcyBib3RoIGhlYWRlcnMgYW5kIHF1ZXJ5IHBhcmFtZXRlcnMgKi8KY2xhc3MgUmVxdWVzdDogcHVibGljIFdpdGhRdWVyeTxSZXF1ZXN0PiwgcHVibGljIFdpdGhIZWFkZXJzPFJlcXVlc3Q+IHsKcHVibGljOgoJdXNpbmcgV2l0aEhlYWRlcnM8UmVxdWVzdD46Om9wZXJhdG9yPDw7Cgl1c2luZyBXaXRoUXVlcnk8UmVxdWVzdD46Om9wZXJhdG9yPDw7Cn07CgppbnQgbWFpbigpIHsKCVJlcXVlc3QgcnE7CglycSA8PCBIZWFkZXIoImEiLCAiYiIpOwoJcmV0dXJuIDA7Cn0=