#ifndef HALIDE_RUNTIME_PRINTER_H
#define HALIDE_RUNTIME_PRINTER_H
namespace Halide { namespace Runtime { namespace Internal {
enum PrinterType {BasicPrinter = 0,
ErrorPrinter = 1,
StringStreamPrinter = 2};
namespace {
template<int type, uint64_t length = 1024>
class Printer {
public:
char *buf, *dst, *end;
void *user_context;
bool own_mem;
Printer(void *ctx, char *mem = NULL) : user_context(ctx), own_mem(mem == NULL) {
buf = mem ? mem : (char *)halide_malloc(user_context, length);
dst = buf;
if (dst) {
end = buf + (length-1);
*end = 0;
} else {
end = dst;
}
}
Printer &operator<<(const char *arg) {
dst = halide_string_to_string(dst, end, arg);
return *this;
}
Printer &operator<<(int64_t arg) {
dst = halide_int64_to_string(dst, end, arg, 1);
return *this;
}
Printer &operator<<(int32_t arg) {
dst = halide_int64_to_string(dst, end, arg, 1);
return *this;
}
Printer &operator<<(uint64_t arg) {
dst = halide_uint64_to_string(dst, end, arg, 1);
return *this;
}
Printer &operator<<(uint32_t arg) {
dst = halide_uint64_to_string(dst, end, arg, 1);
return *this;
}
Printer &operator<<(double arg) {
dst = halide_double_to_string(dst, end, arg, 1);
return *this;
}
Printer &operator<<(float arg) {
dst = halide_double_to_string(dst, end, arg, 0);
return *this;
}
Printer &operator<<(const void *arg) {
dst = halide_pointer_to_string(dst, end, arg);
return *this;
}
Printer & write_float16_from_bits(const uint16_t arg) {
double value = halide_float16_bits_to_double(arg);
dst = halide_double_to_string(dst, end, value, 1);
return *this;
}
Printer &operator<<(const halide_type_t &t) {
dst = halide_type_to_string(dst, end, &t);
return *this;
}
Printer &operator<<(const halide_buffer_t &buf) {
dst = halide_buffer_to_string(dst, end, &buf);
return *this;
}
const char *str() {
if (buf) {
return buf;
} else {
return allocation_error();
}
}
void clear() {
dst = buf;
if (dst) {
dst[0] = 0;
}
}
uint64_t size() const {
return (uint64_t)(dst - buf);
}
void erase(int n) {
if (dst) {
dst -= n;
if (dst < buf) {
dst = buf;
}
dst[0] = 0;
}
}
const char *allocation_error() {
return "Printer buffer allocation failed.\n";
}
void msan_annotate_is_initialized() {
halide_msan_annotate_memory_is_initialized(user_context, buf, dst - buf + 1);
}
~Printer() {
if (!buf) {
halide_error(user_context, allocation_error());
} else {
msan_annotate_is_initialized();
if (type == ErrorPrinter) {
halide_error(user_context, buf);
} else if (type == BasicPrinter) {
halide_print(user_context, buf);
} else {
}
}
if (own_mem) {
halide_free(user_context, buf);
}
}
};
class SinkPrinter {
public:
SinkPrinter(void *user_context) {}
};
template<typename T>
SinkPrinter operator<<(const SinkPrinter &s, T) {
return s;
}
typedef Printer<BasicPrinter> print;
typedef Printer<ErrorPrinter> error;
typedef Printer<StringStreamPrinter> stringstream;
#ifdef DEBUG_RUNTIME
typedef Printer<BasicPrinter> debug;
#else
typedef SinkPrinter debug;
#endif
}
}}}
#endif