dconv 2.0
C++14 library for printing and parsing floating point numbers
Loading...
Searching...
No Matches
probe.hpp
Go to the documentation of this file.
1
25#ifndef __DCONV_PROBE_HPP__
26#define __DCONV_PROBE_HPP__
27
28// C++.
29#include <istream>
30#include <limits>
31
32// C.
33#include <cstring>
34#include <cstdint>
35#include <cstddef>
36
37#define DCONV_LIKELY(x) __builtin_expect ((x), 1)
38#define DCONV_UNLIKELY(x) __builtin_expect ((x), 0)
39#define DCONV_COLD __attribute__ ((cold, noinline))
40
41namespace dconv
42{
47 {
48 public:
49 using ProbePos = const char*;
50
56 constexpr StringProbe (const char* in, size_t count)
57 : _cur (in)
58 , _beg (in)
59 , _end (in ? in + count : in)
60 {
61 }
62
68 constexpr StringProbe (const char* first, const char* last)
69 : _cur (first)
70 , _beg (first)
71 , _end (last)
72 {
73 }
74
79 explicit StringProbe (const char* in)
80 : _cur (in)
81 , _beg (in)
82 , _end (in ? in + std::char_traits<char>::length (in) : in)
83 {
84 }
85
90 StringProbe (const StringProbe& other) = default;
91
97 StringProbe& operator= (const StringProbe& other) = default;
98
103 StringProbe (StringProbe&& other) = default;
104
110 StringProbe& operator= (StringProbe&& other) = default;
111
115 ~StringProbe () = default;
116
121 inline int peek () const noexcept
122 {
123 if (DCONV_LIKELY (_cur < _end))
124 {
125 return static_cast<unsigned char> (*_cur);
126 }
127 return std::char_traits<char>::eof ();
128 }
129
134 inline int get () noexcept
135 {
136 if (DCONV_LIKELY (_cur < _end))
137 {
138 return static_cast<unsigned char> (*_cur++);
139 }
140 return std::char_traits<char>::eof ();
141 }
142
148 inline bool getIf (char expected) noexcept
149 {
150 if (DCONV_LIKELY (_cur < _end) && (*_cur == expected))
151 {
152 ++_cur;
153 return true;
154 }
155 return false;
156 }
157
163 inline bool getIfNoCase (char expected) noexcept
164 {
165 if (DCONV_LIKELY (_cur < _end))
166 {
167 const char c = *_cur;
168 if ((c | 32) == (expected | 32))
169 {
170 ++_cur;
171 return true;
172 }
173 }
174 return false;
175 }
176
183 inline size_t readDigits (uint64_t& value, size_t max = std::numeric_limits<size_t>::max ()) noexcept
184 {
185 const char* cur = _cur;
186 const char* end = (static_cast<size_t> (_end - _cur) > max) ? _cur + max : _end;
187 uint64_t word;
188
189 while ((end - cur >= 8) &&
190 (std::memcpy (&word, cur, 8),
191 ((word & 0xF0F0F0F0F0F0F0F0ULL) |
192 (((word + 0x0606060606060606ULL) & 0xF0F0F0F0F0F0F0F0ULL) >> 4)) == 0x3333333333333333ULL))
193 {
194 word = ((word & 0x0F0F0F0F0F0F0F0FULL) * 2561) >> 8;
195 word = ((word & 0x00FF00FF00FF00FFULL) * 6553601) >> 16;
196 word = ((word & 0x0000FFFF0000FFFFULL) * 42949672960001ULL) >> 32;
197 value = (value * 100000000) + word;
198 cur += 8;
199 }
200
201 while ((cur < end) && (static_cast<unsigned char> (*cur - '0') < 10))
202 {
203 value = (value * 10) + (*cur++ - '0');
204 }
205
206 size_t count = cur - _cur;
207 _cur = cur;
208 return count;
209 }
210
217 inline size_t read (char* buf, size_t count) noexcept
218 {
219 const size_t available = _end - _cur;
220 const size_t nread = (count < available) ? count : available;
221 std::memcpy (buf, _cur, nread);
222 _cur += nread;
223 return nread;
224 }
225
230 inline ProbePos tell () const noexcept
231 {
232 return _cur;
233 }
234
239 inline ProbePos end () const noexcept
240 {
241 return _end;
242 }
243
248 inline void seek (ProbePos pos) noexcept
249 {
250 if (DCONV_LIKELY (pos >= _beg && pos <= _end))
251 {
252 _cur = pos;
253 }
254 else if (pos < _beg)
255 {
256 _cur = _beg;
257 }
258 else
259 {
260 _cur = _end;
261 }
262 }
263
264 private:
266 const char* _cur = nullptr;
267
269 const char* _beg = nullptr;
270
272 const char* _end = nullptr;
273 };
274
279 {
280 public:
285 explicit StreamProbe (std::istream& in)
286 : _in (in.rdbuf ())
287 {
288 }
289
294 StreamProbe (const StreamProbe& other) = delete;
295
301 StreamProbe& operator= (const StreamProbe& other) = delete;
302
307 StreamProbe (StreamProbe&& other) = delete;
308
315
319 ~StreamProbe () = default;
320
325 inline int peek () const noexcept
326 {
327 return _in->sgetc ();
328 }
329
334 inline int get () noexcept
335 {
336 return _in->sbumpc ();
337 }
338
344 inline bool getIf (char expected) noexcept
345 {
346 if (_in->sgetc () == static_cast<int> (static_cast<unsigned char> (expected)))
347 {
348 _in->sbumpc ();
349 return true;
350 }
351 return false;
352 }
353
359 inline bool getIfNoCase (char expected) noexcept
360 {
361 const int c = _in->sgetc ();
362 if (DCONV_LIKELY (c != std::char_traits<char>::eof ()))
363 {
364 if ((static_cast<char> (c) | 32) == (expected | 32))
365 {
366 _in->sbumpc ();
367 return true;
368 }
369 }
370 return false;
371 }
372
379 inline size_t readDigits (uint64_t& value, size_t max = std::numeric_limits<size_t>::max ()) noexcept
380 {
381 size_t count = 0;
382 while ((count < max) && (static_cast<unsigned> (peek () - '0') < 10))
383 {
384 value = (value * 10) + (get () - '0');
385 ++count;
386 }
387 return count;
388 }
389
396 inline size_t read (char* buf, size_t count) noexcept
397 {
398 return _in->sgetn (buf, count);
399 }
400
401 private:
403 std::streambuf* _in;
404 };
405}
406
407#endif
stream probe.
Definition probe.hpp:279
int peek() const noexcept
get character without extracting it.
Definition probe.hpp:325
bool getIf(char expected) noexcept
extracts expected character.
Definition probe.hpp:344
~StreamProbe()=default
destroy instance.
StreamProbe(std::istream &in)
default constructor.
Definition probe.hpp:285
StreamProbe(const StreamProbe &other)=delete
copy constructor.
size_t readDigits(uint64_t &value, size_t max=std::numeric_limits< size_t >::max()) noexcept
read consecutive digits.
Definition probe.hpp:379
StreamProbe & operator=(const StreamProbe &other)=delete
copy assignment.
StreamProbe(StreamProbe &&other)=delete
move constructor.
size_t read(char *buf, size_t count) noexcept
read characters.
Definition probe.hpp:396
int get() noexcept
extracts character.
Definition probe.hpp:334
bool getIfNoCase(char expected) noexcept
extracts expected character (case insensitive, ASCII-only).
Definition probe.hpp:359
string probe.
Definition probe.hpp:47
size_t readDigits(uint64_t &value, size_t max=std::numeric_limits< size_t >::max()) noexcept
read consecutive digits.
Definition probe.hpp:183
ProbePos end() const noexcept
get end position indicator.
Definition probe.hpp:239
StringProbe(const StringProbe &other)=default
copy constructor.
void seek(ProbePos pos) noexcept
seek to the specified position.
Definition probe.hpp:248
~StringProbe()=default
destroy instance.
bool getIf(char expected) noexcept
extracts expected character.
Definition probe.hpp:148
size_t read(char *buf, size_t count) noexcept
read characters.
Definition probe.hpp:217
ProbePos tell() const noexcept
get input position indicator.
Definition probe.hpp:230
StringProbe & operator=(const StringProbe &other)=default
copy assignment.
bool getIfNoCase(char expected) noexcept
extracts expected character (case insensitive, ASCII-only).
Definition probe.hpp:163
int peek() const noexcept
get character without extracting it.
Definition probe.hpp:121
int get() noexcept
extracts character.
Definition probe.hpp:134
constexpr StringProbe(const char *in, size_t count)
default constructor.
Definition probe.hpp:56
StringProbe(const char *in)
default constructor.
Definition probe.hpp:79
const char * ProbePos
Definition probe.hpp:49
StringProbe(StringProbe &&other)=default
move constructor.
constexpr StringProbe(const char *first, const char *last)
default constructor.
Definition probe.hpp:68
Definition atod.hpp:47
Definition error.hpp:112
#define DCONV_LIKELY(x)
Definition probe.hpp:37