InsightsStrCat.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * C++ Insights, copyright (C) by Andreas Fertig
4  * Distributed under an MIT license. See LICENSE for details
5  *
6  ****************************************************************************/
7 
8 #ifndef INSIGHTS_STRCAT_H
9 #define INSIGHTS_STRCAT_H
10 
11 #include "clang/AST/AST.h"
12 #include "llvm/ADT/StringExtras.h"
13 
14 #include <string>
15 #include <type_traits>
16 #include <utility>
17 
18 #include "ClangCompat.h"
19 //-----------------------------------------------------------------------------
20 
21 namespace clang::insights {
22 
23 namespace details {
24 /// \brief Convert a boolean value to a string representation of "true" or "false"
25 inline std::string ConvertToBoolString(bool b)
26 {
27  return b ? std::string{"true"} : std::string{"false"};
28 }
29 
30 } // namespace details
31 
32 inline std::string ToString(const llvm::APSInt& val)
33 {
34  if(1 == val.getBitWidth()) {
35  return details::ConvertToBoolString(0 != val.getExtValue());
36  }
37 
38  return llvm::toString(val, 10);
39 }
40 //-----------------------------------------------------------------------------
41 
42 inline uint64_t Normalize(const llvm::APInt& arg)
43 {
44  return arg.getZExtValue();
45 }
46 //-----------------------------------------------------------------------------
47 
48 inline std::string Normalize(const llvm::APSInt& arg)
49 {
50  return ToString(arg);
51 }
52 //-----------------------------------------------------------------------------
53 
54 inline std::string Normalize(const llvm::APFloat& arg)
55 {
56  std::string str{};
57  ::llvm::raw_string_ostream stream{str};
58 
59  arg.print(stream);
60  str.pop_back();
61 
62  if(std::string::npos == str.find('.')) {
63  /* in case it is a number like 10.0 toString() seems to leave out the .0. However, as this distinguished
64  * between an integer and a floating point literal we need that dot. */
65  str.append(".0");
66  }
67 
68  return str;
69 }
70 //-----------------------------------------------------------------------------
71 
72 inline std::string Normalize(const APValue& arg)
73 {
74  switch(arg.getKind()) {
75  case APValue::Int: return Normalize(arg.getInt());
76  case APValue::Float: return Normalize(arg.getFloat());
77  default: break;
78  }
79 
80  return std::string{"unsupported APValue"};
81 }
82 //-----------------------------------------------------------------------------
83 
84 inline std::string_view Normalize(const StringRef& arg)
85 {
86  return arg;
87 }
88 //-----------------------------------------------------------------------------
89 
90 static inline std::string Normalize(const CharUnits& arg)
91 {
92  return std::to_string(arg.getQuantity());
93 }
94 //-----------------------------------------------------------------------------
95 
96 template<class T>
97 inline decltype(auto) Normalize(const T& arg)
98 {
99  // Handle bool's first, we like their string representation.
100  if constexpr(std::is_same_v<std::remove_cvref_t<T>, bool>) {
101  return details::ConvertToBoolString(arg);
102 
103  } else if constexpr(std::is_integral_v<T>) {
104  return std::to_string(arg);
105 
106  } else {
107  return (arg);
108  }
109 }
110 //-----------------------------------------------------------------------------
111 
112 namespace details {
113 void StrCat(std::string& ret, const auto&... args)
114 {
115  (ret += ... += ::clang::insights::Normalize(args));
116 }
117 //-----------------------------------------------------------------------------
118 } // namespace details
119 
120 inline std::string StrCat(const auto&... args)
121 {
122  std::string ret{};
123  details::StrCat(ret, args...);
124 
125  return ret;
126 }
127 //-----------------------------------------------------------------------------
128 
129 } // namespace clang::insights
130 
131 #endif /* INSIGHTS_STRCAT_H */
void StrCat(std::string &ret, const auto &... args)
std::string ConvertToBoolString(bool b)
Convert a boolean value to a string representation of "true" or "false".
std::string ToString(const llvm::APSInt &val)
uint64_t Normalize(const llvm::APInt &arg)
decltype(auto) Normalize(const T &arg)
std::string StrCat(const auto &... args)