Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate functions with [[lifetimebound]] attribute where applicable. #46

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 35 additions & 27 deletions include/st_charbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,13 @@ namespace ST
}

ST_DEPRECATED_IN_3_4("Use clear() instead")
buffer<char_T> &operator=(const null_t &) noexcept
buffer<char_T> &operator=(const null_t &) noexcept ST_LIFETIME_BOUND
{
clear();
return *this;
}

buffer<char_T> &operator=(const buffer<char_T> &copy)
buffer<char_T> &operator=(const buffer<char_T> &copy) ST_LIFETIME_BOUND
{
if (this == &copy)
return *this;
Expand All @@ -186,7 +186,7 @@ namespace ST
return *this;
}

buffer<char_T> &operator=(buffer<char_T> &&move) noexcept
buffer<char_T> &operator=(buffer<char_T> &&move) noexcept ST_LIFETIME_BOUND
{
std::swap(m_chars, move.m_chars);
std::swap(m_size, move.m_size);
Expand Down Expand Up @@ -275,16 +275,17 @@ namespace ST
}

ST_NODISCARD
char_T *data() noexcept { return m_chars; }
char_T *data() noexcept ST_LIFETIME_BOUND { return m_chars; }

ST_NODISCARD
const char_T *data() const noexcept { return m_chars; }
const char_T *data() const noexcept ST_LIFETIME_BOUND { return m_chars; }

ST_NODISCARD
const char_T *c_str() const noexcept { return m_chars; }
const char_T *c_str() const noexcept ST_LIFETIME_BOUND { return m_chars; }

ST_NODISCARD
const char_T *c_str(const char_T *substitute) const noexcept
const char_T *c_str(const char_T *substitute ST_LIFETIME_BOUND)
const noexcept ST_LIFETIME_BOUND
{
return empty() ? substitute : m_chars;
}
Expand All @@ -296,107 +297,113 @@ namespace ST
bool empty() const noexcept { return m_size == 0; }

ST_NODISCARD
char_T &at(size_t index)
char_T &at(size_t index) ST_LIFETIME_BOUND
{
if (index >= size())
throw std::out_of_range("Character index out of range");
return m_chars[index];
}

ST_NODISCARD
const char_T &at(size_t index) const
const char_T &at(size_t index) const ST_LIFETIME_BOUND
{
if (index >= size())
throw std::out_of_range("Character index out of range");
return m_chars[index];
}

ST_NODISCARD
char_T &operator[](size_t index) noexcept
char_T &operator[](size_t index) noexcept ST_LIFETIME_BOUND
{
return m_chars[index];
}

ST_NODISCARD
const char_T &operator[](size_t index) const noexcept
const char_T &operator[](size_t index) const noexcept ST_LIFETIME_BOUND
{
return m_chars[index];
}

ST_NODISCARD
char_T &front() noexcept
char_T &front() noexcept ST_LIFETIME_BOUND
{
return m_chars[0];
}

ST_NODISCARD
const char_T &front() const noexcept
const char_T &front() const noexcept ST_LIFETIME_BOUND
{
return m_chars[0];
}

ST_NODISCARD
char_T &back() noexcept
char_T &back() noexcept ST_LIFETIME_BOUND
{
return empty() ? m_chars[0] : m_chars[m_size - 1];
}

ST_NODISCARD
const char_T &back() const noexcept
const char_T &back() const noexcept ST_LIFETIME_BOUND
{
return empty() ? m_chars[0] : m_chars[m_size - 1];
}

ST_NODISCARD
iterator begin() noexcept { return m_chars; }
iterator begin() noexcept ST_LIFETIME_BOUND { return m_chars; }

ST_NODISCARD
const_iterator begin() const noexcept { return m_chars; }
const_iterator begin() const noexcept ST_LIFETIME_BOUND { return m_chars; }

ST_NODISCARD
const_iterator cbegin() const noexcept { return m_chars; }
const_iterator cbegin() const noexcept ST_LIFETIME_BOUND { return m_chars; }

ST_NODISCARD
iterator end() noexcept { return m_chars + m_size; }
iterator end() noexcept ST_LIFETIME_BOUND { return m_chars + m_size; }

ST_NODISCARD
const_iterator end() const noexcept { return m_chars + m_size; }
const_iterator end() const noexcept ST_LIFETIME_BOUND
{
return m_chars + m_size;
}

ST_NODISCARD
const_iterator cend() const noexcept { return m_chars + m_size; }
const_iterator cend() const noexcept ST_LIFETIME_BOUND
{
return m_chars + m_size;
}

ST_NODISCARD
reverse_iterator rbegin() noexcept
reverse_iterator rbegin() noexcept ST_LIFETIME_BOUND
{
return reverse_iterator(end());
}

ST_NODISCARD
const_reverse_iterator rbegin() const noexcept
const_reverse_iterator rbegin() const noexcept ST_LIFETIME_BOUND
{
return const_reverse_iterator(end());
}

ST_NODISCARD
const_reverse_iterator crbegin() const noexcept
const_reverse_iterator crbegin() const noexcept ST_LIFETIME_BOUND
{
return const_reverse_iterator(cend());
}

ST_NODISCARD
reverse_iterator rend() noexcept
reverse_iterator rend() noexcept ST_LIFETIME_BOUND
{
return reverse_iterator(begin());
}

ST_NODISCARD
const_reverse_iterator rend() const noexcept
const_reverse_iterator rend() const noexcept ST_LIFETIME_BOUND
{
return const_reverse_iterator(begin());
}

