ImStrv: rework toward ensuring End is always set to constant can be compile time calculated

This commit is contained in:
ocornut 2020-11-26 22:17:55 +01:00
parent 35c0f9a29b
commit 7abe463801
4 changed files with 11 additions and 33 deletions

View File

@ -1632,7 +1632,6 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char
const char* ImStrstr(ImStrv haystack, ImStrv needle) const char* ImStrstr(ImStrv haystack, ImStrv needle)
{ {
IM_IMSTR_ENSURE_HAS_END(needle);
const char un0 = (char)*needle.Begin; const char un0 = (char)*needle.Begin;
while ((!haystack.End && *haystack.Begin) || (haystack.End && haystack.Begin < haystack.End)) while ((!haystack.End && *haystack.Begin) || (haystack.End && haystack.Begin < haystack.End))
{ {
@ -2361,8 +2360,7 @@ bool ImGuiTextFilter::PassFilter(ImStrv text) const
if (Filters.empty()) if (Filters.empty())
return true; return true;
IM_IMSTR_ENSURE_HAS_END(text); if (text.Empty()) // FIXME-IMSTR
if (text.Empty())
text.Begin = text.End = ""; text.Begin = text.End = "";
for (int i = 0; i != Filters.Size; i++) for (int i = 0; i != Filters.Size; i++)
@ -3032,14 +3030,9 @@ void ImGui::RenderText(ImVec2 pos, ImStrv text, bool hide_text_after_hash)
// Hide anything after a '##' string // Hide anything after a '##' string
const char* text_display_end; const char* text_display_end;
if (hide_text_after_hash) if (hide_text_after_hash)
{
text_display_end = FindRenderedTextEnd(text); text_display_end = FindRenderedTextEnd(text);
}
else else
{
IM_IMSTR_ENSURE_HAS_END(text);
text_display_end = text.End; text_display_end = text.End;
}
if (text.Begin != text_display_end) if (text.Begin != text_display_end)
{ {
@ -3053,7 +3046,6 @@ void ImGui::RenderTextWrapped(ImVec2 pos, ImStrv text, float wrap_width)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
IM_IMSTR_ENSURE_HAS_END(text);
if (text.Begin != text.End) if (text.Begin != text.End)
{ {
@ -3313,7 +3305,6 @@ ImGuiID ImGuiWindow::GetID(ImStrv str)
ImGuiID id = ImHashStr(str, seed); ImGuiID id = ImHashStr(str, seed);
ImGui::KeepAliveID(id); ImGui::KeepAliveID(id);
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_IMSTR_ENSURE_HAS_END(str);
if (g.DebugHookIdInfo == id) if (g.DebugHookIdInfo == id)
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str.Begin, str.End); ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str.Begin, str.End);
return id; return id;
@ -3344,8 +3335,7 @@ ImGuiID ImGuiWindow::GetID(int n)
ImGuiID ImGuiWindow::GetIDNoKeepAlive(ImStrv str) ImGuiID ImGuiWindow::GetIDNoKeepAlive(ImStrv str)
{ {
ImGuiID seed = IDStack.back(); ImGuiID seed = IDStack.back();
IM_IMSTR_ENSURE_HAS_END(str); ImGuiID id = ImHashStr(str, seed);
ImGuiID id = ImHashStr(str.Begin, str.End - str.Begin, seed);
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.DebugHookIdInfo == id) if (g.DebugHookIdInfo == id)
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str.Begin, str.End); ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str.Begin, str.End);
@ -5009,7 +4999,6 @@ ImVec2 ImGui::CalcTextSize(ImStrv text, bool hide_text_after_double_hash, float
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_IMSTR_ENSURE_HAS_END(text);
if (hide_text_after_double_hash) if (hide_text_after_double_hash)
text.End = FindRenderedTextEnd(text); // Hide anything after a '##' string text.End = FindRenderedTextEnd(text); // Hide anything after a '##' string

15
imgui.h
View File

@ -269,8 +269,7 @@ struct ImVec4
#endif #endif
}; };
#define IM_IMSTR_LENGTH(s) (s.Begin ? (s.End ? (size_t)(s.End - s.Begin) : strlen(s.Begin)) : 0) #define IM_IMSTR_LENGTH(s) (size_t)(s.End - s.Begin)
#define IM_IMSTR_ENSURE_HAS_END(s) if (s.End == NULL) s.End = s.Begin + strlen(s.Begin)
// String view class. // String view class.
#define IMGUI_HAS_IMSTR #define IMGUI_HAS_IMSTR
@ -279,10 +278,10 @@ struct ImStrv
const char* Begin; const char* Begin;
const char* End; const char* End;
ImStrv() { Begin = End = NULL; } ImStrv() { Begin = End = NULL; }
ImStrv(const char* b) { Begin = b; End = NULL; } ImStrv(const char* b) { Begin = b; End = b ? b + strlen(b) : NULL; }
ImStrv(const char* b, const char* e) { Begin = b; End = e; } ImStrv(const char* b, const char* e){ Begin = b; End = e ? e : b + strlen(b); }
ImStrv(const char* b, size_t size) { Begin = b; End = b + size; } ImStrv(const char* b, size_t size) { Begin = b; End = b + size; }
bool Empty() const { return Begin == NULL || Begin == End || Begin[0] == 0; } bool Empty() const { return Begin == End || Begin[0] == 0; } // FIXME: Ambiguous
// void EnsureHasEnd() { if (End == NULL) End = Begin + Length(); } // void EnsureHasEnd() { if (End == NULL) End = Begin + Length(); }
// size_t Length() const // size_t Length() const
// { // {
@ -301,10 +300,10 @@ struct ImStrv
return memcmp(Begin, other.Begin, len) == 0; return memcmp(Begin, other.Begin, len) == 0;
return false; return false;
} }
operator bool() const { return Begin != NULL; } inline operator bool() const { return Begin != NULL; }
char operator[](int index) const { return Begin[index]; } inline char operator[](int index) const { return Begin[index]; }
#ifdef IM_IMSTR_CLASS_EXTRA #ifdef IM_IMSTR_CLASS_EXTRA
IM_IMSTR_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImStrv. IM_IMSTR_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your string types and ImStrv.
#endif #endif
}; };

