Files
textmate/Shared/include/oak/iterator_macros.h
2013-08-12 19:32:23 +02:00

54 lines
1.6 KiB
C++

#ifndef OAK_ITERATOR_MACROS_H_1SQFE1YN
#define OAK_ITERATOR_MACROS_H_1SQFE1YN
// The essential macro is foreeach, rforeach doing a reverse iteration. Example:
//
// std::vector<char> v;
// foreach(it, v.begin(), v.end())
// cout << *it;
//
// The iterate/riterate macros are taking a container instead, and calls beginof/endof on the container. Example:
//
// std::vector<char> v;
// iterate(it, v)
// cout << *it;
//
// The citerate macro is like iterate but will use a temporary variable for the result of the expression passed in as the container, take this example:
//
// std::vector<char> create_vector () { return std::vector<char>(32, 'a'); }
//
// …later…
//
// citerate(it, create_vector())
// cout << *it;
//
// Using the regular iterate macro is not safe since we would call create_vector() twice and (likely) get incompatible begin/end iterators.
#ifndef foreach
#define foreach(v,f,l) for(decltype(f) v = (f), _end = (l); v != _end; ++v)
#endif
#ifdef iterate
#undef iterate
#endif
#define iterate(v,c) foreach(v, std::begin(c), std::end(c))
#ifndef uiterate
#define uiterate(v,c,u) \
decltype(c) u = (c); foreach(v, std::begin(u), std::end(u))
#endif
#define OAK_UNIQUE __COUNTER__
#define OAK_MERGE_IMPL(a,c) a ## c
#define OAK_MERGE(a,c) OAK_MERGE_IMPL(a,c)
#ifndef citerate
#define citerate(v,c) uiterate(v,c,OAK_MERGE(_tmp_,OAK_UNIQUE))
#endif
#ifndef riterate
#define riterate(v,c) foreach(v, std::reverse_iterator<decltype(std::end(c))>(std::end(c)), std::reverse_iterator<decltype(std::begin(c))>(std::begin(c)))
#endif
#endif /* end of include guard: OAK_ITERATOR_MACROS_H_1SQFE1YN */