49 #ifndef UTIL_FORALL_HPP
50 #define UTIL_FORALL_HPP
61 struct BaseForwardIter {
62 virtual ~BaseForwardIter() {
66 template <
typename iterator>
struct ForwardIter :
public BaseForwardIter {
67 typedef typename std::iterator_traits<iterator>::value_type value_type;
68 typedef typename std::iterator_traits<iterator>::reference reference;
77 const reference value()
const
83 return (it == end) || brk;
90 template <
typename Pair,
typename iterator>
inline ForwardIter<iterator> forwardIter(
const Pair& range,
const iterator*)
92 return ForwardIter<iterator>(range.first, range.second);
95 template <
typename iterator>
96 inline const ForwardIter<iterator>* castForwardIter(
const BaseForwardIter* base,
const iterator*)
98 return static_cast<const ForwardIter<iterator>*
>(base);
101 template <
typename T>
inline T* pointer(
const T&) {
105 template <
typename Container>
106 std::pair<typename Container::iterator, typename Container::iterator> make_range(Container& cont)
108 return std::make_pair(cont.begin(), cont.end());
111 template <
typename Container>
112 std::pair<typename Container::const_iterator, typename Container::const_iterator> make_range(
const Container& cont)
114 return std::make_pair(cont.begin(), cont.end());
117 template <
typename Iterator> std::pair<Iterator, Iterator> make_range(
const std::pair<Iterator, Iterator>& cont)
122 template <
typename Container>
123 std::pair<typename Container::reverse_iterator, typename Container::reverse_iterator>
124 make_reverse_range(Container& cont)
126 return std::make_pair(cont.rbegin(), cont.rend());
129 template <
typename Container>
130 std::pair<typename Container::const_reverse_iterator, typename Container::const_reverse_iterator>
131 make_reverse_range(
const Container& cont)
133 return std::make_pair(cont.rbegin(), cont.rend());
136 template <
typename Iterator>
137 std::pair<std::reverse_iterator<Iterator>, std::reverse_iterator<Iterator> >
138 make_reverse_range(
const std::pair<Iterator, Iterator>& cont)
140 typedef std::reverse_iterator<Iterator> reverse_it;
141 return make_pair(reverse_it(cont.second), reverse_it(cont.first));
147 #define forall_pointer(obj) (true ? 0 : mgx::util::ForAll::pointer(obj))
154 #define forall_range(typed_var, range) \
155 for(const mgx::util::ForAll::BaseForwardIter& iter \
156 = mgx::util::ForAll::forwardIter(range, forall_pointer((range).first)); \
157 !mgx::util::ForAll::castForwardIter(&iter, forall_pointer((range).first))->is_end(); \
158 ++(mgx::util::ForAll::castForwardIter(&iter, forall_pointer((range).first))->it)) \
159 for(typed_var = mgx::util::ForAll::castForwardIter(&iter, forall_pointer((range).first))->value(); \
160 mgx::util::ForAll::castForwardIter(&iter, forall_pointer((range).first))->brk; \
161 --(mgx::util::ForAll::castForwardIter(&iter, forall_pointer((range).first))->brk))
173 #define forall(typed_var, cont) forall_range(typed_var, mgx::util::ForAll::make_range(cont))
186 #define forall_reverse(typed_var, cont) forall_range(typed_var, mgx::util::ForAll::make_reverse_range(cont))
194 #define forall_named(typed_var, cont, name) \
195 forall_range(typed_var, std::make_pair((cont).begin_ ## name(), (cont).end_ ## name()))
196 #endif // UTIL_FORALL_HPP