11#include <unordered_set>
23 class IBasicCSVParser;
25 static const std::string ERROR_NAN =
"Not a number.";
26 static const std::string ERROR_OVERFLOW =
"Overflow error.";
27 static const std::string ERROR_FLOAT_TO_INT =
28 "Attempted to convert a floating point value to an integral type.";
29 static const std::string ERROR_NEG_TO_UNSIGNED =
"Negative numbers cannot be converted to unsigned types.";
44 operator std::string()
const {
45 return std::string(
"<CSVField> ") + std::string(this->sv);
76 template<
typename T = std::
string> T
get() {
80 throw std::runtime_error(internals::ERROR_NAN);
87 throw std::runtime_error(internals::ERROR_FLOAT_TO_INT);
91 if (this->value < 0) {
92 throw std::runtime_error(internals::ERROR_NEG_TO_UNSIGNED);
102 throw std::runtime_error(internals::ERROR_OVERFLOW);
106 throw std::runtime_error(internals::ERROR_OVERFLOW);
110 return static_cast<T
>(this->value);
148 template<
typename T = std::
string>
164 if (this->value < 0) {
182 out =
static_cast<T
>(this->value);
189 template<
typename T =
long long>
191 static_assert(std::is_integral<T>::value,
192 "try_parse_hex only works with integral types (int, long, long long, etc.)");
193 return internals::try_parse_hex(this->sv, parsedValue);
220 static_assert(std::is_arithmetic<T>::value,
221 "T should be a numeric value.");
223 if (this->_type != DataType::UNKNOWN) {
266 long double value = 0;
269 CONSTEXPR_14
void get_value() noexcept {
273 if ((
int)_type < 0) {
287 CSVRow(internals::RawCSVDataPtr _data) : data(_data) {}
288 CSVRow(internals::RawCSVDataPtr _data,
size_t _data_start,
size_t _field_bounds)
289 : data(_data), data_start(_data_start), fields_start(_field_bounds) {}
290 CSVRow(internals::RawCSVDataPtr _data,
size_t _data_start,
size_t _field_bounds,
size_t _row_length)
291 : data(_data), data_start(_data_start), fields_start(_field_bounds), row_length(_row_length) {}
303 std::string
to_json(
const std::vector<std::string>& subset = {})
const;
304 std::string
to_json_array(
const std::vector<std::string>& subset = {})
const;
308 return this->data->col_names->get_col_names();
322 const std::vector<std::string>& subset
329 operator std::vector<std::string>()
const;
337#ifndef DOXYGEN_SHOULD_SKIP_THIS
339 using difference_type = int;
340 using pointer = std::shared_ptr<CSVField>;
342 using iterator_category = std::random_access_iterator_tag;
346 reference operator*()
const;
347 pointer operator->()
const;
353 iterator operator+(difference_type n)
const;
354 iterator operator-(difference_type n)
const;
358 return this->i == other.i;
368 const CSVRow * daddy =
nullptr;
369 internals::RawCSVDataPtr data =
nullptr;
370 std::shared_ptr<CSVField> field =
nullptr;
389 inline
csv::
string_view get_field_impl(
size_t index, const internals::RawCSVDataPtr& _data)
const {
392 if (index >= this->
size())
393 throw std::runtime_error(
"Index out of bounds.");
395 const size_t field_index = this->fields_start + index;
396 auto field = _data->fields[field_index];
397 auto field_str =
csv::string_view(_data->data).substr(this->data_start + field.start);
399 if (field.has_double_quote) {
400 auto& value = _data->double_quote_fields[field_index];
403 std::lock_guard<std::mutex> lock(_data->double_quote_init_lock);
407 bool prev_ch_quote =
false;
408 for (
size_t i = 0; i < field.length; i++) {
409 if (_data->parse_flags[field_str[i] +
CHAR_OFFSET] == ParseFlags::QUOTE) {
411 prev_ch_quote =
false;
415 prev_ch_quote =
true;
419 value += field_str[i];
427 return field_str.substr(0, field.length);
436 csv::string_view get_field_safe(
size_t index, internals::RawCSVDataPtr _data)
const;
438 internals::RawCSVDataPtr data;
441 size_t data_start = 0;
444 size_t fields_start = 0;
447 size_t row_length = 0;
451#pragma region CSVField::get Specializations
455 inline std::string CSVField::get<std::string>() {
456 return std::string(this->sv);
471 CONSTEXPR_14
long double CSVField::get<long double>() {
473 throw std::runtime_error(internals::ERROR_NAN);
480 inline bool CSVField::try_get<std::string>(std::string& out)
noexcept {
481 out = std::string(this->sv);
494 CONSTEXPR_14
bool CSVField::try_get<long double>(
long double& out)
noexcept {
502#pragma endregion CSVField::get Specializations
509 return this->sv == other;
516 return this->sv == other;
520inline std::ostream& operator << (std::ostream& os,
csv::CSVField const& value) {
521 os << std::string(value);
Data type representing individual CSV values.
CONSTEXPR_14 bool is_num() noexcept
Returns true if field is an integer or float.
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...
CONSTEXPR_14 bool is_str() noexcept
Returns true if field is a non-numeric, non-empty string.
CONSTEXPR_14 bool is_int() noexcept
Returns true if field is an integer.
CONSTEXPR_14 bool is_null() noexcept
Returns true if field is an empty string or string of whitespace characters.
constexpr CSVField(csv::string_view _sv) noexcept
Constructs a CSVField from a string_view.
CONSTEXPR_14 DataType type() noexcept
Return the type of the underlying CSV data.
T get()
Returns the value casted to the requested type, performing type checking before.
CONSTEXPR_14 bool operator==(T other) const noexcept
Compares the contents of this field to a numeric value.
bool try_get(T &out) noexcept
Attempts to retrieve the value as the requested type without throwing exceptions.
CONSTEXPR_14 bool is_float() noexcept
Returns true if field is a floating point value.
CONSTEXPR csv::string_view get_sv() const noexcept
Return a string view over the field's contents.
bool try_parse_hex(T &parsedValue)
Parse a hexadecimal value, returning false if the value is not hex.
A random access iterator over the contents of a CSV row.
CONSTEXPR bool operator==(const iterator &other) const noexcept
Two iterators are equal if they point to the same field.
Data structure for representing CSV rows.
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.
std::string to_json(const std::vector< std::string > &subset={}) const
Convert a CSV row to a JSON object, i.e.
CONSTEXPR bool empty() const noexcept
Indicates whether row is empty or not.
std::string to_json_array(const std::vector< std::string > &subset={}) const
Convert a CSV row to a JSON array, i.e.
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.
std::vector< std::string > get_col_names() const
Retrieve this row's associated column names.
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.
CSVRow(internals::RawCSVDataPtr _data)
Construct a CSVRow from a RawCSVDataPtr.
Abstract base class which provides CSV parsing logic.
A standalone header file containing shared code.
#define IF_CONSTEXPR
Expands to if constexpr in C++17 and if otherwise.
#define CONSTEXPR
Expands to constexpr in decent compilers and inline otherwise.
Implements data type parsing functionality.
CONSTEXPR_14 DataType data_type(csv::string_view in, long double *const out, const char decimalSymbol)
Distinguishes numeric from other text values.
bool is_equal(T a, T b, T epsilon=0.001)
ParseFlags
An enum used for describing the significance of each character with respect to CSV parsing.
CSV_CONST CONSTEXPR_17 OutArray arrayToDefault(T &&value)
Helper constexpr function to initialize an array with all the elements set to value.
CONSTEXPR_14 long double get_uint_max()
Given a byte size, return the largest number than can be stored in an unsigned integer of that size.
The all encompassing namespace.
DataType
Enumerates the different CSV field types that are recognized by this library.
@ CSV_INT64
64-bit integer (long long on MSVC/GCC)
@ CSV_DOUBLE
Floating point value.
@ CSV_STRING
Non-numeric string.
constexpr unsigned CHAR_OFFSET
Offset to convert char into array index.
nonstd::string_view string_view
The string_view class used by this library.
Implements Functions related to hexadecimal parsing.
Internal data structures for CSV parsing.