#pragma once #include #include /** * Calculate the length of the string (in bytes) pointed to by str, excluding * the terminating null character. */ constexpr size_t strlen(const char* str) { size_t len = 0; while (str[len]) ++len; return len; } /* reverse: reverse string s in place */ constexpr void reverse(char s[], int strlen) { int i, j; char c; for (i = 0, j = strlen - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } /* itoa: convert n to characters in s */ template constexpr size_t itoa(T n, char s[]) { const bool is_negative = (n < 0); if constexpr (!is_unsigned()) { if (n < 0) n = -n; } int i = 0; do { /* generate digits in reverse order */ s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ } while ((n /= base) > 0); /* delete it */ if (is_negative) s[i++] = '-'; s[i] = '\0'; reverse(s, i); return i; } class ViewIterator { public: virtual char next() = 0; virtual operator bool() const = 0; }; class StringView { public: class Iterator : public ViewIterator { friend class StringView; public: char next() override { return p->buffer[pos++]; } operator bool() const override { return (pos < p->m_length); } private: Iterator(const StringView* s) : p(s) {} size_t pos = 0; const StringView* p; }; friend class Iterator; StringView(const char* d) : buffer{d}, m_length{strlen(d)} {} StringView(const char* d, size_t l) : buffer{d}, m_length{l} {} Iterator begin() const { return Iterator(this); } private: const char* const buffer; const size_t m_length; }; class IntegerView { public: template struct HexFormat { T n; }; class Iterator : public ViewIterator { friend class IntegerView; public: char next() override { return _p->buffer[pos++]; }; operator bool() const override { return (pos < _p->length); } private: Iterator(const IntegerView* v) : _p(v) {} size_t pos = 0; const IntegerView* _p; }; IntegerView(int32_t n) { length = itoa(n, buffer); } template IntegerView(HexFormat f) { buffer[0] = '0'; buffer[1] = 'x'; length = itoa(f.n, buffer + 2) + 2; } Iterator begin() const { return Iterator(this); } private: char buffer[128]; size_t length = 0; }; using hex = IntegerView::HexFormat; using uhex = IntegerView::HexFormat; using hex_addr = IntegerView::HexFormat; // TODO causes crash