From 4a7a4032998162cba576abc52536733446491ae3 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 22 Apr 2002 12:58:36 +0000 Subject: [PATCH] Work around a second bug in Intels icc compiler regarding pointers to constant member functions. git-svn-id: https://svn.dealii.org/trunk@5707 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/aclocal.m4 | 61 ++ deal.II/base/include/base/thread_management.h | 539 +++++++++++++++++- deal.II/configure.in | 1 + 3 files changed, 580 insertions(+), 21 deletions(-) diff --git a/deal.II/aclocal.m4 b/deal.II/aclocal.m4 index 323002abb2..8c40e53e41 100644 --- a/deal.II/aclocal.m4 +++ b/deal.II/aclocal.m4 @@ -1553,6 +1553,67 @@ AC_DEFUN(DEAL_II_CHECK_TEMPL_CONST_MEM_PTR_BUG, dnl +dnl ------------------------------------------------------------- +dnl More Intel ICC 5.0.1 compiler lossage with pointers to constant +dnl member functions +dnl --------------------------------- +dnl template struct Y { +dnl typedef void (Class::*FunPtr) (); +dnl FunPtr fun_ptr; +dnl Class *object; +dnl void foo () { +dnl (object->*fun_ptr)(); +dnl }; +dnl }; +dnl +dnl struct X {}; +dnl +dnl template class Y; +dnl --------------------------------- +dnl Again, it does not store the information that the member function pointer +dnl refers to a constant object, so complains that the object is constant, +dnl but the member function is not. +dnl +dnl Usage: DEAL_II_CHECK_CONST_MEM_FUN_PTR_BUG +dnl +dnl ------------------------------------------------------------- +AC_DEFUN(DEAL_II_CHECK_CONST_MEM_FUN_PTR_BUG, dnl +[ + AC_MSG_CHECKING(for templates and pointers to const member functions bug) + AC_LANG(C++) + CXXFLAGS="$CXXFLAGSG" + AC_TRY_COMPILE( + [ + template struct Y { + typedef void (Class::*FunPtr) (); + FunPtr fun_ptr; + Class *object; + void foo () { + (object->*fun_ptr)(); + }; + }; + + struct X {}; + + template class Y; + ], + [], + [ + AC_MSG_RESULT(no) + ], + [ + AC_MSG_RESULT(yes. using workaround) + AC_DEFINE(DEAL_II_CONST_MEM_FUN_PTR_BUG, 1, + [Define if we have to work around another bug in Intel's icc + compiler in which the compiler refuses to store the const + attribute at a member function pointer with a constant class. + See the aclocal.m4 file in the top-level directory + for a description of this bug.]) + ]) +]) + + + dnl ------------------------------------------------------------- dnl gcc2.95 doesn't have the std::iterator class, but the standard diff --git a/deal.II/base/include/base/thread_management.h b/deal.II/base/include/base/thread_management.h index aeccaee8d4..58dcd1b6be 100644 --- a/deal.II/base/include/base/thread_management.h +++ b/deal.II/base/include/base/thread_management.h @@ -206,7 +206,229 @@ namespace Threads typedef DummyBarrier Barrier; #endif - + + + /** + * Given a class, argument type, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr0 + { + typedef RetType (Class::*type) (); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr0 + { + typedef RetType (Class::*type) () const; + }; +#endif + /** + * Given a class, argument types, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr1 + { + typedef RetType (Class::*type) (Arg1); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr1 + { + typedef RetType (Class::*type) (Arg1) const; + }; +#endif + /** + * Given a class, argument types, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr2 + { + typedef RetType (Class::*type) (Arg1, Arg2); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr2 + { + typedef RetType (Class::*type) (Arg1, Arg2) const; + }; +#endif + + /** + * Given a class, argument types, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr3 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr3 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3) const; + }; +#endif + + /** + * Given a class, argument types, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr4 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr4 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4) const; + }; +#endif + + /** + * Given a class, argument types, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr5 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr5 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5) const; + }; +#endif + + /** + * Given a class, argument types, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr6 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr6 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const; + }; +#endif + + /** + * Given a class, argument types, + * and the return type, generate a + * local typedef denoting a pointer + * to such a member function. + */ + template + struct MemFunPtr7 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); + }; + +#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG + /** + * Same as above, but for the case + * of a member function marked + * @p{const}. This should not + * really be necessary, but Intel's + * compiler has a bug here so we + * have to work around. + */ + template + struct MemFunPtr7 + { + typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const; + }; +#endif /** * Class used to store a pointer temporarily and delete the object @@ -1735,11 +1957,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (); + typedef typename MemFunPtr0::type FunPtr; /** * Constructor. Store pointer to @@ -1845,6 +2067,13 @@ namespace Threads friend typename MemFunData0::ArgCollector encapsulate (void (Class_::*fun_ptr)()); + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData0::ArgCollector + encapsulate (void (Class_::*fun_ptr)() const); +#endif }; @@ -1861,11 +2090,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (Arg1); + typedef typename MemFunPtr1::type FunPtr; /** * Constructor. Store pointer to @@ -1980,6 +2209,13 @@ namespace Threads friend typename MemFunData1::ArgCollector encapsulate (void (Class_::*fun_ptr)(Arg1_)); + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData1::ArgCollector + encapsulate (void (Class_::*fun_ptr)(Arg1_) const); +#endif }; @@ -1996,11 +2232,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (Arg1, Arg2); + typedef typename MemFunPtr2::type FunPtr; /** * Constructor. Store pointer to @@ -2119,6 +2355,13 @@ namespace Threads friend typename MemFunData2::ArgCollector encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_)); + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData2::ArgCollector + encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_) const); +#endif }; @@ -2134,11 +2377,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3); + typedef typename MemFunPtr3::type FunPtr; /** * Constructor. Store pointer to @@ -2261,6 +2504,13 @@ namespace Threads friend typename MemFunData3::ArgCollector encapsulate (void (Class_::*fun_ptr)(Arg1_,Arg2_,Arg3_)); + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData3::ArgCollector + encapsulate (void (Class_::*fun_ptr)(Arg1_,Arg2_,Arg3_) const); +#endif }; @@ -2277,11 +2527,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3, Arg4); + typedef typename MemFunPtr4::type FunPtr; /** * Constructor. Store pointer to @@ -2407,7 +2657,14 @@ namespace Threads friend typename MemFunData4::ArgCollector encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_)); - }; + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData4::ArgCollector + encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_) const); +#endif +}; @@ -2423,11 +2680,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5); + typedef typename MemFunPtr5::type FunPtr; /** * Constructor. Store pointer to @@ -2558,6 +2815,14 @@ namespace Threads typename MemFunData5::ArgCollector encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_, Arg5_)); + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData5::ArgCollector + encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, + Arg4_, Arg5_) const); +#endif }; @@ -2574,11 +2839,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); + typedef typename MemFunPtr6::type FunPtr; /** * Constructor. Store pointer to @@ -2713,6 +2978,14 @@ namespace Threads typename MemFunData6::ArgCollector encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_, Arg5_, Arg6_)); + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData6::ArgCollector + encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, + Arg4_, Arg5_, Arg6_) const); +#endif }; @@ -2729,11 +3002,11 @@ namespace Threads { public: /** - * Typedef a pointer to a global + * Typedef a pointer to a member * function which we will call * from this class. */ - typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); + typedef typename MemFunPtr7::type FunPtr; /** * Constructor. Store pointer to @@ -2872,6 +3145,14 @@ namespace Threads typename MemFunData7::ArgCollector encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_, Arg5_, Arg6_, Arg7_)); + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + friend + typename MemFunData7::ArgCollector + encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, + Arg4_, Arg5_, Arg6_, Arg7_) const); +#endif }; @@ -3078,6 +3359,24 @@ namespace Threads typename MemFunData0::ArgCollector encapsulate (void (Class::*fun_ptr)()); +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData0::ArgCollector + encapsulate (void (Class::*fun_ptr)() const); +#endif + /** * Encapsulate a member function * pointer into an object with @@ -3095,6 +3394,24 @@ namespace Threads typename MemFunData1::ArgCollector encapsulate (void (Class::*fun_ptr)(Arg1)); +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData1::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1) const); +#endif + /** * Encapsulate a member function @@ -3112,7 +3429,25 @@ namespace Threads inline typename MemFunData2::ArgCollector encapsulate (void (Class::*fun_ptr)(Arg1, Arg2)); - + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData2::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2) const); +#endif + /** * Encapsulate a member function @@ -3130,7 +3465,25 @@ namespace Threads inline typename MemFunData3::ArgCollector encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3)); - + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData3::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3) const); +#endif + /** * Encapsulate a member function @@ -3148,7 +3501,25 @@ namespace Threads inline typename MemFunData4::ArgCollector encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4)); - + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData4::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4) const); +#endif + /** * Encapsulate a member function @@ -3167,6 +3538,24 @@ namespace Threads typename MemFunData5::ArgCollector encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5)); +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData5::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5) const); +#endif + /** * Encapsulate a member function @@ -3185,6 +3574,24 @@ namespace Threads typename MemFunData6::ArgCollector encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)); +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData6::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const); +#endif + /** * Encapsulate a member function * pointer into an object with @@ -3202,6 +3609,24 @@ namespace Threads typename MemFunData7::ArgCollector encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)); +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + /** + * Same as the previous function, + * but for member functions marked + * @p{const}. This function should + * not be necessary, since the + * compiler should deduce a + * constant class as template + * argument, but we have to work + * around a bug in Intel's icc + * compiler with this. + */ + template + inline + typename MemFunData7::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const); +#endif + /** * Spawn a new thread using the @@ -5425,6 +5850,15 @@ namespace Threads return fun_ptr; } +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData0::ArgCollector + encapsulate (void (Class::*fun_ptr)() const) + { + return fun_ptr; + } +#endif + template @@ -5433,6 +5867,15 @@ namespace Threads { return fun_ptr; } + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData1::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1) const) + { + return fun_ptr; + } +#endif @@ -5442,6 +5885,15 @@ namespace Threads { return fun_ptr; } + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData2::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2) const) + { + return fun_ptr; + } +#endif @@ -5451,6 +5903,15 @@ namespace Threads { return fun_ptr; } + +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData3::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3) const) + { + return fun_ptr; + } +#endif @@ -5461,6 +5922,15 @@ namespace Threads return fun_ptr; } +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData4::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4) const) + { + return fun_ptr; + } +#endif + template @@ -5470,6 +5940,15 @@ namespace Threads return fun_ptr; } +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData5::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5) const) + { + return fun_ptr; + } +#endif + template @@ -5479,6 +5958,15 @@ namespace Threads return fun_ptr; } +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData6::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const) + { + return fun_ptr; + } +#endif + template @@ -5488,6 +5976,15 @@ namespace Threads return fun_ptr; } +#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG + template + typename MemFunData7::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const) + { + return fun_ptr; + } +#endif + template diff --git a/deal.II/configure.in b/deal.II/configure.in index dde6080bfb..e9c4619214 100644 --- a/deal.II/configure.in +++ b/deal.II/configure.in @@ -156,6 +156,7 @@ DEAL_II_CHECK_TEMPLATE_SPEC_ACCESS DEAL_II_CHECK_MEMBER_OP_TEMPLATE_INST DEAL_II_CHECK_NAMESP_TEMPL_FRIEND_BUG DEAL_II_CHECK_TEMPL_CONST_MEM_PTR_BUG +DEAL_II_CHECK_CONST_MEM_FUN_PTR_BUG DEAL_II_HAVE_STD_ITERATOR DEAL_II_HAVE_STD_STRINGSTREAM DEAL_II_HAVE_STD_NUMERIC_LIMITS -- 2.39.5