Vince's CSV Parser
Loading...
Searching...
No Matches
csv_row.cpp
Go to the documentation of this file.
1
5#include <cassert>
6#include <functional>
7#include "csv_row.hpp"
8
9namespace csv {
10
21 return CSVField(this->get_field(n));
22 }
23
33 CSV_INLINE CSVField CSVRow::operator[](const std::string& col_name) const {
34 auto & col_names = this->data->col_names;
35 auto col_pos = col_names->index_of(col_name);
36 if (col_pos > -1) {
37 return this->operator[](col_pos);
38 }
39
40 throw std::runtime_error("Can't find a column named " + col_name);
41 }
42
43 CSV_INLINE CSVRow::operator std::vector<std::string>() const {
44 std::vector<std::string> ret;
45 for (size_t i = 0; i < size(); i++)
46 ret.push_back(std::string(this->get_field(i)));
47
48 return ret;
49 }
50
52 CSV_INLINE std::unordered_map<std::string, std::string> CSVRow::to_unordered_map() const {
53 std::unordered_map<std::string, std::string> row_map;
54 row_map.reserve(this->size());
55
56 for (size_t i = 0; i < this->size(); i++) {
57 auto col_name = (*this->data->col_names)[i];
58 row_map[col_name] = this->operator[](i).get<std::string>();
59 }
60
61 return row_map;
62 }
63
69 CSV_INLINE std::unordered_map<std::string, std::string> CSVRow::to_unordered_map(
70 const std::vector<std::string>& subset
71 ) const {
72 std::unordered_map<std::string, std::string> row_map;
73 row_map.reserve(subset.size());
74
75 for (const auto& col_name : subset)
76 row_map[col_name] = this->operator[](col_name).get<std::string>();
77
78 return row_map;
79 }
80
81 CSV_INLINE csv::string_view CSVRow::get_field(size_t index) const
82 {
83 return this->get_field_impl(index, this->data);
84 }
85
86 CSV_INLINE csv::string_view CSVRow::get_field_safe(size_t index, internals::RawCSVDataPtr _data) const
87 {
88 return this->get_field_impl(index, _data);
89 }
90
91 CSV_INLINE bool CSVField::try_parse_decimal(long double& dVal, const char decimalSymbol) {
92 // If field has already been parsed to empty, no need to do it aagin:
93 if (this->_type == DataType::CSV_NULL)
94 return false;
95
96 // Not yet parsed or possibly parsed with other decimalSymbol
97 if (this->_type == DataType::UNKNOWN || this->_type == DataType::CSV_STRING || this->_type == DataType::CSV_DOUBLE)
98 this->_type = internals::data_type(this->sv, &this->value, decimalSymbol); // parse again
99
100 // Integral types are not affected by decimalSymbol and need not be parsed again
101
102 // Either we already had an integral type before, or we we just got any numeric type now.
103 if (this->_type >= DataType::CSV_INT8 && this->_type <= DataType::CSV_DOUBLE) {
104 dVal = this->value;
105 return true;
106 }
107
108 // CSV_NULL or CSV_STRING, not numeric
109 return false;
110 }
111
112#ifdef _MSC_VER
113#pragma region CSVRow Iterator
114#endif
117 return CSVRow::iterator(this, 0);
118 }
119
126 return CSVRow::iterator(this, (int)this->size());
127 }
128
129 CSV_INLINE CSVRow::reverse_iterator CSVRow::rbegin() const noexcept {
130 return std::reverse_iterator<CSVRow::iterator>(this->end());
131 }
132
133 CSV_INLINE CSVRow::reverse_iterator CSVRow::rend() const {
134 return std::reverse_iterator<CSVRow::iterator>(this->begin());
135 }
136
137 CSV_INLINE CSV_NON_NULL(2)
138 CSVRow::iterator::iterator(const CSVRow* _reader, int _i)
139 : daddy(_reader), data(_reader->data), i(_i) {
140 if (_i < (int)this->daddy->size())
141 this->field = std::make_shared<CSVField>(
142 CSVField(this->daddy->get_field_safe(_i, this->data)));
143 else
144 this->field = nullptr;
145 }
146
147 CSV_INLINE CSVRow::iterator::reference CSVRow::iterator::operator*() const {
148 return *(this->field.get());
149 }
150
151 CSV_INLINE CSVRow::iterator::pointer CSVRow::iterator::operator->() const {
152 return this->field;
153 }
154
155 CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator++() {
156 // Pre-increment operator
157 this->i++;
158 if (this->i < (int)this->daddy->size())
159 this->field = std::make_shared<CSVField>(
160 CSVField(this->daddy->get_field_safe(i, this->data)));
161 else // Reached the end of row
162 this->field = nullptr;
163 return *this;
164 }
165
166 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator++(int) {
167 // Post-increment operator
168 auto temp = *this;
169 this->operator++();
170 return temp;
171 }
172
173 CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator--() {
174 // Pre-decrement operator
175 this->i--;
176 this->field = std::make_shared<CSVField>(
177 CSVField(this->daddy->get_field_safe(this->i, this->data)));
178 return *this;
179 }
180
181 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator--(int) {
182 // Post-decrement operator
183 auto temp = *this;
184 this->operator--();
185 return temp;
186 }
187
188 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator+(difference_type n) const {
189 // Allows for iterator arithmetic
190 return CSVRow::iterator(this->daddy, i + (int)n);
191 }
192
193 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator-(difference_type n) const {
194 // Allows for iterator arithmetic
195 return CSVRow::iterator::operator+(-n);
196 }
197#ifdef _MSC_VER
198#pragma endregion CSVRow Iterator
199#endif
200}
Data type representing individual CSV values.
Definition csv_row.hpp:39
bool try_parse_decimal(long double &dVal, const char decimalSymbol='.')
Attempts to parse a decimal (or integer) value using the given symbol, returning true if the value is...
Definition csv_row.cpp:91
T get()
Returns the value casted to the requested type, performing type checking before.
Definition csv_row.hpp:76
A random access iterator over the contents of a CSV row.
Definition csv_row.hpp:335
iterator end() const noexcept
Return an iterator pointing to just after the end of the CSVRow.
Definition csv_row.cpp:125
std::reverse_iterator< iterator > reverse_iterator
A reverse iterator over the contents of a CSVRow.
Definition csv_row.hpp:375
std::unordered_map< std::string, std::string > to_unordered_map() const
Convert this CSVRow into an unordered map.
Definition csv_row.cpp:52
CONSTEXPR size_t size() const noexcept
Return the number of fields in this row.
Definition csv_row.hpp:297
CSVField operator[](size_t n) const
Return a CSVField object corrsponding to the nth value in the row.
Definition csv_row.cpp:20
iterator begin() const
Return an iterator pointing to the first field.
Definition csv_row.cpp:116
#define CSV_INLINE
Helper macro which should be #defined as "inline" in the single header version.
Definition common.hpp:26
Defines the data type used for storing information about a CSV row.
CONSTEXPR_14 DataType data_type(csv::string_view in, long double *const out, const char decimalSymbol)
Distinguishes numeric from other text values.
The all encompassing namespace.
@ CSV_DOUBLE
Floating point value.
@ CSV_NULL
Empty string.
@ CSV_INT8
8-bit integer
@ CSV_STRING
Non-numeric string.
nonstd::string_view string_view
The string_view class used by this library.
Definition common.hpp:99