52 #include <type_traits>
53 #include <unordered_map>
54 #include <unordered_set>
58 #ifdef ENABLE_TOSTRING_RAPIDJSON
59 #if __has_include(<rapidjson/document.h> )
60 #include <rapidjson/document.h>
61 #include <rapidjson/stringbuffer.h>
62 #include <rapidjson/writer.h>
64 #undefine ENABLE_TOSTRING_RAPIDJSON
68 #ifdef ENABLE_TOSTRING_LLVM
69 #if __has_include(<llvm/Support/raw_os_ostream.h> )
70 #include <llvm/IR/Value.h>
71 #include <llvm/Support/raw_os_ostream.h>
72 #include "clang/Driver/Job.h"
73 #include "llvm/IR/Function.h"
74 #include "llvm/IR/Module.h"
75 #include "llvm/Option/ArgList.h"
77 #undefine ENABLE_TOSTRING_LLVM
81 #ifdef ENABLE_TOSTRING_PTHREAD
89 #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
92 std::lock_guard<std::mutex> print_lock(toString_PRINT_mutex); \
93 std::cout << std::hex \
94 << ((std::hash<std::thread::id>()(std::this_thread::get_id())) & 0xffff) \
95 << std::dec << " [" << __FILENAME__ << ":" << __func__ << "#" << __LINE__ \
96 << "]: " #__VA_ARGS__ "=" << ::toString(std::make_tuple(__VA_ARGS__)) \
101 template <
typename T>
103 std::stringstream stream;
106 stream << std::string(
typeid(
T).
name());
108 char* demangled = abi::__cxa_demangle(
typeid(
T).
name(), 0, 0, &status);
109 stream << std::string(demangled);
115 template <
typename T,
typename... Args>
117 std::stringstream stream;
120 stream << std::string(
typeid(v).
name());
122 char* demangled = abi::__cxa_demangle(
typeid(v).
name(), 0, 0, &status);
123 stream << std::string(demangled);
126 stream <<
"@0x" << std::hex << (uintptr_t)(reinterpret_cast<const void*>(v));
132 template <
typename T,
typename =
void>
134 template <
typename T>
140 template <
typename T,
typename =
void>
142 template <
typename T>
148 #ifdef ENABLE_TOSTRING_to_string
149 template <
typename T,
typename =
void>
150 struct has_to_string : std::false_type {};
151 template <
typename T>
152 struct has_to_string<
T, decltype(std::declval<T>().
to_string(), void())>
155 inline constexpr
bool has_to_string_v = has_to_string<T>::value;
158 #ifdef ENABLE_TOSTRING_str
159 template <
typename T,
typename =
void>
160 struct has_str : std::false_type {};
161 template <
typename T>
162 struct has_str<
T, decltype(std::declval<T>().str(), void())> : std::true_type {};
164 inline constexpr
bool has_str_v = has_str<T>::value;
167 template <
typename T,
typename =
void>
169 template <
typename T>
171 decltype(std::declval<T>().printTo(std::declval<std::ostream&>()),
172 void())> : std::true_type {};
178 template <
typename T>
180 if constexpr (std::is_same_v<T, std::string>) {
181 return "\"" + v +
"\"";
182 #ifdef ENABLE_TOSTRING_RAPIDJSON
183 }
else if constexpr (std::is_same_v<T, rapidjson::Value>) {
184 rapidjson::StringBuffer buffer;
185 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
187 return buffer.GetString();
189 #ifdef ENABLE_TOSTRING_LLVM
190 }
else if constexpr (std::is_same_v<T, llvm::Module>) {
191 std::string type_str;
192 llvm::raw_string_ostream rso(type_str);
193 v.print(rso,
nullptr);
194 return "(" + rso.str() +
")";
195 }
else if constexpr (std::is_same_v<T, llvm::Function>) {
196 std::string type_str;
197 llvm::raw_string_ostream rso(type_str);
198 v.print(rso,
nullptr);
199 return "(" + rso.str() +
")";
200 }
else if constexpr (std::is_same_v<T, llvm::Value>) {
201 std::string type_str;
202 llvm::raw_string_ostream rso(type_str);
204 return "(" + rso.str() +
")";
205 }
else if constexpr (std::is_same_v<T, llvm::Argument>) {
206 std::string type_str;
207 llvm::raw_string_ostream rso(type_str);
209 return "(" + rso.str() +
")";
210 }
else if constexpr (std::is_same_v<T, llvm::Type>) {
211 std::string type_str;
212 llvm::raw_string_ostream rso(type_str);
214 return "(" + rso.str() +
")";
215 }
else if constexpr (std::is_same_v<T, llvm::Triple>) {
217 }
else if constexpr (std::is_same_v<T, llvm::opt::ArgStringList>) {
219 for (
unsigned i = 0; i < v.size(); i++) {
225 return "[" + r +
"]";
226 }
else if constexpr (std::is_same_v<T, llvm::opt::DerivedArgList>) {
228 for (
unsigned i = 0; i < v.getNumInputArgStrings(); i++) {
232 r += v.getArgString(i);
234 return "[" + r +
"]";
235 }
else if constexpr (std::is_same_v<T, clang::driver::JobList>) {
236 std::string type_str;
237 llvm::raw_string_ostream rso(type_str);
238 v.Print(rso,
nullptr,
true);
241 #ifdef ENABLE_TOSTRING_PTHREAD
242 }
else if constexpr (std::is_same_v<T, pthread_mutex_t>) {
248 return "{" + r +
"}";
250 }
else if constexpr (std::is_same_v<T, bool>) {
251 return v ?
"True" :
"False";
252 }
else if constexpr (std::is_arithmetic_v<T>) {
254 #ifdef ENABLE_TOSTRING_str
255 }
else if constexpr (has_str_v<T>) {
258 #ifdef ENABLE_TOSTRING_to_string
259 }
else if constexpr (has_to_string_v<T>) {
260 return v.to_string();
262 }
else if constexpr (has_toString_v<T>) {
264 }
else if constexpr (get_has_toString_v<T>) {
266 return (ptr == NULL ?
"NULL" :
"&" + ptr->toString());
267 }
else if constexpr (std::is_same_v<T, void*>) {
268 std::ostringstream ss;
269 ss << std::hex << (uintptr_t)v;
270 return "0x" + ss.str();
271 }
else if constexpr (std::is_same_v<
273 std::chrono::time_point<std::chrono::system_clock>>) {
274 std::string s(30,
'\0');
275 auto converted_v = (std::chrono::time_point<std::chrono::system_clock>)v;
276 std::time_t ts = std::chrono::system_clock::to_time_t(v);
277 std::strftime(&s[0], s.size(),
"%Y-%m-%d %H:%M:%S", std::localtime(&ts));
279 std::to_string((converted_v.time_since_epoch().count() / 1000) % 1000000);
280 }
else if constexpr (std::is_same_v<T, JoinType>) {
295 }
else if constexpr (std::is_pointer_v<T>) {
296 return (v == NULL ?
"NULL" :
"&" +
toString(*v));
297 }
else if constexpr (has_printTo_v<T>) {
298 std::ostringstream ss;
306 #ifdef ENABLE_TOSTRING_PTHREAD
307 template <
typename T>
309 if constexpr (std::is_same_v<T, std::mutex>) {
310 auto p = v.native_handle();
319 template <
typename T1,
typename T2>
324 template <
typename T>
326 auto result = std::string(
"[");
327 for (
size_t i = 0; i < v.size(); ++i) {
337 template <
typename T1,
typename T2>
338 std::string
toString(
const std::unordered_map<T1, T2>& v) {
339 auto result = std::string(
"{");
341 for (
const auto& p : v) {
352 template <
typename T1,
typename T2>
354 auto result = std::string(
"{");
356 for (
const auto& p : v) {
367 template <
typename T>
369 auto result = std::string(
"[");
371 for (
const auto& p : v) {
382 template <
typename T>
383 std::string
toString(
const std::unordered_set<T>& v) {
384 auto result = std::string(
"{");
386 for (
const auto& p : v) {
397 template <
typename T>
399 auto result = std::string(
"{");
401 for (
const auto& p : v) {
412 template <
typename... Ts,
size_t... Is>
414 const std::index_sequence<0, Is...>) {
415 return (
toString(std::get<0>(t)) + ... + (
", " +
toString(std::get<Is>(t))));
418 template <
typename...
T>
419 std::string
toStringImpl(
const std::tuple<>& t,
const std::index_sequence<>) {
423 template <
typename... Ts>
425 return "(" +
toStringImpl(t, std::index_sequence_for<Ts...>{}) +
")";
428 #endif // ifndef __CUDACC__
static std::mutex toString_PRINT_mutex
constexpr bool has_toString_v
std::string toStringImpl(const std::tuple< Ts...> &t, const std::index_sequence< 0, Is...>)
struct get_has_toString< T, decltype(std::declval< T >().get() -> void())> constexpr bool get_has_toString_v
std::string toString(const Executor::ExtModuleKinds &kind)
std::string typeName(const T *v)
constexpr bool has_printTo_v
Common Enum definitions for SQL processing.