File indexing completed on 2025-12-13 09:54:58
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MYSQL_IMPL_INTERNAL_DT_TO_STRING_HPP
0009 #define BOOST_MYSQL_IMPL_INTERNAL_DT_TO_STRING_HPP
0010
0011 #include <boost/mysql/time.hpp>
0012
0013 #include <boost/assert.hpp>
0014 #include <boost/charconv/to_chars.hpp>
0015 #include <boost/core/span.hpp>
0016
0017 #include <cstddef>
0018 #include <cstdint>
0019 #include <cstdlib>
0020 #include <system_error>
0021 #include <type_traits>
0022
0023
0024 #if BOOST_GCC >= 70000
0025 #pragma GCC diagnostic push
0026 #pragma GCC diagnostic ignored "-Wstringop-overflow"
0027 #endif
0028
0029 namespace boost {
0030 namespace mysql {
0031 namespace detail {
0032
0033
0034 template <class IntType>
0035 inline char* call_to_chars(char* begin, char* end, IntType value) noexcept
0036 {
0037 auto r = charconv::to_chars(begin, end, value);
0038 BOOST_ASSERT(r.ec == std::errc());
0039 return r.ptr;
0040 }
0041
0042 template <class UnsignedInt>
0043 inline char* write_pad2(char* begin, char* end, UnsignedInt value) noexcept
0044 {
0045 static_assert(std::is_unsigned<UnsignedInt>::value, "");
0046 if (value < 10u)
0047 *begin++ = '0';
0048 return call_to_chars(begin, end, value);
0049 }
0050
0051 inline char* write_pad4(char* begin, char* end, unsigned long value) noexcept
0052 {
0053 for (auto l : {1000u, 100u, 10u})
0054 {
0055 if (value < l)
0056 *begin++ = '0';
0057 }
0058 return call_to_chars(begin, end, value);
0059 }
0060
0061 inline char* write_pad6(char* begin, char* end, unsigned long value) noexcept
0062 {
0063 for (auto l : {100000u, 10000u, 1000u, 100u, 10u})
0064 {
0065 if (value < l)
0066 *begin++ = '0';
0067 }
0068 return call_to_chars(begin, end, value);
0069 }
0070
0071 inline std::size_t date_to_string(
0072 std::uint16_t year,
0073 std::uint8_t month,
0074 std::uint8_t day,
0075 span<char, 32> output
0076 ) noexcept
0077 {
0078
0079
0080
0081 char* it = output.data();
0082 char* end = it + output.size();
0083
0084
0085 it = write_pad4(it, end, year);
0086
0087
0088 *it++ = '-';
0089 it = write_pad2(it, end, static_cast<unsigned long>(month));
0090
0091
0092 *it++ = '-';
0093 it = write_pad2(it, end, static_cast<unsigned long>(day));
0094
0095
0096 return it - output.data();
0097 }
0098
0099 inline std::size_t datetime_to_string(
0100 std::uint16_t year,
0101 std::uint8_t month,
0102 std::uint8_t day,
0103 std::uint8_t hour,
0104 std::uint8_t minute,
0105 std::uint8_t second,
0106 std::uint32_t microsecond,
0107 span<char, 64> output
0108 ) noexcept
0109 {
0110
0111
0112
0113 char* it = output.data();
0114 char* end = it + output.size();
0115
0116
0117 it += date_to_string(year, month, day, span<char, 32>(it, 32));
0118
0119
0120 *it++ = ' ';
0121 it = write_pad2(it, end, static_cast<unsigned long>(hour));
0122
0123
0124 *it++ = ':';
0125 it = write_pad2(it, end, static_cast<unsigned long>(minute));
0126
0127
0128 *it++ = ':';
0129 it = write_pad2(it, end, static_cast<unsigned long>(second));
0130
0131
0132 *it++ = '.';
0133 it = write_pad6(it, end, microsecond);
0134
0135
0136 return it - output.data();
0137 }
0138
0139 inline std::size_t time_to_string(::boost::mysql::time value, span<char, 64> output) noexcept
0140 {
0141
0142
0143
0144
0145 constexpr auto min_val = (::boost::mysql::time::min)();
0146 using unsigned_t = typename std::make_unsigned<typename ::boost::mysql::time::rep>::type;
0147 auto total_count = value == min_val ? static_cast<unsigned_t>(min_val.count())
0148 : static_cast<unsigned_t>(std::abs(value.count()));
0149
0150 auto num_micros = total_count % 1000000u;
0151 total_count /= 1000000u;
0152
0153 auto num_secs = total_count % 60u;
0154 total_count /= 60u;
0155
0156 auto num_mins = total_count % 60u;
0157 total_count /= 60u;
0158
0159 auto num_hours = total_count;
0160
0161
0162 char* it = output.data();
0163 char* end = it + output.size();
0164
0165
0166 if (value.count() < 0)
0167 *it++ = '-';
0168
0169
0170 it = write_pad2(it, end, num_hours);
0171
0172
0173 *it++ = ':';
0174 it = write_pad2(it, end, static_cast<unsigned long>(num_mins));
0175
0176
0177 *it++ = ':';
0178 it = write_pad2(it, end, static_cast<unsigned long>(num_secs));
0179
0180
0181 *it++ = '.';
0182 it = write_pad6(it, end, static_cast<unsigned long>(num_micros));
0183
0184
0185 return it - output.data();
0186 }
0187
0188 }
0189 }
0190 }
0191
0192 #if BOOST_GCC >= 110000
0193 #pragma GCC diagnostic pop
0194 #endif
0195
0196 #endif