#include <tuple>
#include <utility>
#include <boost/preprocessor.hpp>
#define FOREACH_PREFIX BOOST_PP_CAT(__foreach_, __LINE__)
#define FOREACH_BODY BOOST_PP_CAT(FOREACH_PREFIX, _body__)
#define FOREACH_BREAK BOOST_PP_CAT(FOREACH_PREFIX, _break__)
#define FOREACH_CONTINUE BOOST_PP_CAT(FOREACH_PREFIX, _continue__)
#define FOREACH_ELEM BOOST_PP_CAT(FOREACH_PREFIX, _elem__)
#define FOREACH_ONCE BOOST_PP_CAT(FOREACH_PREFIX, _once__)
#define foreachpair(KEY, VALUE, ELEMS) \
for (auto&& FOREACH_ELEM : ELEMS) \
if (false) FOREACH_BREAK: break; /* set up the break path */ \
else if (bool FOREACH_CONTINUE = false) {} /* var decl */ \
else if (true) goto FOREACH_BODY; /* skip the loop exit checks */ \
else for (;;) /* determine whether we should break or continue. */ \
if (!FOREACH_CONTINUE) goto FOREACH_BREAK; /* break */ \
else if (true) break; /* continue */ \
else \
FOREACH_BODY: \
if (bool FOREACH_ONCE = false) {} /* var decl */ \
else for (KEY = std::get<0>( \
std::forward<decltype(FOREACH_ELEM)>(FOREACH_ELEM)); \
!FOREACH_ONCE; \
FOREACH_ONCE = true) \
for (VALUE = std::get<1>( \
std::forward<decltype(FOREACH_ELEM)>(FOREACH_ELEM)); \
!FOREACH_CONTINUE; \
FOREACH_CONTINUE = true)
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <map>
#include <vector>
int main() {
{
std::cout << "{}: start" << std::endl;
std::map<int, double> elems;
foreachpair (int key, double value, elems) {
std::cout << key << " " << value << std::endl;
}
std::cout << "{}: end" << std::endl;
}
{
std::cout << "{{101, 202}, {303, 404}}: start" << std::endl;
std::map<int, int> elems = {{101, 202}, {303, 404}};
foreachpair (int key, int value, elems) {
std::cout << key << " " << value << std::endl;
}
std::cout << "{{101, 202}, {303, 404}}: end" << std::endl;
}
{
std::cout << "break: {{1, 2}, {3, 4}}: start" << std::endl;
std::map<int, int> elems = {{1, 2}, {3, 4}};
foreachpair (int key, int value, elems) {
std::cout << key << " " << value << std::endl;
if (key == 1) break;
}
std::cout << "break: {{1, 2}, {3, 4}}: end" << std::endl;
}
{
std::cout << "continue: {{1, 2}, {3, 4}}: start" << std::endl;
std::map<int, int> elems = {{1, 2}, {3, 4}};
foreachpair (int key, int value, elems) {
if (key == 1) continue;
std::cout << key << " " << value << std::endl;
}
std::cout << "continue: {{1, 2}, {3, 4}}: end" << std::endl;
}
{
std::cout << "{{1, 2}, {3, 4}}: start" << std::endl;
std::vector<std::tuple<int, int>> elems = {std::make_tuple(1, 2),
std::make_tuple(3, 4)};
foreachpair (int key, int value, elems) {
std::cout << key << " " << value << std::endl;
}
std::cout << "{{1, 2}, {3, 4}}: end" << std::endl;
}
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8dXRpbGl0eT4KCiNpbmNsdWRlIDxib29zdC9wcmVwcm9jZXNzb3IuaHBwPgoKI2RlZmluZSBGT1JFQUNIX1BSRUZJWCBCT09TVF9QUF9DQVQoX19mb3JlYWNoXywgX19MSU5FX18pCgojZGVmaW5lIEZPUkVBQ0hfQk9EWSAgICAgQk9PU1RfUFBfQ0FUKEZPUkVBQ0hfUFJFRklYLCBfYm9keV9fKQojZGVmaW5lIEZPUkVBQ0hfQlJFQUsgICAgQk9PU1RfUFBfQ0FUKEZPUkVBQ0hfUFJFRklYLCBfYnJlYWtfXykKI2RlZmluZSBGT1JFQUNIX0NPTlRJTlVFIEJPT1NUX1BQX0NBVChGT1JFQUNIX1BSRUZJWCwgX2NvbnRpbnVlX18pCiNkZWZpbmUgRk9SRUFDSF9FTEVNICAgICBCT09TVF9QUF9DQVQoRk9SRUFDSF9QUkVGSVgsIF9lbGVtX18pCiNkZWZpbmUgRk9SRUFDSF9PTkNFICAgICBCT09TVF9QUF9DQVQoRk9SRUFDSF9QUkVGSVgsIF9vbmNlX18pCgojZGVmaW5lIGZvcmVhY2hwYWlyKEtFWSwgVkFMVUUsIEVMRU1TKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgZm9yIChhdXRvJiYgRk9SRUFDSF9FTEVNIDogRUxFTVMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGlmIChmYWxzZSkgRk9SRUFDSF9CUkVBSzogYnJlYWs7IC8qIHNldCB1cCB0aGUgYnJlYWsgcGF0aCAqLyAgICAgICAgICAgXAogICAgZWxzZSBpZiAoYm9vbCBGT1JFQUNIX0NPTlRJTlVFID0gZmFsc2UpIHt9IC8qIHZhciBkZWNsICovICAgICAgICAgICAgICBcCiAgICBlbHNlIGlmICh0cnVlKSBnb3RvIEZPUkVBQ0hfQk9EWTsgLyogc2tpcCB0aGUgbG9vcCBleGl0IGNoZWNrcyAqLyAgICAgIFwKICAgIGVsc2UgZm9yICg7OykgLyogZGV0ZXJtaW5lIHdoZXRoZXIgd2Ugc2hvdWxkIGJyZWFrIG9yIGNvbnRpbnVlLiAqLyAgICAgXAogICAgICBpZiAoIUZPUkVBQ0hfQ09OVElOVUUpIGdvdG8gRk9SRUFDSF9CUkVBSzsgLyogYnJlYWsgKi8gICAgICAgICAgICAgICBcCiAgICAgIGVsc2UgaWYgKHRydWUpIGJyZWFrOyAvKiBjb250aW51ZSAqLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIEZPUkVBQ0hfQk9EWTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgaWYgKGJvb2wgRk9SRUFDSF9PTkNFID0gZmFsc2UpIHt9IC8qIHZhciBkZWNsICovICAgICAgICAgICAgICAgICAgIFwKICAgICAgICBlbHNlIGZvciAoS0VZID0gc3RkOjpnZXQ8MD4oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICAgICAgICAgICAgc3RkOjpmb3J3YXJkPGRlY2x0eXBlKEZPUkVBQ0hfRUxFTSk+KEZPUkVBQ0hfRUxFTSkpOyBcCiAgICAgICAgICAgICAgICAgICFGT1JFQUNIX09OQ0U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgICAgICAgICAgRk9SRUFDSF9PTkNFID0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgZm9yIChWQUxVRSA9IHN0ZDo6Z2V0PDE+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgICAgICAgICBzdGQ6OmZvcndhcmQ8ZGVjbHR5cGUoRk9SRUFDSF9FTEVNKT4oRk9SRUFDSF9FTEVNKSk7ICAgIFwKICAgICAgICAgICAgICAgIUZPUkVBQ0hfQ09OVElOVUU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICAgICBGT1JFQUNIX0NPTlRJTlVFID0gdHJ1ZSkKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDx2ZWN0b3I+CgppbnQgbWFpbigpIHsKICB7CiAgCXN0ZDo6Y291dCA8PCAie306IHN0YXJ0IiA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6Om1hcDxpbnQsIGRvdWJsZT4gZWxlbXM7CiAgICBmb3JlYWNocGFpciAoaW50IGtleSwgZG91YmxlIHZhbHVlLCBlbGVtcykgewogICAgICBzdGQ6OmNvdXQgPDwga2V5IDw8ICIgIiA8PCB2YWx1ZSA8PCBzdGQ6OmVuZGw7CiAgICB9CiAgICBzdGQ6OmNvdXQgPDwgInt9OiBlbmQiIDw8IHN0ZDo6ZW5kbDsKICB9CiAgewogIAlzdGQ6OmNvdXQgPDwgInt7MTAxLCAyMDJ9LCB7MzAzLCA0MDR9fTogc3RhcnQiIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6bWFwPGludCwgaW50PiBlbGVtcyA9IHt7MTAxLCAyMDJ9LCB7MzAzLCA0MDR9fTsKICAgIGZvcmVhY2hwYWlyIChpbnQga2V5LCBpbnQgdmFsdWUsIGVsZW1zKSB7CiAgICAgIHN0ZDo6Y291dCA8PCBrZXkgPDwgIiAiIDw8IHZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgIH0KICAgIHN0ZDo6Y291dCA8PCAie3sxMDEsIDIwMn0sIHszMDMsIDQwNH19OiBlbmQiIDw8IHN0ZDo6ZW5kbDsKICB9CiAgewogIAlzdGQ6OmNvdXQgPDwgImJyZWFrOiB7ezEsIDJ9LCB7MywgNH19OiBzdGFydCIgPDwgc3RkOjplbmRsOwogICAgc3RkOjptYXA8aW50LCBpbnQ+IGVsZW1zID0ge3sxLCAyfSwgezMsIDR9fTsKICAgIGZvcmVhY2hwYWlyIChpbnQga2V5LCBpbnQgdmFsdWUsIGVsZW1zKSB7CiAgICAgIHN0ZDo6Y291dCA8PCBrZXkgPDwgIiAiIDw8IHZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgICAgaWYgKGtleSA9PSAxKSBicmVhazsKICAgIH0KICAgIHN0ZDo6Y291dCA8PCAiYnJlYWs6IHt7MSwgMn0sIHszLCA0fX06IGVuZCIgPDwgc3RkOjplbmRsOwogIH0KICB7CiAgCXN0ZDo6Y291dCA8PCAiY29udGludWU6IHt7MSwgMn0sIHszLCA0fX06IHN0YXJ0IiA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6Om1hcDxpbnQsIGludD4gZWxlbXMgPSB7ezEsIDJ9LCB7MywgNH19OwogICAgZm9yZWFjaHBhaXIgKGludCBrZXksIGludCB2YWx1ZSwgZWxlbXMpIHsKICAgICAgaWYgKGtleSA9PSAxKSBjb250aW51ZTsKICAgICAgc3RkOjpjb3V0IDw8IGtleSA8PCAiICIgPDwgdmFsdWUgPDwgc3RkOjplbmRsOwogICAgfQogICAgc3RkOjpjb3V0IDw8ICJjb250aW51ZToge3sxLCAyfSwgezMsIDR9fTogZW5kIiA8PCBzdGQ6OmVuZGw7CiAgfQogIHsKICAJc3RkOjpjb3V0IDw8ICJ7ezEsIDJ9LCB7MywgNH19OiBzdGFydCIgPDwgc3RkOjplbmRsOwogICAgc3RkOjp2ZWN0b3I8c3RkOjp0dXBsZTxpbnQsIGludD4+IGVsZW1zID0ge3N0ZDo6bWFrZV90dXBsZSgxLCAyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1ha2VfdHVwbGUoMywgNCl9OwogICAgZm9yZWFjaHBhaXIgKGludCBrZXksIGludCB2YWx1ZSwgZWxlbXMpIHsKICAgICAgc3RkOjpjb3V0IDw8IGtleSA8PCAiICIgPDwgdmFsdWUgPDwgc3RkOjplbmRsOwogICAgfQogICAgc3RkOjpjb3V0IDw8ICJ7ezEsIDJ9LCB7MywgNH19OiBlbmQiIDw8IHN0ZDo6ZW5kbDsKICB9Cn0=