diff --git a/dune/common/deprecated.hh b/dune/common/deprecated.hh index 50b581d7b8484433b15deccca0124598a1080308..ffa65ef9195f5022379ba0796669759ea79f5af3 100644 --- a/dune/common/deprecated.hh +++ b/dune/common/deprecated.hh @@ -5,7 +5,7 @@ //! @addtogroup Common //! @{ -#if defined(DOXYGEN) or not defined(DUNE_DEPRECATED) +#if defined(DOXYGEN) or not defined(HAS_ATTRIBUTE_DEPRECATED) //! Mark some entity as deprecated /** * \code @@ -76,7 +76,94 @@ * \endcode */ #define DUNE_DEPRECATED +#else // defined(HAS_ATTRIBUTE_DEPRECATED) +#define DUNE_DEPRECATED __attribute__((deprecated)) #endif + +#if defined(DOXYGEN) or not defined(HAS_ATTRIBUTE_DEPRECATED_MSG) +//! Mark some entity as deprecated +/** + * \code + *#include <dune/common/deprecated.hh> + * \endcode + * + * This is a preprocessor define which can be used to mark functions, + * typedefs, enums and other stuff deprecated and to also specify a + * hint what replaces the given functionality. If something is marked + * deprecated, users are advised to migrate to the new interface, + * since it will probably be removed in the next release of Dune. + * + * DUNE_DEPRECATED_MSG currently works only for compilers which + * support the attribute __attribute__((deprecated("message")). For + * other compilers it will be defined empty. This way the user will + * not get any deprecation warning, but at least his code still + * compiles (well, until the next Dune release, that is). + * + * Here are some examples how to mark different stuff deprecated: + * - Classes + * \code + class DUNE_DEPRECATED_MSG("In the future, please use 'Glass'") Class {}; // 1) + class Class {} DUNE_DEPRECATED("In the future, please use 'Glass'"); // 2) + * \endcode + * For both forms, deprecation warnings and the additional hint "In + * the future, please use 'Glass'" will be printed on compilers + * which support it (e.g. G++ >= 4.5.0, clang++ >= 1.1). For compilers + * which support deprecating but do not take an additional hint + * (e.g. G++ < 4.5.0), only the deprecation warning is printed, and + * finally compilers which do not support deprecation of code won't + * print anything, but the code will still compile. 1) should be + * preferred over 2) since 2) does not work with clang++-1.1 + * (again, no warning will be given but code still compiles) + * - Template classes + * \code + template<class T> + class DUNE_DEPRECATED_MSG("In the future, please use 'Glass'") Class {}; // 1) + template<class T> + class Class {} DUNE_DEPRECATED_MSG("In the future, please use 'Glass'"); // 2) + * \endcode + * This works works with g++ >= 4.5, clang++ until at least version + * 1.1 will compile the code without warning in both cases. + * Furthermore, the warning is only triggered when copying an + * object of that template class, neither making a typedef nor + * simply creating such an object emit the warning. It is thus + * recommended that some essential class member be marked + * deprecated as well, if possible. + * - Member constants + * \code + template<typename T> struct Class { + static const int c0 DUNE_DEPRECATED_MSG("c2 is the new hype") = 0; + static const int DUNE_DEPRECATED_MSG("c2 is the new hype") c1 = 1; + }; + * \endcode + * Works without printing the hint on g++-4.1, g++-4.3, g++-4.4 and + * fully on g++ >= 4.5. No warning but clean compile with + * clang++-1.1. + * - Member enumerators + * \code + template<typename T> struct Class { + enum enumeration { enumerator = 0 }; + }; + * \endcode + * No form of deprecation is known that does not trigger an error on most + * compilers. + * - Member functions + * \code + template<typename T> struct Class { + void frob() DUNE_DEPRECATED_MSG("frogs() are beautiful from now on") {} + }; + template<typename T> struct Class { + void DUNE_DEPRECATED_MSG("frogs() are beautiful from now on") frob() {} + }; + template<typename T> struct Class { + DUNE_DEPRECATED_MSG("frogs() are beautiful from now on") void frob() {} + }; + * \endcode + */ +#define DUNE_DEPRECATED_MSG(text) DUNE_DEPRECATED +#else // defined(HAS_ATTRIBUTE_DEPRECATED_MSG) +#define DUNE_DEPRECATED_MSG(text) __attribute__((deprecated(text))) +#endif + //! @} #endif diff --git a/m4/dune_deprecated.m4 b/m4/dune_deprecated.m4 index 1591230b8e778728e1a7e23e97b5a5a23a4b6d33..2ad573588974f0650497ba39d7c2e6ec7155380b 100644 --- a/m4/dune_deprecated.m4 +++ b/m4/dune_deprecated.m4 @@ -14,9 +14,9 @@ AC_DEFUN([DUNE_CHECKDEPRECATED],[ class t_peng { t_peng() {}; } DEP; void foo() DEP; void foo() {};],[], - [DUNE_DEPRECATED="__attribute__((deprecated))" + [HAS_ATTRIBUTE_DEPRECATED="yes" AC_MSG_RESULT(yes)], - [DUNE_DEPRECATED="" + [HAS_ATTRIBUTE_DEPRECATED="no" AC_MSG_RESULT(no)]) AC_LANG_POP([C++]) @@ -32,14 +32,21 @@ AC_DEFUN([DUNE_CHECKDEPRECATED],[ class t_peng { t_peng() {}; } DEP; void foo() DEP; void foo() {};],[], - [DUNE_DEPRECATED_MSG="__attribute__((deprecated(msg) ))" + [HAS_ATTRIBUTE_DEPRECATED_MSG="yes" AC_MSG_RESULT(yes)], - [DUNE_DEPRECATED_MSG="$DUNE_DEPRECATED" + [HAS_ATTRIBUTE_DEPRECATED_MSG="no" AC_MSG_RESULT(no)]) AC_LANG_POP([C++]) - AC_DEFINE_UNQUOTED(DUNE_DEPRECATED, $DUNE_DEPRECATED, - [how to create a deprecation warning]) - AC_DEFINE_UNQUOTED(DUNE_DEPRECATED_MSG(msg), $DUNE_DEPRECATED_MSG, - [how to create a deprecation warning with an additional message]) + if test "$HAS_ATTRIBUTE_DEPRECATED" = "yes"; then + AC_DEFINE_UNQUOTED(HAS_ATTRIBUTE_DEPRECATED, 1, + [does the compiler support __attribute__((deprecated))?]) + fi + + if test "$HAS_ATTRIBUTE_DEPRECATED_MSG" = "yes"; then + AC_DEFINE_UNQUOTED(HAS_ATTRIBUTE_DEPRECATED_MSG, 1, + [does the compiler support __attribute__((deprecated("text"))?]) + fi + + AH_BOTTOM([#include <dune/common/deprecated.hh>]) ])