Last active
November 15, 2017 09:53
-
-
Save rangerz/f62d52e5120d5d7d1f07 to your computer and use it in GitHub Desktop.
[C++] foreach for pure macro, Qt, and boost
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/***** macro foreach *****/ | |
#define EASY_FOREACH(it, container) \ | |
for(typeof((container).begin()) it = (container).begin();it != (container).end(); ++it) | |
/***** qt foreach *****/ | |
template <typename T> | |
class ForeachContainer { | |
public: | |
inline ForeachContainer(const T& t) : c(t), brk(0), i(c.begin()), e(c.end()) { } | |
const T c; // avoid copy op, using reference (const T &c) | |
int brk; | |
typename T::const_iterator i, e; | |
}; | |
#define QT_FOREACH(variable, container) \ | |
for (ForeachContainer<__typeof__(container)> _container_(container) \ | |
!_container_.brk && _container_.i != _container_.e \ | |
__extension__({ ++_container_.brk; ++_container_.i; }) \ | |
for (variable = *_container_.i;; __extension__({--_container_.brk; break;})) | |
/***** boost foreach for pair *****/ | |
#include <boost/foreach.hpp> | |
#include <boost/tuple/tuple.hpp> | |
namespace __foreach__ { | |
// NOTE: This is a copied from Boost | |
// (boost/tuple/detail/tuple_basic_no_partial_spec.hpp) because the | |
// new 'boost::tuples::ignore' does not work in our 'foreachkey' and | |
// 'foreachvalue'. | |
struct swallow_assign { | |
template<typename T> | |
swallow_assign const& operator=(const T&) const { | |
return *this; | |
} | |
}; | |
swallow_assign const ignore = swallow_assign(); | |
} /* namespace __foreach__ */ | |
#define BOOST_FOREACH_PAIR(VARFIRST, VARSECOND, COL) \ | |
BOOST_FOREACH_PREAMBLE() \ | |
if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \ | |
if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \ | |
if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else \ | |
for (bool BOOST_FOREACH_ID(_foreach_continue) = true, BOOST_FOREACH_ID(_foreach_onetime) = true; \ | |
BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL); \ | |
BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \ | |
if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_onetime))) {} else \ | |
for (VARFIRST = BOOST_FOREACH_DEREF(COL).first; \ | |
!BOOST_FOREACH_ID(_foreach_onetime); \ | |
BOOST_FOREACH_ID(_foreach_onetime) = true) \ | |
if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \ | |
for (VARSECOND = BOOST_FOREACH_DEREF(COL).second; \ | |
!BOOST_FOREACH_ID(_foreach_continue); \ | |
BOOST_FOREACH_ID(_foreach_continue) = true) | |
#define FOREACH BOOST_FOREACH | |
#define FOREACH_PAIR BOOST_FOREACH_PAIR | |
#define FOREACH_KEY(VAR, COL) \ | |
FOREACH_PAIR (VAR, __foreach__::ignore, COL) | |
#define FOREACH_VALUE(VAR, COL) \ | |
FOREACH_PAIR (__foreach__::ignore, VAR, COL) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment