mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 21:07:26 +02:00
@ -5,6 +5,7 @@ Version 54:
|
||||
* multi_buffer coverage
|
||||
* consuming_buffers members and coverage
|
||||
* basic_fields members and coverage
|
||||
* Add string_param
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -177,6 +177,7 @@
|
||||
<member><link linkend="beast.ref.static_buffer">static_buffer</link></member>
|
||||
<member><link linkend="beast.ref.static_buffer_n">static_buffer_n</link></member>
|
||||
<member><link linkend="beast.ref.static_string">static_string</link></member>
|
||||
<member><link linkend="beast.ref.string_param">string_param</link></member>
|
||||
<member><link linkend="beast.ref.string_view">string_view</link></member>
|
||||
<member><link linkend="beast.ref.system_error">system_error</link></member>
|
||||
</simplelist>
|
||||
|
@ -14,9 +14,10 @@
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/buffer_cat.hpp>
|
||||
#include <beast/core/buffer_prefix.hpp>
|
||||
#include <beast/core/buffered_read_stream.hpp>
|
||||
#include <beast/core/buffers_adapter.hpp>
|
||||
#include <beast/core/consuming_buffers.hpp>
|
||||
#include <beast/core/buffered_read_stream.hpp>
|
||||
#include <beast/core/drain_buffer.hpp>
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/core/flat_buffer.hpp>
|
||||
#include <beast/core/handler_alloc.hpp>
|
||||
@ -25,6 +26,8 @@
|
||||
#include <beast/core/ostream.hpp>
|
||||
#include <beast/core/static_buffer.hpp>
|
||||
#include <beast/core/static_string.hpp>
|
||||
#include <beast/core/string_param.hpp>
|
||||
#include <beast/core/string_view.hpp>
|
||||
#include <beast/core/type_traits.hpp>
|
||||
|
||||
#endif
|
||||
|
133
include/beast/core/detail/static_ostream.hpp
Normal file
133
include/beast/core/detail/static_ostream.hpp
Normal file
@ -0,0 +1,133 @@
|
||||
//
|
||||
// Copyright (c) 2013-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)
|
||||
//
|
||||
|
||||
#ifndef BEAST_DETAIL_STATIC_OSTREAM_HPP
|
||||
#define BEAST_DETAIL_STATIC_OSTREAM_HPP
|
||||
|
||||
#include <locale>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
|
||||
|
||||
class static_ostream_buffer
|
||||
: public std::basic_streambuf<char>
|
||||
{
|
||||
using CharT = char;
|
||||
using Traits = std::char_traits<CharT>;
|
||||
using int_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::int_type;
|
||||
using traits_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::traits_type;
|
||||
|
||||
char buf_[128];
|
||||
std::string s_;
|
||||
std::size_t len_ = 0;
|
||||
|
||||
public:
|
||||
static_ostream_buffer(static_ostream_buffer&&) = delete;
|
||||
static_ostream_buffer(static_ostream_buffer const&) = delete;
|
||||
|
||||
static_ostream_buffer()
|
||||
{
|
||||
this->setp(buf_, buf_ + sizeof(buf_) - 1);
|
||||
}
|
||||
|
||||
~static_ostream_buffer() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
string_view
|
||||
str() const
|
||||
{
|
||||
if(! s_.empty())
|
||||
return {s_.data(), len_};
|
||||
return {buf_, len_};
|
||||
}
|
||||
|
||||
int_type
|
||||
overflow(int_type ch) override
|
||||
{
|
||||
if(! Traits::eq_int_type(ch, Traits::eof()))
|
||||
{
|
||||
Traits::assign(*this->pptr(), ch);
|
||||
flush(1);
|
||||
prepare();
|
||||
return ch;
|
||||
}
|
||||
flush();
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
int
|
||||
sync() override
|
||||
{
|
||||
flush();
|
||||
prepare();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
prepare()
|
||||
{
|
||||
static auto const growth_factor = 1.5;
|
||||
|
||||
if(len_ < sizeof(buf_) - 1)
|
||||
{
|
||||
this->setp(&buf_[len_],
|
||||
&buf_[sizeof(buf_) - 2]);
|
||||
return;
|
||||
}
|
||||
if(s_.empty())
|
||||
{
|
||||
s_.resize(static_cast<std::size_t>(
|
||||
growth_factor * len_));
|
||||
Traits::copy(&s_[0], buf_, len_);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_.resize(static_cast<std::size_t>(
|
||||
growth_factor * len_));
|
||||
}
|
||||
this->setp(&s_[len_], &s_[len_] +
|
||||
s_.size() - len_ - 1);
|
||||
}
|
||||
|
||||
void
|
||||
flush(int extra = 0)
|
||||
{
|
||||
len_ += static_cast<std::size_t>(
|
||||
this->pptr() - this->pbase() + extra);
|
||||
}
|
||||
};
|
||||
|
||||
class static_ostream : public std::basic_ostream<char>
|
||||
{
|
||||
static_ostream_buffer osb_;
|
||||
|
||||
public:
|
||||
static_ostream()
|
||||
: std::basic_ostream<char>(&this->osb_)
|
||||
{
|
||||
imbue(std::locale::classic());
|
||||
}
|
||||
|
||||
string_view
|
||||
str() const
|
||||
{
|
||||
return osb_.str();
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
125
include/beast/core/string_param.hpp
Normal file
125
include/beast/core/string_param.hpp
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// Copyright (c) 2013-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)
|
||||
//
|
||||
|
||||
#ifndef BEAST_STRING_PARAM_HPP
|
||||
#define BEAST_STRING_PARAM_HPP
|
||||
|
||||
#include <beast/config.hpp>
|
||||
#include <beast/core/string_view.hpp>
|
||||
#include <beast/core/detail/static_ostream.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A function parameter which efficiently converts to string.
|
||||
|
||||
This is used as a function parameter type to allow callers
|
||||
notational convenience: objects other than strings may be
|
||||
passed in contexts where a string is expected. The conversion
|
||||
to string is made using `operator<<` to a non-dynamically
|
||||
allocated static buffer if possible, else to a `std::string`
|
||||
on overflow.
|
||||
*/
|
||||
class string_param
|
||||
{
|
||||
template<class T, class = void>
|
||||
struct is_streamable : std::false_type{};
|
||||
|
||||
#if ! BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_streamable<T, detail::void_t<decltype(
|
||||
std::declval<std::ostream&>() << std::declval<T const&>()
|
||||
)>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
void
|
||||
assign(T const& t, std::true_type)
|
||||
{
|
||||
sv_ = t;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
assign(T const& t, std::false_type)
|
||||
{
|
||||
os_ << t;
|
||||
os_.flush();
|
||||
sv_ = os_.str();
|
||||
}
|
||||
|
||||
detail::static_ostream os_;
|
||||
string_view sv_;
|
||||
|
||||
public:
|
||||
/// Copy constructor (disallowed)
|
||||
string_param(string_param const&) = delete;
|
||||
|
||||
/// Copy assignment (disallowed)
|
||||
string_param& operator=(string_param const&) = delete;
|
||||
|
||||
/** Constructor
|
||||
|
||||
This function constructs a string from the specified
|
||||
parameter.
|
||||
|
||||
If @ref string_view is constructible from `T` then
|
||||
the complexity is O(1), and no dynamic allocation
|
||||
takes place.
|
||||
|
||||
Otherwise, the argument is converted to a string
|
||||
as if by a call to `boost::lexical_cast<std::string>(t)`.
|
||||
An attempt is made to store this string in a reasonably
|
||||
sized buffer inside the class, to avoid dynamic allocation.
|
||||
|
||||
If the argument could not be converted given the space
|
||||
of the class buffer, a final attempt is made to convert
|
||||
the argument to a `std::string`. This attempt may cause
|
||||
a memory allocation.
|
||||
|
||||
@param t The argument to convert to string.
|
||||
|
||||
@note This function participates in overload resolution
|
||||
only if `T` is convertible to @ref string_view, or if
|
||||
`operator<<(std::ostream&, T)` is defined.
|
||||
*/
|
||||
#if BEAST_DOXYGEN
|
||||
template<class T>
|
||||
#else
|
||||
template<class T, class = typename std::enable_if<
|
||||
std::is_convertible<T, string_view>::value ||
|
||||
is_streamable<T>::value
|
||||
>::type>
|
||||
#endif
|
||||
string_param(T const& t);
|
||||
|
||||
/// Conversion to @ref string_view for the converted argument.
|
||||
string_view const
|
||||
str() const
|
||||
{
|
||||
return sv_;
|
||||
}
|
||||
|
||||
/// Conversion to @ref string_view operator
|
||||
operator string_view const() const
|
||||
{
|
||||
return sv_;
|
||||
}
|
||||
};
|
||||
|
||||
#if ! BEAST_DOXYGEN
|
||||
template<class T, class>
|
||||
string_param::
|
||||
string_param(T const& t)
|
||||
{
|
||||
assign(t, std::is_convertible<T, string_view>{});
|
||||
}
|
||||
#endif
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
@ -36,6 +36,7 @@ unit-test core-tests :
|
||||
core/ostream.cpp
|
||||
core/static_buffer.cpp
|
||||
core/static_string.cpp
|
||||
core/string_param.cpp
|
||||
core/string_view.cpp
|
||||
core/type_traits.cpp
|
||||
core/base64.cpp
|
||||
|
@ -31,6 +31,7 @@ add_executable (core-tests
|
||||
ostream.cpp
|
||||
static_buffer.cpp
|
||||
static_string.cpp
|
||||
string_param.cpp
|
||||
string_view.cpp
|
||||
type_traits.cpp
|
||||
base64.cpp
|
||||
|
44
test/core/string_param.cpp
Normal file
44
test/core/string_param.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Copyright (c) 2013-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)
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/core/string_param.hpp>
|
||||
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class string_param_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
struct nop {};
|
||||
|
||||
static_assert(! std::is_constructible<string_param, nop>::value, "");
|
||||
|
||||
void
|
||||
check(string_param const& v, string_view s)
|
||||
{
|
||||
BEAST_EXPECT(v.str() == s);
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
check(std::string("hello"), "hello");
|
||||
check("xyz", "xyz");
|
||||
check(1, "1");
|
||||
check(12, "12");
|
||||
check(123, "123");
|
||||
check(1234, "1234");
|
||||
check(12345, "12345");
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(string_param,core,beast);
|
||||
|
||||
} // beast
|
Reference in New Issue
Block a user