]> git.lyx.org Git - lyx.git/commitdiff
add a convienient foreach implementation
authorAndré Pönitz <poenitz@gmx.net>
Fri, 7 Mar 2008 23:05:33 +0000 (23:05 +0000)
committerAndré Pönitz <poenitz@gmx.net>
Fri, 7 Mar 2008 23:05:33 +0000 (23:05 +0000)
code is stolen from Qt, slightly adapted to
avoid a container copy.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23547 a592a061-630c-0410-9148-cb99ea01b6c8

src/support/Makefile.am
src/support/foreach.h [new file with mode: 0644]

index 417e20efb11995e335cc3adf466a6294d0d6c221..c9d7a68286ea1d5649cbd84e328014df58f4b817 100644 (file)
@@ -59,6 +59,7 @@ liblyxsupport_la_SOURCES = \
        FileName.h \
        filetools.cpp \
        filetools.h \
+       foreach.h \
        ForkedCalls.cpp \
        ForkedCalls.h \
        gettext.cpp \
diff --git a/src/support/foreach.h b/src/support/foreach.h
new file mode 100644 (file)
index 0000000..3bcb1a0
--- /dev/null
@@ -0,0 +1,66 @@
+
+/**
+ * \file foreach.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Matthias Ettrich
+ *
+ * Full author contact details are available in file CREDITS.
+ *
+ * A collection of unicode conversion functions, using iconv.
+ */
+
+#ifndef FOREACH_H
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
+
+/* make use of typeof-extension */
+template <typename T>
+class ForeachContainer {
+public:
+    inline ForeachContainer(const T & t) : c(t), brk(0), i(c.begin()), e(c.end()) { }
+    const T & c;
+    int brk;
+    typename T::const_iterator i, e;
+};
+
+#define 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;}))
+
+#else 
+
+struct ForeachContainerBase {};
+
+template <typename T>
+class ForeachContainer : public ForeachContainerBase {
+public:
+    inline ForeachContainer(const T& t): c(t), brk(0), i(c.begin()), e(c.end()){};
+    const T & c;
+    mutable int brk;
+    mutable typename T::const_iterator i, e;
+    inline bool condition() const { return (!brk++ && i != e); }
+};
+
+template <typename T> inline T *foreachPointer(const T &) { return 0; }
+
+template <typename T> inline ForeachContainer<T> foreachContainerNew(const T& t)
+{ return ForeachContainer<T>(t); }
+
+template <typename T>
+inline const ForeachContainer<T> *foreachContainer(const ForeachContainerBase *base, const T *)
+{ return static_cast<const ForeachContainer<T> *>(base); }
+
+#define foreach(variable, container) \
+       for (const ForeachContainerBase &_container_ = foreachContainerNew(container); \
+                        foreachContainer(&_container_, true ? 0 : foreachPointer(container))->condition();       \
+                        ++foreachContainer(&_container_, true ? 0 : foreachPointer(container))->i)               \
+                       for (variable = *foreachContainer(&_container_, true ? 0 : foreachPointer(container))->i; \
+                                        foreachContainer(&_container_, true ? 0 : foreachPointer(container))->brk;           \
+                                        --foreachContainer(&_container_, true ? 0 : foreachPointer(container))->brk)
+#endif
+
+#endif // FOREACH_H