summaryrefslogtreecommitdiff
path: root/boost/beast/core/impl/static_string.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/core/impl/static_string.ipp')
-rw-r--r--boost/beast/core/impl/static_string.ipp618
1 files changed, 618 insertions, 0 deletions
diff --git a/boost/beast/core/impl/static_string.ipp b/boost/beast/core/impl/static_string.ipp
new file mode 100644
index 0000000000..29571dfeee
--- /dev/null
+++ b/boost/beast/core/impl/static_string.ipp
@@ -0,0 +1,618 @@
+//
+// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_IMPL_STATIC_STRING_IPP
+#define BOOST_BEAST_IMPL_STATIC_STRING_IPP
+
+#include <boost/beast/core/detail/static_string.hpp>
+#include <boost/beast/core/detail/type_traits.hpp>
+#include <boost/throw_exception.hpp>
+
+namespace boost {
+namespace beast {
+
+//
+// (constructor)
+//
+
+template<std::size_t N, class CharT, class Traits>
+static_string<N, CharT, Traits>::
+static_string()
+{
+ n_ = 0;
+ term();
+}
+
+template<std::size_t N, class CharT, class Traits>
+static_string<N, CharT, Traits>::
+static_string(size_type count, CharT ch)
+{
+ assign(count, ch);
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<std::size_t M>
+static_string<N, CharT, Traits>::
+static_string(static_string<M, CharT, Traits> const& other,
+ size_type pos)
+{
+ assign(other, pos);
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<std::size_t M>
+static_string<N, CharT, Traits>::
+static_string(static_string<M, CharT, Traits> const& other,
+ size_type pos, size_type count)
+{
+ assign(other, pos, count);
+}
+
+template<std::size_t N, class CharT, class Traits>
+static_string<N, CharT, Traits>::
+static_string(CharT const* s, size_type count)
+{
+ assign(s, count);
+}
+
+template<std::size_t N, class CharT, class Traits>
+static_string<N, CharT, Traits>::
+static_string(CharT const* s)
+{
+ assign(s);
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<class InputIt>
+static_string<N, CharT, Traits>::
+static_string(InputIt first, InputIt last)
+{
+ assign(first, last);
+}
+
+template<std::size_t N, class CharT, class Traits>
+static_string<N, CharT, Traits>::
+static_string(static_string const& s)
+{
+ assign(s);
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<std::size_t M>
+static_string<N, CharT, Traits>::
+static_string(static_string<M, CharT, Traits> const& s)
+{
+ assign(s);
+}
+
+template<std::size_t N, class CharT, class Traits>
+static_string<N, CharT, Traits>::
+static_string(std::initializer_list<CharT> init)
+{
+ assign(init.begin(), init.end());
+}
+
+template<std::size_t N, class CharT, class Traits>
+static_string<N, CharT, Traits>::
+static_string(string_view_type sv)
+{
+ assign(sv);
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<class T, class>
+static_string<N, CharT, Traits>::
+static_string(T const& t, size_type pos, size_type n)
+{
+ assign(t, pos, n);
+}
+
+//
+// (assignment)
+//
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+assign(size_type count, CharT ch) ->
+ static_string&
+{
+ if(count > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "count > max_size()"});
+ n_ = count;
+ Traits::assign(&s_[0], n_, ch);
+ term();
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+assign(static_string const& str) ->
+ static_string&
+{
+ n_ = str.n_;
+ Traits::copy(&s_[0], &str.s_[0], n_ + 1);
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<std::size_t M>
+auto
+static_string<N, CharT, Traits>::
+assign(static_string<M, CharT, Traits> const& str,
+ size_type pos, size_type count) ->
+ static_string&
+{
+ auto const ss = str.substr(pos, count);
+ return assign(ss.data(), ss.size());
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+assign(CharT const* s, size_type count) ->
+ static_string&
+{
+ if(count > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "count > max_size()"});
+ n_ = count;
+ Traits::copy(&s_[0], s, n_);
+ term();
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<class InputIt>
+auto
+static_string<N, CharT, Traits>::
+assign(InputIt first, InputIt last) ->
+ static_string&
+{
+ std::size_t const n = std::distance(first, last);
+ if(n > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "n > max_size()"});
+ n_ = n;
+ for(auto it = &s_[0]; first != last; ++it, ++first)
+ Traits::assign(*it, *first);
+ term();
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<class T>
+auto
+static_string<N, CharT, Traits>::
+assign(T const& t, size_type pos, size_type count) ->
+ typename std::enable_if<std::is_convertible<T,
+ string_view_type>::value, static_string&>::type
+{
+ auto const sv = string_view_type(t).substr(pos, count);
+ if(sv.size() > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "sv.size() > max_size()"});
+ n_ = sv.size();
+ Traits::copy(&s_[0], &sv[0], n_);
+ term();
+ return *this;
+}
+
+//
+// Element access
+//
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+at(size_type pos) ->
+ reference
+{
+ if(pos >= size())
+ BOOST_THROW_EXCEPTION(std::out_of_range{
+ "pos >= size()"});
+ return s_[pos];
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+at(size_type pos) const ->
+ const_reference
+{
+ if(pos >= size())
+ BOOST_THROW_EXCEPTION(std::out_of_range{
+ "pos >= size()"});
+ return s_[pos];
+}
+
+//
+// Capacity
+//
+
+template<std::size_t N, class CharT, class Traits>
+void
+static_string<N, CharT, Traits>::
+reserve(std::size_t n)
+{
+ if(n > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "n > max_size()"});
+}
+
+//
+// Operations
+//
+
+template<std::size_t N, class CharT, class Traits>
+void
+static_string<N, CharT, Traits>::
+clear()
+{
+ n_ = 0;
+ term();
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+insert(size_type index, size_type count, CharT ch) ->
+ static_string&
+{
+ if(index > size())
+ BOOST_THROW_EXCEPTION(std::out_of_range{
+ "index > size()"});
+ insert(begin() + index, count, ch);
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+insert(size_type index, CharT const* s, size_type count) ->
+ static_string&
+{
+ if(index > size())
+ BOOST_THROW_EXCEPTION(std::out_of_range{
+ "index > size()"});
+ if(size() + count > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "size() + count > max_size()"});
+ Traits::move(
+ &s_[index + count], &s_[index], size() - index);
+ n_ += count;
+ Traits::copy(&s_[index], s, count);
+ term();
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<std::size_t M>
+auto
+static_string<N, CharT, Traits>::
+insert(size_type index,
+ static_string<M, CharT, Traits> const& str,
+ size_type index_str, size_type count) ->
+ static_string&
+{
+ auto const ss = str.substr(index_str, count);
+ return insert(index, ss.data(), ss.size());
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+insert(const_iterator pos, size_type count, CharT ch) ->
+ iterator
+{
+ if(size() + count > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "size() + count() > max_size()"});
+ auto const index = pos - &s_[0];
+ Traits::move(
+ &s_[index + count], &s_[index], size() - index);
+ n_ += count;
+ Traits::assign(&s_[index], count, ch);
+ term();
+ return &s_[index];
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<class InputIt>
+auto
+static_string<N, CharT, Traits>::
+insert(const_iterator pos, InputIt first, InputIt last) ->
+ typename std::enable_if<
+ detail::is_input_iterator<InputIt>::value,
+ iterator>::type
+{
+ std::size_t const count = std::distance(first, last);
+ if(size() + count > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "size() + count > max_size()"});
+ std::size_t const index = pos - begin();
+ Traits::move(
+ &s_[index + count], &s_[index], size() - index);
+ n_ += count;
+ for(auto it = begin() + index;
+ first != last; ++it, ++first)
+ Traits::assign(*it, *first);
+ term();
+ return begin() + index;
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<class T>
+auto
+static_string<N, CharT, Traits>::
+insert(size_type index, const T& t,
+ size_type index_str, size_type count) ->
+ typename std::enable_if<std::is_convertible<
+ T const&, string_view_type>::value &&
+ ! std::is_convertible<T const&, CharT const*>::value,
+ static_string&>::type
+{
+ auto const str =
+ string_view_type(t).substr(index_str, count);
+ return insert(index, str.data(), str.size());
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+erase(size_type index, size_type count) ->
+ static_string&
+{
+ if(index > size())
+ BOOST_THROW_EXCEPTION(std::out_of_range{
+ "index > size()"});
+ auto const n = (std::min)(count, size() - index);
+ Traits::move(
+ &s_[index], &s_[index + n], size() - (index + n) + 1);
+ n_ -= n;
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+erase(const_iterator pos) ->
+ iterator
+{
+ erase(pos - begin(), 1);
+ return begin() + (pos - begin());
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+erase(const_iterator first, const_iterator last) ->
+ iterator
+{
+ erase(first - begin(),
+ std::distance(first, last));
+ return begin() + (first - begin());
+}
+
+template<std::size_t N, class CharT, class Traits>
+void
+static_string<N, CharT, Traits>::
+push_back(CharT ch)
+{
+ if(size() >= max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "size() >= max_size()"});
+ Traits::assign(s_[n_++], ch);
+ term();
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<std::size_t M>
+auto
+static_string<N, CharT, Traits>::
+append(static_string<M, CharT, Traits> const& str,
+ size_type pos, size_type count) ->
+ static_string&
+{
+ // Valid range is [0, size)
+ if(pos >= str.size())
+ BOOST_THROW_EXCEPTION(std::out_of_range{
+ "pos > str.size()"});
+ string_view_type const ss{&str.s_[pos],
+ (std::min)(count, str.size() - pos)};
+ insert(size(), ss.data(), ss.size());
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+substr(size_type pos, size_type count) const ->
+ string_view_type
+{
+ if(pos > size())
+ BOOST_THROW_EXCEPTION(std::out_of_range{
+ "pos > size()"});
+ return{&s_[pos], (std::min)(count, size() - pos)};
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+copy(CharT* dest, size_type count, size_type pos) const ->
+ size_type
+{
+ auto const str = substr(pos, count);
+ Traits::copy(dest, str.data(), str.size());
+ return str.size();
+}
+
+template<std::size_t N, class CharT, class Traits>
+void
+static_string<N, CharT, Traits>::
+resize(std::size_t n)
+{
+ if(n > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "n > max_size()"});
+ n_ = n;
+ term();
+}
+
+template<std::size_t N, class CharT, class Traits>
+void
+static_string<N, CharT, Traits>::
+resize(std::size_t n, CharT c)
+{
+ if(n > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "n > max_size()"});
+ if(n > n_)
+ Traits::assign(&s_[n_], n - n_, c);
+ n_ = n;
+ term();
+}
+
+template<std::size_t N, class CharT, class Traits>
+void
+static_string<N, CharT, Traits>::
+swap(static_string& str)
+{
+ static_string tmp(str);
+ str.n_ = n_;
+ Traits::copy(&str.s_[0], &s_[0], n_ + 1);
+ n_ = tmp.n_;
+ Traits::copy(&s_[0], &tmp.s_[0], n_ + 1);
+}
+
+template<std::size_t N, class CharT, class Traits>
+template<std::size_t M>
+void
+static_string<N, CharT, Traits>::
+swap(static_string<M, CharT, Traits>& str)
+{
+ if(size() > str.max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "size() > str.max_size()"});
+ if(str.size() > max_size())
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "str.size() > max_size()"});
+ static_string tmp(str);
+ str.n_ = n_;
+ Traits::copy(&str.s_[0], &s_[0], n_ + 1);
+ n_ = tmp.n_;
+ Traits::copy(&s_[0], &tmp.s_[0], n_ + 1);
+}
+
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+assign_char(CharT ch, std::true_type) ->
+ static_string&
+{
+ n_ = 1;
+ Traits::assign(s_[0], ch);
+ term();
+ return *this;
+}
+
+template<std::size_t N, class CharT, class Traits>
+auto
+static_string<N, CharT, Traits>::
+assign_char(CharT, std::false_type) ->
+ static_string&
+{
+ BOOST_THROW_EXCEPTION(std::length_error{
+ "max_size() == 0"});
+}
+
+namespace detail {
+
+template<class Integer>
+static_string<max_digits(sizeof(Integer))>
+to_static_string(Integer x, std::true_type)
+{
+ if(x == 0)
+ return {'0'};
+ static_string<detail::max_digits(
+ sizeof(Integer))> s;
+ if(x < 0)
+ {
+ x = -x;
+ char buf[max_digits(sizeof(x))];
+ char* p = buf;
+ for(;x > 0; x /= 10)
+ *p++ = "0123456789"[x % 10];
+ s.resize(1 + p - buf);
+ s[0] = '-';
+ auto d = &s[1];
+ while(p > buf)
+ *d++ = *--p;
+ }
+ else
+ {
+ char buf[max_digits(sizeof(x))];
+ char* p = buf;
+ for(;x > 0; x /= 10)
+ *p++ = "0123456789"[x % 10];
+ s.resize(p - buf);
+ auto d = &s[0];
+ while(p > buf)
+ *d++ = *--p;
+ }
+ return s;
+}
+
+template<class Integer>
+static_string<max_digits(sizeof(Integer))>
+to_static_string(Integer x, std::false_type)
+{
+ if(x == 0)
+ return {'0'};
+ char buf[max_digits(sizeof(x))];
+ char* p = buf;
+ for(;x > 0; x /= 10)
+ *p++ = "0123456789"[x % 10];
+ static_string<detail::max_digits(
+ sizeof(Integer))> s;
+ s.resize(p - buf);
+ auto d = &s[0];
+ while(p > buf)
+ *d++ = *--p;
+ return s;
+}
+
+} // detail
+
+template<class Integer>
+static_string<detail::max_digits(sizeof(Integer))>
+to_static_string(Integer x)
+{
+ using CharT = char;
+ using Traits = std::char_traits<CharT>;
+ BOOST_STATIC_ASSERT(std::is_integral<Integer>::value);
+ char buf[detail::max_digits(sizeof(Integer))];
+ auto last = buf + sizeof(buf);
+ auto it = detail::raw_to_string<
+ CharT, Integer, Traits>(last, sizeof(buf), x);
+ static_string<detail::max_digits(sizeof(Integer))> s;
+ s.resize(static_cast<std::size_t>(last - it));
+ auto p = s.data();
+ while(it < last)
+ Traits::assign(*p++, *it++);
+ return s;
+}
+
+} // beast
+} // boost
+
+#endif