54 #include <type_traits>
55 #include <unordered_map>
56 #include <unordered_set>
62 #ifdef ENABLE_TOSTRING_RAPIDJSON
63 #if __has_include(<rapidjson/document.h> )
64 #include <rapidjson/document.h>
65 #include <rapidjson/stringbuffer.h>
66 #include <rapidjson/writer.h>
68 #undefine ENABLE_TOSTRING_RAPIDJSON
72 #ifdef ENABLE_TOSTRING_LLVM
73 #if __has_include(<llvm/Support/raw_os_ostream.h> )
74 #include <llvm/IR/Value.h>
75 #include <llvm/Support/raw_os_ostream.h>
76 #include "clang/Driver/Job.h"
77 #include "llvm/IR/Function.h"
78 #include "llvm/IR/Module.h"
79 #include "llvm/Option/ArgList.h"
81 #undefine ENABLE_TOSTRING_LLVM
85 #ifdef ENABLE_TOSTRING_PTHREAD
93 #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
96 std::lock_guard<std::mutex> print_lock(toString_PRINT_mutex); \
97 std::cout << std::hex \
98 << ((std::hash<std::thread::id>()(std::this_thread::get_id())) & 0xffff) \
99 << std::dec << " [" << __FILENAME__ << ":" << __func__ << "#" << __LINE__ \
100 << "]: " #__VA_ARGS__ "=" << ::toString(std::make_tuple(__VA_ARGS__)) \
105 template <
typename T>
107 std::stringstream stream;
110 stream << std::string(
typeid(
T).
name());
112 char* demangled = abi::__cxa_demangle(
typeid(
T).
name(), 0, 0, &status);
113 stream << std::string(demangled);
119 template <
typename T,
typename... Args>
121 std::stringstream stream;
124 stream << std::string(
typeid(v).
name());
126 char* demangled = abi::__cxa_demangle(
typeid(v).
name(), 0, 0, &status);
127 stream << std::string(demangled);
130 stream <<
"@0x" << std::hex << (uintptr_t)(reinterpret_cast<const void*>(v));
136 template <
typename T,
typename =
void>
138 template <
typename T>
144 template <
typename T,
typename =
void>
146 template <
typename T>
152 #ifdef ENABLE_TOSTRING_to_string
153 template <
typename T,
typename =
void>
154 struct has_to_string : std::false_type {};
155 template <
typename T>
156 struct has_to_string<
T, decltype(std::declval<T>().
to_string(), void())>
159 inline constexpr
bool has_to_string_v = has_to_string<T>::value;
162 #ifdef ENABLE_TOSTRING_str
163 template <
typename T,
typename =
void>
164 struct has_str : std::false_type {};
165 template <
typename T>
166 struct has_str<
T, decltype(std::declval<T>().str(), void())> : std::true_type {};
168 inline constexpr
bool has_str_v = has_str<T>::value;
171 template <
typename T,
typename =
void>
173 template <
typename T>
175 decltype(std::declval<T>().printTo(std::declval<std::ostream&>()),
176 void())> : std::true_type {};
181 template <
typename T,
typename =
void>
183 template <
typename T>
185 decltype(std::declval<std::ostream&>() << std::declval<T>(),
186 void())> : std::true_type {};
193 template <
typename T>
195 if constexpr (std::is_same_v<T, std::string>) {
196 return "\"" + v +
"\"";
197 #ifdef ENABLE_TOSTRING_RAPIDJSON
198 }
else if constexpr (std::is_same_v<T, rapidjson::Value>) {
199 rapidjson::StringBuffer buffer;
200 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
202 return buffer.GetString();
204 #ifdef ENABLE_TOSTRING_LLVM
205 }
else if constexpr (std::is_same_v<T, llvm::Module>) {
206 std::string type_str;
207 llvm::raw_string_ostream rso(type_str);
208 v.print(rso,
nullptr);
209 return "(" + rso.str() +
")";
210 }
else if constexpr (std::is_same_v<T, llvm::Function>) {
211 std::string type_str;
212 llvm::raw_string_ostream rso(type_str);
213 v.print(rso,
nullptr);
214 return "(" + rso.str() +
")";
215 }
else if constexpr (std::is_same_v<T, llvm::Value>) {
216 std::string type_str;
217 llvm::raw_string_ostream rso(type_str);
219 return "(" + rso.str() +
")";
220 }
else if constexpr (std::is_same_v<T, llvm::Argument>) {
221 std::string type_str;
222 llvm::raw_string_ostream rso(type_str);
224 return "(" + rso.str() +
")";
225 }
else if constexpr (std::is_same_v<T, llvm::Type>) {
226 std::string type_str;
227 llvm::raw_string_ostream rso(type_str);
229 return "(" + rso.str() +
")";
230 }
else if constexpr (std::is_same_v<T, llvm::Triple>) {
232 }
else if constexpr (std::is_same_v<T, llvm::opt::ArgStringList>) {
234 for (
unsigned i = 0; i < v.size(); i++) {
240 return "[" + r +
"]";
241 }
else if constexpr (std::is_same_v<T, llvm::opt::DerivedArgList>) {
243 for (
unsigned i = 0; i < v.getNumInputArgStrings(); i++) {
247 r += v.getArgString(i);
249 return "[" + r +
"]";
250 }
else if constexpr (std::is_same_v<T, clang::driver::JobList>) {
251 std::string type_str;
252 llvm::raw_string_ostream rso(type_str);
253 v.Print(rso,
nullptr,
true);
256 #ifdef ENABLE_TOSTRING_PTHREAD
257 }
else if constexpr (std::is_same_v<T, pthread_mutex_t>) {
263 return "{" + r +
"}";
265 }
else if constexpr (std::is_same_v<T, bool>) {
266 return v ?
"True" :
"False";
267 }
else if constexpr (std::is_arithmetic_v<T>) {
269 #ifdef ENABLE_TOSTRING_str
270 }
else if constexpr (has_str_v<T>) {
273 #ifdef ENABLE_TOSTRING_to_string
274 }
else if constexpr (has_to_string_v<T>) {
275 return v.to_string();
277 }
else if constexpr (has_toString_v<T>) {
279 }
else if constexpr (get_has_toString_v<T>) {
281 return (ptr == NULL ?
"NULL" :
"&" + ptr->toString());
282 }
else if constexpr (std::is_same_v<T, void*>) {
283 std::ostringstream ss;
284 ss << std::hex << (uintptr_t)v;
285 return "0x" + ss.str();
286 }
else if constexpr (std::is_same_v<
288 std::chrono::time_point<std::chrono::system_clock>>) {
289 std::string s(30,
'\0');
290 auto converted_v = (std::chrono::time_point<std::chrono::system_clock>)v;
291 std::time_t ts = std::chrono::system_clock::to_time_t(v);
292 std::strftime(&s[0], s.size(),
"%Y-%m-%d %H:%M:%S", std::localtime(&ts));
294 std::to_string((converted_v.time_since_epoch().count() / 1000) % 1000000);
295 }
else if constexpr (std::is_same_v<T, JoinType>) {
306 return "WINDOW_FUNCTION";
308 return "WINDOW_FUNCTION_FRAMING";
314 }
else if constexpr (std::is_same_v<T, Data_Namespace::MemoryLevel>) {
327 }
else if constexpr (std::is_pointer_v<T>) {
328 return (v == NULL ?
"NULL" :
"&" +
toString(*v));
329 }
else if constexpr (has_printTo_v<T>) {
330 std::ostringstream ss;
334 }
else if constexpr (has_operator_lshift_v<T>) {
335 std::stringstream stream;
344 #ifdef ENABLE_TOSTRING_PTHREAD
345 template <
typename T>
347 if constexpr (std::is_same_v<T, std::mutex>) {
348 auto p = v.native_handle();
357 template <
typename T1,
typename T2>
362 template <
typename T>
364 auto result = std::string(
"[");
365 for (
size_t i = 0; i < v.size(); ++i) {
375 template <
typename T1,
typename T2>
376 std::string
toString(
const std::unordered_map<T1, T2>& v) {
377 auto result = std::string(
"{");
379 for (
const auto& p : v) {
390 template <
typename T1,
typename T2>
392 auto result = std::string(
"{");
394 for (
const auto& p : v) {
405 template <
typename T>
407 auto result = std::string(
"[");
409 for (
const auto& p : v) {
420 template <
typename T>
421 std::string
toString(
const std::unordered_set<T>& v) {
422 auto result = std::string(
"{");
424 for (
const auto& p : v) {
435 template <
typename T>
437 auto result = std::string(
"{");
439 for (
const auto& p : v) {
450 template <
typename... Ts,
size_t... Is>
452 const std::index_sequence<0, Is...>) {
453 return (
toString(std::get<0>(t)) + ... + (
", " +
toString(std::get<Is>(t))));
456 template <
typename...
T>
457 std::string
toStringImpl(
const std::tuple<>& t,
const std::index_sequence<>) {
461 template <
typename... Ts>
463 return "(" +
toStringImpl(t, std::index_sequence_for<Ts...>{}) +
")";
470 #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.
constexpr bool has_operator_lshift_v