iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
static_string.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13#ifndef IOX2_INCLUDE_GUARD_BB_STATIC_STRING_HPP
14#define IOX2_INCLUDE_GUARD_BB_STATIC_STRING_HPP
15
18#include "iox2/bb/optional.hpp"
20
21#include <algorithm>
22#include <cassert>
23#include <cstddef>
24#include <cstdint>
25#include <cstring>
26#include <functional>
27#include <ostream>
28#include <type_traits>
29
30namespace iox2 {
31namespace bb {
32template <uint64_t Capacity>
34
35template <uint64_t Capacity>
37
38template <typename, uint64_t Capacity, DoesContainInvalidContent<Capacity>, DoesContainInvalidCharacter<Capacity>>
39class SemanticString;
40
41namespace detail {
45template <uint64_t StringCapacity>
46auto is_valid_path_to_file(const StaticString<StringCapacity>& name) noexcept -> bool;
47
50template <uint64_t StringCapacity>
51auto is_valid_path_to_directory(const StaticString<StringCapacity>& name) noexcept -> bool;
52
53} // namespace detail
54
55template <uint64_t>
56class StaticString;
57
58template <typename>
59struct IsStaticString : std::false_type { };
60
61template <uint64_t N>
62struct IsStaticString<StaticString<N>> : std::true_type { };
63
64template <typename T, typename ReturnType>
66 typename std::enable_if_t<IsStaticString<T>::value || legacy::is_char_array<T>::value, ReturnType>;
67
80template <uint64_t N>
82 public:
83 using ValueType = char;
84 using CodeUnitValueType = char;
85 using CodePointValueType = char32_t;
86 using SizeType = size_t;
87 using DifferenceType = ptrdiff_t;
88 using Reference = char&;
89 using ConstReference = char const&;
90 using Pointer = char*;
91 using ConstPointer = char const*;
98
102 friend class StaticString;
103
104 private:
105 StaticString const* m_parent;
106
107 constexpr explicit UncheckedConstAccessor(StaticString const& parent)
108 : m_parent(&parent) {
109 }
110
111 public:
114 // NOTE: can be changed to '= delete' when C++17 becomes mandatory and we can rely on RVO
118
119 constexpr auto operator[](SizeType index) const -> ConstReference {
120 return m_parent->m_string[index];
121 }
122
123 constexpr auto begin() const noexcept -> ConstIterator {
124 return &(m_parent->m_string[0]);
125 }
126
127 constexpr auto end() const noexcept -> ConstIterator {
128 return &(m_parent->m_string[m_parent->m_size]);
129 }
130
131 constexpr auto data() const noexcept -> ConstPointer {
132 return &(m_parent->m_string[0]);
133 }
134
135 constexpr auto c_str() const noexcept -> char const* {
136 return data();
137 }
138 };
139
145 friend class StaticString;
146
147 private:
148 StaticString* m_parent;
149
150 constexpr explicit UncheckedAccessor(StaticString& parent)
151 : m_parent(&parent) {
152 }
153
154 public:
157 // NOTE: can be changed to '= delete' when C++17 becomes mandatory and we can rely on RVO
161
162 constexpr auto operator[](SizeType index) -> Reference {
163 return m_parent->m_string[index];
164 }
165
166 constexpr auto begin() noexcept -> Iterator {
167 return &(m_parent->m_string[0]);
168 }
169
170 constexpr auto end() noexcept -> Iterator {
171 return &(m_parent->m_string[m_parent->m_size]);
172 }
173
174 constexpr auto data() noexcept -> Pointer {
175 return &(m_parent->m_string[0]);
176 }
177
178 constexpr auto c_str() noexcept -> char const* {
179 return data();
180 }
181 };
182
187 friend class StaticString;
188 template <typename,
189 uint64_t Capacity,
192 friend class bb::SemanticString;
193
194 private:
195 StaticString* m_parent;
196
197 constexpr explicit UncheckedAccessorCodeUnits(StaticString& parent)
198 : m_parent(&parent) {
199 }
200
206 template <typename T>
207 auto insert(SizeType index, T const& str, SizeType s_index, SizeType count = T::capacity()) ->
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()) {
211 return false;
212 }
213
214 auto const sub_str_size = sub_str->size();
215 auto const new_size = m_parent->m_size + sub_str_size;
216 // check if the new size would exceed capacity or a size overflow occured
217 if (new_size > N || new_size < m_parent->m_size) {
218 return false;
219 }
220
221 if (index > m_parent->m_size) {
222 return false;
223 }
224 std::copy_backward(
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]);
227
228 m_parent->m_string[new_size] = '\0';
229 m_parent->m_size = new_size;
230
231 return true;
232 }
233
234 public:
237 // NOTE: can be changed to '= delete' when C++17 becomes mandatory and we can rely on RVO
241
245 if (index < m_parent->m_size) {
246 return m_parent->m_string[index];
247 } else {
248 return bb::NULLOPT;
249 }
250 }
251
255 if (!m_parent->empty()) {
256 return m_parent->m_string[0];
257 } else {
258 return bb::NULLOPT;
259 }
260 }
261
265 if (!m_parent->empty()) {
266 return m_parent->m_string[m_parent->size() - 1];
267 } else {
268 return bb::NULLOPT;
269 }
270 }
271
273 auto try_erase_at(SizeType index) noexcept -> bool {
274 return try_erase_at(index, index + 1);
275 }
276
278 auto try_erase_at(SizeType begin_index, SizeType end_index) noexcept -> bool {
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;
285 return true;
286 } else {
287 return false;
288 }
289 }
290 };
291
294 friend class StaticString;
295 friend auto bb::detail::is_valid_path_to_file<N>(const bb::StaticString<N>& name) noexcept -> bool;
296 friend auto bb::detail::is_valid_path_to_directory<N>(const bb::StaticString<N>& name) noexcept -> bool;
297
298 private:
299 StaticString const* m_parent;
300
301 constexpr explicit ConstAccessorCodeUnits(StaticString const& parent)
302 : m_parent(&parent) {
303 }
304
310 auto substr(SizeType pos, SizeType count) const -> bb::Optional<StaticString> {
311 return m_parent->code_unit_based_substr(pos, count);
312 }
313
320 template <typename T>
321 auto find_first_of(T const& str, SizeType pos = 0U) const
323 if (pos > m_parent->m_size) {
324 return bb::NULLOPT;
325 }
326
327 auto str_data = detail::get_data(str);
328 auto str_size = detail::get_size(str);
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) {
332 return position;
333 }
334 }
335 return bb::NULLOPT;
336 }
337
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) {
348 return bb::NULLOPT;
349 }
350
351 auto position = std::min(static_cast<uint64_t>(pos), m_parent->m_size - 1);
352 auto str_data = detail::get_data(str);
353 auto str_size = detail::get_size(str);
354 for (; position > 0; --position) {
355 auto found = memchr(str_data, m_parent->m_string[position], str_size);
356 if (found != nullptr) {
357 return position;
358 }
359 }
360 auto found = memchr(str_data, m_parent->m_string[0], static_cast<size_t>(str_size));
361 if (found != nullptr) {
362 return 0U;
363 }
364 return bb::NULLOPT;
365 }
366
367 public:
370 // NOTE: can be changed to '= delete' when C++17 becomes mandatory and we can rely on RVO
374
377 auto element_at(SizeType index) const noexcept -> OptionalConstCodeUnitReference {
378 if (index < m_parent->m_size) {
379 return m_parent->m_string[index];
380 } else {
381 return bb::NULLOPT;
382 }
383 }
384
388 if (!m_parent->empty()) {
389 return m_parent->m_string[0];
390 } else {
391 return bb::NULLOPT;
392 }
393 }
394
398 if (!m_parent->empty()) {
399 return m_parent->m_string[m_parent->size() - 1];
400 } else {
401 return bb::NULLOPT;
402 }
403 }
404 };
405
406 private:
407 template <uint64_t>
408 friend class StaticString;
409
410 // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) encapsulated storage
411 char m_string[N + 1] = {};
412 uint64_t m_size = 0;
413
414 public:
415 // constructors
416 constexpr StaticString() noexcept = default;
417 constexpr StaticString(StaticString const&) noexcept = default;
418 constexpr StaticString(StaticString&&) noexcept = default;
419
420 template <uint64_t M, std::enable_if_t<(N > M), bool> = true>
421 // NOLINTNEXTLINE(hicpp-explicit-conversions), conceptually a copy constructor
422 constexpr StaticString(StaticString<M> const& rhs)
423 : m_size(rhs.m_size) {
424 for (size_t i = 0; i < m_size; ++i) {
425 m_string[i] = rhs.m_string[i];
426 }
427 }
428
429 // destructor
431
432 // assignment
433 constexpr auto operator=(StaticString const&) noexcept -> StaticString& = default;
434 constexpr auto operator=(StaticString&&) noexcept -> StaticString& = default;
435
436 template <uint64_t M, std::enable_if_t<(N > M), bool> = true>
437 constexpr auto operator=(StaticString<M> const& rhs) noexcept -> StaticString& {
438 m_size = rhs.m_size;
439 for (size_t i = 0; i < m_size; ++i) {
440 m_string[i] = rhs.m_string[i];
441 }
442 for (size_t i = m_size; i < N; ++i) {
443 m_string[i] = '\0';
444 }
445 return *this;
446 }
447
451 template <uint64_t M, std::enable_if_t<(N >= (M - 1)), bool> = true>
452 // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) statically bounds checked
453 static auto from_utf8(char const (&utf8_str)[M]) noexcept -> bb::Optional<StaticString> {
454 if (utf8_str[M - 1] != '\0') {
455 return bb::NULLOPT;
456 }
457 StaticString ret;
458 for (uint64_t i = 0; i < M - 1; ++i) {
459 char const character = utf8_str[i];
460 if (!ret.try_push_back(character)) {
461 return bb::NULLOPT;
462 }
463 }
464 return ret;
465 }
466
473 StaticString ret;
474 while (*utf8_str != '\0') {
475 if (!ret.try_push_back(*utf8_str)) {
476 return bb::NULLOPT;
477 }
478 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic), unchecked access into c-style string
479 ++utf8_str;
480 }
481 return ret;
482 }
483
486 template <uint64_t M, std::enable_if_t<(N >= (M - 1)), bool> = true>
487 // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) statically bounds checked
488 static auto from_utf8_unchecked(char const (&utf8_str)[M]) noexcept -> StaticString {
489 StaticString ret;
490 for (uint64_t i = 0; i < M - 1; ++i) {
491 char const character = utf8_str[i];
492 if (character == '\0') {
493 break;
494 }
495 ret.push_back(character);
496 }
497 return ret;
498 }
499
505 static auto from_utf8_null_terminated_unchecked_truncated(char const* utf8_str, SizeType count) -> StaticString {
506 StaticString ret;
507 auto index = std::min(static_cast<uint64_t>(count), N);
508 while (*utf8_str != '\0' && index > 0) {
509 ret.push_back(*utf8_str);
510 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic), unchecked access into c-style string
511 ++utf8_str;
512 --index;
513 }
514 return ret;
515 }
516
521 constexpr auto try_push_back(CodeUnitValueType character) noexcept -> bool {
522 if ((m_size < N) && (is_valid_next(character))) {
523 m_string[m_size] = character;
524 ++m_size;
525 // we explicitly write the terminator here, as the rust string
526 // may contain non-null characters after the end
527 m_string[m_size] = '\0';
528 return true;
529 } else {
530 return false;
531 }
532 }
533
538 constexpr auto try_pop_back() noexcept -> bool {
539 if (m_size > 0) {
540 m_string[m_size - 1] = '\0';
541 --m_size;
542 return true;
543 } else {
544 return false;
545 }
546 }
547
552 constexpr auto try_append(SizeType count, CodeUnitValueType character) noexcept -> bool {
553 if ((m_size + count <= N) && (is_valid_next(character))) {
554 std::fill(&(m_string[m_size]), &(m_string[m_size + count]), character);
555 m_size += count;
556 // we explicitly write the terminator here, as the rust string
557 // may contain non-null characters after the end
558 m_string[m_size] = '\0';
559 return true;
560 } else {
561 return false;
562 }
563 }
564
570 constexpr auto try_append_utf8_null_terminated_unchecked(char const* utf8_str) -> bool {
571 auto const old_size = size();
572 while (*utf8_str != '\0') {
573 if (!try_push_back(*utf8_str)) {
574 std::fill(&m_string[old_size], &m_string[m_size], '\0');
575 m_size = old_size;
576 return false;
577 }
578 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic), unchecked access into c-style string
579 ++utf8_str;
580 }
581 return true;
582 }
583
584 static constexpr auto capacity() noexcept -> SizeType {
585 return N;
586 }
587
588 constexpr auto size() const noexcept -> SizeType {
589 return m_size;
590 }
591
592 constexpr auto empty() const -> bool {
593 return size() == 0;
594 }
595
600
603 return ConstAccessorCodeUnits { *this };
604 }
605
608 return UncheckedAccessor { *this };
609 }
610
613 return UncheckedConstAccessor { *this };
614 }
615
616 // comparison operators
617 friend auto operator==(StaticString const& lhs, StaticString const& rhs) -> bool {
618 return std::equal(lhs.unchecked_access().begin(),
619 lhs.unchecked_access().end(),
620 rhs.unchecked_access().begin(),
621 rhs.unchecked_access().end());
622 }
623
624 friend auto operator!=(StaticString const& lhs, StaticString const& rhs) -> bool {
625 return !(lhs == rhs);
626 }
627
628 friend auto operator<(StaticString const& lhs, StaticString const& rhs) -> bool {
629 return lhs.compare(rhs) < 0;
630 }
631
632 friend auto operator<=(StaticString const& lhs, StaticString const& rhs) -> bool {
633 return lhs.compare(rhs) <= 0;
634 }
635
636 friend auto operator>(StaticString const& lhs, StaticString const& rhs) -> bool {
637 return lhs.compare(rhs) > 0;
638 }
639
640 friend auto operator>=(StaticString const& lhs, StaticString const& rhs) -> bool {
641 return lhs.compare(rhs) >= 0;
642 }
643
646 constexpr auto static_memory_layout_metrics() noexcept {
647 struct StringMemoryLayoutMetrics {
648 size_t string_alignment;
649 size_t string_size;
650 size_t sizeof_data;
651 size_t offset_data;
652 size_t sizeof_size;
653 size_t offset_size;
654 bool size_is_unsigned;
655 } ret;
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;
664 return ret;
665 }
666
667 private:
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);
671 }
672
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)));
676 if (res == 0) {
677 if (m_size < other_size) {
678 return -1;
679 }
680 return ((m_size > other_size) ? 1 : 0);
681 }
682 return res;
683 }
684
685 constexpr void push_back(CodeUnitValueType character) noexcept {
686 m_string[m_size] = character;
687 ++m_size;
688 m_string[m_size] = '\0';
689 }
690
691 // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) private method, only used internally
692 auto code_unit_based_substr(SizeType pos, SizeType count) const -> bb::Optional<StaticString> {
693 if (pos > m_size) {
694 return bb::NULLOPT;
695 }
696
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;
700 StaticString sub_str;
701 // NOLINTNEXTLINE(clang-analyzer-security.ArrayBound) false positive; it is ensured that 'substr_end_position' does not exceed the buffer
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;
705 return sub_str;
706 }
707};
708
709} // namespace bb
710} // namespace iox2
711
712template <uint64_t N>
713auto operator<<(std::ostream& stream, const iox2::bb::StaticString<N>& value) -> std::ostream& {
714 stream << "StaticString::<" << N << "> { m_size: " << value.size() << ", m_string: \""
715 << value.unchecked_access().c_str() << "\" }";
716 return stream;
717}
718
719#endif // IOX2_INCLUDE_GUARD_BB_STATIC_STRING_HPP
#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(ConstAccessorCodeUnits const &)=delete
auto element_at(SizeType index) const noexcept -> OptionalConstCodeUnitReference
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
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
IOX2_CONSTEXPR_DTOR ~StaticString()=default
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
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
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 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
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
Definition optional.hpp:28
bool(*)(const StaticString< Capacity > &value) DoesContainInvalidCharacter
iox2::bb::variation::Optional< T > Optional
Definition optional.hpp:25
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