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
21namespace clang::insights {
22
23namespace details {
24/// \brief Convert a boolean value to a string representation of "true" or "false"
25inline std::string ConvertToBoolString(bool b)
26{
27 return b ? std::string{"true"} : std::string{"false"};
28}
29
30} // namespace details
31
32inline 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
42inline uint64_t Normalize(const llvm::APInt& arg)
43{
44 return arg.getZExtValue();
45}
46//-----------------------------------------------------------------------------
47
48inline std::string Normalize(const llvm::APSInt& arg)
49{
50 return ToString(arg);
51}
52//-----------------------------------------------------------------------------
53
54inline 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#if IS_CLANG_NEWER_THAN(19)
61#else
62 str.pop_back();
63#endif
64
65 if(std::string::npos == str.find('.')) {
66 /* in case it is a number like 10.0 toString() seems to leave out the .0. However, as this distinguished
67 * between an integer and a floating point literal we need that dot. */
68 str.append(".0");
69 }
70
71 return str;
72}
73//-----------------------------------------------------------------------------
74
75inline std::string Normalize(const APValue& arg)
76{
77 switch(arg.getKind()) {
78 case APValue::Int: return Normalize(arg.getInt());
79 case APValue::Float: return Normalize(arg.getFloat());
80 default: break;
81 }
82
83 return std::string{"unsupported APValue"};
84}
85//-----------------------------------------------------------------------------
86
87inline std::string_view Normalize(const StringRef& arg)
88{
89 return arg;
90}
91//-----------------------------------------------------------------------------
92
93static inline std::string Normalize(const CharUnits& arg)
94{
95 return std::to_string(arg.getQuantity());
96}
97//-----------------------------------------------------------------------------
98
99template<class T>
100inline decltype(auto) Normalize(const T& arg)
101{
102 // Handle bool's first, we like their string representation.
103 if constexpr(std::is_same_v<std::remove_cvref_t<T>, bool>) {
105
106 } else if constexpr(std::is_integral_v<T>) {
107 return std::to_string(arg);
108
109 } else {
110 return (arg);
111 }
112}
113//-----------------------------------------------------------------------------
114
115namespace details {
116void StrCat(std::string& ret, const auto&... args)
117{
118 (ret += ... += ::clang::insights::Normalize(args));
119}
120//-----------------------------------------------------------------------------
121} // namespace details
122
123inline std::string StrCat(const auto&... args)
124{
125 std::string ret{};
126 details::StrCat(ret, args...);
127
128 return ret;
129}
130//-----------------------------------------------------------------------------
131
132} // namespace clang::insights
133
134#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)
std::string StrCat(const auto &... args)