template<class T>
Corrade::Containers::BasicStringView class new in Git master

Base for string views.

A lighter alternative to C++17 std::string_view that has also a mutable variant and additional optimizations for reducing unnecessary copies and allocations. An owning version of this container is a String.

Usage

The class is meant to be used through either the StringView or MutableStringView typedefs. It's implicitly convertible from C string literals, but the recommended way is using the operator""_s() literal:

using namespace Containers::Literals;

Containers::StringView a = "hello world!";
Containers::StringView b = "hello world!"_s;

While both expressions are mostly equivalent, the literal is constexpr so you can use it in a compile-time context (and on the other hand, the implicit conversion uses std::strlen() which has some runtime impact). The main difference is however that the literal will annotate the view as global and null-terminated, which can help avoid copies and allocations when lifetime of the data needs to be extended or when dealing with APIs that expect null-terminated strings. Additionally, the literal will also preserve zero bytes inside the string, while implicit conversion from a C string won't:

Containers::StringView a = "hello\0world!";     // a.size() == 5
Containers::StringView b = "hello\0world!"_s;   // a.size() == 12

C string literals are implicitly immutable, in order to create a mutable one you need to assign the literal to a char[] (instead of const char*) and then create a MutableStringView in a second step. For example:

char a[] = "hello world!";
Containers::MutableStringView view = a;
view[5] = '\0';

This class is implicitly convertible from and to ArrayView, however note that the conversion will not preserve the global / null-terminated annotations.

String view slicing

The string view class inherits the slicing APIs of ArrayViewslice(), prefix(), suffix() and except() — and in addition it provides string-specific utilities. These are are all derived from the slicing APIs, which means they also return sub-views of the original string:

STL compatibility

Instances of StringView and BasicStringView are implicitly convertible from and to std::string if you include Corrade/Containers/StringStl.h. The conversion is provided in a separate header to avoid unconditional #include <string>, which significantly affects compile times. The following table lists allowed conversions:

Corrade typeSTL type
StringViewstd::string
StringViewconst std::string
MutableStringViewstd::string
MutableStringViewconst std::string

Example:

using namespace Containers::Literals;

std::string a = "Hello\0world!"_s;

Containers::MutableStringView b = a;
b[5] = ' ';

Creating a std::string instance always involves an allocation and a copy, while going the other way always creates a non-owning reference without allocations or copies. StringView / MutableStringView created from a std::string always have StringViewFlag::NullTerminated set, but the usual conditions regarding views apply — if the original string is modified, view pointer, size or the null termination property may not be valid anymore.

Constructors, destructors, conversion operators

BasicStringView(std::nullptr_t = nullptr) constexpr noexcept
Default constructor.
BasicStringView(T* data, std::size_t size, StringViewFlags flags = {}) constexpr noexcept
Construct from a C string of known size.
BasicStringView(String& data) noexcept
Construct from a String.
template<class U = T, class = typename std::enable_if<std::is_const<U>::value>::type>
BasicStringView(const String& data) noexcept
Construct from a const String.
BasicStringView(ArrayView<T> data, StringViewFlags flags = {}) noexcept
Construct from an ArrayView.
template<class U, class = typename std::enable_if<std::is_same<const U, T>::value>::type>
BasicStringView(BasicStringView<U> mutable_) constexpr noexcept
Construct a StringView from a MutableStringView.
BasicStringView(T* data, StringViewFlags extraFlags = {}) noexcept
Construct from a null-terminated C string.
template<class U, class = decltype(Implementation::StringViewConverter<T, typename std::decay<U && >::type>::from(std::declval<U && >()))>
BasicStringView(U&& other) constexpr noexcept
Construct a view on an external type / from an external representation.
operator ArrayView<T>() const noexcept
Convert to an ArrayView.
operator ArrayView<typename std::conditional<std::is_const<T>::value, const void, void>::type>() const noexcept
template<class U, class = decltype(Implementation::StringViewConverter<T, U>::to(std::declval<BasicStringView<T>>()))>
operator U() const constexpr
Convert the view to external representation.

