void SmallMem::free(void* addr) { if (addr == nullptr) { return; } ptrdiff_t offset = char_ptr(addr) - sizeof(mem_info) - char_ptr(reserved_mem); mem_info* info = get_mem_info(addr); ptrdiff_t end = (char_ptr(addr) + info->size) - char_ptr(reserved_mem); for (ptrdiff_t i = offset; i < end; i++) { clear_bit(i); } }
/// return a code point (max 16 bits?) and the len in code units of the character at pos wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len) { const char* ptr; if (pos) { ptr = char_ptr(text_utf8, pos); if (!ptr) return 0; } else ptr = text_utf8.c_str(); const wchar_t uch = *reinterpret_cast<const unsigned char*>(ptr); if (uch < 0x80) { if (len) *len = 1; return *ptr; } if (uch < 0xC0) { if (len) *len = 0; return 0; } const auto end = text_utf8.c_str() + text_utf8.size(); if (uch < 0xE0 && (ptr + 1 <= end)) { if (len) *len = 2; return (wchar_t(uch & 0x1F) << 6) | (reinterpret_cast<const unsigned char*>(ptr)[1] & 0x3F); } else if (uch < 0xF0 && (ptr + 2 <= end)) { if (len) *len = 3; return ((((uch & 0xF) << 6) | (reinterpret_cast<const unsigned char*>(ptr)[1] & 0x3F)) << 6) | (reinterpret_cast<const unsigned char*>(ptr)[2] & 0x3F); } else if (uch < 0x1F && (ptr + 3 <= end)) { if (len) *len = 4; return ((((((uch & 0x7) << 6) | (reinterpret_cast<const unsigned char*>(ptr)[1] & 0x3F)) << 6) | (reinterpret_cast<const unsigned char*>(ptr)[2] & 0x3F)) << 6) | (reinterpret_cast<const unsigned char*>(ptr)[3] & 0x3F); } if (len) *len = 0; return 0; }
/// return a code point (max 16 bits?) and the len in code units of the character at pos wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len) { if (!text_utf8) return 0; if (pos) { text_utf8 = char_ptr(text_utf8, pos); if (!text_utf8) return 0; } const wchar_t uch = *reinterpret_cast<const unsigned char*>(text_utf8); if (uch < 0x80) { if (len) *len = 1; return *text_utf8; // uch ? } if (uch < 0xC0) // use police or ?? { if (len) *len = 0; return 0; } const auto end = text_utf8 + std::strlen(text_utf8); if (uch < 0xE0 && (text_utf8 + 1 <= end)) { if (len) *len = 2; return (wchar_t(uch & 0x1F) << 6) | (reinterpret_cast<const unsigned char*>(text_utf8)[1] & 0x3F); } else if (uch < 0xF0 && (text_utf8 + 2 <= end)) { if (len) *len = 3; return ((((uch & 0xF) << 6) | (reinterpret_cast<const unsigned char*>(text_utf8)[1] & 0x3F)) << 6) | (reinterpret_cast<const unsigned char*>(text_utf8)[2] & 0x3F); } else if (uch < 0x1F && (text_utf8 + 3 <= end)) { if (len) *len = 4; return ((((((uch & 0x7) << 6) | (reinterpret_cast<const unsigned char*>(text_utf8)[1] & 0x3F)) << 6) | (reinterpret_cast<const unsigned char*>(text_utf8)[2] & 0x3F)) << 6) | (reinterpret_cast<const unsigned char*>(text_utf8)[3] & 0x3F); } if (len) *len = 0; return 0; }
constexpr bigmem_info* get_mem_info(void* ptr) { return reinterpret_cast<bigmem_info*>(char_ptr(ptr) - sizeof(bigmem_info)); }
constexpr mem_info* get_mem_info(T* ptr) { return reinterpret_cast<mem_info*>(char_ptr(ptr) - sizeof(mem_info)); }