[wpilib] Make Color::HexString() constexpr (#5985)

Related improvements to wpi::ct_string:
* Implicitly convert to std::string
* Add operator== for std::string, std::string_view, and const Char*
This commit is contained in:
Tyler Veness
2023-12-04 21:20:49 -08:00
committed by GitHub
parent 2676b77873
commit 90757b9e90
7 changed files with 105 additions and 36 deletions

View File

@@ -31,7 +31,7 @@ struct ct_string {
template <size_t M>
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<Char, Traits> s) {
explicit constexpr ct_string(std::basic_string_view<Char, Traits> s) {
// avoid dependency on <algorithm>
// auto p = std::ranges::copy(s, chars.begin()).out;
auto p = chars.begin();
@@ -63,6 +63,64 @@ struct ct_string {
}
}
constexpr bool operator==(const ct_string<Char, Traits, N>&) const = default;
constexpr bool operator==(const std::basic_string<Char, Traits>& 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;
}
constexpr bool operator==(std::basic_string_view<Char, Traits> 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 <size_t M>
requires(N + 1 == M)
constexpr bool operator==(Char const (&rhs)[M]) const {
for (size_t i = 0; i < M; ++i) {
if (chars[i] != rhs[i]) {
return false;
}
}
return true;
}
constexpr bool operator==(const Char* rhs) const {
for (size_t i = 0; i < N + 1; ++i) {
if (chars[i] != rhs[i]) {
return false;
}
// If index of rhs's null terminator is less than lhs's size - 1, rhs is
// shorter than lhs
if (rhs[i] == '\0' && i < N) {
return false;
}
}
return true;
}
constexpr auto size() const noexcept { return N; }
constexpr auto begin() const noexcept { return chars.begin(); }
@@ -71,6 +129,11 @@ struct ct_string {
constexpr auto data() const noexcept { return chars.data(); }
constexpr auto c_str() const noexcept { return chars.data(); }
constexpr operator std::basic_string<Char, Traits>() // NOLINT
const noexcept {
return std::basic_string<Char, Traits>{chars.data(), N};
}
constexpr operator std::basic_string_view<Char, Traits>() // NOLINT
const noexcept {
return std::basic_string_view<Char, Traits>{chars.data(), N};
@@ -82,13 +145,13 @@ ct_string(Char const (&s)[M]) -> ct_string<Char, std::char_traits<Char>, M - 1>;
inline namespace literals {
template <ct_string S>
consteval auto operator""_ct_string() {
constexpr auto operator""_ct_string() {
return S;
}
} // namespace literals
template <typename Char, typename Traits, size_t N1, size_t N2>
consteval auto operator+(ct_string<Char, Traits, N1> const& s1,
constexpr auto operator+(ct_string<Char, Traits, N1> const& s1,
ct_string<Char, Traits, N2> const& s2) noexcept {
return Concat(s1, s2);
}
@@ -102,7 +165,7 @@ consteval auto operator+(ct_string<Char, Traits, N1> const& s1,
* @return concatenated string
*/
template <typename Char, typename Traits, size_t N1, size_t... N>
consteval auto Concat(ct_string<Char, Traits, N1> const& s1,
constexpr auto Concat(ct_string<Char, Traits, N1> const& s1,
ct_string<Char, Traits, N> const&... s) {
// Need a dummy array to instantiate a ct_string.
constexpr Char dummy[1] = {};
@@ -136,7 +199,7 @@ consteval auto Concat(ct_string<Char, Traits, N1> const& s1,
template <intmax_t N, int Base = 10, typename Char = char,
typename Traits = std::char_traits<Char>>
requires(Base >= 2 && Base <= 36)
consteval auto NumToCtString() {
constexpr auto NumToCtString() {
constexpr char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
auto buflen = [] {