#pragma once #include extern "C" { void* memcpy(void* dstptr, const void* srcptr, size_t n); void* memset(void* bufptr, int value, size_t n); void* memmove(void* dstptr, const void* srcptr, size_t n); int memcmp(const void* aptr, const void* bptr, size_t n); } /** * 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] != '\0') ++len; return len; } /** * Reverse array in place */ constexpr void reverse(char s[], size_t 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; } } class ViewIterator { public: char next() { return buffer[reverse ? pos-- : pos++]; } operator bool() const { return reverse ? (pos >= 0) : (pos < length); } explicit ViewIterator(const char* b, size_t l, bool r = false) : buffer(b), length(l), reverse(r) { if (reverse) pos = length - 1; }; private: ssize_t pos = 0; const char* const buffer; // const pointer to const char* const size_t length; const bool reverse; }; class StringView { public: StringView(const char* d) : buffer{d}, m_length{strlen(d)} {} StringView(const char* d, size_t l) : buffer{d}, m_length{l} {} auto begin() const { return ViewIterator(buffer, m_length); } private: const char* const buffer; const size_t m_length; }; class IntegerView { public: struct HexFormat_int32 { int32_t n; }; struct HexFormat_uint32 { uint32_t n; }; IntegerView(int32_t n); IntegerView(uint32_t n); IntegerView(HexFormat_int32 f); IntegerView(HexFormat_uint32 f); auto begin() const { return ViewIterator(buffer, length, true); } private: char buffer[32]; size_t length = 0; }; using hex = IntegerView::HexFormat_int32; using uhex = IntegerView::HexFormat_uint32; // using hex_addr = IntegerView::HexFormat; // TODO causes crash