mirror of
https://github.com/boostorg/static_string.git
synced 2025-07-29 20:17:35 +02:00
to_static_string and to_static_wstring overloads
This commit is contained in:
@ -15,14 +15,22 @@
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <cwchar>
|
||||
|
||||
namespace boost {
|
||||
namespace static_string {
|
||||
namespace detail {
|
||||
|
||||
template<std::size_t, typename, typename>
|
||||
class basic_static_string;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<std::size_t N>
|
||||
using static_string = basic_static_string<N, char, std::char_traits<char>>;
|
||||
|
||||
template<std::size_t N>
|
||||
using static_wstring = basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
|
||||
|
||||
// At minimum an integral type shall not qualify as an iterator (Agustin Berge)
|
||||
template<class T>
|
||||
using is_input_iterator =
|
||||
@ -288,73 +296,128 @@ lexicographical_compare(
|
||||
s1.data(), s1.size(), s2.data(), s2.size());
|
||||
}
|
||||
|
||||
// Maximum number of characters in the decimal
|
||||
// representation of a binary number. This includes
|
||||
// the potential minus sign.
|
||||
//
|
||||
BOOST_STATIC_STRING_CPP11_CONSTEXPR
|
||||
template<typename Traits, typename Integer>
|
||||
inline
|
||||
std::size_t
|
||||
max_digits(std::size_t bytes)
|
||||
char*
|
||||
integer_to_string(
|
||||
char* str_end, Integer value, std::true_type)
|
||||
{
|
||||
return static_cast<std::size_t>(
|
||||
bytes * 2.41) + 1 + 1;
|
||||
if (value == 0)
|
||||
{
|
||||
Traits::assign(*--str_end, '0');
|
||||
return str_end;
|
||||
}
|
||||
if (value < 0)
|
||||
{
|
||||
value = -value;
|
||||
for(; value > 0; value /= 10)
|
||||
Traits::assign(*--str_end, "0123456789"[value % 10]);
|
||||
Traits::assign(*--str_end, '-');
|
||||
return str_end;
|
||||
}
|
||||
for (; value > 0; value /= 10)
|
||||
Traits::assign(*--str_end, "0123456789"[value % 10]);
|
||||
return str_end;
|
||||
}
|
||||
|
||||
template<typename CharT, class Integer, typename Traits>
|
||||
template<typename Traits, typename Integer>
|
||||
inline
|
||||
CharT*
|
||||
raw_to_string(
|
||||
CharT* buf, Integer x, std::true_type)
|
||||
char*
|
||||
integer_to_string(
|
||||
char* str_end, Integer value, std::false_type)
|
||||
{
|
||||
if(x == 0)
|
||||
if (value == 0)
|
||||
{
|
||||
Traits::assign(*--buf, '0');
|
||||
return buf;
|
||||
Traits::assign(*--str_end, '0');
|
||||
return str_end;
|
||||
}
|
||||
if(x < 0)
|
||||
{
|
||||
x = -x;
|
||||
for(;x > 0; x /= 10)
|
||||
Traits::assign(*--buf ,
|
||||
"0123456789"[x % 10]);
|
||||
Traits::assign(*--buf, '-');
|
||||
return buf;
|
||||
}
|
||||
for(;x > 0; x /= 10)
|
||||
Traits::assign(*--buf ,
|
||||
"0123456789"[x % 10]);
|
||||
return buf;
|
||||
for (; value > 0; value /= 10)
|
||||
Traits::assign(*--str_end, "0123456789"[value % 10]);
|
||||
return str_end;
|
||||
}
|
||||
|
||||
template<typename CharT, class Integer, typename Traits>
|
||||
template<typename Traits, typename Integer>
|
||||
inline
|
||||
CharT*
|
||||
raw_to_string(
|
||||
CharT* buf, Integer x, std::false_type)
|
||||
wchar_t*
|
||||
integer_to_wstring(
|
||||
wchar_t* str_end, Integer value, std::true_type)
|
||||
{
|
||||
if(x == 0)
|
||||
{
|
||||
*--buf = '0';
|
||||
return buf;
|
||||
}
|
||||
for(;x > 0; x /= 10)
|
||||
Traits::assign(*--buf ,
|
||||
"0123456789"[x % 10]);
|
||||
return buf;
|
||||
if (value == 0)
|
||||
{
|
||||
Traits::assign(*--str_end, L'0');
|
||||
return str_end;
|
||||
}
|
||||
if (value < 0)
|
||||
{
|
||||
value = -value;
|
||||
for (; value > 0; value /= 10)
|
||||
Traits::assign(*--str_end, L"0123456789"[value % 10]);
|
||||
Traits::assign(*--str_end, L'-');
|
||||
return str_end;
|
||||
}
|
||||
for (; value > 0; value /= 10)
|
||||
Traits::assign(*--str_end, L"0123456789"[value % 10]);
|
||||
return str_end;
|
||||
}
|
||||
|
||||
template<
|
||||
typename CharT,
|
||||
class Integer,
|
||||
typename Traits = std::char_traits<CharT>>
|
||||
template<typename Traits, typename Integer>
|
||||
inline
|
||||
CharT*
|
||||
raw_to_string(CharT* last, std::size_t size, Integer i)
|
||||
wchar_t*
|
||||
integer_to_wstring(
|
||||
wchar_t* str_end, Integer value, std::false_type)
|
||||
{
|
||||
BOOST_STATIC_STRING_ASSERT(size >= max_digits(sizeof(Integer)));
|
||||
return raw_to_string<CharT, Integer, Traits>(
|
||||
last, i, std::is_signed<Integer>{});
|
||||
if (value == 0)
|
||||
{
|
||||
Traits::assign(*--str_end, L'0');
|
||||
return str_end;
|
||||
}
|
||||
for (; value > 0; value /= 10)
|
||||
Traits::assign(*--str_end, L"0123456789"[value % 10]);
|
||||
return str_end;
|
||||
}
|
||||
|
||||
template<typename Traits, std::size_t N, typename Integer>
|
||||
inline
|
||||
static_string<N>
|
||||
to_static_string_int_impl(Integer value)
|
||||
{
|
||||
char buffer[N];
|
||||
const auto digits_end = std::end(buffer);
|
||||
const auto digits_begin = integer_to_string<Traits, Integer>(
|
||||
digits_end, value, std::is_signed<Integer>{});
|
||||
return static_string<N>(digits_begin, std::distance(digits_begin, digits_end));
|
||||
}
|
||||
|
||||
template<typename Traits, std::size_t N, typename Integer>
|
||||
inline
|
||||
static_wstring<N>
|
||||
to_static_wstring_int_impl(Integer value)
|
||||
{
|
||||
wchar_t buffer[N];
|
||||
const auto digits_end = std::end(buffer);
|
||||
const auto digits_begin = integer_to_wstring<Traits, Integer>(
|
||||
digits_end, value, std::is_signed<Integer>{});
|
||||
return static_wstring<N>(digits_begin, std::distance(digits_begin, digits_end));
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Floating>
|
||||
inline
|
||||
static_string<N>
|
||||
to_static_string_float_impl(Floating value)
|
||||
{
|
||||
char buffer[N];
|
||||
std::sprintf(buffer, "%f", value);
|
||||
return static_string<N>(buffer);
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Floating>
|
||||
inline
|
||||
static_wstring<N>
|
||||
to_static_wstring_float_impl(Floating value)
|
||||
{
|
||||
wchar_t buffer[N];
|
||||
std::swprintf(buffer, L"%f", value);
|
||||
return static_wstring<N>(buffer);
|
||||
}
|
||||
|
||||
template<
|
||||
|
@ -836,24 +836,152 @@ assign_char(CharT, std::false_type) ->
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Integer, class>
|
||||
// string
|
||||
|
||||
static_string<std::numeric_limits<int>::digits10 + 1>
|
||||
inline
|
||||
basic_static_string<detail::max_digits(sizeof(Integer)), char>
|
||||
to_static_string(Integer x)
|
||||
to_static_string(int value)
|
||||
{
|
||||
using CharT = char;
|
||||
using Traits = std::char_traits<CharT>;
|
||||
BOOST_STATIC_STRING_STATIC_ASSERT(std::is_integral<Integer>::value, "Integer must be an integral type");
|
||||
char buf[detail::max_digits(sizeof(Integer))];
|
||||
auto last = buf + sizeof(buf);
|
||||
auto it = detail::raw_to_string<
|
||||
CharT, Integer, Traits>(last, sizeof(buf), x);
|
||||
basic_static_string<detail::max_digits(sizeof(Integer)), char> s;
|
||||
s.resize(static_cast<std::size_t>(last - it));
|
||||
auto p = s.data();
|
||||
while(it < last)
|
||||
Traits::assign(*p++, *it++);
|
||||
return s;
|
||||
return detail::to_static_string_int_impl<
|
||||
std::char_traits<char>, std::numeric_limits<int>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(long value)
|
||||
{
|
||||
return detail::to_static_string_int_impl<
|
||||
std::char_traits<char>, std::numeric_limits<long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(long long value)
|
||||
{
|
||||
return detail::to_static_string_int_impl<
|
||||
std::char_traits<char>, std::numeric_limits<long long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<unsigned int>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(unsigned int value)
|
||||
{
|
||||
return detail::to_static_string_int_impl<
|
||||
std::char_traits<char>, std::numeric_limits<unsigned int>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<unsigned long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(unsigned long value)
|
||||
{
|
||||
return detail::to_static_string_int_impl<
|
||||
std::char_traits<char>, std::numeric_limits<unsigned long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<unsigned long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(unsigned long long value)
|
||||
{
|
||||
return detail::to_static_string_int_impl<
|
||||
std::char_traits<char>, std::numeric_limits<unsigned long long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<float>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_string(float value)
|
||||
{
|
||||
return detail::to_static_string_float_impl<
|
||||
std::numeric_limits<float>::max_digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_string(double value)
|
||||
{
|
||||
return detail::to_static_string_float_impl<
|
||||
std::numeric_limits<double>::max_digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_string<std::numeric_limits<long double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_string(long double value)
|
||||
{
|
||||
return detail::to_static_string_float_impl<
|
||||
std::numeric_limits<long double>::max_digits10 + 1>(value);
|
||||
}
|
||||
|
||||
// wstring
|
||||
|
||||
static_wstring<std::numeric_limits<int>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(int value)
|
||||
{
|
||||
return detail::to_static_wstring_int_impl<
|
||||
std::char_traits<wchar_t>, std::numeric_limits<int>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(long value)
|
||||
{
|
||||
return detail::to_static_wstring_int_impl<
|
||||
std::char_traits<wchar_t>, std::numeric_limits<long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(long long value)
|
||||
{
|
||||
return detail::to_static_wstring_int_impl<
|
||||
std::char_traits<wchar_t>, std::numeric_limits<long long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<unsigned int>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(unsigned int value)
|
||||
{
|
||||
return detail::to_static_wstring_int_impl<
|
||||
std::char_traits<wchar_t>, std::numeric_limits<unsigned int>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<unsigned long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(unsigned long value)
|
||||
{
|
||||
return detail::to_static_wstring_int_impl<
|
||||
std::char_traits<wchar_t>, std::numeric_limits<unsigned long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<unsigned long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(unsigned long long value)
|
||||
{
|
||||
return detail::to_static_wstring_int_impl<
|
||||
std::char_traits<wchar_t>, std::numeric_limits<unsigned long long>::digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<float>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(float value)
|
||||
{
|
||||
return detail::to_static_wstring_float_impl<
|
||||
std::numeric_limits<float>::max_digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(double value)
|
||||
{
|
||||
return detail::to_static_wstring_float_impl<
|
||||
std::numeric_limits<double>::max_digits10 + 1>(value);
|
||||
}
|
||||
|
||||
static_wstring<std::numeric_limits<long double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(long double value)
|
||||
{
|
||||
return detail::to_static_wstring_float_impl<
|
||||
std::numeric_limits<long double>::max_digits10 + 1>(value);
|
||||
}
|
||||
|
||||
} // static_string
|
||||
|
@ -2773,31 +2773,105 @@ operator<<(std::basic_ostream<CharT, Traits>& os,
|
||||
return os << basic_string_view<CharT, Traits>(s.data(), s.size());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<std::size_t N>
|
||||
using static_string = basic_static_string<N, char>;
|
||||
|
||||
template<std::size_t N>
|
||||
using static_wstring = basic_static_string<N, wchar_t>;
|
||||
|
||||
template<std::size_t N>
|
||||
using static_u16string = basic_static_string<N, char16_t>;
|
||||
|
||||
template<std::size_t N>
|
||||
using static_u32string = basic_static_string<N, char32_t>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Numeric conversions
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Returns a static string representing an integer as a decimal.
|
||||
// string
|
||||
|
||||
@param x The signed or unsigned integer to convert.
|
||||
This must be an integral type.
|
||||
|
||||
@return A @ref basic_static_string with an implementation defined
|
||||
maximum size at least as large enough to hold the longest
|
||||
possible decimal representation of any integer of the given type.
|
||||
*/
|
||||
template<
|
||||
class Integer
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
, class = typename std::enable_if<
|
||||
std::is_integral<Integer>::value>::type
|
||||
#endif
|
||||
>
|
||||
static_string<std::numeric_limits<int>::digits10 + 1>
|
||||
inline
|
||||
basic_static_string<detail::max_digits(sizeof(Integer)), char>
|
||||
to_static_string(Integer x);
|
||||
to_static_string(int value);
|
||||
|
||||
static_string<std::numeric_limits<long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(long value);
|
||||
|
||||
static_string<std::numeric_limits<long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(long long value);
|
||||
|
||||
static_string<std::numeric_limits<unsigned int>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(unsigned int value);
|
||||
|
||||
static_string<std::numeric_limits<unsigned long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(unsigned long value);
|
||||
|
||||
static_string<std::numeric_limits<unsigned long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_string(unsigned long long value);
|
||||
|
||||
static_string<std::numeric_limits<float>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_string(float value);
|
||||
|
||||
static_string<std::numeric_limits<double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_string(double value);
|
||||
|
||||
static_string<std::numeric_limits<long double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_string(long double value);
|
||||
|
||||
// wstring
|
||||
|
||||
static_wstring<std::numeric_limits<int>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(int value);
|
||||
|
||||
static_wstring<std::numeric_limits<long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(long value);
|
||||
|
||||
static_wstring<std::numeric_limits<long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(long long value);
|
||||
|
||||
static_wstring<std::numeric_limits<unsigned int>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(unsigned int value);
|
||||
|
||||
static_wstring<std::numeric_limits<unsigned long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(unsigned long value);
|
||||
|
||||
static_wstring<std::numeric_limits<unsigned long long>::digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(unsigned long long value);
|
||||
|
||||
static_wstring<std::numeric_limits<float>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(float value);
|
||||
|
||||
static_wstring<std::numeric_limits<double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(double value);
|
||||
|
||||
static_wstring<std::numeric_limits<long double>::max_digits10 + 1>
|
||||
inline
|
||||
to_static_wstring(long double value);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
@ -2829,29 +2903,12 @@ hash_value(
|
||||
return boost::hash_range(str.begin(), str.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<std::size_t N>
|
||||
using static_string = basic_static_string<N, char>;
|
||||
|
||||
template<std::size_t N>
|
||||
using static_wstring = basic_static_string<N, wchar_t>;
|
||||
|
||||
template<std::size_t N>
|
||||
using static_u16string = basic_static_string<N, char16_t>;
|
||||
|
||||
template<std::size_t N>
|
||||
using static_u32string = basic_static_string<N, char32_t>;
|
||||
|
||||
} // static_string
|
||||
} // boost
|
||||
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
// std::hash partial specialization for basic_static_string
|
||||
#endif
|
||||
namespace std
|
||||
{
|
||||
template <std::size_t N, typename CharT, typename Traits>
|
||||
|
Reference in New Issue
Block a user