16 while (start < sv.size() && ws_flags[sv[start] +
CHAR_OFFSET]) {
20 size_t end = sv.size();
21 while (end > start && ws_flags[sv[end - 1] +
CHAR_OFFSET]) {
25 return sv.substr(start, end - start);
39 return this->make_field(n, this->data);
50 auto & col_names = this->data->col_names;
51 auto col_pos = col_names->index_of(col_name);
56 internals::throw_column_not_found(col_name);
58 CSV_INLINE CSVRow::operator std::vector<std::string>()
const {
59 std::vector<std::string> ret;
60 for (
size_t i = 0; i < size(); i++)
61 ret.push_back(std::string(this->get_field(i)));
71 if (data_end != (std::numeric_limits<size_t>::max)()
72 && data_end >= data_start
73 && data_end <= full.size()) {
74 return full.substr(data_start, data_end - data_start);
77 const size_t end = full.find(
'\n', data_start);
78 const size_t len = (
end == csv::string_view::npos)
79 ? (full.size() - data_start)
81 return full.substr(data_start, len);
86 std::unordered_map<std::string, std::string> row_map;
87 row_map.reserve(this->
size());
89 for (
size_t i = 0; i < this->
size(); i++) {
90 auto col_name = (*this->data->col_names)[i];
99 const std::vector<std::string>& subset
101 std::unordered_map<std::string, std::string> row_map;
102 row_map.reserve(subset.size());
104 for (
const auto& col_name : subset)
105 row_map[col_name] = this->
operator[](col_name).get<std::string>();
112 return this->get_field_impl(index, this->data);
117 return this->get_field_impl(index, _data);
120 CSV_INLINE CSVField CSVRow::make_field(
size_t index,
const internals::RawCSVDataPtr& _data)
const
123 const size_t field_index = this->fields_start + index;
124 if (_data->has_field_scalars() && field_index < _data->field_scalars.size()) {
125 return CSVField(field, _data->field_scalars[field_index]);
128 return CSVField(field);
136 if (this->type_ == DataType::UNKNOWN)
143 double parsed_value = 0;
144 if (!classify_scalar::parse_float(this->sv.data(), this->sv.data() + this->sv.size(), parsed_value, decimalSymbol)) {
157 dVal = this->numeric_value_as_long_double();
166 if (this->type_ == DataType::UNKNOWN)
170 out = this->value_.timestamp;
174 if (this->stores_integral() && this->value_.integer >= 0) {
175 out =
static_cast<std::uint64_t
>(this->value_.integer);
183#pragma region CSVRow Iterator
200 return std::reverse_iterator<CSVRow::iterator>(this->
end());
204 return std::reverse_iterator<CSVRow::iterator>(this->
begin());
208 CSVRow::iterator::iterator(const CSVRow* _reader,
int _i)
209 : daddy(_reader), data(_reader->data), i(_i) {
210 if (_i < (
int)this->daddy->size())
211 this->field = std::make_shared<CSVField>(
212 this->daddy->make_field(_i, this->data));
214 this->field =
nullptr;
217 CSV_INLINE CSVRow::iterator::reference CSVRow::iterator::operator*()
const {
218 return *(this->field.get());
221 CSV_INLINE CSVRow::iterator::pointer CSVRow::iterator::operator->()
const {
225 CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator++() {
228 if (this->i < (
int)this->daddy->size())
229 this->field = std::make_shared<CSVField>(
230 this->daddy->make_field(i, this->data));
232 this->field =
nullptr;
236 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator++(
int) {
243 CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator--() {
246 this->field = std::make_shared<CSVField>(
247 this->daddy->make_field(this->i, this->data));
251 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator--(
int) {
258 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator+(difference_type n)
const {
260 return CSVRow::iterator(this->daddy, i + (
int)n);
263 CSV_INLINE CSVRow::iterator CSVRow::iterator::operator-(difference_type n)
const {
265 return CSVRow::iterator::operator+(-n);
268 CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator+=(difference_type n) {
273 CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator-=(difference_type n) {
278 CSV_INLINE CSVRow::iterator::difference_type CSVRow::iterator::operator-(
const iterator& other)
const noexcept {
279 return this->i - other.i;
282#pragma endregion CSVRow Iterator
Data type representing individual CSV values.
bool try_parse_timestamp(std::uint64_t &out) noexcept
Parse this field as Unix milliseconds.
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...
T get()
Returns the value casted to the requested type, performing type checking before.
A random access iterator over the contents of a CSV row.
iterator end() const noexcept
Return an iterator pointing to just after the end of the CSVRow.
std::reverse_iterator< iterator > reverse_iterator
A reverse iterator over the contents of a CSVRow.
csv::string_view raw_str() const noexcept
Return a string_view of the raw bytes of this row as they appear in the underlying parse buffer,...
std::unordered_map< std::string, std::string > to_unordered_map() const
Convert this CSVRow into an unordered map.
CONSTEXPR size_t size() const noexcept
Return the number of fields in this row.
CSVField operator[](size_t n) const
Return a CSVField object corrsponding to the nth value in the row.
iterator begin() const
Return an iterator pointing to the first field.
#define CSV_INLINE
Helper macro which should be #defined as "inline" in the single header version.
Shared exception message templates and throw helpers.
Defines the data type used for storing information about a CSV row.
The all encompassing namespace.
@ CSV_TIMESTAMP
Timestamp value.
@ CSV_DOUBLE
Floating point value.
@ CSV_STRING
Non-scalar string.
constexpr unsigned CHAR_OFFSET
Offset to convert char into array index.
std::string_view string_view
The string_view class used by this library.