ST_NODISCARD
const_reverse_iterator crend() const noexcept
const_reverse_iterator crend() const noexcept ST_LIFETIME_BOUND
{
return const_reverse_iterator(cbegin());
}
Expand Down Expand Up @@ -437,6 +444,7 @@ namespace ST
ST_NODISCARD
std::basic_string_view<char_T> view(size_t start = 0,
size_t length = ST_AUTO_SIZE) const &
ST_LIFETIME_BOUND
{
if (length == ST_AUTO_SIZE)
length = size() - start;
Expand Down
12 changes: 12 additions & 0 deletions include/st_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@
# define ST_NODISCARD
#endif

#ifndef __has_cpp_attribute
# define ST_LIFETIME_BOUND
#elif __has_cpp_attribute(msvc::lifetimebound)
# define ST_LIFETIME_BOUND [[msvc::lifetimebound]]
#elif __has_cpp_attribute(clang::lifetimebound)
# define ST_LIFETIME_BOUND [[clang::lifetimebound]]
#elif __has_cpp_attribute(lifetimebound)
# define ST_LIFETIME_BOUND [[lifetimebound]]
#else
# define ST_LIFETIME_BOUND
#endif

#define ST_MAX_SSO_LENGTH (16)
#define ST_MAX_SSO_SIZE (48)
#define ST_STACK_STRING_SIZE (256)
Expand Down
6 changes: 4 additions & 2 deletions include/st_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ namespace _ST_PRIVATE
explicit string_format_writer(const char *format_str)
: ST::format_writer(format_str) { }

string_format_writer &append(const char *data, size_t size) override
string_format_writer &append(const char *data, size_t size)
ST_LIFETIME_BOUND override
{
m_output.append(data, size);
return *this;
}

string_format_writer &append_char(char ch, size_t count = 1) override
string_format_writer &append_char(char ch, size_t count = 1)
ST_LIFETIME_BOUND override
{
m_output.append_char(ch, count);
return *this;
Expand Down
4 changes: 2 additions & 2 deletions include/st_format_numeric.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ namespace ST
}

ST_NODISCARD
const char *text() const noexcept { return m_start; }
const char *text() const noexcept ST_LIFETIME_BOUND { return m_start; }

ST_NODISCARD
size_t size() const noexcept
Expand Down Expand Up @@ -106,7 +106,7 @@ namespace ST
}

ST_NODISCARD
const char *text() const noexcept { return m_buffer; }
const char *text() const noexcept ST_LIFETIME_BOUND { return m_buffer; }

ST_NODISCARD
size_t size() const noexcept { return m_size; }
Expand Down
8 changes: 4 additions & 4 deletions include/st_formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,15 @@ namespace ST
format_writer& operator=(const format_writer&) = delete;

format_writer(format_writer&&) = default;
format_writer& operator=(format_writer&&) = default;
format_writer& operator=(format_writer&&) ST_LIFETIME_BOUND = default;

virtual ~format_writer() noexcept { }

virtual format_writer &append(const char *data, size_t size) = 0;
virtual format_writer &append_char(char ch, size_t count = 1) = 0;
virtual format_writer &append(const char *data, size_t size) ST_LIFETIME_BOUND = 0;
virtual format_writer &append_char(char ch, size_t count = 1) ST_LIFETIME_BOUND = 0;

template <size_t size>
format_writer &append(const char (&literal)[size])
format_writer &append(const char (&literal)[size]) ST_LIFETIME_BOUND
{
return append(literal, size - 1);
}
Expand Down
12 changes: 8 additions & 4 deletions include/st_iostream.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,15 @@ namespace _ST_PRIVATE
m_stream.write(utf32.data(), utf32.size());
}

ostream_format_writer &append(const char *data, size_t size) override
ostream_format_writer &append(const char *data, size_t size)
ST_LIFETIME_BOUND override
{
write_data<char_T>(data, size);
return *this;
}

ostream_format_writer &append_char(char ch, size_t count = 1) override
ostream_format_writer &append_char(char ch, size_t count = 1)
ST_LIFETIME_BOUND override
{
while (count) {
m_stream.put(char_T(ch));
Expand All @@ -101,7 +103,8 @@ namespace ST

template <class char_T, class traits_T>
std::basic_ostream<char_T, traits_T> &operator<<(
std::basic_ostream<char_T, traits_T> &stream, const ST::string &str)
std::basic_ostream<char_T, traits_T> &stream ST_LIFETIME_BOUND,
const ST::string &str)
{
ST::buffer<char_T> buffer;
str.to_buffer(buffer);
Expand All @@ -110,7 +113,8 @@ std::basic_ostream<char_T, traits_T> &operator<<(

template <class char_T, class traits_T>
std::basic_istream<char_T, traits_T> &operator>>(
std::basic_istream<char_T, traits_T> &stream, ST::string &str)
std::basic_istream<char_T, traits_T> &stream ST_LIFETIME_BOUND,
ST::string &str)
{
std::basic_string<char_T, traits_T> stl_string;
stream >> stl_string;
Expand Down
6 changes: 4 additions & 2 deletions include/st_stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ namespace _ST_PRIVATE
stdio_format_writer(const char *format_str, FILE *stream)
: ST::format_writer(format_str), m_stream(stream) { }

stdio_format_writer &append(const char *data, size_t size) override
stdio_format_writer &append(const char *data, size_t size)
ST_LIFETIME_BOUND override
{
(void)fwrite(data, sizeof(char), size, m_stream);
return *this;
}

stdio_format_writer &append_char(char ch, size_t count = 1) override
stdio_format_writer &append_char(char ch, size_t count = 1)
ST_LIFETIME_BOUND override
{
while (count) {
fputc(ch, m_stream);
Expand Down
Loading
Loading