diff options
Diffstat (limited to 'boost/beast/http/impl/fields.ipp')
-rw-r--r-- | boost/beast/http/impl/fields.ipp | 143 |
1 files changed, 78 insertions, 65 deletions
diff --git a/boost/beast/http/impl/fields.ipp b/boost/beast/http/impl/fields.ipp index 67d7cc45b4..a07fd0fa30 100644 --- a/boost/beast/http/impl/fields.ipp +++ b/boost/beast/http/impl/fields.ipp @@ -272,8 +272,10 @@ writer(basic_fields const& f, template<class Allocator> basic_fields<Allocator>:: value_type:: -value_type(field name, - string_view sname, string_view value) +value_type( + field name, + string_view sname, + string_view value) : off_(static_cast<off_t>(sname.size() + 2)) , len_(static_cast<off_t>(value.size())) , f_(name) @@ -285,13 +287,13 @@ value_type(field name, p[off_-1] = ' '; p[off_ + len_] = '\r'; p[off_ + len_ + 1] = '\n'; - std::memcpy(p, sname.data(), sname.size()); - std::memcpy(p + off_, value.data(), value.size()); + sname.copy(p, sname.size()); + value.copy(p + off_, value.size()); } template<class Allocator> inline -field const +field basic_fields<Allocator>:: value_type:: name() const @@ -349,30 +351,31 @@ basic_fields<Allocator>:: template<class Allocator> basic_fields<Allocator>:: -basic_fields(Allocator const& alloc) - : alloc_(alloc) +basic_fields(Allocator const& alloc) noexcept + : beast::detail::empty_base_optimization<Allocator>(alloc) { } template<class Allocator> basic_fields<Allocator>:: -basic_fields(basic_fields&& other) - : alloc_(std::move(other.alloc_)) +basic_fields(basic_fields&& other) noexcept + : beast::detail::empty_base_optimization<Allocator>( + std::move(other.member())) , set_(std::move(other.set_)) , list_(std::move(other.list_)) , method_(other.method_) , target_or_reason_(other.target_or_reason_) { - other.method_.clear(); - other.target_or_reason_.clear(); + other.method_ = {}; + other.target_or_reason_ = {}; } template<class Allocator> basic_fields<Allocator>:: basic_fields(basic_fields&& other, Allocator const& alloc) - : alloc_(alloc) + : beast::detail::empty_base_optimization<Allocator>(alloc) { - if(alloc_ != other.alloc_) + if(this->member() != other.member()) { copy_all(other); other.clear_all(); @@ -389,8 +392,8 @@ basic_fields(basic_fields&& other, Allocator const& alloc) template<class Allocator> basic_fields<Allocator>:: basic_fields(basic_fields const& other) - : alloc_(alloc_traits:: - select_on_container_copy_construction(other.alloc_)) + : beast::detail::empty_base_optimization<Allocator>(alloc_traits:: + select_on_container_copy_construction(other.member())) { copy_all(other); } @@ -399,7 +402,7 @@ template<class Allocator> basic_fields<Allocator>:: basic_fields(basic_fields const& other, Allocator const& alloc) - : alloc_(alloc) + : beast::detail::empty_base_optimization<Allocator>(alloc) { copy_all(other); } @@ -417,7 +420,7 @@ template<class OtherAlloc> basic_fields<Allocator>:: basic_fields(basic_fields<OtherAlloc> const& other, Allocator const& alloc) - : alloc_(alloc) + : beast::detail::empty_base_optimization<Allocator>(alloc) { copy_all(other); } @@ -425,9 +428,12 @@ basic_fields(basic_fields<OtherAlloc> const& other, template<class Allocator> auto basic_fields<Allocator>:: -operator=(basic_fields&& other) -> - basic_fields& +operator=(basic_fields&& other) noexcept( + alloc_traits::propagate_on_container_move_assignment::value) + -> basic_fields& { + static_assert(is_nothrow_move_assignable<Allocator>::value, + "Allocator must be noexcept assignable."); if(this == &other) return *this; move_assign(other, std::integral_constant<bool, @@ -605,11 +611,11 @@ basic_fields<Allocator>:: erase(const_iterator pos) -> const_iterator { - auto next = pos.iter(); + auto next = pos; auto& e = *next++; set_.erase(e); - list_.erase(e); - delete_element(e); + list_.erase(pos); + delete_element(const_cast<value_type&>(e)); return next; } @@ -1014,13 +1020,13 @@ set_chunked_impl(bool value) // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437 std::string s; #else - using rebind_type = + using A = typename beast::detail::allocator_traits< Allocator>::template rebind_alloc<char>; std::basic_string< char, std::char_traits<char>, - rebind_type> s{rebind_type{alloc_}}; + A> s{A{this->member()}}; #endif s.reserve(it->value().size() + 9); s.append(it->value().data(), it->value().size()); @@ -1051,13 +1057,13 @@ set_chunked_impl(bool value) // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437 std::string s; #else - using rebind_type = + using A = typename beast::detail::allocator_traits< Allocator>::template rebind_alloc<char>; std::basic_string< char, std::char_traits<char>, - rebind_type> s{rebind_type{alloc_}}; + A> s{A{this->member()}}; #endif s.reserve(it->value().size()); detail::filter_token_list_last(s, it->value(), @@ -1108,13 +1114,13 @@ set_keep_alive_impl( // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437 std::string s; #else - using rebind_type = + using A = typename beast::detail::allocator_traits< Allocator>::template rebind_alloc<char>; std::basic_string< char, std::char_traits<char>, - rebind_type> s{rebind_type{alloc_}}; + A> s{A{this->member()}}; #endif s.reserve(value.size()); detail::keep_alive_impl( @@ -1148,13 +1154,14 @@ new_element(field name, static_cast<off_t>(sname.size() + 2); std::uint16_t const len = static_cast<off_t>(value.size()); - auto const p = alloc_traits::allocate(alloc_, - 1 + (off + len + 2 + sizeof(value_type) - 1) / - sizeof(value_type)); + auto a = rebind_type{this->member()}; + auto const p = alloc_traits::allocate(a, + (sizeof(value_type) + off + len + 2 + sizeof(align_type) - 1) / + sizeof(align_type)); // VFALCO allocator can't call the constructor because its private - //alloc_traits::construct(alloc_, p, name, sname, value); + //alloc_traits::construct(a, p, name, sname, value); new(p) value_type{name, sname, value}; - return *p; + return *reinterpret_cast<value_type*>(p); } template<class Allocator> @@ -1162,10 +1169,14 @@ void basic_fields<Allocator>:: delete_element(value_type& e) { - auto const n = 1 + (e.off_ + e.len_ + 2 + - sizeof(value_type) - 1) / sizeof(value_type); - alloc_traits::destroy(alloc_, &e); - alloc_traits::deallocate(alloc_, &e, n); + auto a = rebind_type{this->member()}; + auto const n = + (sizeof(value_type) + e.off_ + e.len_ + 2 + sizeof(align_type) - 1) / + sizeof(align_type); + //alloc_traits::destroy(a, &e); + e.~value_type(); + alloc_traits::deallocate(a, + reinterpret_cast<align_type*>(&e), n); } template<class Allocator> @@ -1207,19 +1218,20 @@ realloc_string(string_view& dest, string_view s) return; auto a = typename beast::detail::allocator_traits< Allocator>::template rebind_alloc< - char>(alloc_); - if(! dest.empty()) + char>(this->member()); + char* p = nullptr; + if(! s.empty()) { + p = a.allocate(s.size()); + s.copy(p, s.size()); + } + if(! dest.empty()) a.deallocate(const_cast<char*>( dest.data()), dest.size()); - dest.clear(); - } - if(! s.empty()) - { - auto const p = a.allocate(s.size()); - std::memcpy(p, s.data(), s.size()); + if(p) dest = {p, s.size()}; - } + else + dest = {}; } template<class Allocator> @@ -1235,20 +1247,21 @@ realloc_target( return; auto a = typename beast::detail::allocator_traits< Allocator>::template rebind_alloc< - char>(alloc_); - if(! dest.empty()) - { - a.deallocate(const_cast<char*>( - dest.data()), dest.size()); - dest.clear(); - } + char>(this->member()); + char* p = nullptr; if(! s.empty()) { - auto const p = a.allocate(1 + s.size()); + p = a.allocate(1 + s.size()); p[0] = ' '; - std::memcpy(p + 1, s.data(), s.size()); - dest = {p, 1 + s.size()}; + s.copy(p + 1, s.size()); } + if(! dest.empty()) + a.deallocate(const_cast<char*>( + dest.data()), dest.size()); + if(p) + dest = {p, 1 + s.size()}; + else + dest = {}; } template<class Allocator> @@ -1296,9 +1309,9 @@ move_assign(basic_fields& other, std::true_type) list_ = std::move(other.list_); method_ = other.method_; target_or_reason_ = other.target_or_reason_; - other.method_.clear(); - other.target_or_reason_.clear(); - alloc_ = other.alloc_; + other.method_ = {}; + other.target_or_reason_ = {}; + this->member() = other.member(); } template<class Allocator> @@ -1308,7 +1321,7 @@ basic_fields<Allocator>:: move_assign(basic_fields& other, std::false_type) { clear_all(); - if(alloc_ != other.alloc_) + if(this->member() != other.member()) { copy_all(other); other.clear_all(); @@ -1319,8 +1332,8 @@ move_assign(basic_fields& other, std::false_type) list_ = std::move(other.list_); method_ = other.method_; target_or_reason_ = other.target_or_reason_; - other.method_.clear(); - other.target_or_reason_.clear(); + other.method_ = {}; + other.target_or_reason_ = {}; } } @@ -1331,7 +1344,7 @@ basic_fields<Allocator>:: copy_assign(basic_fields const& other, std::true_type) { clear_all(); - alloc_ = other.alloc_; + this->member() = other.member(); copy_all(other); } @@ -1352,7 +1365,7 @@ basic_fields<Allocator>:: swap(basic_fields& other, std::true_type) { using std::swap; - swap(alloc_, other.alloc_); + swap(this->member(), other.member()); swap(set_, other.set_); swap(list_, other.list_); swap(method_, other.method_); @@ -1365,7 +1378,7 @@ void basic_fields<Allocator>:: swap(basic_fields& other, std::false_type) { - BOOST_ASSERT(alloc_ == other.alloc_); + BOOST_ASSERT(this->member() == other.member()); using std::swap; swap(set_, other.set_); swap(list_, other.list_); |