5#include "../SqlColumnTypeDefinitions.hpp"
7#include "StringInterface.hpp"
8#include "UnicodeConverter.hpp"
20enum class SqlFixedStringMode : uint8_t
27 FIXED_SIZE_RIGHT_TRIMMED,
39template <std::
size_t N,
typename T =
char, SqlFixedStringMode Mode = SqlFixedStringMode::FIXED_SIZE>
44 std::size_t _size = 0;
70 template <std::
size_t SourceSize>
71 constexpr LIGHTWEIGHT_FORCE_INLINE
SqlFixedString(T
const (&text)[SourceSize]):
72 _size { SourceSize - 1 }
74 static_assert(SourceSize <= N + 1,
"RHS string size must not exceed target string's capacity.");
75 std::copy_n(text, SourceSize, _data);
97 LIGHTWEIGHT_FORCE_INLINE constexpr
SqlFixedString(std::basic_string_view<T> s) noexcept:
98 _size { (std::min) (N, s.size()) }
100 std::copy_n(s.data(), _size, _data);
104 LIGHTWEIGHT_FORCE_INLINE
constexpr SqlFixedString(std::basic_string<T>
const& s)
noexcept:
105 _size { (std::min) (N, s.size()) }
107 std::copy_n(s.data(), _size, _data);
111 LIGHTWEIGHT_FORCE_INLINE
constexpr SqlFixedString(T
const* s, std::size_t len)
noexcept:
112 _size { (std::min) (N, len) }
114 std::copy_n(s, _size, _data);
118 LIGHTWEIGHT_FORCE_INLINE
constexpr SqlFixedString(T
const* s, T
const* e)
noexcept:
119 _size { (std::min) (N,
static_cast<std::size_t
>(e - s)) }
121 std::copy(s, e, _data);
128 throw std::length_error(std::format(
"SqlFixedString: capacity {} exceeds maximum capacity {}",
capacity, N));
132 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr bool empty() const noexcept
138 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr std::size_t
size() const noexcept
145 LIGHTWEIGHT_FORCE_INLINE
void setsize(std::size_t n)
noexcept
147 auto const newSize = (std::min) (n, N);
149 _data[newSize] =
'\0';
156 LIGHTWEIGHT_FORCE_INLINE
constexpr void resize(std::size_t n)
noexcept
158 auto const newSize = (std::min) (n, N);
160 _data[newSize] =
'\0';
164 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr std::size_t
capacity() const noexcept
170 LIGHTWEIGHT_FORCE_INLINE
constexpr void clear() noexcept
192 LIGHTWEIGHT_FORCE_INLINE
constexpr void push_back(T c)
noexcept
202 LIGHTWEIGHT_FORCE_INLINE
constexpr void pop_back() noexcept
209 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr std::basic_string_view<T>
substr(
210 std::size_t offset = 0, std::size_t count = (std::numeric_limits<std::size_t>::max)()) const noexcept
214 if (count == (std::numeric_limits<std::size_t>::max)())
215 return std::basic_string_view<T>(_data + offset, _size - offset);
216 if (offset + count > _size)
217 return std::basic_string_view<T>(_data + offset, _size - offset);
218 return std::basic_string_view<T>(_data + offset, count);
222 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr std::basic_string_view<T>
str() const noexcept
224 return std::basic_string_view<T> { _data, _size };
229 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr pointer_type data() noexcept {
return _data; }
231 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr iterator begin() noexcept {
return _data; }
233 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr iterator end() noexcept {
return _data +
size(); }
235 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr T&
operator[](std::size_t i)
noexcept {
return _data[i]; }
246 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr T
const&
operator[](std::size_t i)
const noexcept {
return _data[i]; }
250 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr std::basic_string<T>
ToString() const noexcept
252 return { _data, _size };
256 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr explicit operator std::basic_string<T>() const noexcept
262 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr std::basic_string_view<T>
ToStringView() const noexcept
264 return { _data, _size };
268 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr explicit operator std::basic_string_view<T>() const noexcept
274 template <std::
size_t OtherSize, SqlFixedStringMode OtherMode>
278 if ((
void*)
this == (
void*) &other) [[unlikely]]
279 return std::weak_ordering::equivalent;
281 for (
auto const i: std::views::iota(0U, (std::min) (
size(), other.size())))
282 if (
auto const cmp = _data[i] <=> other._data[i]; cmp != std::weak_ordering::equivalent) [[unlikely]]
284 return size() <=> other.size();
288 template <std::
size_t OtherSize, SqlFixedStringMode OtherMode>
291 return (*this <=> other) == std::weak_ordering::equivalent;
295 template <std::
size_t OtherSize, SqlFixedStringMode OtherMode>
298 return !(*
this == other);
302 LIGHTWEIGHT_FORCE_INLINE
constexpr bool operator==(std::basic_string_view<T> other)
const noexcept
304 return (
substr() <=> other) == std::weak_ordering::equivalent;
308 LIGHTWEIGHT_FORCE_INLINE
constexpr bool operator!=(std::basic_string_view<T> other)
const noexcept
310 return !(*
this == other);
314static_assert(SqlStringInterface<SqlFixedString<10>>);
316template <std::
size_t N,
typename CharT, SqlFixedStringMode Mode>
317struct detail::SqlViewHelper<SqlFixedString<N, CharT, Mode>>
319 static LIGHTWEIGHT_FORCE_INLINE std::basic_string_view<CharT> View(SqlFixedString<N, CharT, Mode>
const& str)
noexcept
321 return { str.data(), str.size() };
329 struct IsSqlFixedStringTypeImpl: std::false_type
333 template <std::
size_t N,
typename T, SqlFixedStringMode Mode>
334 struct IsSqlFixedStringTypeImpl<SqlFixedString<N, T, Mode>>: std::true_type
341constexpr bool IsSqlFixedString = detail::IsSqlFixedStringTypeImpl<T>::value;
346template <std::
size_t N>
352template <std::
size_t N>
358template <std::
size_t N>
364template <std::
size_t N>
370template <std::
size_t N>
376template <std::
size_t N>
379template <std::
size_t N,
typename T =
char>
382template <std::
size_t N,
typename T, SqlFixedStringMode Mode>
387 static constexpr auto ColumnType = []()
constexpr -> SqlColumnTypeDefinition {
388 if constexpr (std::same_as<CharType, char>)
390 if constexpr (Mode == SqlFixedStringMode::VARIABLE_SIZE)
391 return SqlColumnTypeDefinitions::Varchar { N };
393 return SqlColumnTypeDefinitions::Char { N };
397 if constexpr (Mode == SqlFixedStringMode::VARIABLE_SIZE)
398 return SqlColumnTypeDefinitions::NVarchar { N };
400 return SqlColumnTypeDefinitions::NChar { N };
404 static CharType
const* Data(ValueType
const* str)
noexcept
409 static CharType* Data(ValueType* str)
noexcept
414 static SQLULEN Size(ValueType
const* str)
noexcept
419 static void Clear(ValueType* str)
noexcept
424 static void Reserve(ValueType* str,
size_t capacity)
noexcept
426 str->reserve((std::min) (N, capacity));
427 str->resize((std::min) (N, capacity));
430 static void Resize(ValueType* str, SQLLEN indicator)
noexcept
432 str->resize(
static_cast<size_t>(indicator));
435 static void PostProcessOutputColumn(ValueType* result, SQLLEN indicator)
446 auto const len = (std::min) (N,
static_cast<std::size_t
>(indicator) /
sizeof(CharType));
447 result->setsize(len);
449 if constexpr (Mode == SqlFixedStringMode::FIXED_SIZE_RIGHT_TRIMMED)
451 TrimRight(result, indicator);
456 StripTrailingNulls(result);
463 LIGHTWEIGHT_FORCE_INLINE
static void StripTrailingNulls(ValueType* str)
noexcept
465 size_t n = str->size();
466 while (n > 0 && (*str)[n - 1] ==
'\0')
471 LIGHTWEIGHT_FORCE_INLINE
static void TrimRight(ValueType* boundOutputString, SQLLEN indicator)
noexcept
474 size_t n = (std::min) (
static_cast<size_t>(indicator) /
sizeof(CharType), N - 1);
476 size_t n = std::min(
static_cast<size_t>(indicator), N - 1);
479 while (n > 0 && (std::isspace((*boundOutputString)[n - 1]) || (*boundOutputString)[n - 1] ==
'\0'))
481 boundOutputString->setsize(n);
487template <std::
size_t N,
typename T, Lightweight::SqlFixedStringMode P>
488struct std::formatter<Lightweight::SqlFixedString<N, T, P>>: std::formatter<std::string>
491 auto format(value_type
const& text, format_context& ctx)
const -> format_context::iterator
493 if constexpr (std::same_as<T, char16_t> || std::same_as<T, char32_t> || std::same_as<T, wchar_t>)
496 auto const stdstring = std::string(
reinterpret_cast<char const*
>(utf8.data()), utf8.size());
497 return std::formatter<std::string>::format(stdstring, ctx);
500 return std::formatter<std::string>::format(std::string(text.data(), text.size()), ctx);
LIGHTWEIGHT_FORCE_INLINE constexpr SqlFixedString(T const *s, std::size_t len) noexcept
Constructs a fixed-size string from a string pointer and length.
LIGHTWEIGHT_FORCE_INLINE constexpr const_iterator end() const noexcept
Returns a const iterator to the end.
static constexpr SqlFixedStringMode PostRetrieveOperation
LIGHTWEIGHT_FORCE_INLINE constexpr std::size_t capacity() const noexcept
Returns the maximum capacity of the string.
static constexpr std::size_t Capacity
The specified width of the string, which is also the maximum size of the string.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlFixedString(T const *s, T const *e) noexcept
Constructs a fixed-size string from a string pointer and end pointer.
LIGHTWEIGHT_FORCE_INLINE constexpr bool operator==(SqlFixedString< OtherSize, T, OtherMode > const &other) const noexcept
Equality comparison operator.
T * pointer_type
Pointer type for the string.
LIGHTWEIGHT_FORCE_INLINE constexpr const_pointer_type c_str() const noexcept
Returns a pointer to the null-terminated C string.
LIGHTWEIGHT_FORCE_INLINE constexpr std::basic_string_view< T > str() const noexcept
Returns a string view of the string.
T const * const_pointer_type
Const pointer type for the string.
LIGHTWEIGHT_FORCE_INLINE constexpr void clear() noexcept
Clears the string.
LIGHTWEIGHT_FORCE_INLINE constexpr void resize(std::size_t n) noexcept
LIGHTWEIGHT_FORCE_INLINE constexpr void push_back(T c) noexcept
Appends a character to the string.
LIGHTWEIGHT_FORCE_INLINE void reserve(std::size_t capacity)
Reserves capacity for the string. Throws if capacity exceeds the maximum.
T * iterator
Iterator type for the string.
LIGHTWEIGHT_FORCE_INLINE constexpr bool operator!=(SqlFixedString< OtherSize, T, OtherMode > const &other) const noexcept
Inequality comparison operator.
LIGHTWEIGHT_FORCE_INLINE constexpr bool empty() const noexcept
Tests if the string is empty.
LIGHTWEIGHT_FORCE_INLINE constexpr const_iterator begin() const noexcept
Returns a const iterator to the beginning.
LIGHTWEIGHT_FORCE_INLINE constexpr bool operator==(std::basic_string_view< T > other) const noexcept
Equality comparison with a string view.
constexpr LIGHTWEIGHT_FORCE_INLINE SqlFixedString(T const (&text)[SourceSize])
Constructs a fixed-size string from a string literal.
LIGHTWEIGHT_FORCE_INLINE constexpr const_pointer_type data() const noexcept
Returns a const pointer to the underlying data.
LIGHTWEIGHT_FORCE_INLINE constexpr std::basic_string_view< T > ToStringView() const noexcept
Returns a std::basic_string_view<T> from the string.
LIGHTWEIGHT_FORCE_INLINE constexpr std::basic_string_view< T > substr(std::size_t offset=0, std::size_t count=(std::numeric_limits< std::size_t >::max)()) const noexcept
Returns a sub string of the string.
LIGHTWEIGHT_FORCE_INLINE constexpr std::basic_string< T > ToString() const noexcept
Returns a std::basic_string<T> from the string.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlFixedString() noexcept=default
Defaulted default constructor.
LIGHTWEIGHT_FORCE_INLINE constexpr bool operator!=(std::basic_string_view< T > other) const noexcept
Inequality comparison with a string view.
T value_type
The element type of the string.
LIGHTWEIGHT_FORCE_INLINE constexpr T & operator[](std::size_t i) noexcept
Returns a mutable reference to the element at the given index.
LIGHTWEIGHT_FORCE_INLINE void setsize(std::size_t n) noexcept
Sets the size of the string, capped at the maximum capacity.
T const * const_iterator
Const iterator type for the string.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlFixedString(std::basic_string< T > const &s) noexcept
Constructs a fixed-size string from a string.
LIGHTWEIGHT_FORCE_INLINE constexpr iterator begin() noexcept
Returns a mutable iterator to the beginning.
LIGHTWEIGHT_FORCE_INLINE std::weak_ordering operator<=>(SqlFixedString< OtherSize, T, OtherMode > const &other) const noexcept
Three-way comparison operator.
LIGHTWEIGHT_FORCE_INLINE constexpr std::size_t size() const noexcept
Returns the size of the string.
LIGHTWEIGHT_FORCE_INLINE constexpr void pop_back() noexcept
Removes the last character from the string.
LIGHTWEIGHT_FORCE_INLINE constexpr pointer_type data() noexcept
Returns a pointer to the underlying mutable data.
LIGHTWEIGHT_FORCE_INLINE constexpr T const & operator[](std::size_t i) const noexcept
Returns a const reference to the element at the given index.
LIGHTWEIGHT_FORCE_INLINE constexpr iterator end() noexcept
Returns a mutable iterator to the end.
LIGHTWEIGHT_API std::u8string ToUtf8(std::u32string_view u32InputString)