11#include <boost/container/small_vector.hpp>
13#include <userver/utils/assert.hpp>
15USERVER_NAMESPACE_BEGIN
25template <std::size_t N>
55 const char&
operator[](std::size_t pos)
const;
61 const char&
at(std::size_t pos)
const;
64 char&
at(std::size_t pos);
70 iterator begin()
noexcept;
71 const_iterator begin()
const noexcept;
73 iterator end()
noexcept;
74 const_iterator end()
const noexcept;
77 std::size_t
size()
const noexcept;
81 const char*
data()
const noexcept;
85 char*
data()
noexcept;
89 void resize(std::size_t n,
char c);
93 template <
class Operation>
100 std::size_t
capacity()
const noexcept;
106 void clear()
noexcept;
109 bool empty()
const noexcept;
115 const char&
front()
const;
121 const char&
back()
const;
127 void append(std::string_view str);
133 boost::container::small_vector<
char, N> data_;
136template <std::size_t N>
140template <std::size_t N>
141SmallString<N>::operator std::string_view()
const {
142 return std::string_view{data_.data(), data_.size()};
145template <std::size_t N>
146SmallString<N>& SmallString<N>::operator=(std::string_view sv) {
147 data_ = {sv.begin(), sv.end()};
151template <std::size_t N>
152bool operator==(
const SmallString<N>& str, std::string_view sv) {
153 return std::string_view{str} == sv;
156template <std::size_t N>
157bool operator==(std::string_view sv,
const SmallString<N>& str) {
158 return std::string_view{str} == sv;
161template <std::size_t N>
162bool operator==(
const SmallString<N>& str1,
const SmallString<N>& str2) {
163 return std::string_view{str1} == std::string_view{str2};
166template <std::size_t N>
167bool operator!=(
const SmallString<N>& str1,
const SmallString<N>& str2) {
168 return !(str1 == str2);
171template <std::size_t N>
172const char& SmallString<N>::operator[](std::size_t pos)
const {
176template <std::size_t N>
177char& SmallString<N>::operator[](std::size_t pos) {
181template <std::size_t N>
182const char& SmallString<N>::at(std::size_t pos)
const {
183 if (size() <= pos)
throw std::out_of_range(
"at");
187template <std::size_t N>
188char& SmallString<N>::at(std::size_t pos) {
189 if (size() <= pos)
throw std::out_of_range(
"at");
193template <std::size_t N>
194typename SmallString<N>::iterator SmallString<N>::begin()
noexcept {
195 return {data_.begin()};
198template <std::size_t N>
199typename SmallString<N>::const_iterator SmallString<N>::begin()
const noexcept {
200 return {data_.begin()};
203template <std::size_t N>
204typename SmallString<N>::iterator SmallString<N>::end()
noexcept {
205 return {data_.end()};
208template <std::size_t N>
209typename SmallString<N>::const_iterator SmallString<N>::end()
const noexcept {
210 return {data_.end()};
213template <std::size_t N>
214std::size_t SmallString<N>::size()
const noexcept {
218template <std::size_t N>
219const char* SmallString<N>::data()
const noexcept {
223template <std::size_t N>
224char* SmallString<N>::data()
noexcept {
228template <std::size_t N>
229bool SmallString<N>::empty()
const noexcept {
230 return data_.empty();
233template <std::size_t N>
234char& SmallString<N>::front() {
235 return data_.front();
238template <std::size_t N>
239const char& SmallString<N>::front()
const {
240 return data_.front();
243template <std::size_t N>
244char& SmallString<N>::back() {
248template <std::size_t N>
249const char& SmallString<N>::back()
const {
253template <std::size_t N>
254void SmallString<N>::push_back(
char c) {
258template <std::size_t N>
259void SmallString<N>::append(std::string_view str) {
260 std::size_t old_size = data_.size();
261 data_.insert(data_.begin() + old_size, str.begin(), str.end());
264template <std::size_t N>
265void SmallString<N>::pop_back() {
269template <std::size_t N>
270void SmallString<N>::resize(std::size_t n,
char c) {
274template <std::size_t N>
275template <
class Operation>
276void SmallString<N>::resize_and_overwrite(std::size_t size, Operation op) {
277 data_.resize(size, boost::container::default_init);
278 data_.resize(std::move(op)(data_.data(), size),
279 boost::container::default_init);
283template <std::size_t N>
284void SmallString<N>::shrink_to_fit() {
285 data_.shrink_to_fit();
288template <std::size_t N>
289std::size_t SmallString<N>::capacity()
const noexcept {
290 return data_.capacity();
293template <std::size_t N>
294void SmallString<N>::reserve(std::size_t n) {
295 return data_.reserve(n);
298template <std::size_t N>
299void SmallString<N>::clear()
noexcept {
307template <std::size_t N>
309 std::size_t operator()(
310 const USERVER_NAMESPACE::utils::
SmallString<N>& s)
const noexcept {
311 return std::hash<std::string_view>{}(std::string_view{s});