Files
boost_beast/include/beast/http/impl/basic_fields.ipp
T

267 lines
5.5 KiB
C++
Raw Normal View History

2016-04-19 20:29:16 -04:00
//
2017-02-06 20:07:03 -05:00
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
2016-04-19 20:29:16 -04:00
//
// 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)
//
2016-03-11 06:40:37 -05:00
#ifndef BEAST_HTTP_IMPL_BASIC_FIELDS_IPP
#define BEAST_HTTP_IMPL_BASIC_FIELDS_IPP
2016-03-11 06:40:37 -05:00
2016-05-24 06:17:04 -04:00
#include <beast/http/detail/rfc7230.hpp>
2016-07-04 13:57:59 -04:00
#include <algorithm>
2016-05-24 06:17:04 -04:00
2016-03-11 06:40:37 -05:00
namespace beast {
namespace http {
template<class Allocator>
void
basic_fields<Allocator>::
2016-03-11 06:40:37 -05:00
delete_all()
{
for(auto it = list_.begin(); it != list_.end();)
{
auto& e = *it++;
2016-05-04 14:22:58 -04:00
alloc_traits::destroy(this->member(), &e);
2016-03-11 06:40:37 -05:00
alloc_traits::deallocate(
this->member(), &e, 1);
}
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
move_assign(basic_fields& other, std::false_type)
2016-03-11 06:40:37 -05:00
{
if(this->member() != other.member())
{
copy_from(other);
other.clear();
}
else
{
set_ = std::move(other.set_);
list_ = std::move(other.list_);
}
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
move_assign(basic_fields& other, std::true_type)
2016-03-11 06:40:37 -05:00
{
this->member() = std::move(other.member());
set_ = std::move(other.set_);
list_ = std::move(other.list_);
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
copy_assign(basic_fields const& other, std::false_type)
2016-03-11 06:40:37 -05:00
{
copy_from(other);
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
copy_assign(basic_fields const& other, std::true_type)
2016-03-11 06:40:37 -05:00
{
this->member() = other.member();
copy_from(other);
}
//------------------------------------------------------------------------------
template<class Allocator>
basic_fields<Allocator>::
~basic_fields()
2016-03-11 06:40:37 -05:00
{
delete_all();
}
template<class Allocator>
basic_fields<Allocator>::
basic_fields(Allocator const& alloc)
2016-04-19 20:29:16 -04:00
: beast::detail::empty_base_optimization<
2016-03-11 06:40:37 -05:00
alloc_type>(alloc)
{
}
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields&& other)
2016-04-19 20:29:16 -04:00
: beast::detail::empty_base_optimization<alloc_type>(
2016-03-11 06:40:37 -05:00
std::move(other.member()))
, detail::basic_fields_base(
2016-03-11 06:40:37 -05:00
std::move(other.set_), std::move(other.list_))
{
}
template<class Allocator>
auto
basic_fields<Allocator>::
operator=(basic_fields&& other) ->
basic_fields&
2016-03-11 06:40:37 -05:00
{
if(this == &other)
return *this;
clear();
move_assign(other, std::integral_constant<bool,
alloc_traits::propagate_on_container_move_assignment::value>{});
return *this;
}
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields const& other)
: basic_fields(alloc_traits::
2016-03-11 06:40:37 -05:00
select_on_container_copy_construction(other.member()))
{
copy_from(other);
}
template<class Allocator>
auto
basic_fields<Allocator>::
operator=(basic_fields const& other) ->
basic_fields&
2016-03-11 06:40:37 -05:00
{
clear();
copy_assign(other, std::integral_constant<bool,
alloc_traits::propagate_on_container_copy_assignment::value>{});
return *this;
}
template<class Allocator>
template<class OtherAlloc>
basic_fields<Allocator>::
basic_fields(basic_fields<OtherAlloc> const& other)
2016-03-11 06:40:37 -05:00
{
copy_from(other);
}
template<class Allocator>
template<class OtherAlloc>
auto
basic_fields<Allocator>::
operator=(basic_fields<OtherAlloc> const& other) ->
basic_fields&
2016-03-11 06:40:37 -05:00
{
clear();
copy_from(other);
return *this;
}
template<class Allocator>
template<class FwdIt>
basic_fields<Allocator>::
basic_fields(FwdIt first, FwdIt last)
2016-03-11 06:40:37 -05:00
{
for(;first != last; ++first)
insert(first->name(), first->value());
}
2016-07-04 13:57:59 -04:00
template<class Allocator>
std::size_t
basic_fields<Allocator>::
2016-07-04 13:57:59 -04:00
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::size_t>(std::distance(it, last));
}
2016-03-11 06:40:37 -05:00
template<class Allocator>
auto
basic_fields<Allocator>::
2016-03-11 06:40:37 -05:00
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<class Allocator>
boost::string_ref
basic_fields<Allocator>::
2016-03-11 06:40:37 -05:00
operator[](boost::string_ref const& name) const
{
auto const it = find(name);
if(it == end())
2016-07-04 13:57:59 -04:00
return {};
2016-03-11 06:40:37 -05:00
return it->second;
}
template<class Allocator>
void
basic_fields<Allocator>::
2016-03-11 06:40:37 -05:00
clear() noexcept
{
delete_all();
list_.clear();
set_.clear();
}
template<class Allocator>
std::size_t
basic_fields<Allocator>::
2016-03-11 06:40:37 -05:00
erase(boost::string_ref const& name)
{
2016-07-04 13:57:59 -04:00
auto it = set_.find(name, less{});
2016-03-11 06:40:37 -05:00
if(it == set_.end())
return 0;
2016-07-04 13:57:59 -04:00
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;
2016-03-11 06:40:37 -05:00
}
template<class Allocator>
void
basic_fields<Allocator>::
2016-03-11 06:40:37 -05:00
insert(boost::string_ref const& name,
2016-05-24 06:17:04 -04:00
boost::string_ref value)
2016-03-11 06:40:37 -05:00
{
2016-05-24 06:17:04 -04:00
value = detail::trim(value);
2016-07-04 13:57:59 -04:00
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);
2016-03-11 06:40:37 -05:00
}
template<class Allocator>
void
basic_fields<Allocator>::
2016-03-11 06:40:37 -05:00
replace(boost::string_ref const& name,
2016-05-24 06:17:04 -04:00
boost::string_ref value)
2016-03-11 06:40:37 -05:00
{
2016-05-24 06:17:04 -04:00
value = detail::trim(value);
2016-03-11 06:40:37 -05:00
erase(name);
insert(name, value);
}
} // http
} // beast
#endif