10#ifndef XTENSOR_CSV_HPP
11#define XTENSOR_CSV_HPP
19#include "../containers/xtensor.hpp"
20#include "../core/xtensor_config.hpp"
29 template <
class T,
class A = std::allocator<T>>
32 template <
class T,
class A = std::allocator<T>>
35 const char delimiter =
',',
36 const std::size_t skip_rows = 0,
37 const std::ptrdiff_t max_rows = -1,
38 const std::string comments =
"#"
51 inline T lexical_cast(
const std::string& cell)
54 std::istringstream iss(cell);
60 inline std::string lexical_cast(
const std::string& cell)
62 size_t first = cell.find_first_not_of(
' ');
63 if (first == std::string::npos)
68 size_t last = cell.find_last_not_of(
' ');
69 return cell.substr(first, last == std::string::npos ? cell.size() : last + 1);
73 inline float lexical_cast<float>(
const std::string& cell)
75 return std::stof(cell);
79 inline double lexical_cast<double>(
const std::string& cell)
81 return std::stod(cell);
85 inline long double lexical_cast<long double>(
const std::string& cell)
87 return std::stold(cell);
91 inline int lexical_cast<int>(
const std::string& cell)
93 return std::stoi(cell);
97 inline long lexical_cast<long>(
const std::string& cell)
99 return std::stol(cell);
103 inline long long lexical_cast<long long>(
const std::string& cell)
105 return std::stoll(cell);
109 inline unsigned int lexical_cast<unsigned int>(
const std::string& cell)
111 return static_cast<unsigned int>(std::stoul(cell));
115 inline unsigned long lexical_cast<unsigned long>(
const std::string& cell)
117 return std::stoul(cell);
121 inline unsigned long long lexical_cast<unsigned long long>(
const std::string& cell)
123 return std::stoull(cell);
126 template <
class ST,
class T,
class OI>
127 ST load_csv_row(std::istream& row_stream, OI output, std::string cell,
const char delimiter =
',')
130 while (std::getline(row_stream, cell, delimiter))
132 *output++ = lexical_cast<T>(cell);
150 template <
class T,
class A>
152 std::istream& stream,
153 const char delimiter,
154 const std::size_t skip_rows,
155 const std::ptrdiff_t max_rows,
156 const std::string comments
159 using tensor_type = xcsv_tensor<T, A>;
160 using storage_type =
typename tensor_type::storage_type;
161 using size_type =
typename tensor_type::size_type;
162 using inner_shape_type =
typename tensor_type::inner_shape_type;
163 using inner_strides_type =
typename tensor_type::inner_strides_type;
164 using output_iterator = std::back_insert_iterator<storage_type>;
167 size_type nbrow = 0, nbcol = 0, nhead = 0;
169 output_iterator output(data);
170 std::string
row, cell;
171 while (std::getline(stream,
row))
173 if (nhead < skip_rows)
178 if (std::equal(comments.begin(), comments.end(),
row.begin()))
182 if (0 < max_rows && max_rows <=
static_cast<const long long>(nbrow))
186 std::stringstream row_stream(
row);
187 nbcol = detail::load_csv_row<size_type, T, output_iterator>(row_stream, output, cell, delimiter);
191 inner_shape_type shape = {nbrow, nbcol};
195 if (data.size() != data_size)
197 XTENSOR_THROW(std::runtime_error,
"Inconsistent row lengths in CSV");
199 return tensor_type(std::move(data), std::move(shape), std::move(
strides));
211 using size_type =
typename E::size_type;
213 if (ex.dimension() == 1)
215 const size_type n = ex.shape()[0];
216 for (size_type i = 0; i != n; ++i)
226 else if (ex.dimension() == 2)
228 const size_type nbrows = ex.shape()[0];
229 const size_type nbcols = ex.shape()[1];
230 for (size_type r = 0; r != nbrows; ++r)
232 for (size_type c = 0; c != nbcols; ++c)
245 XTENSOR_THROW(std::runtime_error,
"Only 1-D and 2-D expressions can be serialized to CSV");
252 std::size_t skip_rows;
253 std::ptrdiff_t max_rows;
254 std::string comments;
278 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.