Public functions

auto flags() const -> StringViewFlags constexpr
Flags.
auto data() const -> T* constexpr
String data.
auto size() const -> std::size_t constexpr
String size.
auto isEmpty() const -> bool constexpr
Whether the string is empty.
auto begin() const -> T* constexpr
Pointer to the first byte.
auto cbegin() const -> T* constexpr
auto end() const -> T* constexpr
Pointer to (one item after) the last byte.
auto cend() const -> T* constexpr
auto front() const -> T&
First byte.
auto back() const -> T&
Last byte.
auto operator[](std::size_t i) const -> T& constexpr
Element access.
auto slice(T* begin, T* end) const -> BasicStringView<T> constexpr
String slice.
auto slice(std::size_t begin, std::size_t end) const -> BasicStringView<T> constexpr
auto prefix(T* end) const -> BasicStringView<T> constexpr
String prefix.
auto prefix(std::size_t end) const -> BasicStringView<T> constexpr
String prefix.
auto suffix(T* begin) const -> BasicStringView<T> constexpr
String suffix.
auto suffix(std::size_t begin) const -> BasicStringView<T> constexpr
String suffix.
auto except(std::size_t count) const -> BasicStringView<T> constexpr
String prefix except the last count items.
auto split(char delimiter) const -> Array<BasicStringView<T>>
Split on given character.
auto splitWithoutEmptyParts(char delimiter) const -> Array<BasicStringView<T>>
Split on given character, removing empty parts.
auto splitWithoutEmptyParts(StringView delimiters) const -> Array<BasicStringView<T>>
Split on any character from given set, removing empty parts.
auto splitWithoutEmptyParts() const -> Array<BasicStringView<T>>
Split on whitespace, removing empty parts.
auto partition(char separator) const -> Array3<BasicStringView<T>>
Partition.
auto join(ArrayView<const StringView> strings) const -> String
Join strings with this view as the delimiter.
auto join(std::initializer_list<StringView> strings) const -> String
auto joinWithoutEmptyParts(ArrayView<const StringView> strings) const -> String
Join strings with this view as the delimiter, skipping empty parts.
auto joinWithoutEmptyParts(std::initializer_list<StringView> strings) const -> String
auto hasPrefix(StringView prefix) const -> bool
Whether the string begins with given prefix.
auto hasSuffix(StringView suffix) const -> bool
Whether the string ends with given suffix.
auto exceptPrefix(StringView prefix) const -> BasicStringView<T>
View with given prefix stripped.
auto stripPrefix(StringView prefix) const -> BasicStringView<T> deprecated in Git master
View with given prefix stripped.
auto exceptSuffix(StringView suffix) const -> BasicStringView<T>
View with given suffix stripped.
auto stripSuffix(StringView suffix) const -> BasicStringView<T> deprecated in Git master
View with given suffix stripped.
auto trimmed(StringView characters) const -> BasicStringView<T>
View with given characters trimmed from prefix and suffix.
auto trimmed() const -> BasicStringView<T>
View with whitespace trimmed from prefix and suffix.
auto trimmedPrefix(StringView characters) const -> BasicStringView<T>
View with given characters trimmed from prefix.
auto trimmedPrefix() const -> BasicStringView<T>
View with whitespace trimmed from prefix.
auto trimmedSuffix(StringView characters) const -> BasicStringView<T>
View with given characters trimmed from suffix.
auto trimmedSuffix() const -> BasicStringView<T>
View with whitespace trimmed from suffix.
auto find(StringView substring) const -> BasicStringView<T>
Find a substring.
auto contains(StringView substring) const -> bool
Whether the view contains a substring.

Friends

auto operator==(StringView a, StringView b) -> bool new in Git master
String view equality comparison.
auto operator!=(StringView a, StringView b) -> bool new in Git master
String view non-equality comparison.
auto operator<(StringView a, StringView b) -> bool new in Git master
String view less-than comparison.
auto operator<=(StringView a, StringView b) -> bool new in Git master
String view less-than-or-equal comparison.
auto operator>=(StringView a, StringView b) -> bool new in Git master
String view greater-than-or-equal comparison.
auto operator>(StringView a, StringView b) -> bool new in Git master
String view greater-than comparison.

