Flatstring

#include <xo/flatstring/flatstring.hpp>

A flatstring is a thin wrapper around a character array.

template<std::size_t N>
class flatstring

class to represent a string with a fixed amount of storage space.

  • Flatstring memory layout is a fixed-size, null-terminated char array.

  • With a few exceptions, flatstring methods are noexcept. flatstring<N>::at() may throw, for consistency with std::string::at() behavior

  • Construction and concatenation of flatstrings are constexpr, and can be done at compile time. We rely on this in related projects (e.g. https://github.com:rconybea/xo-unit)

  • Preserves as much of the c++23 std::string api as practicable

N includes mandatory null terminator, so we require N > 0.

Invariant

all flatstring instances are null-terminated.

Invariant

sizeof(flatstring<N>) == N

Instance Variables

char value_[N]

characters comprising this literal string

Types

group flatstring-types

Template types exposed by flatstring<N>

Typedefs

using traits_type = std::char_traits<char>

character traits for this flatstring

using value_type = char

type of each character in this flatstring

using allocator_type = std::allocator<char>
using size_type = std::allocator_traits<allocator_type>::size_type
using difference_type = std::allocator_traits<allocator_type>::difference_type
using reference = value_type&

type of a character reference

using const_reference = const value_type&

type of a readonly character reference

using pointer = std::allocator_traits<allocator_type>::pointer
using const_pointer = std::allocator_traits<allocator_type>::const_pointer
using iterator = char*

representation for a read/write iterator

using const_iterator = const char*

representation for a readonly iterator

struct reverse_iterator
#include <flatstring.hpp>

representation for a read/write reverse iterator

constexpr implementation is tricky here, since we can’t form the address ‘just before the beginning of the string’ for rend() without losing constexprness (at least with gcc 13.1)

Instead iterator always refers to the address immediately after its real target. This works since rbegin() refers to the char just before trailing null

struct const_reverse_iterator
#include <flatstring.hpp>

representation for a readonly reverse iterator

constexpr implementation is tricky here, since we can’t form the address ‘just before the beginning of the string’ for rend() without losing constexprness (at least with gcc 13.1)

Instead iterator always refers to the address immediately after its real target. This works since rbegin() refers to the char just before trailing null

Constants

static constexpr const size_type npos = size_type(-1)
static constexpr const std::size_t fixed_capacity = N

capacity of this flatstring, including final null terminator.

Note

not present in std::string api

Constructors

inline constexpr flatstring() noexcept

create empty string literal. Will contain N null characters

Example

constexpr flatstring<5> s1;
static_assert(s1.empty());

inline constexpr flatstring(const char (&str)[N]) noexcept

create string literal from a correctly-sized char array

Example

constexpr flatstring s1("hello");
static_assert(s1.size() > 0);

Properties

inline constexpr bool empty() const noexcept

true if (and only if) string is empty

inline constexpr size_type size() const noexcept

returns current size of this string

inline constexpr size_type length() const noexcept

synonym for size()

inline constexpr size_type capacity() const noexcept
inline constexpr size_type max_size() const noexcept
inline constexpr const char *c_str() const noexcept

contents as plain old C-style string.

Access Methods

inline constexpr value_type &at(size_type pos)

return char at position pos in this string (counting from zero).

Throws std::out_of_range exception if pos >= N

inline constexpr const value_type &at(size_type pos) const
inline constexpr value_type &operator[](size_type pos) noexcept

return char at position pos in this string (counting from zero).

Does not check bounds: undefined behavior if pos >= N

Pre:

0<=pos<=N-1

inline constexpr const value_type &operator[](size_type pos) const noexcept

Iterators

inline constexpr iterator begin()
inline constexpr iterator end()
inline constexpr const_iterator cbegin() const
inline constexpr const_iterator cend() const
inline constexpr const_iterator begin() const
inline constexpr const_iterator end() const
inline constexpr reverse_iterator rbegin()
inline constexpr reverse_iterator rend()
inline constexpr const_reverse_iterator crbegin() const
inline constexpr const_reverse_iterator crend() const
inline constexpr const_reverse_iterator rbegin() const
inline constexpr const_reverse_iterator rend() const

Assignment

inline constexpr void clear() noexcept

put string into empty state. fills entire char array with nulls

inline constexpr flatstring &assign(size_type count, value_type ch)

replace contents with min(count,N-1) copies of character ch

inline constexpr flatstring &assign(const flatstring &x)

replace contents with first N-1 characters of x

template<std::size_t N2>
inline constexpr flatstring &assign(const flatstring<N2> &x, size_type pos, size_type count = npos)

replace contents with substring [pos,pos+count] of str

inline constexpr flatstring &assign(const value_type *cstr, size_type count)

replace contents with range [cstr, cstr + count)

inline constexpr flatstring &assign(const value_type *cstr)

replace contents with C-style string cstr

template<typename InputIter>
inline constexpr flatstring &assign(InputIter first, InputIter last)

replace contents with iterator range [first, last)

Conversion

inline std::string str() const

conversion to std::string

Example

constexpr flatstring s("bazinga!");
std::string s_str{s.str()};

inline constexpr operator std::string_view() const noexcept

conversion operator to string_view

inline constexpr operator const char*() const noexcept

conversion operator to C-style string.

Example

constexpr flatstring s("obey gravity..");
strcmp(s, "obey...");