lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 52e11311 3/9: Print type name with garniture


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 52e11311 3/9: Print type name with garniture
Date: Fri, 29 Jul 2022 20:42:33 -0400 (EDT)

branch: master
commit 52e1131121ece4f3609e7151b06669cc696e467d
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Print type name with garniture
    
    Written to support the 'decltype' experiment here:
      https://lists.nongnu.org/archive/html/lmi/2022-07/msg00103.html
    and retained because it might be useful elsewhere someday.
---
 rtti_lmi.hpp      | 24 +++++++++++++++++++++++-
 rtti_lmi_test.cpp | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/rtti_lmi.hpp b/rtti_lmi.hpp
index 0a38941a..046f5b0e 100644
--- a/rtti_lmi.hpp
+++ b/rtti_lmi.hpp
@@ -31,6 +31,7 @@
 
 #include <ostream>
 #include <string>
+#include <type_traits>
 #include <typeinfo>
 
 class RttiLmiTest;
@@ -116,7 +117,8 @@ namespace lmi
 ///   lmi::TypeInfo(&ti); // Would refer to typeid(lmi::TypeInfo*).
 /// Those problems are avoided by requiring the idiomatic usage
 ///   lmi::TypeInfo(typeid(X));
-/// and resisting the temptation to add syntactic sugar.
+/// and resisting the temptation to add syntactic sugar here. Use
+/// particularized_type<>() when such information is desired.
 
 class TypeInfo final
 {
@@ -139,6 +141,26 @@ inline std::ostream& operator<<(std::ostream& os, TypeInfo 
const& z)
     return os << z.Name();
 }
 
+/// Underlying 'typeid' type, with cv and reference garniture.
+///
+/// This could be extended, e.g., to handle (multi-level) pointers,
+/// as needs arise.
+
+template<typename T>
+std::string particularized_type()
+{
+    std::string s {lmi::TypeInfo(typeid(T)).Name()};
+    using U = std::remove_reference_t<T>;
+    s += std::is_const_v   <U> ? " const"    : "";
+    s += std::is_volatile_v<U> ? " volatile" : "";
+    s +=
+          std::is_lvalue_reference_v<T> ? "&"
+        : std::is_rvalue_reference_v<T> ? "&&"
+        :                                 ""
+        ;
+    return s;
+}
+
 } // namespace lmi
 
 #endif // rtti_lmi_hpp
diff --git a/rtti_lmi_test.cpp b/rtti_lmi_test.cpp
index bd338621..cd4154c3 100644
--- a/rtti_lmi_test.cpp
+++ b/rtti_lmi_test.cpp
@@ -34,6 +34,7 @@ struct RttiLmiTest
 {
     class X {};
     static void TestTypeInfo();
+    static void test_particularized_type();
 };
 
 void RttiLmiTest::TestTypeInfo()
@@ -91,8 +92,41 @@ void RttiLmiTest::TestTypeInfo()
 //    std::cout << lmi::TypeId<int>() << std::endl;
 }
 
+namespace
+{
+// Shorter name for testing.
+//
+// C++20 generic lambdas can be written tersely:
+//   auto f = []<typename T>(){return lmi::particularized_type<T>();};
+// but must be called verbosely:
+//   f.template operator()<int const volatile&>();
+// which isn't as tidy an alias as "p_t".
+template<typename T>
+std::string p_t()
+{
+    return lmi::particularized_type<T>();
+}
+} // Unnamed namespace.
+
+void RttiLmiTest::test_particularized_type()
+{
+    LMI_TEST_EQUAL("int const volatile"   , p_t<int const volatile  >());
+    LMI_TEST_EQUAL("int volatile"         , p_t<int volatile        >());
+    LMI_TEST_EQUAL("int const"            , p_t<int const           >());
+    LMI_TEST_EQUAL("int"                  , p_t<int                 >());
+    LMI_TEST_EQUAL("int const volatile&"  , p_t<int const volatile& >());
+    LMI_TEST_EQUAL("int volatile&"        , p_t<int volatile&       >());
+    LMI_TEST_EQUAL("int const&"           , p_t<int const&          >());
+    LMI_TEST_EQUAL("int&"                 , p_t<int&                >());
+    LMI_TEST_EQUAL("int const volatile&&" , p_t<int const volatile&&>());
+    LMI_TEST_EQUAL("int volatile&&"       , p_t<int volatile&&      >());
+    LMI_TEST_EQUAL("int const&&"          , p_t<int const&&         >());
+    LMI_TEST_EQUAL("int&&"                , p_t<int&&               >());
+}
+
 int test_main(int, char*[])
 {
     RttiLmiTest::TestTypeInfo();
+    RttiLmiTest::test_particularized_type();
     return 0;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]