Function documentation

template<class T>
Corrade::Containers::BasicStringView<T>::BasicStringView(std::nullptr_t = nullptr) constexpr noexcept

Default constructor.

A default-constructed instance has StringViewFlag::Global set.

template<class T>
Corrade::Containers::BasicStringView<T>::BasicStringView(T* data, std::size_t size, StringViewFlags flags = {}) constexpr noexcept

Construct from a C string of known size.

Parameters
data C string
size Size of the C string, excluding the null terminator
flags Flags describing additional string properties

If StringViewFlag::Global is set, the data pointer is assumed to never go out of scope, which can avoid copies and allocations in code using the instance. If StringViewFlag::NullTerminated is set, it's expected that data is not nullptr and data[size] == '\0'. That can avoid copies and allocations in code that passes such string to APIs that expect null-terminated strings (such as std::fopen()).

If you're unsure about data origin, the safe bet is to keep flags at their default. On the other hand, C string literals are always global and null-terminated — for those, the recommended way is to use the operator""_s() literal instead.

template<class T>
Corrade::Containers::BasicStringView<T>::BasicStringView(String& data) noexcept

Construct from a String.

The resulting view has StringViewFlag::NullTerminated set.

template<class T> template<class U = T, class = typename std::enable_if<std::is_const<U>::value>::type>
Corrade::Containers::BasicStringView<T>::BasicStringView(const String& data) noexcept

Construct from a const String.

Enabled only if the view is not mutable. The resulting view has StringViewFlag::NullTerminated set.

template<class T>
Corrade::Containers::BasicStringView<T>::BasicStringView(ArrayView<T> data, StringViewFlags flags = {}) noexcept

Construct from an ArrayView.

The resulting view has the same size as other, by default no null-termination is assumed.

template<class T>
Corrade::Containers::BasicStringView<T>::BasicStringView(T* data, StringViewFlags extraFlags = {}) noexcept

Construct from a null-terminated C string.

Contrary to the behavior of std::string, data is allowed to be nullptr — in that case an empty view is constructed.

Calls BasicStringView(T*, std::size_t, StringViewFlags) with size set to std::strlen() of data if data is not nullptr. If data is nullptr, size is set to 0. In addition to extraFlags, if data is not nullptr, StringViewFlag::NullTerminated is set, otherwise StringViewFlag::Global is set.

The BasicStringView(std::nullptr_t) overload (which is a default constructor) is additionally constexpr.

template<class T> template<class U, class = decltype(Implementation::StringViewConverter<T, typename std::decay<U && >::type>::from(std::declval<U && >()))>
Corrade::Containers::BasicStringView<T>::BasicStringView(U&& other) constexpr noexcept

Construct a view on an external type / from an external representation.

template<class T>
Corrade::Containers::BasicStringView<T>::operator ArrayView<T>() const noexcept

Convert to an ArrayView.

The resulting view has the same size as this string size() — the null terminator, if any, is not counted into it.

template<class T>
Corrade::Containers::BasicStringView<T>::operator ArrayView<typename std::conditional<std::is_const<T>::value, const void, void>::type>() const noexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T> template<class U, class = decltype(Implementation::StringViewConverter<T, U>::to(std::declval<BasicStringView<T>>()))>
Corrade::Containers::BasicStringView<T>::operator U() const constexpr

Convert the view to external representation.

template<class T>
T* Corrade::Containers::BasicStringView<T>::data() const constexpr

String data.

The pointer is not guaranteed to be null-terminated, use flags() and StringViewFlag::NullTerminated to check for the presence of a null terminator.

template<class T>
std::size_t Corrade::Containers::BasicStringView<T>::size() const constexpr

String size.

Excludes the null terminator.

