#include <iostream>
#include <map>
#include <vector>
template <typename T>
struct ChooseKfromN{
T mbegin;
T mend;
std::vector<T> combo;
ChooseKfromN(T first,T last,int k) : mbegin(first),mend(last),combo(k,first) {}
bool increment(){
for (auto it = combo.begin();it!=combo.end();it++){
if (++(*it) == mend){
if (it != combo.end()){
auto next = it;
next++;
auto nexit = (*next);
nexit++;
std::fill(combo.begin(),next,nexit);
}
} else { return true;}
}
std::cout << "THIS IS NEVER REACHED FOR A MAP !! \n" << std::endl;
return false;
}
typename std::vector<T>::const_iterator begin(){ return combo.begin();}
typename std::vector<T>::const_iterator end() { return combo.end();}
};
template <typename T>
ChooseKfromN<T> createChooseKfromN(T first,T last,int k) { return ChooseKfromN<T>(first,last,k); }
int main(){
std::vector<std::string> xx = {"A","B","C"};
//std::map<int,int> xx;
//xx[1] = 1;
//xx[2] = 2;
auto kn = createChooseKfromN(xx.begin(),xx.end(),2);
int counter = 0;
do {
for (auto it = kn.begin();it != kn.end();it++){
std::cout << (**it) << "\t";
}
std::cout << "\n";
counter++;
} while(kn.increment());
std::cout << "counter = " << counter << "\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8dmVjdG9yPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBDaG9vc2VLZnJvbU57CiAgICBUICAgbWJlZ2luOwogICAgVCAgIG1lbmQ7CiAgICBzdGQ6OnZlY3RvcjxUPiBjb21ibzsKICAgIENob29zZUtmcm9tTihUIGZpcnN0LFQgbGFzdCxpbnQgaykgOiBtYmVnaW4oZmlyc3QpLG1lbmQobGFzdCksY29tYm8oayxmaXJzdCkge30KICAgIGJvb2wgaW5jcmVtZW50KCl7CiAgICAgICAgZm9yIChhdXRvIGl0ID0gY29tYm8uYmVnaW4oKTtpdCE9Y29tYm8uZW5kKCk7aXQrKyl7CiAgICAgICAgICAgIGlmICgrKygqaXQpID09IG1lbmQpewogICAgICAgICAgICAgICAgaWYgKGl0ICE9IGNvbWJvLmVuZCgpKXsKICAgICAgICAgICAgICAgICAgICBhdXRvIG5leHQgID0gaXQ7CiAgICAgICAgICAgICAgICAgICAgbmV4dCsrOwogICAgICAgICAgICAgICAgICAgIGF1dG8gbmV4aXQgPSAoKm5leHQpOwogICAgICAgICAgICAgICAgICAgIG5leGl0Kys7CiAgICAgICAgICAgICAgICAgICAgc3RkOjpmaWxsKGNvbWJvLmJlZ2luKCksbmV4dCxuZXhpdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSAgeyByZXR1cm4gdHJ1ZTt9CiAgICAgICAgfQogICAgICAgIHN0ZDo6Y291dCA8PCAiVEhJUyBJUyBORVZFUiBSRUFDSEVEIEZPUiBBIE1BUCAhISBcbiIgPDwgc3RkOjplbmRsOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHR5cGVuYW1lIHN0ZDo6dmVjdG9yPFQ+Ojpjb25zdF9pdGVyYXRvciBiZWdpbigpeyByZXR1cm4gY29tYm8uYmVnaW4oKTt9CiAgICB0eXBlbmFtZSBzdGQ6OnZlY3RvcjxUPjo6Y29uc3RfaXRlcmF0b3IgZW5kKCkgIHsgcmV0dXJuIGNvbWJvLmVuZCgpO30KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpDaG9vc2VLZnJvbU48VD4gY3JlYXRlQ2hvb3NlS2Zyb21OKFQgZmlyc3QsVCBsYXN0LGludCBrKSB7IHJldHVybiBDaG9vc2VLZnJvbU48VD4oZmlyc3QsbGFzdCxrKTsgfQoKCmludCBtYWluKCl7CiAgICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4geHggPSB7IkEiLCJCIiwiQyJ9OwogICAgLy9zdGQ6Om1hcDxpbnQsaW50PiB4eDsKICAgIC8veHhbMV0gPSAxOwogICAgLy94eFsyXSA9IDI7CgogICAgYXV0byBrbiA9IGNyZWF0ZUNob29zZUtmcm9tTih4eC5iZWdpbigpLHh4LmVuZCgpLDIpOwogICAgaW50IGNvdW50ZXIgPSAwOwogICAgZG8gewogICAgICAgIGZvciAoYXV0byBpdCA9IGtuLmJlZ2luKCk7aXQgIT0ga24uZW5kKCk7aXQrKyl7CiAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAoKippdCkgPDwgIlx0IjsKICAgICAgICB9CiAgICAgICAgc3RkOjpjb3V0IDw8ICJcbiI7CiAgICAgICAgY291bnRlcisrOwogICAgfSB3aGlsZShrbi5pbmNyZW1lbnQoKSk7CiAgICBzdGQ6OmNvdXQgPDwgImNvdW50ZXIgPSAiIDw8IGNvdW50ZXIgPDwgIlxuIjsKfQo=