From 09ec4971abfa99db7ee91b394bc0db1d0241ded3 Mon Sep 17 00:00:00 2001 From: dedner <a.s.dedner@warwick.ac.uk> Date: Mon, 27 Jul 2015 18:32:02 +0100 Subject: [PATCH] Improve the className function to provide more information --- dune/common/classname.hh | 32 ++++++++--------- dune/common/test/CMakeLists.txt | 2 ++ dune/common/test/Makefile.am | 3 ++ dune/common/test/classnametest.cc | 58 +++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 dune/common/test/classnametest.cc diff --git a/dune/common/classname.hh b/dune/common/classname.hh index 0bc7d8b80..57e0a9a21 100644 --- a/dune/common/classname.hh +++ b/dune/common/classname.hh @@ -18,11 +18,12 @@ namespace Dune { - /** \brief Provide the demangled class name of a given object as a string */ + /** \brief Provide the demangled class name of a type T as a string */ template <class T> - std::string className ( T &t ) + std::string className () { - std::string className = typeid( t ).name(); + typedef typename std::remove_reference<T>::type TR; + std::string className = typeid( TR ).name(); #if HAVE_CXA_DEMANGLE int status; char *demangled = abi::__cxa_demangle( className.c_str(), 0, 0, &status ); @@ -32,26 +33,23 @@ namespace Dune { std::free( demangled ); } #endif // #if HAVE_CXA_DEMANGLE + if (std::is_const<TR>::value) + className += " const"; + if (std::is_volatile<TR>::value) + className += " volatile"; + if (std::is_lvalue_reference<T>::value) + className += "&"; + else if (std::is_rvalue_reference<T>::value) + className += "&&"; return className; } - /** \brief Provide the demangled class name of a type T as a string */ + /** \brief Provide the demangled class name of a given object as a string */ template <class T> - std::string className () + std::string className ( T& t ) { - std::string className = typeid( T ).name(); -#if HAVE_CXA_DEMANGLE - int status; - char *demangled = abi::__cxa_demangle( className.c_str(), 0, 0, &status ); - if( demangled ) - { - className = demangled; - std::free( demangled ); - } -#endif // #if HAVE_CXA_DEMANGLE - return className; + return className<T>(); } - } // namespace Dune #endif // DUNE_CLASSNAME_HH diff --git a/dune/common/test/CMakeLists.txt b/dune/common/test/CMakeLists.txt index 05d2d0b55..2d791a9e6 100644 --- a/dune/common/test/CMakeLists.txt +++ b/dune/common/test/CMakeLists.txt @@ -6,6 +6,7 @@ set(TESTS bitsetvectortest calloncetest check_fvector_size + classnametest conversiontest diagonalmatrixtest dynmatrixtest @@ -68,6 +69,7 @@ add_executable("check_fvector_size_fail1" EXCLUDE_FROM_ALL check_fvector_size_fa set_target_properties(check_fvector_size_fail1 PROPERTIES COMPILE_FLAGS "-DDIM=1") add_executable("check_fvector_size_fail2" EXCLUDE_FROM_ALL check_fvector_size_fail.cc) set_target_properties(check_fvector_size_fail2 PROPERTIES COMPILE_FLAGS "-DDIM=3") +add_executable("classnametest" classnametest.cc) add_executable("conversiontest" conversiontest.cc) add_executable("dynmatrixtest" dynmatrixtest.cc) diff --git a/dune/common/test/Makefile.am b/dune/common/test/Makefile.am index 00a21fb7b..07276bd00 100644 --- a/dune/common/test/Makefile.am +++ b/dune/common/test/Makefile.am @@ -7,6 +7,7 @@ TESTPROGS = \ bitsetvectortest \ calloncetest \ check_fvector_size \ + classnametest \ conversiontest \ diagonalmatrixtest \ dynmatrixtest \ @@ -104,6 +105,8 @@ check_fvector_size_fail2_CPPFLAGS = $(AM_CPPFLAGS) -DDIM=3 check_fvector_size_SOURCES = check_fvector_size.cc +classnametest_SOURCES = classnametest.cc + conversiontest_SOURCES = conversiontest.cc diagonalmatrixtest_SOURCES = diagonalmatrixtest.cc diff --git a/dune/common/test/classnametest.cc b/dune/common/test/classnametest.cc new file mode 100644 index 000000000..be61bc6d2 --- /dev/null +++ b/dune/common/test/classnametest.cc @@ -0,0 +1,58 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <dune/common/fvector.hh> +#include <dune/common/classname.hh> +#include <iostream> +#include <complex> + + +using Dune::FieldVector; +using std::complex; + +int main() +{ + try { + std::cout << "First three simple class names extracted from variables:" << std::endl; + FieldVector<int, 3> xi; + std::cout << className(xi) << std::endl; + FieldVector<double, 1> xd; + std::cout << className(xd) << std::endl; + FieldVector<complex<double>, 10> xcd; + std::cout << className(xcd) << std::endl; + std::cout << std::endl; + + std::cout << "Adding const:" << std::endl; + const FieldVector<int, 3> cxi; + std::cout << className(cxi) << std::endl; + std::cout << std::endl; + + std::cout << "If a variable is a reference can not be extracted (needs decltype as used below): " << std::endl; + FieldVector<double, 1> &rxd = xd; + std::cout << className(rxd) << std::endl; + std::cout << std::endl; + + std::cout << "Extracting the class name using a type directly - " + << "also extractes references correctly: " << std::endl; + std::cout << Dune::className<decltype(rxd)>() << std::endl; + const FieldVector<double, 1> &rcxd = xd; + std::cout << Dune::className<decltype(rcxd)>() << std::endl; + const FieldVector<int, 3> &rcxi = cxi; + std::cout << Dune::className<decltype(rcxi)>() << std::endl; + std::cout << std::endl; + + std::cout << "Test some further types:" << std::endl; + std::cout << Dune::className< volatile FieldVector<complex<double>, 10>& >() << std::endl; + std::cout << Dune::className< FieldVector<complex<double>, 10>&& >() << std::endl; + std::cout << std::endl; + + } catch (Dune::Exception& e) { + std::cerr << e << std::endl; + return 1; + } catch (...) { + std::cerr << "Generic exception!" << std::endl; + return 2; + } +} -- GitLab