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});