Warn against Microsoft <windows.h> min and max macro (#1084)

Warn users they have defined the min/max macros which is not 
compatible with other code from the standard library or FTXUI.

Co-authored-by: Sylko Olzscher <sylko.olzscher@solostec.ch>
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
Sylko Olzscher 2025-08-17 11:18:25 +02:00 committed by GitHub
parent 8ef18ab647
commit 40e1fac3d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 141 additions and 87 deletions

View File

@ -2,3 +2,6 @@
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html # http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium BasedOnStyle: Chromium
Standard: Cpp11 Standard: Cpp11
InsertBraces: true
InsertNewlineAtEOF: true

View File

@ -133,8 +133,9 @@ int main() {
float dy = 50.f; float dy = 50.f;
ys[x] = int(dy + 20 * cos(dx * 0.14) + 10 * sin(dx * 0.42)); ys[x] = int(dy + 20 * cos(dx * 0.14) + 10 * sin(dx * 0.42));
} }
for (int x = 1; x < 99; x++) for (int x = 1; x < 99; x++) {
c.DrawPointLine(x, ys[x], x + 1, ys[x + 1]); c.DrawPointLine(x, ys[x], x + 1, ys[x + 1]);
}
return canvas(std::move(c)); return canvas(std::move(c));
}); });

View File

