An easy way to do it is to pass the block as one of the macro arguments, so something like this:
#include <iostream>
#define MY_OWN_LOOP(A, B, C, ...) do { \
auto&& a = (A); \
auto&& b = (B); \
auto&& c = (C); \
\
std::cout << "predefined-function1(" << a << ", " << b << ")\n"; \
while (1) { \
std::cout << "predefined-function2(" << c << ")\n"; \
{ \
__VA_ARGS__ \
} \
std::cout << "predefined-function3(" << a << ", " << b << ", " << c << ")\n";\
} \
} while (0)
int main() {
int counter = 2;
MY_OWN_LOOP('a', 'b', 'c', {
// Can also access variables `a`, `b` and `c` here
if (--counter < 0) break;
std::cout << "user-statement, counter = " << counter << "\n";
});
}
(Where std::cout << "predefined-function"
is replaced with what you want, and instead of MY_OWN_LOOP(a, b, c) { BLOCK }
, MY_OWN_LOOP(a, b, c, { BLOCK })
)
You can also use a helper function, but it gets complicated trying to handle continue
and break
. If you don't need to use control flow, a simple function like this would work:
#include <iostream>
template<class A, class B, class C, class F>
void my_own_loop(A&& a, B&& b, C&& c, F&& f) {
std::cout << "predefined-function1(" << a << ", " << b << ")\n";
while (1) {
std::cout << "predefined-function2(" << c << ")\n";
f(a, b, c); // Or don't pass the arguments if you don't need them
std::cout << "predefined-function3(" << a << ", " << b << ", " << c << ")\n";\
}
}
int main() {
int counter = 2;
my_own_loop('a', 'b', 'c', [&](const auto& a, const auto& b, const auto& c) {
if (--counter < 0) std::exit(0);
std::cout << "user-statement, counter = " << counter << "\n";
});
}
Alternative designs could be certain exceptions thrown or values returned signifying continue
or break
. For example:
#include <iostream>
enum class control_flow {
none,
break_,
continue_
};
template<class A, class B, class C, class F>
void my_own_loop(A&& a, B&& b, C&& c, F&& f) {
std::cout << "predefined-function1(" << a << ", " << b << ")\n";
while (1) {
std::cout << "predefined-function2(" << c << ")\n";
control_flow x = f(a, b, c);
if (x == control_flow::break_) break;
if (x == control_flow::continue_) continue;
std::cout << "predefined-function3(" << a << ", " << b << ", " << c << ")\n";\
}
}
int main() {
int counter = 2;
my_own_loop('a', 'b', 'c', [&](const auto& a, const auto& b, const auto& c) {
if (--counter < 0) return control_flow::break_;
std::cout << "user-statement, counter = " << counter << "\n";
return control_flow::none;
});
}