10#ifndef XTENSOR_CSV_HPP
11#define XTENSOR_CSV_HPP
21#include "xtensor_config.hpp"
30 template <
class T,
class A = std::allocator<T>>
33 template <
class T,
class A = std::allocator<T>>
36 const char delimiter =
',',
37 const std::size_t skip_rows = 0,
38 const std::ptrdiff_t max_rows = -1,
39 const std::string comments =
"#"
52 inline T lexical_cast(
const std::string& cell)
55 std::istringstream iss(cell);
61 inline std::string lexical_cast(
const std::string& cell)
63 size_t first = cell.find_first_not_of(
' ');
64 if (first == std::string::npos)
69 size_t last = cell.find_last_not_of(
' ');
70 return cell.substr(first, last == std::string::npos ? cell.size() : last + 1);
74 inline float lexical_cast<float>(
const std::string& cell)
76 return std::stof(cell);
80 inline double lexical_cast<double>(
const std::string& cell)
82 return std::stod(cell);
86 inline long double lexical_cast<long double>(
const std::string& cell)
88 return std::stold(cell);
92 inline int lexical_cast<int>(
const std::string& cell)
94 return std::stoi(cell);
98 inline long lexical_cast<long>(
const std::string& cell)
100 return std::stol(cell);
104 inline long long lexical_cast<long long>(
const std::string& cell)
106 return std::stoll(cell);
110 inline unsigned int lexical_cast<unsigned int>(
const std::string& cell)
112 return static_cast<unsigned int>(std::stoul(cell));
116 inline unsigned long lexical_cast<unsigned long>(
const std::string& cell)
118 return std::stoul(cell);
122 inline unsigned long long lexical_cast<unsigned long long>(
const std::string& cell)
124 return std::stoull(cell);
127 template <
class ST,
class T,
class OI>
128 ST load_csv_row(std::istream& row_stream, OI output, std::string cell,
const char delimiter =
',')
131 while (std::getline(row_stream, cell, delimiter))
133 *output++ = lexical_cast<T>(cell);
151 template <
class T,
class A>
153 std::istream& stream,
154 const char delimiter,
155 const std::size_t skip_rows,
156 const std::ptrdiff_t max_rows,
157 const std::string comments
160 using tensor_type = xcsv_tensor<T, A>;
161 using storage_type =
typename tensor_type::storage_type;
162 using size_type =
typename tensor_type::size_type;
163 using inner_shape_type =
typename tensor_type::inner_shape_type;
164 using inner_strides_type =
typename tensor_type::inner_strides_type;
165 using output_iterator = std::back_insert_iterator<storage_type>;
168 size_type nbrow = 0, nbcol = 0, nhead = 0;
170 output_iterator output(data);
171 std::string
row, cell;
172 while (std::getline(stream,
row))
174 if (nhead < skip_rows)
179 if (std::equal(comments.begin(), comments.end(),
row.begin()))
183 if (0 < max_rows && max_rows <=
static_cast<const long long>(nbrow))
187 std::stringstream row_stream(
row);
188 nbcol = detail::load_csv_row<size_type, T, output_iterator>(row_stream, output, cell, delimiter);
192 inner_shape_type shape = {nbrow, nbcol};
196 if (data.size() != data_size)
198 XTENSOR_THROW(std::runtime_error,
"Inconsistent row lengths in CSV");
200 return tensor_type(std::move(data), std::move(shape), std::move(
strides));
212 using size_type =
typename E::size_type;
214 if (ex.dimension() != 2)
216 XTENSOR_THROW(std::runtime_error,
"Only 2-D expressions can be serialized to CSV");
218 size_type nbrows = ex.shape()[0], nbcols = ex.shape()[1];
219 auto st = ex.stepper_begin(ex.shape());
220 for (size_type r = 0; r != nbrows; ++r)
222 for (size_type c = 0; c != nbcols; ++c)
243 std::size_t skip_rows;
244 std::ptrdiff_t max_rows;
245 std::string comments;
269 void dump_file(std::ostream& stream,
const xexpression<E>& e,
const xcsv_config&)
Base class for xexpressions.
derived_type & derived_cast() &noexcept
Returns a reference to the actual derived type of the xexpression.
Dense multidimensional container with tensor semantic and fixed dimension.
std::size_t compute_strides(const shape_type &shape, layout_type l, strides_type &strides)
Compute the strides given the shape and the layout of an array.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
standard mathematical functions for xexpressions
xcsv_tensor< T, A > load_csv(std::istream &stream, const char delimiter=',', const std::size_t skip_rows=0, const std::ptrdiff_t max_rows=-1, const std::string comments="#")
Load tensor from CSV.
auto row(E &&e, std::ptrdiff_t index)
Constructs and returns a row (sliced view) on the specified expression.
void dump_csv(std::ostream &stream, const xexpression< E > &e)
Dump tensor to CSV.