diff --git a/src/support/Makefile.am b/src/support/Makefile.am index 417e20efb1..c9d7a68286 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -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 index 0000000000..3bcb1a03c8 --- /dev/null +++ b/src/support/foreach.h @@ -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 +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 +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 inline T *foreachPointer(const T &) { return 0; } + +template inline ForeachContainer foreachContainerNew(const T& t) +{ return ForeachContainer(t); } + +template +inline const ForeachContainer *foreachContainer(const ForeachContainerBase *base, const T *) +{ return static_cast *>(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