forked from andrewprock/ustl
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsistream.h
134 lines (123 loc) · 5.65 KB
/
sistream.h
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
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <[email protected]>
// This file is free software, distributed under the MIT License.
#pragma once
#include "mistream.h"
#include "ustring.h"
#ifndef EOF
#define EOF (-1)
#endif
namespace ustl {
/// \class istringstream sistream.h ustl.h
/// \ingroup TextStreams
///
/// \brief A stream that reads textual data from a memory block.
///
class istringstream : public istream {
public:
static const size_type c_MaxDelimiters = 16; ///< Maximum number of word delimiters.
public:
istringstream (void) noexcept;
istringstream (const void* p, size_type n) noexcept;
explicit istringstream (const cmemlink& source) noexcept;
inline fmtflags flags (void) const { return _flags; }
inline fmtflags flags (fmtflags f) { fmtflags of (_flags); _flags = f; return of; }
inline fmtflags setf (fmtflags f) { fmtflags of (_flags); _flags |= f; return of; }
inline fmtflags unsetf (fmtflags f) { fmtflags of (_flags); _flags &= ~f; return of; }
inline fmtflags setf (fmtflags f, fmtflags m) { unsetf(m); return setf(f); }
inline void iread (char& v) { v = skip_delimiters(); }
inline void iread (unsigned char& v) { char c; iread(c); v = c; }
void iread (int& v);
inline void iread (unsigned int& v) { int c; iread(c); v = c; }
inline void iread (short& v) { int c; iread(c); v = c; }
inline void iread (unsigned short& v) { int c; iread(c); v = c; }
void iread (long& v);
inline void iread (unsigned long& v) { long c; iread(c); v = c; }
#if HAVE_THREE_CHAR_TYPES
void iread (signed char& v) { char c; iread(c); v = c; }
#endif
#if HAVE_LONG_LONG
void iread (long long& v);
inline void iread (unsigned long long& v) { long long c; iread(c); v = c; }
#endif
inline void iread (float& v) { double c; iread(c); v = c; }
inline void iread (long double& v) { double c; iread(c); v = c; }
inline void iread (fmtflags_bits f);
inline void iread (unsigned long long& v) { long long c; iread(c); v = c; }
/*void iread (double& v);
inline void iread (float& v) { double c; iread(c); v = c; }
inline void iread (long double& v) { double c; iread(c); v = c; }*/
void iread (bool& v);
void iread (wchar_t& v);
void iread (string& v);
inline void iread (fmtflags_bits f);
inline string str (void) const { string s; s.link (*this); return s; }
inline istringstream& str (const string& s) { link (s); return *this; }
inline istringstream& get (char& c) { return read (&c, sizeof(c)); }
inline int get (void) { char c = EOF; get(c); return c; }
istringstream& get (char* p, size_type n, char delim = '\n');
istringstream& get (string& s, char delim = '\n');
istringstream& getline (char* p, size_type n, char delim = '\n');
istringstream& getline (string& s, char delim = '\n');
istringstream& ignore (size_type n, char delim = '\0');
inline char peek (void) { char v = get(); ungetc(); return v; }
inline istringstream& unget (void) { ungetc(); return *this; }
inline void set_delimiters (const char* delimiters);
istringstream& read (void* buffer, size_type size);
inline istringstream& read (memlink& buf) { return read (buf.begin(), buf.size()); }
inline size_type gcount (void) const { return _gcount; }
inline istringstream& seekg (off_t p, seekdir d =beg) { istream::seekg(p,d); return *this; }
inline int sync (void) { skip (remaining()); return 0; }
protected:
char skip_delimiters (void);
private:
inline void read_strz (string&) { assert (!"Reading nul characters is not allowed from text streams"); }
inline bool is_delimiter (char c) const noexcept;
template <typename T> void read_number (T& v);
private:
fmtflags _flags;
uint32_t _gcount;
char _delimiters [c_MaxDelimiters];
};
//----------------------------------------------------------------------
void istringstream::iread (fmtflags_bits f)
{
if (f & basefield) setf (f, basefield);
else if (f & floatfield) setf (f, floatfield);
else if (f & adjustfield) setf (f, adjustfield);
setf (f);
}
/// Sets delimiters to the contents of \p delimiters.
void istringstream::set_delimiters (const char* delimiters)
{
#if __x86__ && __SSE__ && HAVE_VECTOR_EXTENSIONS
typedef uint32_t v16ud_t __attribute__((vector_size(16)));
asm("xorps\t%%xmm0, %%xmm0\n\tmovups\t%%xmm0, %0":"=m"(*noalias_cast<v16ud_t*>(_delimiters))::"xmm0");
#else
memset (_delimiters, 0, sizeof(_delimiters));
#endif
memcpy (_delimiters, delimiters, min (strlen(delimiters),sizeof(_delimiters)-1));
}
/// Reads a line of text from \p is into \p s
inline istringstream& getline (istringstream& is, string& s, char delim = '\n')
{ return is.getline (s, delim); }
//----------------------------------------------------------------------
template <typename T> struct object_text_reader {
inline void operator()(istringstream& is, T& v) const { v.text_read (is); }
};
template <typename T> struct integral_text_object_reader {
inline void operator()(istringstream& is, T& v) const { is.iread (v); }
};
template <typename T>
inline istringstream& operator>> (istringstream& is, T& v) {
typedef typename tm::Select <numeric_limits<T>::is_integral,
integral_text_object_reader<T>, object_text_reader<T> >::Result object_reader_t;
object_reader_t()(is, v);
return is;
}
//----------------------------------------------------------------------
template <> struct object_text_reader<string> {
inline void operator()(istringstream& is, string& v) const { is.iread (v); }
};
} // namespace ustl