Browse Source

Use range-based for in ForEach.h if available. Closes #561.

Lasse Öörni 11 years ago
parent
commit
c75f38b5a1
1 changed files with 46 additions and 10 deletions
  1. 46 10
      Source/Urho3D/Container/ForEach.h

+ 46 - 10
Source/Urho3D/Container/ForEach.h

@@ -23,10 +23,52 @@
 #pragma once
 
 #include "../Container/Vector.h"
+#include "../Container/List.h"
+#include "../Container/HashSet.h"
+#include "../Container/HashMap.h"
 
-// Note: ForEach is not supported on all compilers, such as VS2008.
+#include <algorithm>
 
-namespace Urho3D {
+namespace std
+{
+
+template <class T> typename Urho3D::Vector<T>::ConstIterator begin(const Urho3D::Vector<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::Vector<T>::ConstIterator end(const Urho3D::Vector<T>& v) { return v.End(); }
+template <class T> typename Urho3D::Vector<T>::Iterator begin(Urho3D::Vector<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::Vector<T>::Iterator end(Urho3D::Vector<T>& v) { return v.End(); }
+
+template <class T> typename Urho3D::PODVector<T>::ConstIterator begin(const Urho3D::PODVector<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::PODVector<T>::ConstIterator end(const Urho3D::PODVector<T>& v) { return v.End(); }
+template <class T> typename Urho3D::PODVector<T>::Iterator begin(Urho3D::PODVector<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::PODVector<T>::Iterator end(Urho3D::PODVector<T>& v) { return v.End(); }
+
+template <class T> typename Urho3D::List<T>::ConstIterator begin(const Urho3D::List<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::List<T>::ConstIterator end(const Urho3D::List<T>& v) { return v.End(); }
+template <class T> typename Urho3D::List<T>::Iterator begin(Urho3D::List<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::List<T>::Iterator end(Urho3D::List<T>& v) { return v.End(); }
+
+template <class T, class U> typename Urho3D::HashMap<T, U>::ConstIterator begin(const Urho3D::HashMap<T, U>& v) { return v.Begin(); }
+template <class T, class U> typename Urho3D::HashMap<T, U>::ConstIterator end(const Urho3D::HashMap<T, U>& v) { return v.End(); }
+template <class T, class U> typename Urho3D::HashMap<T, U>::Iterator begin(Urho3D::HashMap<T, U>& v) { return v.Begin(); }
+template <class T, class U> typename Urho3D::HashMap<T, U>::Iterator end(Urho3D::HashMap<T, U>& v) { return v.End(); }
+
+template <class T> typename Urho3D::HashSet<T>::ConstIterator begin(const Urho3D::HashSet<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::HashSet<T>::ConstIterator end(const Urho3D::HashSet<T>& v) { return v.End(); }
+template <class T> typename Urho3D::HashSet<T>::Iterator begin(Urho3D::HashSet<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::HashSet<T>::Iterator end(Urho3D::HashSet<T>& v) { return v.End(); }
+
+}
+
+// VS2010+ and other compilers: use std::begin(), std::end() & range based for
+// C++11 features need to be enabled
+#if !defined(_MSC_VER) || _MSC_VER > 1600
+#define foreach(VAL, VALS) for (VAL : VALS)
+// Fallback solution for VS2010. Will have problem with break statement.
+// See https://github.com/urho3d/Urho3D/issues/561
+#else
+
+namespace Urho3D
+{
 
 template<typename T>
 struct false_wrapper {
@@ -116,7 +158,7 @@ Urho3D::RandomAccessConstIterator<T> End(const Urho3D::PODVector<T> *v) {
     return v->End();
 }
 
-} // namespace Urho3D
+}
 
 #define foreach(VAL, VALS) \
     if (const auto& _foreach_begin = Urho3D::make_false_wrapper(Urho3D::Begin(VALS))) { } else \
@@ -125,10 +167,4 @@ Urho3D::RandomAccessConstIterator<T> End(const Urho3D::PODVector<T> *v) {
     if (bool _foreach_flag = false) { } else \
     for (VAL = *it; !_foreach_flag; _foreach_flag = true)
 
-#define foreachv(ITER, VAL, VALS) \
-    if (const auto& _foreach_begin = Urho3D::make_false_wrapper(Urho3D::Begin(VALS))) { } else \
-    if (const auto& _foreach_end = Urho3D::make_false_wrapper(Urho3D::End(VALS))) { } else \
-    if (int ITER = 0) { } else \
-    for (auto it = _foreach_begin.value; it != _foreach_end.value; ++it) \
-    if (bool _foreach_flag = false) { } else \
-    for (VAL = *it; !_foreach_flag; ITER++, _foreach_flag = true)
+#endif