@ -82,10 +82,12 @@ int main() {
size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy) | size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy) |
bgcolor(Color::HSV(index * 25, 255, 255)) | bgcolor(Color::HSV(index * 25, 255, 255)) |
color(Color::Black); color(Color::Black);
if (element_xflex_grow) if (element_xflex_grow) {
element = element | xflex_grow; element = element | xflex_grow;
if (element_yflex_grow) }
if (element_yflex_grow) {
element = element | yflex_grow; element = element | yflex_grow;
}
return element; return element;
}; };
@ -119,10 +121,12 @@ int main() {
group = group | notflex; group = group | notflex;
if (!group_xflex_grow) if (!group_xflex_grow) {
group = hbox(group, filler()); group = hbox(group, filler());
if (!group_yflex_grow) }
if (!group_yflex_grow) {
group = vbox(group, filler()); group = vbox(group, filler());
}
group = group | flex; group = group | flex;
return group; return group;

View File

@ -22,10 +22,12 @@ MenuEntryOption Colored(ftxui::Color c) {
option.transform = [c](EntryState state) { option.transform = [c](EntryState state) {
state.label = (state.active ? "> " : " ") + state.label; state.label = (state.active ? "> " : " ") + state.label;
Element e = text(state.label) | color(c); Element e = text(state.label) | color(c);
if (state.focused) if (state.focused) {
e = e | inverted; e = e | inverted;
if (state.active) }
if (state.active) {
e = e | bold; e = e | bold;
}
return e; return e;
}; };
return option; return option;

View File

@ -17,8 +17,9 @@ int main() {
std::vector<std::string> entries; std::vector<std::string> entries;
int selected = 0; int selected = 0;
for (int i = 0; i < 30; ++i) for (int i = 0; i < 30; ++i) {
entries.push_back("Entry " + std::to_string(i)); entries.push_back("Entry " + std::to_string(i));
}
auto radiobox = Menu(&entries, &selected); auto radiobox = Menu(&entries, &selected);
auto renderer = Renderer(radiobox, [&] { auto renderer = Renderer(radiobox, [&] {
return radiobox->Render() | vscroll_indicator | frame | return radiobox->Render() | vscroll_indicator | frame |

View File

@ -17,8 +17,9 @@ int main() {
std::vector<std::string> entries; std::vector<std::string> entries;
int selected = 0; int selected = 0;
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i) {
entries.push_back(std::to_string(i)); entries.push_back(std::to_string(i));
}
auto radiobox = Menu(&entries, &selected, MenuOption::Horizontal()); auto radiobox = Menu(&entries, &selected, MenuOption::Horizontal());
auto renderer = Renderer( auto renderer = Renderer(
radiobox, [&] { return radiobox->Render() | hscroll_indicator | frame; }); radiobox, [&] { return radiobox->Render() | hscroll_indicator | frame; });

View File

@ -116,10 +116,12 @@ Component VMenu1(std::vector<std::string>* entries, int* selected) {
option.entries_option.transform = [](EntryState state) { option.entries_option.transform = [](EntryState state) {
state.label = (state.active ? "> " : " ") + state.label; state.label = (state.active ? "> " : " ") + state.label;
Element e = text(state.label); Element e = text(state.label);
if (state.focused) if (state.focused) {
e = e | bgcolor(Color::Blue); e = e | bgcolor(Color::Blue);
if (state.active) }
if (state.active) {
e = e | bold; e = e | bold;
}
return e; return e;
}; };
return Menu(entries, selected, option); return Menu(entries, selected, option);
@ -130,10 +132,12 @@ Component VMenu2(std::vector<std::string>* entries, int* selected) {
option.entries_option.transform = [](EntryState state) { option.entries_option.transform = [](EntryState state) {
state.label += (state.active ? " <" : " "); state.label += (state.active ? " <" : " ");
Element e = hbox(filler(), text(state.label)); Element e = hbox(filler(), text(state.label));
if (state.focused) if (state.focused) {
e = e | bgcolor(Color::Red); e = e | bgcolor(Color::Red);
if (state.active) }
if (state.active) {
e = e | bold; e = e | bold;
}
return e; return e;
}; };
return Menu(entries, selected, option); return Menu(entries, selected, option);
@ -144,13 +148,16 @@ Component VMenu3(std::vector<std::string>* entries, int* selected) {
option.entries_option.transform = [](EntryState state) { option.entries_option.transform = [](EntryState state) {
Element e = state.active ? text("[" + state.label + "]") Element e = state.active ? text("[" + state.label + "]")
: text(" " + state.label + " "); : text(" " + state.label + " ");
if (state.focused) if (state.focused) {
e = e | bold; e = e | bold;
}
if (state.focused) if (state.focused) {
e = e | color(Color::Blue); e = e | color(Color::Blue);
if (state.active) }
if (state.active) {
e = e | bold; e = e | bold;
}
return e; return e;
}; };
return Menu(entries, selected, option); return Menu(entries, selected, option);
@ -245,10 +252,12 @@ Component HMenu5(std::vector<std::string>* entries, int* selected) {
animation::easing::ElasticOut); animation::easing::ElasticOut);
option.entries_option.transform = [](EntryState state) { option.entries_option.transform = [](EntryState state) {
Element e = text(state.label) | hcenter | flex; Element e = text(state.label) | hcenter | flex;
if (state.active && state.focused) if (state.active && state.focused) {
e = e | bold; e = e | bold;
if (!state.focused && !state.active) }
if (!state.focused && !state.active) {
e = e | dim; e = e | dim;
}
return e; return e;
}; };
option.underline.color_inactive = Color::Default; option.underline.color_inactive = Color::Default;

View File

@ -20,8 +20,9 @@ using namespace ftxui;
Component DummyComponent(int id) { Component DummyComponent(int id) {
return Renderer([id](bool focused) { return Renderer([id](bool focused) {
auto t = text("component " + std::to_string(id)); auto t = text("component " + std::to_string(id));
if (focused) if (focused) {
t = t | inverted; t = t | inverted;
}
return t; return t;
}); });
} }

View File

@ -17,8 +17,9 @@ int main() {
std::vector<std::string> entries; std::vector<std::string> entries;
int selected = 0; int selected = 0;
for (int i = 0; i < 30; ++i) for (int i = 0; i < 30; ++i) {
entries.push_back("RadioBox " + std::to_string(i)); entries.push_back("RadioBox " + std::to_string(i));
}
auto radiobox = Radiobox(&entries, &selected); auto radiobox = Radiobox(&entries, &selected);
auto renderer = Renderer(radiobox, [&] { auto renderer = Renderer(radiobox, [&] {
return radiobox->Render() | vscroll_indicator | frame | return radiobox->Render() | vscroll_indicator | frame |

View File

@ -19,10 +19,11 @@ int main() {
// 1. Example of focusable renderer: // 1. Example of focusable renderer:
auto renderer_focusable = Renderer([](bool focused) { auto renderer_focusable = Renderer([](bool focused) {
if (focused) if (focused) {
return text("FOCUSABLE RENDERER()") | center | bold | border; return text("FOCUSABLE RENDERER()") | center | bold | border;
else } else {
return text(" Focusable renderer() ") | center | border; return text(" Focusable renderer() ") | center | border;
}
}); });
// 2. Examples of a non focusable renderer. // 2. Examples of a non focusable renderer.
@ -33,10 +34,11 @@ int main() {
// 3. Renderer can wrap other components to redefine their Render() function. // 3. Renderer can wrap other components to redefine their Render() function.
auto button = Button("Wrapped quit button", screen.ExitLoopClosure()); auto button = Button("Wrapped quit button", screen.ExitLoopClosure());
auto renderer_wrap = Renderer(button, [&] { auto renderer_wrap = Renderer(button, [&] {
if (button->Focused()) if (button->Focused()) {
return button->Render() | bold | color(Color::Red); return button->Render() | bold | color(Color::Red);
else } else {
return button->Render(); return button->Render();
}
}); });
// Let's renderer everyone: // Let's renderer everyone:

View File

@ -32,10 +32,12 @@ int main() {
// Plot a function: // Plot a function:
std::vector<int> ys(100); std::vector<int> ys(100);
for (int x = 0; x < 100; x++) for (int x = 0; x < 100; x++) {
ys[x] = int(80 + 20 * cos(x * 0.2)); ys[x] = int(80 + 20 * cos(x * 0.2));
for (int x = 0; x < 99; x++) }
for (int x = 0; x < 99; x++) {
c.DrawPointLine(x, ys[x], x + 1, ys[x + 1], Color::Red); c.DrawPointLine(x, ys[x], x + 1, ys[x + 1], Color::Red);
}
auto document = canvas(&c) | border; auto document = canvas(&c) | border;

View File

@ -86,8 +86,9 @@ int main() {
auto render = [&]() { auto render = [&]() {
std::vector<Element> entries; std::vector<Element> entries;
for (auto& task : displayed_task) for (auto& task : displayed_task) {
entries.push_back(renderTask(task)); entries.push_back(renderTask(task));
}
return vbox({ return vbox({
// List of tasks. // List of tasks.
@ -138,8 +139,9 @@ int main() {
std::this_thread::sleep_for(0.01s); std::this_thread::sleep_for(0.01s);
// Exit // Exit
if (nb_active + nb_queued == 0) if (nb_active + nb_queued == 0) {
break; break;
}
// Update the model for the next frame. // Update the model for the next frame.
updateModel(); updateModel();

View File

@ -21,8 +21,9 @@ int main() {
for (int index = 0; index < 200; ++index) { for (int index = 0; index < 200; ++index) {
std::vector<Element> entries; std::vector<Element> entries;
for (int i = 0; i < 23; ++i) { for (int i = 0; i < 23; ++i) {
if (i != 0) if (i != 0) {
entries.push_back(separator()); entries.push_back(separator());
}
entries.push_back( // entries.push_back( //
hbox({ hbox({
text(std::to_string(i)) | size(WIDTH, EQUAL, 2), text(std::to_string(i)) | size(WIDTH, EQUAL, 2),

View File

@ -8,6 +8,7 @@
#include <memory> // for make_shared, shared_ptr #include <memory> // for make_shared, shared_ptr
#include <utility> // for forward #include <utility> // for forward
#include <ftxui/util/warn_windows_macro.hpp>
#include "ftxui/component/component_base.hpp" // for Component, Components #include "ftxui/component/component_base.hpp" // for Component, Components
#include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, MenuOption #include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, MenuOption
#include "ftxui/dom/elements.hpp" // for Element #include "ftxui/dom/elements.hpp" // for Element

View File

@ -9,6 +9,7 @@
#include <ftxui/dom/direction.hpp> // for Direction, Direction::Left, Direction::Right, Direction::Down #include <ftxui/dom/direction.hpp> // for Direction, Direction::Left, Direction::Right, Direction::Down
#include <ftxui/dom/elements.hpp> // for Element, separator #include <ftxui/dom/elements.hpp> // for Element, separator
#include <ftxui/util/ref.hpp> // for Ref, ConstRef, StringRef #include <ftxui/util/ref.hpp> // for Ref, ConstRef, StringRef
#include <ftxui/util/warn_windows_macro.hpp>
#include <functional> // for function #include <functional> // for function
#include <string> // for string #include <string> // for string

View File

@ -4,6 +4,7 @@
#ifndef FTXUI_COMPONENT_RECEIVER_HPP_ #ifndef FTXUI_COMPONENT_RECEIVER_HPP_
#define FTXUI_COMPONENT_RECEIVER_HPP_ #define FTXUI_COMPONENT_RECEIVER_HPP_
#include <ftxui/util/warn_windows_macro.h>
#include <algorithm> // for copy, max #include <algorithm> // for copy, max
#include <atomic> // for atomic, __atomic_base #include <atomic> // for atomic, __atomic_base
#include <condition_variable> // for condition_variable #include <condition_variable> // for condition_variable

View File

@ -168,7 +168,6 @@ class ScreenInteractive : public Screen {
Component component_; Component component_;
public: public:
class Private { class Private {
public: public:

View File

@ -0,0 +1,18 @@
// Copyright 2025 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#ifndef FTXUI_UTIL_WARN_WINDOWS_MACRO_H_
#define FTXUI_UTIL_WARN_WINDOWS_MACRO_H_
#ifdef min
#error \
"The macro 'min' is defined, which conflicts with the standard C++ library and FTXUI. This is often caused by including <windows.h>. To fix this, add '#define NOMINMAX' before including <windows.h>, or pass '/DNOMINMAX' as a compiler flag."
#endif
#ifdef max
#error \
"The macro 'max' is defined, which conflicts with the standard C++ library and FTXUI. This is often caused by including <windows.h>. To fix this, add '#define NOMINMAX' before including <windows.h>, or pass '/DNOMINMAX' as a compiler flag."
#endif
#endif // FTXUI_UTIL_WARN_WINDOWS_MACRO_H_

View File

@ -23,8 +23,9 @@ bool GeneratorBool(const char*& data, size_t& size) {
std::string GeneratorString(const char*& data, size_t& size) { std::string GeneratorString(const char*& data, size_t& size) {
int index = 0; int index = 0;
while (index < size && data[index]) while (index < size && data[index]) {
++index; ++index;
}
auto out = std::string(data, data + index); auto out = std::string(data, data + index);
data += index; data += index;
@ -40,8 +41,9 @@ std::string GeneratorString(const char*& data, size_t& size) {
} }
int GeneratorInt(const char* data, size_t size) { int GeneratorInt(const char* data, size_t size) {
if (size == 0) if (size == 0) {
return 0; return 0;
}
auto out = int(data[0]); auto out = int(data[0]);
data++; data++;
size--; size--;
@ -113,8 +115,9 @@ Components GeneratorComponents(const char*& data, size_t& size, int depth);
Component GeneratorComponent(const char*& data, size_t& size, int depth) { Component GeneratorComponent(const char*& data, size_t& size, int depth) {
depth--; depth--;
int value = GeneratorInt(data, size); int value = GeneratorInt(data, size);
if (depth <= 0) if (depth <= 0) {
return Button(GeneratorString(data, size), [] {}); return Button(GeneratorString(data, size), [] {});
}
constexpr int value_max = 19; constexpr int value_max = 19;
value = (value % value_max + value_max) % value_max; value = (value % value_max + value_max) % value_max;

View File

@ -1057,8 +1057,9 @@ void ScreenInteractive::FetchTerminalEvents() {
case KEY_EVENT: { case KEY_EVENT: {
auto key_event = r.Event.KeyEvent; auto key_event = r.Event.KeyEvent;
// ignore UP key events // ignore UP key events
if (key_event.bKeyDown == FALSE) if (key_event.bKeyDown == FALSE) {
continue; continue;
}
std::wstring wstring; std::wstring wstring;
wstring += key_event.uChar.UnicodeChar; wstring += key_event.uChar.UnicodeChar;
for (auto it : to_string(wstring)) { for (auto it : to_string(wstring)) {

View File

@ -28,8 +28,9 @@ namespace {
class StdCapture { class StdCapture {
public: public:
explicit StdCapture(std::string* captured) : captured_(captured) { explicit StdCapture(std::string* captured) : captured_(captured) {
if (pipe(pipefd_) != 0) if (pipe(pipefd_) != 0) {
return; return;
}
old_stdout_ = dup(fileno(stdout)); old_stdout_ = dup(fileno(stdout));
fflush(stdout); fflush(stdout);
dup2(pipefd_[1], fileno(stdout)); dup2(pipefd_[1], fileno(stdout));

View File

@ -17,4 +17,3 @@ bool PendingTask::operator<(const PendingTask& other) const {
return time.value() > other.time.value(); return time.value() > other.time.value();
} }
} // namespace ftxui::task } // namespace ftxui::task

View File

@ -21,8 +21,7 @@ struct PendingTask {
// Delayed task with a duration // Delayed task with a duration
PendingTask(Task t, std::chrono::steady_clock::duration duration) PendingTask(Task t, std::chrono::steady_clock::duration duration)
: task(std::move(t)), : task(std::move(t)), time(std::chrono::steady_clock::now() + duration) {}
time(std::chrono::steady_clock::now() + duration) {}
/// The task to be executed. /// The task to be executed.
Task task; Task task;
@ -38,5 +37,4 @@ struct PendingTask {
} // namespace ftxui::task } // namespace ftxui::task
#endif // TASK_HPP_ #endif // TASK_HPP_

View File

@ -51,4 +51,3 @@ auto TaskQueue::Get() -> MaybeTask {
} }
} // namespace ftxui::task } // namespace ftxui::task

View File

@ -25,9 +25,7 @@ struct TaskQueue {
std::variant<Task, std::chrono::steady_clock::duration, std::monostate>; std::variant<Task, std::chrono::steady_clock::duration, std::monostate>;
auto Get() -> MaybeTask; auto Get() -> MaybeTask;
bool HasImmediateTasks() const { bool HasImmediateTasks() const { return !immediate_tasks_.empty(); }
return !immediate_tasks_.empty();
}
private: private:
std::queue<PendingTask> immediate_tasks_; std::queue<PendingTask> immediate_tasks_;
@ -36,5 +34,4 @@ struct TaskQueue {
} // namespace ftxui::task } // namespace ftxui::task
#endif #endif

View File

@ -20,7 +20,6 @@ TaskRunner::~TaskRunner() {
current_task_runner = previous_task_runner_; current_task_runner = previous_task_runner_;
} }
// static // static
auto TaskRunner::Current() -> TaskRunner* { auto TaskRunner::Current() -> TaskRunner* {
assert(current_task_runner); assert(current_task_runner);
@ -74,4 +73,3 @@ auto TaskRunner::Run() -> void {
} }
} // namespace ftxui::task } // namespace ftxui::task

View File

@ -21,8 +21,8 @@ class TaskRunner {
auto PostTask(Task task) -> void; auto PostTask(Task task) -> void;
/// Schedules a task to be executed after a certain duration. /// Schedules a task to be executed after a certain duration.
auto PostDelayedTask(Task task, auto PostDelayedTask(Task task, std::chrono::steady_clock::duration duration)
std::chrono::steady_clock::duration duration) -> void; -> void;
/// Runs the tasks in the queue, return the delay until the next delayed task /// Runs the tasks in the queue, return the delay until the next delayed task
/// can be executed. /// can be executed.
@ -31,9 +31,7 @@ class TaskRunner {
// Runs the tasks in the queue, blocking until all tasks are executed. // Runs the tasks in the queue, blocking until all tasks are executed.
auto Run() -> void; auto Run() -> void;
bool HasImmediateTasks() const { bool HasImmediateTasks() const { return queue_.HasImmediateTasks(); }
return queue_.HasImmediateTasks();
}
size_t ExecutedTasks() const { return executed_tasks_; } size_t ExecutedTasks() const { return executed_tasks_; }
@ -45,5 +43,4 @@ class TaskRunner {
} // namespace ftxui::task } // namespace ftxui::task
#endif // TASK_RUNNER_HPP #endif // TASK_RUNNER_HPP

View File

@ -17,16 +17,19 @@ namespace ftxui {
// Test char |c| to are trivially converted into |Event::Character(c)|. // Test char |c| to are trivially converted into |Event::Character(c)|.
TEST(Event, Character) { TEST(Event, Character) {
std::vector<char> basic_char; std::vector<char> basic_char;
for (char c = 'a'; c <= 'z'; ++c) for (char c = 'a'; c <= 'z'; ++c) {
basic_char.push_back(c); basic_char.push_back(c);
for (char c = 'A'; c <= 'Z'; ++c) }
for (char c = 'A'; c <= 'Z'; ++c) {
basic_char.push_back(c); basic_char.push_back(c);
}
std::vector<Event> received_events; std::vector<Event> received_events;
auto parser = TerminalInputParser( auto parser = TerminalInputParser(
[&](Event event) { received_events.push_back(std::move(event)); }); [&](Event event) { received_events.push_back(std::move(event)); });
for (char c : basic_char) for (char c : basic_char) {
parser.Add(c); parser.Add(c);
}
for (size_t i = 0; i < basic_char.size(); ++i) { for (size_t i = 0; i < basic_char.size(); ++i) {
EXPECT_TRUE(received_events[i].is_character()); EXPECT_TRUE(received_events[i].is_character());
@ -285,8 +288,9 @@ TEST(Event, UTF8) {
std::vector<Event> received_events; std::vector<Event> received_events;
auto parser = TerminalInputParser( auto parser = TerminalInputParser(
[&](Event event) { received_events.push_back(std::move(event)); }); [&](Event event) { received_events.push_back(std::move(event)); });
for (auto input : test.input) for (auto input : test.input) {
parser.Add(input); parser.Add(input);
}
if (test.valid) { if (test.valid) {
EXPECT_EQ(1, received_events.size()); EXPECT_EQ(1, received_events.size());
@ -315,8 +319,9 @@ TEST(Event, Control) {
}; };
std::vector<TestCase> cases; std::vector<TestCase> cases;
for (int i = 0; i < 32; ++i) { for (int i = 0; i < 32; ++i) {
if (i == 8 || i == 13 || i == 24 || i == 26 || i == 27) if (i == 8 || i == 13 || i == 24 || i == 26 || i == 27) {
continue; continue;
}
cases.push_back({char(i), false}); cases.push_back({char(i), false});
} }
cases.push_back({char(24), false}); cases.push_back({char(24), false});
@ -341,8 +346,9 @@ TEST(Event, Control) {
TEST(Event, Special) { TEST(Event, Special) {
auto str = [](std::string input) { auto str = [](std::string input) {
std::vector<unsigned char> output; std::vector<unsigned char> output;
for (auto it : input) for (auto it : input) {
output.push_back(it); output.push_back(it);
}
return output; return output;
}; };
@ -351,9 +357,12 @@ TEST(Event, Special) {
Event expected; Event expected;
} kTestCase[] = { } kTestCase[] = {
// Arrow (default cursor mode) // Arrow (default cursor mode)
{str(""), Event::ArrowUp}, {str(""), Event::ArrowDown}, {str(""), Event::ArrowUp},
{str(""), Event::ArrowRight}, {str(""), Event::ArrowLeft}, {str(""), Event::ArrowDown},
{str(""), Event::Home}, {str(""), Event::End}, {str(""), Event::ArrowRight},
{str(""), Event::ArrowLeft},
{str(""), Event::Home},
{str(""), Event::End},
// Arrow (application cursor mode) // Arrow (application cursor mode)
{str("\x1BOA"), Event::ArrowUp}, {str("\x1BOA"), Event::ArrowUp},

View File

@ -47,8 +47,9 @@ namespace {
#if defined(_WIN32) #if defined(_WIN32)
void WindowsEmulateVT100Terminal() { void WindowsEmulateVT100Terminal() {
static bool done = false; static bool done = false;
if (done) if (done) {
return; return;
}
done = true; done = true;
// Enable VT processing on stdout and stdin // Enable VT processing on stdout and stdin

View File

@ -1284,8 +1284,9 @@ bool IsCombining(uint32_t ucs) {
} }
bool IsFullWidth(uint32_t ucs) { bool IsFullWidth(uint32_t ucs) {
if (ucs < 0x0300) // Quick path: // NOLINT if (ucs < 0x0300) { // Quick path: // NOLINT
return false; return false;
}
return Bisearch(ucs, g_full_width_characters); return Bisearch(ucs, g_full_width_characters);
} }

View File

@ -1,4 +1,4 @@
// Copyright 2024 Arthur Sonzogni. All rights reserved. // Copyright 2025 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in
// the LICENSE file. // the LICENSE file.