template<class T>
T* Corrade::Containers::BasicStringView<T>::begin() const constexpr

Pointer to the first byte.

template<class T>
T* Corrade::Containers::BasicStringView<T>::cbegin() const constexpr

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
T* Corrade::Containers::BasicStringView<T>::end() const constexpr

Pointer to (one item after) the last byte.

template<class T>
T* Corrade::Containers::BasicStringView<T>::cend() const constexpr

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
T& Corrade::Containers::BasicStringView<T>::front() const

First byte.

Expects there is at least one byte.

template<class T>
T& Corrade::Containers::BasicStringView<T>::back() const

Last byte.

Expects there is at least one byte.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::slice(T* begin, T* end) const constexpr

String slice.

Both arguments are expected to be in range. Propagates the StringViewFlag::Global flag and if end points to (one item after) the end of the original null-terminated string, the result has StringViewFlag::NullTerminated also.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::slice(std::size_t begin, std::size_t end) const constexpr

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::prefix(T* end) const constexpr

String prefix.

Equivalent to string.slice(string.begin(), end). If end is nullptr, returns zero-sized nullptr view.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::prefix(std::size_t end) const constexpr

String prefix.

Equivalent to string.slice(0, end).

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::suffix(T* begin) const constexpr

String suffix.

Equivalent to string.slice(begin, string.end()). If begin is nullptr and the original view isn't, returns a zero-sized nullptr view.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::suffix(std::size_t begin) const constexpr

String suffix.

Equivalent to string.slice(begin, string.size()).

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::except(std::size_t count) const constexpr

String prefix except the last count items.

Equivalent to string.slice(0, string.size() - count).

template<class T>
Array<BasicStringView<T>> Corrade::Containers::BasicStringView<T>::split(char delimiter) const

Split on given character.

If delimiter is not found, returns a single-item array containing the full input string. If the string is empty, returns an empty array. The function uses slice() internally, meaning it propagates the flags() as appropriate.

template<class T>
Array<BasicStringView<T>> Corrade::Containers::BasicStringView<T>::splitWithoutEmptyParts(char delimiter) const

Split on given character, removing empty parts.

If delimiter is not found, returns a single-item array containing the full input string. If the string is empty or consists just of delimiter characters, returns an empty array. The function uses slice() internally, meaning it propagates the flags() as appropriate.

template<class T>
Array<BasicStringView<T>> Corrade::Containers::BasicStringView<T>::splitWithoutEmptyParts(StringView delimiters) const

Split on any character from given set, removing empty parts.

If no characters from delimiters are found, returns a single-item array containing the full input string. If the string is empty or consists just of characters from delimiters, returns an empty array. The function uses slice() internally, meaning it propagates the flags() as appropriate.

template<class T>
Array<BasicStringView<T>> Corrade::Containers::BasicStringView<T>::splitWithoutEmptyParts() const

Split on whitespace, removing empty parts.

Equivalent to calling splitWithoutEmptyParts(StringView) const with " \t\f\v\r\n" passed to delimiters.

template<class T>
Array3<BasicStringView<T>> Corrade::Containers::BasicStringView<T>::partition(char separator) const

Partition.

Equivalent to Python's str.partition(). Splits string at the first occurence of separator. First returned value is the part before the separator, second the separator, third a part after the separator. If the separator is not found, returns the input string followed by two empty strings.

The function uses slice() internally, meaning it propagates the flags() as appropriate. Additionally, the resulting views are nullptr only if the input is nullptr, otherwise the view always points to existing memory.

template<class T>
String Corrade::Containers::BasicStringView<T>::join(ArrayView<const StringView> strings) const

Join strings with this view as the delimiter.

Similar in usage to Python's str.join() — the following produces "hello, world":

using namespace Containers::Literals;

Containers::String a = ", "_s.join({"hello", "world"});

template<class T>
String Corrade::Containers::BasicStringView<T>::join(std::initializer_list<StringView> strings) const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
String Corrade::Containers::BasicStringView<T>::joinWithoutEmptyParts(ArrayView<const StringView> strings) const

