-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathValueParser.h
More file actions
114 lines (93 loc) · 3 KB
/
Copy pathValueParser.h
File metadata and controls
114 lines (93 loc) · 3 KB
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
#pragma once
#include <string>
#include <iterator>
#include <cstring> // ::strlen
namespace Utility
{
template<typename ValueType>
struct ValueParserMethods
#ifdef PREFER_LINKTIME_ERRORS
{
static inline
ValueType extract( char const* start, char*& next, char const delim );
static inline
void adjust( char const*& start, char*& next, char const delim );
}
#else
// compile-time error if specialization not found
#endif
;
template<typename ValueType, typename Methods = ValueParserMethods<ValueType> >
class ValueParser
{
public:
ValueParser(std::string const& source, char const* delim = ",")
: ValueParser(source.c_str(), source.length(), delim)
{}
ValueParser(char const* source, char const* delim)
: ValueParser(source, ::strlen( source ), delim)
{}
ValueParser(char const* source, size_t length, char const* delim)
: source_(source)
, length_(length)
, delim_(delim[0])
{}
using value_type = ValueType;
class iterator
: public std::iterator<std::input_iterator_tag, value_type>
{
public:
iterator(char const* start, char const delim)
: start_(start)
, next_(const_cast<char*>(start_))
, delim_(delim)
{}
iterator& operator->() { return *this; }
value_type operator*() const
{
return Methods::extract( start_, next_, delim_ );
}
iterator& operator++()
{
Methods::adjust( start_, next_, delim_ );
return *this;
}
bool operator!=( iterator const& rhs ) const { return start_ != rhs.start_; }
bool operator==( iterator const& rhs ) const { return start_ == rhs.start_; }
private:
char const* start_;
mutable char* next_;
char const delim_;
};
iterator begin() { return iterator(source_, delim_); }
iterator end() { return iterator(source_ + length_, delim_); }
private:
char const* source_;
size_t length_;
char const delim_;
};
} // namespace Utility
#include <cstdlib>
#include <limits>
namespace Utility
{
template<>
struct ValueParserMethods<double>
{
static inline
double extract( char const* start, char*& next, char const )
{
return *start
? ::strtod( start, &next )
: std::numeric_limits<double>::quiet_NaN()
;
}
static inline
void adjust( char const*& start, char*& next, char const delim )
{
while ( *next and *next != delim ) { ++next; }
start = *next ? ++next : next;
}
};
using DoubleParser = ValueParser<double>;
} // namespace Utility