13#ifndef IOX2_INCLUDE_GUARD_BB_STATIC_STRING_HPP
14#define IOX2_INCLUDE_GUARD_BB_STATIC_STRING_HPP
32template <u
int64_t Capacity>
35template <u
int64_t Capacity>
38template <
typename, u
int64_t Capacity, DoesContainInval
idContent<Capacity>, DoesContainInval
idCharacter<Capacity>>
45template <u
int64_t StringCapacity>
50template <u
int64_t StringCapacity>
64template <
typename T,
typename ReturnType>
108 : m_parent(&parent) {
120 return m_parent->m_string[index];
124 return &(m_parent->m_string[0]);
128 return &(m_parent->m_string[m_parent->m_size]);
132 return &(m_parent->m_string[0]);
135 constexpr auto c_str() const noexcept ->
char const* {
151 : m_parent(&parent) {
163 return m_parent->m_string[index];
167 return &(m_parent->m_string[0]);
171 return &(m_parent->m_string[m_parent->m_size]);
175 return &(m_parent->m_string[0]);
178 constexpr auto c_str() noexcept ->
char const* {
198 : m_parent(&parent) {
206 template <
typename T>
208 typename std::enable_if_t<IsStaticString<T>::value,
bool> {
209 auto sub_str = str.code_unit_based_substr(s_index, count);
210 if (!sub_str.has_value()) {
214 auto const sub_str_size = sub_str->size();
215 auto const new_size = m_parent->m_size + sub_str_size;
217 if (new_size > N || new_size < m_parent->m_size) {
221 if (index > m_parent->m_size) {
225 &m_parent->m_string[index], &m_parent->m_string[m_parent->m_size], &m_parent->m_string[new_size]);
226 std::copy(&sub_str->m_string[0], &sub_str->m_string[sub_str_size], &m_parent->m_string[index]);
228 m_parent->m_string[new_size] =
'\0';
229 m_parent->m_size = new_size;
245 if (index < m_parent->m_size) {
246 return m_parent->m_string[index];
255 if (!m_parent->
empty()) {
256 return m_parent->m_string[0];
265 if (!m_parent->
empty()) {
266 return m_parent->m_string[m_parent->
size() - 1];
279 if ((begin_index <= end_index) && (end_index <= m_parent->m_size)) {
280 auto const range_size = end_index - begin_index;
281 char*
const string_end = std::end(m_parent->m_string);
282 std::move(&m_parent->m_string[end_index], string_end, &m_parent->m_string[begin_index]);
283 std::fill(&m_parent->m_string[m_parent->m_size - range_size], string_end,
'\0');
284 m_parent->m_size -= range_size;
302 : m_parent(&parent) {
311 return m_parent->code_unit_based_substr(pos, count);
320 template <
typename T>
321 auto find_first_of(T
const& str,
SizeType pos = 0U)
const
323 if (pos > m_parent->m_size) {
329 for (
auto position = pos; position < m_parent->m_size; ++position) {
330 auto found = memchr(str_data, m_parent->m_string[position],
static_cast<size_t>(str_size));
331 if (found !=
nullptr) {
344 template <
typename T>
345 auto find_last_of(T
const& str,
SizeType pos = N)
const
346 -> RequireStaticStringOrCharArray<T, bb::Optional<SizeType>> {
347 if (m_parent->m_size == 0) {
351 auto position = std::min(
static_cast<uint64_t
>(pos), m_parent->m_size - 1);
354 for (; position > 0; --position) {
355 auto found = memchr(str_data, m_parent->m_string[position], str_size);
356 if (found !=
nullptr) {
360 auto found = memchr(str_data, m_parent->m_string[0],
static_cast<size_t>(str_size));
361 if (found !=
nullptr) {
378 if (index < m_parent->m_size) {
379 return m_parent->m_string[index];
388 if (!m_parent->
empty()) {
389 return m_parent->m_string[0];
398 if (!m_parent->
empty()) {
399 return m_parent->m_string[m_parent->
size() - 1];
411 char m_string[N + 1] = {};
420 template <uint64_t M, std::enable_if_t<(N > M),
bool> = true>
423 : m_size(rhs.m_size) {
424 for (
size_t i = 0; i < m_size; ++i) {
425 m_string[i] = rhs.m_string[i];
436 template <uint64_t M, std::enable_if_t<(N > M),
bool> = true>
439 for (
size_t i = 0; i < m_size; ++i) {
440 m_string[i] = rhs.m_string[i];
442 for (
size_t i = m_size; i < N; ++i) {
451 template <u
int64_t M, std::enable_if_t<(N >= (M - 1)),
bool> =
true>
454 if (utf8_str[M - 1] !=
'\0') {
458 for (uint64_t i = 0; i < M - 1; ++i) {
459 char const character = utf8_str[i];
474 while (*utf8_str !=
'\0') {
486 template <u
int64_t M, std::enable_if_t<(N >= (M - 1)),
bool> =
true>
490 for (uint64_t i = 0; i < M - 1; ++i) {
491 char const character = utf8_str[i];
492 if (character ==
'\0') {
495 ret.push_back(character);
507 auto index = std::min(
static_cast<uint64_t
>(count), N);
508 while (*utf8_str !=
'\0' && index > 0) {
509 ret.push_back(*utf8_str);
522 if ((m_size < N) && (is_valid_next(character))) {
523 m_string[m_size] = character;
527 m_string[m_size] =
'\0';
540 m_string[m_size - 1] =
'\0';
553 if ((m_size + count <= N) && (is_valid_next(character))) {
554 std::fill(&(m_string[m_size]), &(m_string[m_size + count]), character);
558 m_string[m_size] =
'\0';
571 auto const old_size =
size();
572 while (*utf8_str !=
'\0') {
574 std::fill(&m_string[old_size], &m_string[m_size],
'\0');
592 constexpr auto empty() const ->
bool {
618 return std::equal(lhs.unchecked_access().begin(),
619 lhs.unchecked_access().end(),
620 rhs.unchecked_access().begin(),
621 rhs.unchecked_access().end());
625 return !(lhs == rhs);
629 return lhs.compare(rhs) < 0;
633 return lhs.compare(rhs) <= 0;
637 return lhs.compare(rhs) > 0;
641 return lhs.compare(rhs) >= 0;
647 struct StringMemoryLayoutMetrics {
648 size_t string_alignment;
654 bool size_is_unsigned;
656 using Self = std::remove_reference_t<
decltype(*this)>;
657 ret.string_size =
sizeof(Self);
658 ret.string_alignment =
alignof(Self);
659 ret.sizeof_data =
sizeof(m_string);
660 ret.offset_data = offsetof(Self, m_string);
661 ret.sizeof_size =
sizeof(m_size);
662 ret.offset_size = offsetof(Self, m_size);
663 ret.size_is_unsigned = std::is_unsigned<
decltype(m_size)>::value;
668 auto is_valid_next(
char character)
const noexcept ->
bool {
669 constexpr char const CODE_UNIT_UPPER_BOUND = 127;
670 return (character > 0) && (character <= CODE_UNIT_UPPER_BOUND);
673 auto compare(
StaticString const& other)
const -> int64_t {
674 auto const other_size = other.size();
675 auto const res = memcmp(&m_string[0], &other.m_string[0], std::min(m_size,
static_cast<uint64_t
>(other_size)));
677 if (m_size < other_size) {
680 return ((m_size > other_size) ? 1 : 0);
686 m_string[m_size] = character;
688 m_string[m_size] =
'\0';
692 auto code_unit_based_substr(
SizeType pos,
SizeType count)
const -> bb::Optional<StaticString> {
697 auto const number_of_chars_to_end = m_size - pos;
698 auto const length = std::min(
static_cast<uint64_t
>(count), number_of_chars_to_end);
699 auto const substr_end_position = pos + length;
702 std::copy(&m_string[pos], &m_string[substr_end_position], &sub_str.m_string[0]);
703 sub_str.m_string[length] =
'\0';
704 sub_str.m_size = length;
714 stream <<
"StaticString::<" << N <<
"> { m_size: " << value.size() <<
", m_string: \""
715 << 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