10#ifndef XTENSOR_CSV_HPP 
   11#define XTENSOR_CSV_HPP 
   20#include "../containers/xtensor.hpp" 
   21#include "../core/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.