/usr/include/xtensor/xcsv.hpp is in xtensor-dev 0.10.11-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | /***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/
#ifndef XCSV_HPP
#define XCSV_HPP
#include <exception>
#include <istream>
#include <iterator>
#include <sstream>
#include <string>
#include <utility>
#include "xtensor.hpp"
namespace xt
{
/**************************************
* load_csv and dump_csv declarations *
**************************************/
template <class T, class A = std::allocator<T>>
xtensor_container<std::vector<T, A>, 2> load_csv(std::istream& stream);
template <class E>
void dump_csv(std::ostream& stream, const xexpression<E>& e);
/*****************************************
* load_csv and dump_csv implementations *
*****************************************/
namespace detail
{
template <class T>
inline T lexical_cast(const std::string& cell)
{
T res;
std::istringstream iss(cell);
iss >> res;
return res;
}
template <>
inline float lexical_cast<float>(const std::string& cell) { return std::stof(cell); }
template <>
inline double lexical_cast<double>(const std::string& cell) { return std::stod(cell); }
template <>
inline long double lexical_cast<long double>(const std::string& cell) { return std::stold(cell); }
template <>
inline int lexical_cast<int>(const std::string& cell) { return std::stoi(cell); }
template <>
inline long lexical_cast<long>(const std::string& cell) { return std::stol(cell); }
template <>
inline long long lexical_cast<long long>(const std::string& cell) { return std::stoll(cell); }
template <>
inline unsigned int lexical_cast<unsigned int>(const std::string& cell) { return static_cast<unsigned int>(std::stoul(cell)); }
template <>
inline unsigned long lexical_cast<unsigned long>(const std::string& cell) { return std::stoul(cell); }
template <>
inline unsigned long long lexical_cast<unsigned long long>(const std::string& cell) { return std::stoull(cell); }
template <class ST, class T, class OI>
ST load_csv_row(std::istream& row_stream, OI output, std::string cell)
{
ST length = 0;
while (std::getline(row_stream, cell, ','))
{
*output++ = lexical_cast<T>(cell);
++length;
}
return length;
}
}
/**
* @brief Load tensor from CSV.
*
* Returns an \ref xexpression for the parsed CSV
* @param stream the input stream containing the CSV encoded values
*/
template <class T, class A>
xtensor_container<std::vector<T, A>, 2> load_csv(std::istream& stream)
{
using container_type = typename std::vector<T, A>;
using tensor_type = xtensor_container<container_type, 2>;
using size_type = typename tensor_type::size_type;
using inner_shape_type = typename tensor_type::inner_shape_type;
using inner_strides_type = typename tensor_type::inner_strides_type;
using output_iterator = std::back_insert_iterator<container_type>;
container_type data;
size_type nbrow = 0, nbcol = 0;
{
output_iterator output(data);
std::string row, cell;
while (std::getline(stream, row))
{
std::stringstream row_stream(row);
nbcol = detail::load_csv_row<size_type, T, output_iterator>(row_stream, output, cell);
++nbrow;
}
}
inner_shape_type shape = {nbrow, nbcol};
inner_strides_type strides; // no need for initializer list for stack-allocated strides_type
size_type data_size = compute_strides(shape, layout_type::row_major, strides);
// Sanity check for data size.
if (data.size() != data_size)
{
throw std::runtime_error("Inconsistent row lengths in CSV");
}
return tensor_type(std::move(data), std::move(shape), std::move(strides));
}
/**
* @brief Dump tensor to CSV.
*
* @param stream the output stream to write the CSV encoded values
* @param e the tensor expression to serialize
*/
template <class E>
void dump_csv(std::ostream& stream, const xexpression<E>& e)
{
using size_type = typename E::size_type;
const E& ex = e.derived_cast();
if (ex.dimension() != 2)
{
throw std::runtime_error("Only 2-D expressions can be serialized to CSV");
}
size_type nbrows = ex.shape()[0], nbcols = ex.shape()[1];
auto st = ex.stepper_begin(ex.shape());
for (size_type r = 0; r != nbrows; ++r)
{
for (size_type c = 0; c != nbcols; ++c)
{
stream << *st;
if (c != nbcols - 1)
{
st.step(1);
stream << ',';
}
else
{
st.reset(1);
st.step(0);
stream << std::endl;
}
}
}
}
}
#endif
|