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