MorphoGraphX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Forall.hpp
Go to the documentation of this file.
1 
49 #ifndef UTIL_FORALL_HPP
50 #define UTIL_FORALL_HPP
51 
52 #include <Config.hpp>
53 
54 #include <iterator>
55 #include <utility>
56 
57 namespace mgx {
58 namespace util {
60 namespace ForAll {
61 struct BaseForwardIter {
62  virtual ~BaseForwardIter() {
63  }
64 };
65 
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;
69 
70  ForwardIter(const iterator& fst, const iterator& lst)
71  : it(fst)
72  , end(lst)
73  , brk(0)
74  {
75  }
76 
77  const reference value() const
78  {
79  ++brk;
80  return *it;
81  }
82  bool is_end() const {
83  return (it == end) || brk;
84  }
85  mutable iterator it;
86  iterator end;
87  mutable int brk;
88 };
89 
90 template <typename Pair, typename iterator> inline ForwardIter<iterator> forwardIter(const Pair& range, const iterator*)
91 {
92  return ForwardIter<iterator>(range.first, range.second);
93 }
94 
95 template <typename iterator>
96 inline const ForwardIter<iterator>* castForwardIter(const BaseForwardIter* base, const iterator*)
97 {
98  return static_cast<const ForwardIter<iterator>*>(base);
99 }
100 
101 template <typename T> inline T* pointer(const T&) {
102  return 0;
103 }
104 
105 template <typename Container>
106 std::pair<typename Container::iterator, typename Container::iterator> make_range(Container& cont)
107 {
108  return std::make_pair(cont.begin(), cont.end());
109 }
110 
111 template <typename Container>
112 std::pair<typename Container::const_iterator, typename Container::const_iterator> make_range(const Container& cont)
113 {
114  return std::make_pair(cont.begin(), cont.end());
115 }
116 
117 template <typename Iterator> std::pair<Iterator, Iterator> make_range(const std::pair<Iterator, Iterator>& cont)
118 {
119  return cont;
120 }
121 
122 template <typename Container>
123 std::pair<typename Container::reverse_iterator, typename Container::reverse_iterator>
124 make_reverse_range(Container& cont)
125 {
126  return std::make_pair(cont.rbegin(), cont.rend());
127 }
128 
129 template <typename Container>
130 std::pair<typename Container::const_reverse_iterator, typename Container::const_reverse_iterator>
131 make_reverse_range(const Container& cont)
132 {
133  return std::make_pair(cont.rbegin(), cont.rend());
134 }
135 
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)
139 {
140  typedef std::reverse_iterator<Iterator> reverse_it;
141  return make_pair(reverse_it(cont.second), reverse_it(cont.first));
142 }
143 } // namespace ForAll
144 } // namespace util
145 } // namespace mgx
146 
147 #define forall_pointer(obj) (true ? 0 : mgx::util::ForAll::pointer(obj))
148 
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))
162 
173 #define forall(typed_var, cont) forall_range(typed_var, mgx::util::ForAll::make_range(cont))
174 
186 #define forall_reverse(typed_var, cont) forall_range(typed_var, mgx::util::ForAll::make_reverse_range(cont))
187 
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