QxOrm  1.2.3
C++ Object Relational Mapping library
QxForeach.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** http://www.qxorm.com/
00004 ** http://sourceforge.net/projects/qxorm/
00005 ** Original file by Lionel Marty
00006 **
00007 ** This file is part of the QxOrm library
00008 **
00009 ** This software is provided 'as-is', without any express or implied
00010 ** warranty. In no event will the authors be held liable for any
00011 ** damages arising from the use of this software.
00012 **
00013 ** GNU Lesser General Public License Usage
00014 ** This file must be used under the terms of the GNU Lesser
00015 ** General Public License version 2.1 as published by the Free Software
00016 ** Foundation and appearing in the file 'license.lgpl.txt' included in the
00017 ** packaging of this file.  Please review the following information to
00018 ** ensure the GNU Lesser General Public License version 2.1 requirements
00019 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
00020 **
00021 ** If you have questions regarding the use of this file, please contact :
00022 ** contact@qxorm.com
00023 **
00024 ****************************************************************************/
00025 
00026 #ifndef _QX_FOREACH_H_
00027 #define _QX_FOREACH_H_
00028 
00029 #ifdef _MSC_VER
00030 #pragma once
00031 #endif
00032 
00049 #include <boost/foreach.hpp>
00050 
00051 #ifndef BOOST_FOREACH_ID
00052 #define BOOST_FOREACH_ID(x) x
00053 #endif
00054 
00055 #include <QxTraits/is_qx_collection.h>
00056 
00057 namespace qx {
00058 
00059 namespace foreach {
00060 
00061 template<typename T, typename C, bool is_qx_collection = false>
00062 struct qx_deref_boost_or_qx
00063 {
00064    typedef typename boost::foreach_detail_::foreach_reference<T, C>::type type;
00065 };
00066 
00067 template<typename T, typename C>
00068 struct qx_deref_boost_or_qx<T, C, true>
00069 {
00070    typedef typename T::type_pair_key_value::second_type type;
00071 };
00072 
00073 template<typename T, typename C, bool is_qx_collection = false>
00074 struct qx_deref_deduce
00075 {
00076    static inline typename qx::foreach::qx_deref_boost_or_qx<T, C, false>::type
00077    deref(boost::foreach_detail_::auto_any_t cur, boost::foreach_detail_::type2type<T, C> * ptmp)
00078    { return boost::foreach_detail_::deref(cur, ptmp); }
00079 
00080    static inline typename qx::foreach::qx_deref_boost_or_qx<T, C, false>::type
00081    rderef(boost::foreach_detail_::auto_any_t cur, boost::foreach_detail_::type2type<T, C> * ptmp)
00082    { return boost::foreach_detail_::rderef(cur, ptmp); }
00083 };
00084 
00085 template<typename T, typename C>
00086 struct qx_deref_deduce<T, C, true>
00087 {
00088    static inline typename qx::foreach::qx_deref_boost_or_qx<T, C, true>::type
00089    deref(boost::foreach_detail_::auto_any_t cur, boost::foreach_detail_::type2type<T, C> * ptmp)
00090    { return boost::foreach_detail_::deref(cur, ptmp).second; }
00091 
00092    static inline typename qx::foreach::qx_deref_boost_or_qx<T, C, true>::type
00093    rderef(boost::foreach_detail_::auto_any_t cur, boost::foreach_detail_::type2type<T, C> * ptmp)
00094    { return boost::foreach_detail_::rderef(cur, ptmp).second; }
00095 };
00096 
00097 struct qx_deref
00098 {
00099    template<typename T, typename C>
00100    static inline typename qx::foreach::qx_deref_boost_or_qx<T, C, qx::trait::is_qx_collection<T>::value>::type
00101    deref(boost::foreach_detail_::auto_any_t cur, boost::foreach_detail_::type2type<T, C> * ptmp)
00102    { return qx::foreach::qx_deref_deduce<T, C, qx::trait::is_qx_collection<T>::value>::deref(cur, ptmp); }
00103 
00104    template<typename T, typename C>
00105    static inline typename qx::foreach::qx_deref_boost_or_qx<T, C, qx::trait::is_qx_collection<T>::value>::type
00106    deref_reverse(boost::foreach_detail_::auto_any_t cur, boost::foreach_detail_::type2type<T, C> * ptmp)
00107    { return qx::foreach::qx_deref_deduce<T, C, qx::trait::is_qx_collection<T>::value>::rderef(cur, ptmp); }
00108 };
00109 
00110 } // namespace foreach
00111 
00112 } // namespace qx
00113 
00114 #define QX_FOREACH_DEREF(COL) \
00115    qx::foreach::qx_deref::deref(BOOST_FOREACH_ID(_foreach_cur), BOOST_FOREACH_TYPEOF(COL))
00116 
00117 #define QX_FOREACH_DEREF_REVERSE(COL) \
00118    qx::foreach::qx_deref::deref_reverse(BOOST_FOREACH_ID(_foreach_cur), BOOST_FOREACH_TYPEOF(COL))
00119 
00120 #define QX_FOREACH(VAR, COL)                                                                    \
00121    BOOST_FOREACH_PREAMBLE()                                                                     \
00122    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else    \
00123    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else      \
00124    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else        \
00125    for (bool BOOST_FOREACH_ID(_foreach_continue) = true;                                                          \
00126          BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL);                                         \
00127          BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0)                                 \
00128       if  (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else                        \
00129       for (VAR = QX_FOREACH_DEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true)
00130 
00131 #define QX_FOREACH_REVERSE(VAR, COL)                                                            \
00132    BOOST_FOREACH_PREAMBLE()                                                                     \
00133    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else    \
00134    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_RBEGIN(COL)) {} else     \
00135    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_REND(COL)) {} else       \
00136    for (bool BOOST_FOREACH_ID(_foreach_continue) = true;                                                          \
00137          BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_RDONE(COL);                                        \
00138          BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_RNEXT(COL) : (void)0)                                \
00139       if  (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else                        \
00140       for (VAR = QX_FOREACH_DEREF_REVERSE(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true)
00141 
00142 #ifdef _foreach
00143 #undef _foreach
00144 #endif // _foreach
00145 
00146 #ifdef _foreach_reverse
00147 #undef _foreach_reverse
00148 #endif // _foreach_reverse
00149 
00150 #ifdef _foreach_if
00151 #undef _foreach_if
00152 #endif // _foreach_if
00153 
00154 #ifdef _foreach_reverse_if
00155 #undef _foreach_reverse_if
00156 #endif // _foreach_reverse_if
00157 
00158 #define _foreach QX_FOREACH
00159 #define _foreach_reverse QX_FOREACH_REVERSE
00160 
00161 #define _foreach_if(VAR, COL, COND) _foreach(VAR, COL) if (COND)
00162 #define _foreach_reverse_if(VAR, COL, COND) _foreach_reverse(VAR, COL) if (COND)
00163 
00164 #endif // _QX_FOREACH_H_