View File

@ -1578,7 +1578,6 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0)
return; return;
IM_IMSTR_ENSURE_HAS_END(text);
if (text.Empty()) if (text.Empty())
return; return;
@ -3345,7 +3344,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, ImStrv text, float wrap_w
// Cut words that cannot possibly fit within one line. // Cut words that cannot possibly fit within one line.
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish" // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
IM_IMSTR_ENSURE_HAS_END(text);
float line_width = 0.0f; float line_width = 0.0f;
float word_width = 0.0f; float word_width = 0.0f;
@ -3431,8 +3429,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, ImStrv text, float wrap_w
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, ImStrv text, const char** remaining) const ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, ImStrv text, const char** remaining) const
{ {
IM_IMSTR_ENSURE_HAS_END(text);
const float line_height = size; const float line_height = size;
const float scale = size / FontSize; const float scale = size / FontSize;
@ -3540,8 +3536,6 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. // Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, ImStrv text, float wrap_width, bool cpu_fine_clip) const void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, ImStrv text, float wrap_width, bool cpu_fine_clip) const
{ {
IM_IMSTR_ENSURE_HAS_END(text); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect // Align to be pixel perfect
pos.x = IM_FLOOR(pos.x); pos.x = IM_FLOOR(pos.x);
pos.y = IM_FLOOR(pos.y); pos.y = IM_FLOOR(pos.y);

View File

@ -155,8 +155,6 @@ void ImGui::TextEx(ImStrv text, ImGuiTextFlags flags)
return; return;
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_IMSTR_ENSURE_HAS_END(text);
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
const float wrap_pos_x = window->DC.TextWrapPos; const float wrap_pos_x = window->DC.TextWrapPos;
const bool wrap_enabled = (wrap_pos_x >= 0.0f); const bool wrap_enabled = (wrap_pos_x >= 0.0f);
@ -4360,7 +4358,6 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
if (ImStrv clipboard = GetClipboardText()) if (ImStrv clipboard = GetClipboardText())
{ {
// Filter pasted buffer // Filter pasted buffer
IM_IMSTR_ENSURE_HAS_END(clipboard);
const int clipboard_len = (int)IM_IMSTR_LENGTH(clipboard); const int clipboard_len = (int)IM_IMSTR_LENGTH(clipboard);
ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((clipboard_len + 1) * sizeof(ImWchar)); ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((clipboard_len + 1) * sizeof(ImWchar));
int clipboard_filtered_len = 0; int clipboard_filtered_len = 0;
@ -4570,7 +4567,6 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
const char* buf_display_end = NULL; // We have specialized paths below for setting the length const char* buf_display_end = NULL; // We have specialized paths below for setting the length
if (is_displaying_hint) if (is_displaying_hint)
{ {
IM_IMSTR_ENSURE_HAS_END(hint);
buf_display = hint.Begin; buf_display = hint.Begin;
buf_display_end = hint.End; buf_display_end = hint.End;
} }