]> git.lyx.org Git - lyx.git/blob - src/support/foreach.h
Continue working on the embedding feature. An additional parameter updateFile is...
[lyx.git] / src / support / foreach.h
1
2 /**
3  * \file foreach.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Matthias Ettrich
8  *
9  * Full author contact details are available in file CREDITS.
10  *
11  * A collection of unicode conversion functions, using iconv.
12  */
13
14 #ifndef FOREACH_H
15
16 #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
17
18 /* make use of typeof-extension */
19 template <typename T>
20 class ForeachContainer {
21 public:
22     inline ForeachContainer(const T & t) : c(t), brk(0), i(c.begin()), e(c.end()) { }
23     const T & c;
24     int brk;
25     typename T::const_iterator i, e;
26 };
27
28 #define foreach(variable, container)                                  \
29 for (ForeachContainer<__typeof__(container)> _container_(container);  \
30      !_container_.brk && _container_.i != _container_.e;              \
31      __extension__  ({ ++_container_.brk; ++_container_.i; }))        \
32     for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))
33
34 #else 
35
36 struct ForeachContainerBase {};
37
38 template <typename T>
39 class ForeachContainer : public ForeachContainerBase {
40 public:
41     inline ForeachContainer(const T& t): c(t), brk(0), i(c.begin()), e(c.end()){};
42     const T & c;
43     mutable int brk;
44     mutable typename T::const_iterator i, e;
45     inline bool condition() const { return (!brk++ && i != e); }
46 };
47
48 template <typename T> inline T *foreachPointer(const T &) { return 0; }
49
50 template <typename T> inline ForeachContainer<T> foreachContainerNew(const T& t)
51 { return ForeachContainer<T>(t); }
52
53 template <typename T>
54 inline const ForeachContainer<T> *foreachContainer(const ForeachContainerBase *base, const T *)
55 { return static_cast<const ForeachContainer<T> *>(base); }
56
57 #define foreach(variable, container) \
58         for (const ForeachContainerBase &_container_ = foreachContainerNew(container); \
59                          foreachContainer(&_container_, true ? 0 : foreachPointer(container))->condition();       \
60                          ++foreachContainer(&_container_, true ? 0 : foreachPointer(container))->i)               \
61                         for (variable = *foreachContainer(&_container_, true ? 0 : foreachPointer(container))->i; \
62                                          foreachContainer(&_container_, true ? 0 : foreachPointer(container))->brk;           \
63                                          --foreachContainer(&_container_, true ? 0 : foreachPointer(container))->brk)
64 #endif
65
66 #endif // FOREACH_H