summaryrefslogtreecommitdiff
path: root/internal/strings/numbers.h
blob: fa47acd58279bd535394b86c4174e2ba01d25903 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#ifndef DYNAMIC_DEPTH_INTERNAL_STRINGS_NUMBERS_H_  // NOLINT
#define DYNAMIC_DEPTH_INTERNAL_STRINGS_NUMBERS_H_  // NOLINT

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <functional>
#include <limits>
#include <string>

#include "base/integral_types.h"
#include "base/port.h"
#include "strings/ascii_ctype.h"

namespace dynamic_depth {
namespace strings {

// Convert strings to numeric values, with strict error checking.
// Leading and trailing spaces are allowed.
// Negative inputs are not allowed for unsigned ints (unlike strtoul).
//
// Base must be [0, 2-36].
// Base 0:
//   auto-select base from first two chars:
//    "0x" -> hex
//    "0" -> octal
//    else -> decimal
// Base 16:
//   Number can start with "0x"
//
// On error, returns false, and sets *value to:
//   std::numeric_limits<T>::max() on overflow
//   std::numeric_limits<T>::min() on underflow
//   conversion of leading substring if available ("123@@@" -> 123)
//   0 if no leading substring available
// The effect on errno is unspecified.
// Do not depend on testing errno.
bool safe_strto32_base(const string& text, int32* value, int base);
bool safe_strto64_base(const string& text, int64* value, int base);
bool safe_strtou32_base(const string& text, uint32* value, int base);
bool safe_strtou64_base(const string& text, uint64* value, int base);
bool safe_strtosize_t_base(const string& text, size_t* value, int base);

// Convenience functions with base == 10.
inline bool safe_strto32(const string& text, int32* value) {
  return safe_strto32_base(text, value, 10);
}

inline bool safe_strto64(const string& text, int64* value) {
  return safe_strto64_base(text, value, 10);
}

inline bool safe_strtou32(const string& text, uint32* value) {
  return safe_strtou32_base(text, value, 10);
}

inline bool safe_strtou64(const string& text, uint64* value) {
  return safe_strtou64_base(text, value, 10);
}

// Convert strings to floating point values.
// Leading and trailing spaces are allowed.
// Values may be rounded on over- and underflow.
bool safe_strtof(const string& str, float* value);

bool safe_strtod(const string& str, double* value);

// Previously documented minimums -- the buffers provided must be at least this
// long, though these numbers are subject to change:
//     Int32, UInt32:                   12 bytes
//     Int64, UInt64, Int, Uint:        22 bytes
//     Time:                            30 bytes
// Use kFastToBufferSize rather than hardcoding constants.
static const int kFastToBufferSize = 32;

// ----------------------------------------------------------------------
// FastInt32ToBufferLeft()
// FastUInt32ToBufferLeft()
// FastInt64ToBufferLeft()
// FastUInt64ToBufferLeft()
//
// Like the Fast*ToBuffer() functions above, these are intended for speed.
// Unlike the Fast*ToBuffer() functions, however, these functions write
// their output to the beginning of the buffer (hence the name, as the
// output is left-aligned).  The caller is responsible for ensuring that
// the buffer has enough space to hold the output.
//
// Returns a pointer to the end of the string (i.e. the null character
// terminating the string).
// ----------------------------------------------------------------------

char* FastInt32ToBufferLeft(int32 i, char* buffer);    // at least 12 bytes
char* FastUInt32ToBufferLeft(uint32 i, char* buffer);  // at least 12 bytes
char* FastInt64ToBufferLeft(int64 i, char* buffer);    // at least 22 bytes
char* FastUInt64ToBufferLeft(uint64 i, char* buffer);  // at least 22 bytes

// ----------------------------------------------------------------------
// SimpleFtoa()
//    Description: converts a double or float to a string which, if passed to
//    strtod() or strtof() respectively, will produce the exact same original
//    double or float.  Exception: for NaN values, strtod(SimpleDtoa(NaN)) or
//    strtof(SimpleFtoa(NaN)) may produce any NaN value, not necessarily the
//    exact same original NaN value.
//
//    The output string is not guaranteed to be as short as possible.
//
//    The output string, including terminating NUL, will have length
//    less than or equal to kFastToBufferSize defined above.  Of course,
//    we would prefer that your code not depend on this property of
//    the output string.  This guarantee derives from a similar guarantee
//    from the previous generation of char-buffer-based functions.
//    We had to carry it forward to preserve compatibility.
// ----------------------------------------------------------------------
string SimpleFtoa(float value);

// ----------------------------------------------------------------------
// SimpleItoa()
//    Description: converts an integer to a string.
//    Faster than printf("%d").
//
//    Return value: string
// ----------------------------------------------------------------------
inline string SimpleItoa(int32 i) {
  char buf[16];  // Longest is -2147483648
  return string(buf, FastInt32ToBufferLeft(i, buf));
}

// We need this overload because otherwise SimpleItoa(5U) wouldn't compile.
inline string SimpleItoa(uint32 i) {
  char buf[16];  // Longest is 4294967295
  return string(buf, FastUInt32ToBufferLeft(i, buf));
}

inline string SimpleItoa(int64 i) {
  char buf[32];  // Longest is -9223372036854775808
  return string(buf, FastInt64ToBufferLeft(i, buf));
}

// We need this overload because otherwise SimpleItoa(5ULL) wouldn't compile.
inline string SimpleItoa(uint64 i) {
  char buf[32];  // Longest is 18446744073709551615
  return string(buf, FastUInt64ToBufferLeft(i, buf));
}

inline string SimpleItoa(long i) {  // NOLINT long is OK here
  if (sizeof(i) == 64 / 8) {
    return SimpleItoa(static_cast<int64>(i));
  } else if (sizeof(i) == 32 / 8) {
    return SimpleItoa(static_cast<int32>(i));
  }
}

inline string SimpleItoa(unsigned long i) {  // NOLINT long is OK here
  if (sizeof(i) == 64 / 8) {
    return SimpleItoa(static_cast<uint64>(i));
  } else if (sizeof(i) == 32 / 8) {
    return SimpleItoa(static_cast<uint32>(i));
  }
}

// Required buffer size for FloatToBuffer is kFastToBufferSize.
char* FloatToBuffer(float i, char* buffer);

}  // namespace strings
}  // namespace dynamic_depth

#endif  // DYNAMIC_DEPTH_INTERNAL_STRINGS_NUMBERS_H_  // NOLINT