// // Copyright (c) 2013-2016 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) // #ifndef BEAST_HTTP_IMPL_BASIC_FIELDS_IPP #define BEAST_HTTP_IMPL_BASIC_FIELDS_IPP #include #include namespace beast { namespace http { template void basic_fields:: delete_all() { for(auto it = list_.begin(); it != list_.end();) { auto& e = *it++; alloc_traits::destroy(this->member(), &e); alloc_traits::deallocate( this->member(), &e, 1); } } template inline void basic_fields:: move_assign(basic_fields& other, std::false_type) { if(this->member() != other.member()) { copy_from(other); other.clear(); } else { set_ = std::move(other.set_); list_ = std::move(other.list_); } } template inline void basic_fields:: move_assign(basic_fields& other, std::true_type) { this->member() = std::move(other.member()); set_ = std::move(other.set_); list_ = std::move(other.list_); } template inline void basic_fields:: copy_assign(basic_fields const& other, std::false_type) { copy_from(other); } template inline void basic_fields:: copy_assign(basic_fields const& other, std::true_type) { this->member() = other.member(); copy_from(other); } //------------------------------------------------------------------------------ template basic_fields:: ~basic_fields() { delete_all(); } template basic_fields:: basic_fields(Allocator const& alloc) : beast::detail::empty_base_optimization< alloc_type>(alloc) { } template basic_fields:: basic_fields(basic_fields&& other) : beast::detail::empty_base_optimization( std::move(other.member())) , detail::basic_fields_base( std::move(other.set_), std::move(other.list_)) { } template auto basic_fields:: operator=(basic_fields&& other) -> basic_fields& { if(this == &other) return *this; clear(); move_assign(other, std::integral_constant{}); return *this; } template basic_fields:: basic_fields(basic_fields const& other) : basic_fields(alloc_traits:: select_on_container_copy_construction(other.member())) { copy_from(other); } template auto basic_fields:: operator=(basic_fields const& other) -> basic_fields& { clear(); copy_assign(other, std::integral_constant{}); return *this; } template template basic_fields:: basic_fields(basic_fields const& other) { copy_from(other); } template template auto basic_fields:: operator=(basic_fields const& other) -> basic_fields& { clear(); copy_from(other); return *this; } template template basic_fields:: basic_fields(FwdIt first, FwdIt last) { for(;first != last; ++first) insert(first->name(), first->value()); } template std::size_t basic_fields:: count(boost::string_ref const& name) const { auto const it = set_.find(name, less{}); if(it == set_.end()) return 0; auto const last = set_.upper_bound(name, less{}); return static_cast(std::distance(it, last)); } template auto basic_fields:: find(boost::string_ref const& name) const -> iterator { auto const it = set_.find(name, less{}); if(it == set_.end()) return list_.end(); return list_.iterator_to(*it); } template boost::string_ref basic_fields:: operator[](boost::string_ref const& name) const { auto const it = find(name); if(it == end()) return {}; return it->second; } template void basic_fields:: clear() noexcept { delete_all(); list_.clear(); set_.clear(); } template std::size_t basic_fields:: erase(boost::string_ref const& name) { auto it = set_.find(name, less{}); if(it == set_.end()) return 0; auto const last = set_.upper_bound(name, less{}); std::size_t n = 1; for(;;) { auto& e = *it++; set_.erase(set_.iterator_to(e)); list_.erase(list_.iterator_to(e)); alloc_traits::destroy(this->member(), &e); alloc_traits::deallocate(this->member(), &e, 1); if(it == last) break; ++n; } return n; } template void basic_fields:: insert(boost::string_ref const& name, boost::string_ref value) { value = detail::trim(value); auto const p = alloc_traits::allocate(this->member(), 1); alloc_traits::construct(this->member(), p, name, value); set_.insert_before(set_.upper_bound(name, less{}), *p); list_.push_back(*p); } template void basic_fields:: replace(boost::string_ref const& name, boost::string_ref value) { value = detail::trim(value); erase(name); insert(name, value); } } // http } // beast #endif