Files
boost_beast/include/beast/http/basic_fields.hpp
T

308 lines
7.8 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_BASIC_FIELDS_HPP
#define BEAST_HTTP_BASIC_FIELDS_HPP
2016-03-11 06:40:37 -05:00
#include <beast/config.hpp>
2016-05-07 14:57:15 -04:00
#include <beast/core/detail/empty_base_optimization.hpp>
#include <beast/http/detail/basic_fields.hpp>
2016-03-11 06:40:37 -05:00
#include <boost/lexical_cast.hpp>
#include <algorithm>
#include <cctype>
#include <memory>
#include <string>
2016-04-19 20:29:16 -04:00
#include <type_traits>
2016-03-11 06:40:37 -05:00
#include <utility>
namespace beast {
namespace http {
/** A container for storing HTTP header fields.
2016-03-11 06:40:37 -05:00
This container is designed to store the field value pairs that make
up the fields and trailers in a HTTP message. Objects of this type
are iterable, with each element holding the field name and field
value.
Field names are stored as-is, but comparisons are case-insensitive.
2016-07-04 13:57:59 -04:00
When the container is iterated, the fields are presented in the order
of insertion. For fields with the same name, the container behaves
as a `std::multiset`; there will be a separate value for each occurrence
2016-07-04 13:57:59 -04:00
of the field name.
@note Meets the requirements of @b FieldSequence.
2016-03-11 06:40:37 -05:00
*/
template<class Allocator>
class basic_fields :
2016-03-11 06:40:37 -05:00
#if ! GENERATING_DOCS
2016-10-09 06:34:35 -04:00
private beast::detail::empty_base_optimization<
2016-03-11 06:40:37 -05:00
typename std::allocator_traits<Allocator>::
template rebind_alloc<
detail::basic_fields_base::element>>,
2016-03-11 06:40:37 -05:00
#endif
public detail::basic_fields_base
2016-03-11 06:40:37 -05:00
{
using alloc_type = typename
std::allocator_traits<Allocator>::
template rebind_alloc<
detail::basic_fields_base::element>;
2016-03-11 06:40:37 -05:00
using alloc_traits =
std::allocator_traits<alloc_type>;
using size_type =
typename std::allocator_traits<Allocator>::size_type;
void
delete_all();
void
move_assign(basic_fields&, std::false_type);
2016-03-11 06:40:37 -05:00
void
move_assign(basic_fields&, std::true_type);
2016-03-11 06:40:37 -05:00
void
copy_assign(basic_fields const&, std::false_type);
2016-03-11 06:40:37 -05:00
void
copy_assign(basic_fields const&, std::true_type);
2016-03-11 06:40:37 -05:00
template<class FieldSequence>
void
copy_from(FieldSequence const& fs)
{
for(auto const& e : fs)
insert(e.first, e.second);
}
public:
/// The type of allocator used.
using allocator_type = Allocator;
2016-10-15 21:02:41 -04:00
/** The value type of the field sequence.
Meets the requirements of @b Field.
*/
#if GENERATING_DOCS
using value_type = implementation_defined;
#endif
/// A const iterator to the field sequence
#if GENERATING_DOCS
using iterator = implementation_defined;
#endif
/// A const iterator to the field sequence
#if GENERATING_DOCS
using const_iterator = implementation_defined;
#endif
2016-03-11 06:40:37 -05:00
/// Default constructor.
basic_fields() = default;
2016-03-11 06:40:37 -05:00
/// Destructor
~basic_fields();
2016-03-11 06:40:37 -05:00
/** Construct the fields.
2016-03-11 06:40:37 -05:00
@param alloc The allocator to use.
*/
explicit
basic_fields(Allocator const& alloc);
2016-03-11 06:40:37 -05:00
/** Move constructor.
The moved-from object becomes an empty field sequence.
@param other The object to move from.
*/
basic_fields(basic_fields&& other);
2016-03-11 06:40:37 -05:00
/** Move assignment.
The moved-from object becomes an empty field sequence.
@param other The object to move from.
*/
basic_fields& operator=(basic_fields&& other);
2016-03-11 06:40:37 -05:00
/// Copy constructor.
basic_fields(basic_fields const&);
2016-03-11 06:40:37 -05:00
/// Copy assignment.
basic_fields& operator=(basic_fields const&);
2016-03-11 06:40:37 -05:00
/// Copy constructor.
template<class OtherAlloc>
basic_fields(basic_fields<OtherAlloc> const&);
2016-03-11 06:40:37 -05:00
/// Copy assignment.
template<class OtherAlloc>
basic_fields& operator=(basic_fields<OtherAlloc> const&);
2016-03-11 06:40:37 -05:00
/// Construct from a field sequence.
template<class FwdIt>
basic_fields(FwdIt first, FwdIt last);
2016-03-11 06:40:37 -05:00
/// Returns `true` if the field sequence contains no elements.
bool
empty() const
{
return set_.empty();
}
/// Returns the number of elements in the field sequence.
std::size_t
size() const
{
return set_.size();
}
2016-10-15 21:02:41 -04:00
/// Returns a const iterator to the beginning of the field sequence.
const_iterator
begin() const
{
return list_.cbegin();
}
/// Returns a const iterator to the end of the field sequence.
const_iterator
end() const
{
return list_.cend();
}
/// Returns a const iterator to the beginning of the field sequence.
const_iterator
cbegin() const
{
return list_.cbegin();
}
/// Returns a const iterator to the end of the field sequence.
const_iterator
cend() const
{
return list_.cend();
}
2016-07-04 13:57:59 -04:00
/// Returns `true` if the specified field exists.
2016-03-11 06:40:37 -05:00
bool
exists(boost::string_ref const& name) const
{
return set_.find(name, less{}) != set_.end();
}
2016-07-04 13:57:59 -04:00
/// Returns the number of values for the specified field.
std::size_t
count(boost::string_ref const& name) const;
/** Returns an iterator to the case-insensitive matching field name.
If more than one field with the specified name exists, the
first field defined by insertion order is returned.
*/
2016-03-11 06:40:37 -05:00
iterator
find(boost::string_ref const& name) const;
2016-07-04 13:57:59 -04:00
/** Returns the value for a case-insensitive matching header, or `""`.
If more than one field with the specified name exists, the
first field defined by insertion order is returned.
*/
2016-03-11 06:40:37 -05:00
boost::string_ref
operator[](boost::string_ref const& name) const;
/// Clear the contents of the basic_fields.
2016-03-11 06:40:37 -05:00
void
clear() noexcept;
/** Remove a field.
2016-07-04 13:57:59 -04:00
If more than one field with the specified name exists, all
matching fields will be removed.
@param name The name of the field(s) to remove.
2016-03-11 06:40:37 -05:00
@return The number of fields removed.
*/
std::size_t
erase(boost::string_ref const& name);
/** Insert a field value.
2016-07-04 13:57:59 -04:00
If a field with the same name already exists, the
existing field is untouched and a new field value pair
is inserted into the container.
@param name The name of the field.
@param value A string holding the value of the field.
2016-03-11 06:40:37 -05:00
*/
void
2016-05-24 06:17:04 -04:00
insert(boost::string_ref const& name, boost::string_ref value);
2016-03-11 06:40:37 -05:00
/** Insert a field value.
2016-07-04 13:57:59 -04:00
If a field with the same name already exists, the
existing field is untouched and a new field value pair
is inserted into the container.
@param name The name of the field
@param value The value of the field. The object will be
converted to a string using `boost::lexical_cast`.
2016-03-11 06:40:37 -05:00
*/
2016-05-27 11:10:45 -04:00
template<class T>
typename std::enable_if<
! std::is_constructible<boost::string_ref, T>::value>::type
2016-03-11 06:40:37 -05:00
insert(boost::string_ref name, T const& value)
{
2016-07-04 13:57:59 -04:00
insert(name, boost::lexical_cast<std::string>(value));
2016-03-11 06:40:37 -05:00
}
/** Replace a field value.
2016-07-04 13:57:59 -04:00
First removes any values with matching field names, then
inserts the new field value.
@param name The name of the field.
@param value A string holding the value of the field.
2016-03-11 06:40:37 -05:00
*/
void
2016-05-24 06:17:04 -04:00
replace(boost::string_ref const& name, boost::string_ref value);
2016-03-11 06:40:37 -05:00
/** Replace a field value.
2016-07-04 13:57:59 -04:00
First removes any values with matching field names, then
inserts the new field value.
@param name The name of the field
@param value The value of the field. The object will be
converted to a string using `boost::lexical_cast`.
2016-03-11 06:40:37 -05:00
*/
2016-05-27 11:10:45 -04:00
template<class T>
typename std::enable_if<
! std::is_constructible<boost::string_ref, T>::value>::type
2016-03-11 06:40:37 -05:00
replace(boost::string_ref const& name, T const& value)
{
replace(name,
boost::lexical_cast<std::string>(value));
}
};
} // http
} // beast
#include <beast/http/impl/basic_fields.ipp>
2016-03-11 06:40:37 -05:00
#endif