// // 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 #include #include #include 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 struct is_streamable : std::false_type{}; #if ! BEAST_DOXYGEN template struct is_streamable() << std::declval() )>> : std::true_type {}; #endif template void assign(T const& t, std::true_type) { sv_ = t; } template 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(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 #else template::value || is_streamable::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 string_param:: string_param(T const& t) { assign(t, std::is_convertible{}); } #endif } // beast #endif