13#ifndef IOX2_INCLUDE_GUARD_BB_STATIC_STRING_HPP
14#define IOX2_INCLUDE_GUARD_BB_STATIC_STRING_HPP
31template <u
int64_t Capacity>
34template <u
int64_t Capacity>
37template <
typename, u
int64_t Capacity, DoesContainInval
idContent<Capacity>, DoesContainInval
idCharacter<Capacity>>
44template <u
int64_t StringCapacity>
49template <u
int64_t StringCapacity>
63template <
typename T,
typename ReturnType>
107 : m_parent(&parent) {
119 return m_parent->m_string[index];
123 return &(m_parent->m_string[0]);
127 return &(m_parent->m_string[m_parent->m_size]);
131 return &(m_parent->m_string[0]);
134 constexpr auto c_str() const noexcept ->
char const* {
150 : m_parent(&parent) {
162 return m_parent->m_string[index];
166 return &(m_parent->m_string[0]);
170 return &(m_parent->m_string[m_parent->m_size]);
174 return &(m_parent->m_string[0]);
177 constexpr auto c_str() noexcept ->
char const* {
197 : m_parent(&parent) {
205 template <
typename T>
207 typename std::enable_if_t<IsStaticString<T>::value,
bool> {
208 auto sub_str = str.code_unit_based_substr(s_index, count);
209 if (!sub_str.has_value()) {
213 auto const sub_str_size = sub_str->size();
214 auto const new_size = m_parent->m_size + sub_str_size;
216 if (new_size > N || new_size < m_parent->m_size) {
220 if (index > m_parent->m_size) {
224 &m_parent->m_string[index], &m_parent->m_string[m_parent->m_size], &m_parent->m_string[new_size]);
225 std::copy(&sub_str->m_string[0], &sub_str->m_string[sub_str_size], &m_parent->m_string[index]);
227 m_parent->m_string[new_size] =
'\0';
228 m_parent->m_size = new_size;
244 if (index < m_parent->m_size) {
245 return m_parent->m_string[index];
254 if (!m_parent->
empty()) {
255 return m_parent->m_string[0];
264 if (!m_parent->
empty()) {
265 return m_parent->m_string[m_parent->
size() - 1];
278 if ((begin_index <= end_index) && (end_index <= m_parent->m_size)) {
279 auto const range_size = end_index - begin_index;
280 char*
const string_end = std::end(m_parent->m_string);
281 std::move(&m_parent->m_string[end_index], string_end, &m_parent->m_string[begin_index]);
282 std::fill(&m_parent->m_string[m_parent->m_size - range_size], string_end,
'\0');
283 m_parent->m_size -= range_size;
301 : m_parent(&parent) {
310 return m_parent->code_unit_based_substr(pos, count);
319 template <
typename T>
320 auto find_first_of(T
const& str,
SizeType pos = 0U)
const
322 if (pos > m_parent->m_size) {
328 for (
auto position = pos; position < m_parent->m_size; ++position) {
329 auto found = memchr(str_data, m_parent->m_string[position],
static_cast<size_t>(str_size));
330 if (found !=
nullptr) {
343 template <
typename T>
344 auto find_last_of(T
const& str,
SizeType pos = N)
const
345 -> RequireStaticStringOrCharArray<T, bb::Optional<SizeType>> {
346 if (m_parent->m_size == 0) {
350 auto position = std::min(
static_cast<uint64_t
>(pos), m_parent->m_size - 1);
353 for (; position > 0; --position) {
354 auto found = memchr(str_data, m_parent->m_string[position], str_size);
355 if (found !=
nullptr) {
359 auto found = memchr(str_data, m_parent->m_string[0],
static_cast<size_t>(str_size));
360 if (found !=
nullptr) {
377 if (index < m_parent->m_size) {
378 return m_parent->m_string[index];
387 if (!m_parent->
empty()) {
388 return m_parent->m_string[0];
397 if (!m_parent->
empty()) {
398 return m_parent->m_string[m_parent->
size() - 1];
410 char m_string[N + 1] = {};
419 template <uint64_t M, std::enable_if_t<(N > M),
bool> = true>
422 : m_size(rhs.m_size) {
423 for (
size_t i = 0; i < m_size; ++i) {
424 m_string[i] = rhs.m_string[i];
435 template <uint64_t M, std::enable_if_t<(N > M),
bool> = true>
438 for (
size_t i = 0; i < m_size; ++i) {
439 m_string[i] = rhs.m_string[i];
441 for (
size_t i = m_size; i < N; ++i) {
450 template <u
int64_t M, std::enable_if_t<(N >= (M - 1)),
bool> =
true>
453 if (utf8_str[M - 1] !=
'\0') {
457 for (uint64_t i = 0; i < M - 1; ++i) {
458 char const character = utf8_str[i];
473 while (*utf8_str !=
'\0') {
485 template <u
int64_t M, std::enable_if_t<(N >= (M - 1)),
bool> =
true>
489 for (uint64_t i = 0; i < M - 1; ++i) {
490 char const character = utf8_str[i];
491 if (character ==
'\0') {
494 ret.push_back(character);
506 auto index = std::min(
static_cast<uint64_t
>(count), N);
507 while (*utf8_str !=
'\0' && index > 0) {
508 ret.push_back(*utf8_str);
521 if ((m_size < N) && (is_valid_next(character))) {
522 m_string[m_size] = character;
526 m_string[m_size] =
'\0';
539 m_string[m_size - 1] =
'\0';
552 if ((m_size + count <= N) && (is_valid_next(character))) {
553 std::fill(&(m_string[m_size]), &(m_string[m_size + count]), character);
557 m_string[m_size] =
'\0';
570 auto const old_size =
size();
571 while (*utf8_str !=
'\0') {
573 std::fill(&m_string[old_size], &m_string[m_size],
'\0');
591 constexpr auto empty() const ->
bool {
617 return std::equal(lhs.unchecked_access().begin(),
618 lhs.unchecked_access().end(),
619 rhs.unchecked_access().begin(),
620 rhs.unchecked_access().end());
624 return !(lhs == rhs);
628 return lhs.compare(rhs) < 0;
632 return lhs.compare(rhs) <= 0;
636 return lhs.compare(rhs) > 0;
640 return lhs.compare(rhs) >= 0;
646 struct StringMemoryLayoutMetrics {
647 size_t string_alignment;
653 bool size_is_unsigned;
655 using Self = std::remove_reference_t<
decltype(*this)>;
656 ret.string_size =
sizeof(Self);
657 ret.string_alignment =
alignof(Self);
658 ret.sizeof_data =
sizeof(m_string);
659 ret.offset_data = offsetof(Self, m_string);
660 ret.sizeof_size =
sizeof(m_size);
661 ret.offset_size = offsetof(Self, m_size);
662 ret.size_is_unsigned = std::is_unsigned<
decltype(m_size)>::value;
667 auto is_valid_next(
char character)
const noexcept ->
bool {
668 constexpr char const CODE_UNIT_UPPER_BOUND = 127;
669 return (character > 0) && (character <= CODE_UNIT_UPPER_BOUND);
672 auto compare(
StaticString const& other)
const -> int64_t {
673 auto const other_size = other.size();
674 auto const res = memcmp(&m_string[0], &other.m_string[0], std::min(m_size,
static_cast<uint64_t
>(other_size)));
676 if (m_size < other_size) {
679 return ((m_size > other_size) ? 1 : 0);
685 m_string[m_size] = character;
687 m_string[m_size] =
'\0';
690 auto code_unit_based_substr(
SizeType pos,
SizeType count)
const -> bb::Optional<StaticString> {
695 auto const length = std::min(
static_cast<uint64_t
>(count), m_size - pos);
697 std::copy(&m_string[pos], &m_string[pos + length], &sub_str.m_string[0]);
698 sub_str.m_string[length] =
'\0';
699 sub_str.m_size = length;
709 stream <<
"StaticString::<" << N <<
"> { m_size: " << value.size() <<
", m_string: \""
710 << value.unchecked_access().c_str() <<
"\" }";
#define IOX2_CONSTEXPR_DTOR
The SemanticString is a string which has an inner syntax and restrictions to valid content....
This class provides the interface for accessing individual code units of the string.
ConstAccessorCodeUnits(ConstAccessorCodeUnits &&)=default
auto front_element() const noexcept -> OptionalConstCodeUnitReference
auto operator=(ConstAccessorCodeUnits const &) -> ConstAccessorCodeUnits &=delete
auto operator=(ConstAccessorCodeUnits &&) -> ConstAccessorCodeUnits &=delete
auto back_element() const noexcept -> OptionalConstCodeUnitReference
~ConstAccessorCodeUnits()=default
ConstAccessorCodeUnits(ConstAccessorCodeUnits const &)=delete
auto element_at(SizeType index) const noexcept -> OptionalConstCodeUnitReference
~UncheckedAccessorCodeUnits()=default
auto operator=(UncheckedAccessorCodeUnits &&) -> UncheckedAccessorCodeUnits &=delete
auto element_at(SizeType index) noexcept -> OptionalCodeUnitReference
UncheckedAccessorCodeUnits(UncheckedAccessorCodeUnits &&)=default
auto try_erase_at(SizeType index) noexcept -> bool
Removes a single code unit at index.
auto front_element() noexcept -> OptionalCodeUnitReference
auto operator=(UncheckedAccessorCodeUnits const &) -> UncheckedAccessorCodeUnits &=delete
UncheckedAccessorCodeUnits(UncheckedAccessorCodeUnits const &)=delete
auto try_erase_at(SizeType begin_index, SizeType end_index) noexcept -> bool
Removes the range of code units at [begin_index, end_index).
auto back_element() noexcept -> OptionalCodeUnitReference
constexpr auto c_str() noexcept -> char const *
auto operator=(UncheckedAccessor const &) -> UncheckedAccessor &=delete
constexpr auto begin() noexcept -> Iterator
constexpr auto end() noexcept -> Iterator
UncheckedAccessor(UncheckedAccessor &&)=default
~UncheckedAccessor()=default
constexpr auto operator[](SizeType index) -> Reference
auto operator=(UncheckedAccessor &&) -> UncheckedAccessor &=delete
constexpr auto data() noexcept -> Pointer
UncheckedAccessor(UncheckedAccessor const &)=delete
constexpr auto operator[](SizeType index) const -> ConstReference
constexpr auto begin() const noexcept -> ConstIterator
auto operator=(UncheckedConstAccessor &&) -> UncheckedConstAccessor &=delete
UncheckedConstAccessor(UncheckedConstAccessor const &)=delete
constexpr auto c_str() const noexcept -> char const *
auto operator=(UncheckedConstAccessor const &) -> UncheckedConstAccessor &=delete
constexpr auto data() const noexcept -> ConstPointer
UncheckedConstAccessor(UncheckedConstAccessor &&)=default
constexpr auto end() const noexcept -> ConstIterator
~UncheckedConstAccessor()=default
IOX2_CONSTEXPR_DTOR ~StaticString()=default
char const * ConstPointer
constexpr auto operator=(StaticString &&) noexcept -> StaticString &=default
static auto from_utf8(char const (&utf8_str)[M]) noexcept -> bb::Optional< StaticString >
static constexpr auto capacity() noexcept -> SizeType
constexpr auto operator=(StaticString const &) noexcept -> StaticString &=default
static auto from_utf8_unchecked(char const (&utf8_str)[M]) noexcept -> StaticString
char const & ConstReference
constexpr auto try_append_utf8_null_terminated_unchecked(char const *utf8_str) -> bool
bb::Optional< std::reference_wrapper< CodeUnitValueType const > > OptionalConstCodeUnitReference
friend auto operator<=(StaticString const &lhs, StaticString const &rhs) -> bool
static auto from_utf8_null_terminated_unchecked_truncated(char const *utf8_str, SizeType count) -> StaticString
bb::Optional< std::reference_wrapper< CodeUnitValueType > > OptionalCodeUnitReference
constexpr auto try_append(SizeType count, CodeUnitValueType character) noexcept -> bool
friend auto operator!=(StaticString const &lhs, StaticString const &rhs) -> bool
friend auto operator>=(StaticString const &lhs, StaticString const &rhs) -> bool
constexpr auto try_pop_back() noexcept -> bool
auto code_units() const -> ConstAccessorCodeUnits
Immutable access to the string contents on a per-code-unit basis.
friend auto operator<(StaticString const &lhs, StaticString const &rhs) -> bool
static auto from_utf8_null_terminated_unchecked(char const *utf8_str) -> bb::Optional< StaticString >
auto unchecked_access() const -> UncheckedConstAccessor
Unchecked immutable access to the string contents.
constexpr auto try_push_back(CodeUnitValueType character) noexcept -> bool
ConstPointer ConstIterator
constexpr auto size() const noexcept -> SizeType
friend auto operator>(StaticString const &lhs, StaticString const &rhs) -> bool
auto unchecked_access() -> UncheckedAccessor
Unchecked mutable access to the string contents.
friend class StaticString
friend auto operator==(StaticString const &lhs, StaticString const &rhs) -> bool
bb::Optional< std::reference_wrapper< char const > > OptionalConstReference
constexpr auto empty() const -> bool
auto unchecked_code_units() -> UncheckedAccessorCodeUnits
Unchecked mutable access to the string contents on a per-code-unit basis.
bb::Optional< std::reference_wrapper< char > > OptionalReference
char32_t CodePointValueType
constexpr StaticString() noexcept=default
constexpr auto static_memory_layout_metrics() noexcept
auto is_valid_path_to_directory(const bb::StaticString< StringCapacity > &name) noexcept -> bool
returns true if the provided name is a valid path, otherwise false
auto is_valid_path_to_file(const bb::StaticString< StringCapacity > &name) noexcept -> bool
verifies if the given string is a valid path to a file
auto get_size(const StaticString< N > &data) -> uint64_t
auto get_data(const StaticString< N > &data) -> const char *
constexpr NulloptT NULLOPT
bool(*)(const StaticString< Capacity > &value) DoesContainInvalidCharacter
iox2::bb::variation::Optional< T > Optional
bool(*)(const StaticString< Capacity > &value) DoesContainInvalidContent
typename std::enable_if_t< IsStaticString< T >::value||legacy::is_char_array< T >::value, ReturnType > RequireStaticStringOrCharArray
auto operator<<(std::ostream &stream, const iox2::bb::StaticString< N > &value) -> std::ostream &
struct to check whether an argument is a char array