From 29ff2872e3d41fe874ae8fd78d8a21b6a9cb1615 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Fri, 1 Dec 2023 14:03:15 -0800 Subject: [PATCH] [wpilib] Make Color::HexString() constexpr --- wpilibc/src/main/native/cpp/util/Color.cpp | 13 ------ .../src/main/native/cpp/util/Color8Bit.cpp | 11 ----- .../src/main/native/include/frc/util/Color.h | 12 ++++- .../main/native/include/frc/util/Color8Bit.h | 8 +++- .../test/native/cpp/util/Color8BitTest.cpp | 6 ++- .../src/test/native/cpp/util/ColorTest.cpp | 6 ++- .../src/main/native/include/wpi/ct_string.h | 44 ++++++++++++++++--- 7 files changed, 64 insertions(+), 36 deletions(-) delete mode 100644 wpilibc/src/main/native/cpp/util/Color.cpp delete mode 100644 wpilibc/src/main/native/cpp/util/Color8Bit.cpp diff --git a/wpilibc/src/main/native/cpp/util/Color.cpp b/wpilibc/src/main/native/cpp/util/Color.cpp deleted file mode 100644 index 6923c9cbec1..00000000000 --- a/wpilibc/src/main/native/cpp/util/Color.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -#include "frc/util/Color.h" - -using namespace frc; - -std::string Color::HexString() const { - return fmt::format("#{:02X}{:02X}{:02X}", static_cast(255.0 * red), - static_cast(255.0 * green), - static_cast(255.0 * blue)); -} diff --git a/wpilibc/src/main/native/cpp/util/Color8Bit.cpp b/wpilibc/src/main/native/cpp/util/Color8Bit.cpp deleted file mode 100644 index e8e46567d70..00000000000 --- a/wpilibc/src/main/native/cpp/util/Color8Bit.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -#include "frc/util/Color8Bit.h" - -using namespace frc; - -std::string Color8Bit::HexString() const { - return fmt::format("#{:02X}{:02X}{:02X}", red, green, blue); -} diff --git a/wpilibc/src/main/native/include/frc/util/Color.h b/wpilibc/src/main/native/include/frc/util/Color.h index b5855e23ce8..4ceb9cbb371 100644 --- a/wpilibc/src/main/native/include/frc/util/Color.h +++ b/wpilibc/src/main/native/include/frc/util/Color.h @@ -11,6 +11,7 @@ #include #include +#include namespace frc { @@ -851,7 +852,16 @@ class Color { * * @return a string of the format \#RRGGBB */ - std::string HexString() const; + constexpr auto HexString() const { + const int r = 255.0 * red; + const int g = 255.0 * green; + const int b = 255.0 * blue; + + return wpi::ct_string, 8>{ + {'#', wpi::hexdigit(r / 16), wpi::hexdigit(r % 16), + wpi::hexdigit(g / 16), wpi::hexdigit(g % 16), wpi::hexdigit(b / 16), + wpi::hexdigit(b % 16)}}; + } double red = 0.0; double green = 0.0; diff --git a/wpilibc/src/main/native/include/frc/util/Color8Bit.h b/wpilibc/src/main/native/include/frc/util/Color8Bit.h index 77bdc9f0ee5..af47e6e072d 100644 --- a/wpilibc/src/main/native/include/frc/util/Color8Bit.h +++ b/wpilibc/src/main/native/include/frc/util/Color8Bit.h @@ -11,6 +11,7 @@ #include #include +#include #include "Color.h" @@ -107,7 +108,12 @@ class Color8Bit { * * @return a string of the format \#RRGGBB */ - std::string HexString() const; + constexpr auto HexString() const { + return wpi::ct_string, 8>{ + {'#', wpi::hexdigit(red / 16), wpi::hexdigit(red % 16), + wpi::hexdigit(green / 16), wpi::hexdigit(green % 16), + wpi::hexdigit(blue / 16), wpi::hexdigit(blue % 16)}}; + } int red = 0; int green = 0; diff --git a/wpilibc/src/test/native/cpp/util/Color8BitTest.cpp b/wpilibc/src/test/native/cpp/util/Color8BitTest.cpp index e0b26dd5790..733c43a3dc6 100644 --- a/wpilibc/src/test/native/cpp/util/Color8BitTest.cpp +++ b/wpilibc/src/test/native/cpp/util/Color8BitTest.cpp @@ -56,7 +56,9 @@ TEST(Color8BitTest, ImplicitConversionToColor) { } TEST(Color8BitTest, ToHexString) { - constexpr frc::Color8Bit color{255, 128, 64}; + constexpr frc::Color8Bit color1{255, 128, 64}; + EXPECT_EQ("#FF8040", color1.HexString()); - EXPECT_EQ("#FF8040", color.HexString()); + frc::Color8Bit color2{255, 128, 64}; + EXPECT_EQ("#FF8040", color2.HexString()); } diff --git a/wpilibc/src/test/native/cpp/util/ColorTest.cpp b/wpilibc/src/test/native/cpp/util/ColorTest.cpp index c76c7f1da29..6722e858ca5 100644 --- a/wpilibc/src/test/native/cpp/util/ColorTest.cpp +++ b/wpilibc/src/test/native/cpp/util/ColorTest.cpp @@ -56,7 +56,9 @@ TEST(ColorTest, FromHSV) { } TEST(ColorTest, ToHexString) { - constexpr frc::Color color{255, 128, 64}; + constexpr frc::Color color1{255, 128, 64}; + EXPECT_EQ("#FF8040", color1.HexString()); - EXPECT_EQ("#FF8040", color.HexString()); + frc::Color color2{255, 128, 64}; + EXPECT_EQ("#FF8040", color2.HexString()); } diff --git a/wpiutil/src/main/native/include/wpi/ct_string.h b/wpiutil/src/main/native/include/wpi/ct_string.h index 9f0ef907508..4d3d9dc757d 100644 --- a/wpiutil/src/main/native/include/wpi/ct_string.h +++ b/wpiutil/src/main/native/include/wpi/ct_string.h @@ -31,7 +31,7 @@ struct ct_string { template requires(M <= (N + 1)) - consteval ct_string(Char const (&s)[M]) { // NOLINT + constexpr ct_string(Char const (&s)[M]) { // NOLINT if constexpr (M == (N + 1)) { if (s[N] != Char{}) { throw std::logic_error{"char array not null terminated"}; @@ -50,7 +50,7 @@ struct ct_string { } } - explicit consteval ct_string(std::basic_string_view s) { + explicit constexpr ct_string(std::basic_string_view s) { // avoid dependency on // auto p = std::ranges::copy(s, chars.begin()).out; auto p = chars.begin(); @@ -63,6 +63,38 @@ struct ct_string { } } + constexpr bool operator==(const ct_string&) const = default; + + constexpr bool operator==( + const std::basic_string_view& rhs) const { + if (size() != rhs.size()) { + return false; + } + + for (size_t i = 0; i < size(); ++i) { + if (chars[i] != rhs[i]) { + return false; + } + } + + return true; + } + + template + constexpr bool operator==(Char const (&rhs)[M]) const { + if (size() != M) { + return false; + } + + for (size_t i = 0; i < size(); ++i) { + if (chars[i] != rhs[i]) { + return false; + } + } + + return true; + } + constexpr auto size() const noexcept { return N; } constexpr auto begin() const noexcept { return chars.begin(); } @@ -82,13 +114,13 @@ ct_string(Char const (&s)[M]) -> ct_string, M - 1>; inline namespace literals { template -consteval auto operator""_ct_string() { +constexpr auto operator""_ct_string() { return S; } } // namespace literals template -consteval auto operator+(ct_string const& s1, +constexpr auto operator+(ct_string const& s1, ct_string const& s2) noexcept { return Concat(s1, s2); } @@ -102,7 +134,7 @@ consteval auto operator+(ct_string const& s1, * @return concatenated string */ template -consteval auto Concat(ct_string const& s1, +constexpr auto Concat(ct_string const& s1, ct_string const&... s) { // Need a dummy array to instantiate a ct_string. constexpr Char dummy[1] = {}; @@ -136,7 +168,7 @@ consteval auto Concat(ct_string const& s1, template > requires(Base >= 2 && Base <= 36) -consteval auto NumToCtString() { +constexpr auto NumToCtString() { constexpr char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; auto buflen = [] {