Join strings with this view as the delimiter, skipping empty parts.

Like join(), but empty views in strings are skipped instead of causing multiple repeated delimiters in the output.

template<class T>
String Corrade::Containers::BasicStringView<T>::joinWithoutEmptyParts(std::initializer_list<StringView> strings) const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
bool Corrade::Containers::BasicStringView<T>::hasPrefix(StringView prefix) const

Whether the string begins with given prefix.

For an empty string returns true only if prefix is empty as well.

template<class T>
bool Corrade::Containers::BasicStringView<T>::hasSuffix(StringView suffix) const

Whether the string ends with given suffix.

For an empty string returns true only if suffix is empty as well.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::exceptPrefix(StringView prefix) const

View with given prefix stripped.

Expects that the string actually begins with given prefix. The function uses slice() internally, meaning it propagates the flags() as appropriate. Additionally, the resulting view is nullptr only if the input is nullptr, otherwise the view always points to existing memory.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::stripPrefix(StringView prefix) const

View with given prefix stripped.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::exceptSuffix(StringView suffix) const

View with given suffix stripped.

Expects that the string actually ends with given suffix. The function uses slice() internally, meaning it propagates the flags() as appropriate. Additionally, the resulting view is nullptr only if the input is nullptr, otherwise the view always points to existing memory.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::stripSuffix(StringView suffix) const

View with given suffix stripped.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::trimmed(StringView characters) const

View with given characters trimmed from prefix and suffix.

The function uses slice() internally, meaning it propagates the flags() as appropriate. Additionally, the resulting view is nullptr only if the input is nullptr, otherwise the view always points to existing memory.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::trimmed() const

View with whitespace trimmed from prefix and suffix.

Equivalent to calling trimmed(StringView) const with " \t\f\v\r\n" passed to characters.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::trimmedPrefix(StringView characters) const

View with given characters trimmed from prefix.

The function uses slice() internally, meaning it propagates the flags() as appropriate. Additionally, the resulting view is nullptr only if the input is nullptr, otherwise the view always points to existing memory.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::trimmedPrefix() const

View with whitespace trimmed from prefix.

Equivalent to calling trimmedPrefix(StringView) const with " \t\f\v\r\n" passed to characters.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::trimmedSuffix(StringView characters) const

View with given characters trimmed from suffix.

The function uses slice() internally, meaning it propagates the flags() as appropriate. Additionally, the resulting view is nullptr only if the input is nullptr, otherwise the view always points to existing memory.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::trimmedSuffix() const

View with whitespace trimmed from suffix.

Equivalent to calling trimmedSuffix(StringView) const with " \t\f\v\r\n" passed to characters.

template<class T>
BasicStringView<T> Corrade::Containers::BasicStringView<T>::find(StringView substring) const

Find a substring.

Returns a view pointing to the first found substring. If not found, an empty nullptr view is returned. The function uses slice() internally, meaning it propagates the flags() as appropriate.

Note that the function operates with a $ \mathcal{O}(nm) $ complexity and as such is meant mainly for one-time searches in non-performance-critical code. For repeated searches or searches of large substrings it's recommended to use the std::search() algorithms, especially std::boyer_moore_searcher and its variants. Those algorithms on the other hand have to perform certain preprocessing of the input and keep extra state and due to that overhead aren't generally suited for one-time searches.

template<class T>
bool Corrade::Containers::BasicStringView<T>::contains(StringView substring) const

Whether the view contains a substring.

A slightly lighter variant of find() useful when you only want to know if a substring was found or not.

template<class T>
Utility::Debug& operator<<(Utility::Debug& debug, StringViewFlag value)

Debug output operator.

template<class T>
Utility::Debug& operator<<(Utility::Debug& debug, StringViewFlags value)

Debug output operator.

template<class T>
StringView operator""_s(const char* data, std::size_t size) constexpr new in Git master

String view literal.

The returned instance has both StringViewFlag::Global and StringViewFlag::NullTerminated set. See Usage for more information.