Ookii.CommandLine for C++  2.0.0
type_info.h
Go to the documentation of this file.
1 #ifndef OOKII_TYPE_INFO_H_
4 #define OOKII_TYPE_INFO_H_
5 
6 #pragma once
7 
8 #include <typeinfo>
9 #include <memory>
10 #include "string_helper.h"
11 
12 #ifdef __GNUC__
13 #include <cxxabi.h>
14 #endif
15 
16 namespace ookii
17 {
18  namespace details
19  {
20 #ifdef __GNUC__
21 
22  template<typename T>
23  struct malloc_deleter
24  {
25  void operator()(T *p)
26  {
27  free(p);
28  }
29  };
30 
31  // Unique pointer to free the value returned by __cxa_demangle, which is allocated with
32  // malloc.
33  using name_ptr = std::unique_ptr<char, malloc_deleter<char>>;
34 
35 #endif
36 
37  inline static std::string_view remove_prefix(std::string_view type_name, std::string_view prefix)
38  {
39  if (type_name.starts_with(prefix))
40  return type_name.substr(prefix.length());
41  else
42  return type_name;
43  }
44 
45  inline std::string_view make_short(std::string_view type_name)
46  {
47  // First strip namespaces. These may occur inside template arguments, so check for
48  // those first.
49  auto index = type_name.find_last_of(':', type_name.find_first_of('<'));
50  if (index == std::string_view::npos)
51  {
52  type_name = remove_prefix(type_name, "class ");
53  type_name = remove_prefix(type_name, "struct ");
54  }
55  else
56  {
57  type_name = type_name.substr(index + 1);
58  }
59 
60  return type_name;
61  }
62 
63  template<typename CharType, typename Traits, typename Alloc>
64  inline auto get_type_name(const std::type_info &type, bool short_name)
65  {
66  std::string_view type_name = type.name();
67 #ifdef __GNUC__
68  int status;
69  name_ptr demangled_name{abi::__cxa_demangle(type_name.data(), nullptr, nullptr, &status)};
70  if (demangled_name)
71  type_name = demangled_name.get();
72 #endif
73  if (short_name)
74  type_name = make_short(type_name);
75 
77  }
78 
79  }
80 
89  template<typename CharType = char, typename Traits = std::char_traits<CharType>, typename Alloc = std::allocator<CharType>>
90  inline auto get_type_name(const std::type_info &type)
91  {
92  return details::get_type_name<CharType, Traits, Alloc>(type, false);
93  }
94 
104  template<typename CharType = char, typename Traits = std::char_traits<CharType>, typename Alloc = std::allocator<CharType>>
105  inline auto get_short_type_name(const std::type_info &type)
106  {
107  return details::get_type_name<CharType, Traits, Alloc>(type, true);
108  }
109 
118  template<typename T, typename CharType = char, typename Traits = std::char_traits<CharType>, typename Alloc = std::allocator<CharType>>
119  inline auto get_type_name()
120  {
121  return get_type_name<CharType, Traits, Alloc>(typeid(T));
122  }
123 
133  template<typename T, typename CharType = char, typename Traits = std::char_traits<CharType>, typename Alloc = std::allocator<CharType>>
134  inline auto get_short_type_name()
135  {
136  return get_short_type_name<CharType, Traits, Alloc>(typeid(T));
137  }
138 }
139 
140 #endif // !defined(OOKII_TYPE_INFO_H_)
Namespace containing the core Ookii.CommandLine.Cpp types.
Definition: command_line_argument.h:16
auto get_type_name(const std::type_info &type)
Gets the name of a type.
Definition: type_info.h:90
auto get_short_type_name(const std::type_info &type)
Gets the name of a type excluding the namespace name.
Definition: type_info.h:105
Provides helper types and functions for working with strings.
static std::basic_string< CharType, Traits, Alloc > from_bytes(std::string_view value, const std::locale &loc={})
Converts a string to the specified character type.
Definition: string_helper.h:171