universal internal strlen for all char types
parent
375c014f7a
commit
a93ae710d0
|
@ -73,6 +73,13 @@ static_assert(
|
|||
"wchar_t must correspond to either char, char16_t or char32_t"
|
||||
);
|
||||
|
||||
namespace detail {
|
||||
std::size_t tstrlen(char const *p) noexcept;
|
||||
std::size_t tstrlen(char16_t const *p) noexcept;
|
||||
std::size_t tstrlen(char32_t const *p) noexcept;
|
||||
std::size_t tstrlen(wchar_t const *p) noexcept;
|
||||
}
|
||||
|
||||
/** @addtogroup Strings
|
||||
* @{
|
||||
*/
|
||||
|
@ -135,7 +142,7 @@ public:
|
|||
std::size_t N = std::extent_v<std::remove_reference_t<U>>;
|
||||
p_end = beg + N - (beg[N - 1] == '\0');
|
||||
} else {
|
||||
p_end = beg + (beg ? std::strlen(beg) : 0);
|
||||
p_end = beg + (beg ? detail::tstrlen(beg) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +188,7 @@ public:
|
|||
* The data pointed to by the argument must be zero terminated.
|
||||
*/
|
||||
basic_char_range &operator=(value_type *s) noexcept {
|
||||
p_beg = s; p_end = s + (s ? std::strlen(s) : 0); return *this;
|
||||
p_beg = s; p_end = s + (s ? detail::tstrlen(s) : 0); return *this;
|
||||
}
|
||||
|
||||
/** @brief Checks if the slice is empty. */
|
||||
|
|
|
@ -5,9 +5,57 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include "ostd/string.hh"
|
||||
#include "ostd/format.hh"
|
||||
|
||||
namespace ostd {
|
||||
namespace detail {
|
||||
|
||||
template<typename C>
|
||||
inline std::size_t tstrlen_impl(C const *p) noexcept {
|
||||
using SL = std::numeric_limits<std::size_t>;
|
||||
using UL = std::numeric_limits<std::make_unsigned_t<C>>;
|
||||
constexpr std::size_t Lbits = SL::max() / UL::max();
|
||||
constexpr std::size_t Hbits = Lbits << (UL::digits - 1);
|
||||
|
||||
C const *bp = p;
|
||||
if constexpr(sizeof(C) >= sizeof(std::size_t)) {
|
||||
goto sloop;
|
||||
}
|
||||
for (; std::uintptr_t(p) % sizeof(std::size_t); ++p) {
|
||||
if (!*p) {
|
||||
return (p - bp);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto *wp = reinterpret_cast<std::size_t const *>(p);
|
||||
for (; !(((*wp - Lbits) & ~*wp) & Hbits); ++wp) {}
|
||||
p = reinterpret_cast<C const *>(wp);
|
||||
}
|
||||
sloop:
|
||||
for (; *p; ++p) {}
|
||||
return (p - bp);
|
||||
}
|
||||
|
||||
std::size_t tstrlen(char const *p) noexcept {
|
||||
return tstrlen_impl(p);
|
||||
}
|
||||
std::size_t tstrlen(char16_t const *p) noexcept {
|
||||
return tstrlen_impl(p);
|
||||
}
|
||||
std::size_t tstrlen(char32_t const *p) noexcept {
|
||||
return tstrlen_impl(p);
|
||||
}
|
||||
std::size_t tstrlen(wchar_t const *p) noexcept {
|
||||
return tstrlen_impl(p);
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace ostd */
|
||||
|
||||
namespace ostd {
|
||||
namespace utf {
|
||||
|
||||
|
|
Loading…
Reference in New Issue