Medial Code Documentation
Loading...
Searching...
No Matches
charconv.h
1
8#ifndef XGBOOST_COMMON_CHARCONV_H_
9#define XGBOOST_COMMON_CHARCONV_H_
10
11#include <cstddef>
12#include <system_error>
13#include <iterator>
14#include <limits>
15
16#include "xgboost/logging.h"
17
18namespace xgboost {
19
20struct to_chars_result { // NOLINT
21 char* ptr;
22 std::errc ec;
23};
24
25struct from_chars_result { // NOLINT
26 const char *ptr;
27 std::errc ec;
28};
29
30namespace detail {
31int32_t ToCharsFloatImpl(float f, char * const result);
32to_chars_result ToCharsUnsignedImpl(char *first, char *last,
33 uint64_t const value);
34from_chars_result FromCharFloatImpl(const char *buffer, const int len,
35 float *result);
36} // namespace detail
37
38template <typename T>
40
41template <> struct NumericLimits<float> {
42 // Unlike std::numeric_limit<float>::max_digits10, which represents the **minimum**
43 // length of base10 digits that are necessary to uniquely represent all distinct values.
44 // This value is used to represent the maximum length. As sign bit occupies 1 character:
45 // sign + len(str(2^24)) + decimal point + `E` + sign + len(str(2^8)) + '\0'
46 static constexpr size_t kToCharsSize = 16;
47};
48
49template <> struct NumericLimits<int64_t> {
50 // From llvm libcxx: numeric_limits::digits10 returns value less on 1 than desired for
51 // unsigned numbers. For example, for 1-byte unsigned value digits10 is 2 (999 can not
52 // be represented), so we need +1 here.
53 static constexpr size_t kToCharsSize =
54 std::numeric_limits<int64_t>::digits10 +
55 3; // +1 for minus, +1 for digits10, +1 for '\0' just to be safe.
56};
57
58inline to_chars_result to_chars(char *first, char *last, float value) { // NOLINT
59 if (XGBOOST_EXPECT(!(static_cast<size_t>(last - first) >=
61 false)) {
62 return {first, std::errc::value_too_large};
63 }
64 auto index = detail::ToCharsFloatImpl(value, first);
65 to_chars_result ret;
66 ret.ptr = first + index;
67
68 if (XGBOOST_EXPECT(ret.ptr < last, true)) {
69 ret.ec = std::errc();
70 } else {
71 ret.ec = std::errc::value_too_large;
72 ret.ptr = last;
73 }
74 return ret;
75}
76
77inline to_chars_result to_chars(char *first, char *last, int64_t value) { // NOLINT
78 if (XGBOOST_EXPECT(first == last, false)) {
79 return {first, std::errc::value_too_large};
80 }
81 // first write '-' and convert to unsigned, then write the rest.
82 if (value == 0) {
83 *first = '0';
84 return {std::next(first), std::errc()};
85 }
86 uint64_t unsigned_value = value;
87 if (value < 0) {
88 *first = '-';
89 std::advance(first, 1);
90 unsigned_value = static_cast<uint64_t>(~value) + static_cast<uint64_t>(1);
91 }
92 return detail::ToCharsUnsignedImpl(first, last, unsigned_value);
93}
94
95inline from_chars_result from_chars(const char *buffer, const char *end, // NOLINT
96 float &value) { // NOLINT
97 from_chars_result res =
98 detail::FromCharFloatImpl(buffer, std::distance(buffer, end), &value);
99 return res;
100}
101} // namespace xgboost
102
103#endif // XGBOOST_COMMON_CHARCONV_H_
defines console logging options for xgboost. Use to enforce unified print behavior.
detail namespace with internal helper functions
Definition json.hpp:249
namespace of xgboost
Definition base.h:90
Definition charconv.h:39
Definition charconv.h:25
Definition charconv.h:20