Tsunami Project Lab
Loading...
Searching...
No Matches
Csv.h
Go to the documentation of this file.
1
7#pragma once
8
9#include "../constants.h"
10#include <cstdint>
11#include <cstring>
12#include <fstream>
13#include <iostream>
14#include <optional>
15#include <sstream>
16#include <string_view>
17#include <tuple>
18#include <vector>
19
20namespace tsunami_lab {
21namespace io {
22class Csv;
23}
24}
25
27 public:
40 static void write(
41 t_real i_dxy, t_idx i_nx, t_idx i_ny, t_idx i_stride, t_real const *i_h, t_real const *i_hu,
42 t_real const *i_hv, std::ostream &io_stream
43 );
44
45 // completely in header file for template reasons
46 template <typename... Types>
47 static std::vector<std::tuple<Types...>>
48 getRows(std::string filename, std::uint32_t skipLines, std::uint32_t maxRows = 0) {
49 // read file as stream
50 std::ifstream in(filename);
51 if (!in)
52 throw std::runtime_error("Couldn't open file: " + filename);
53
54 std::vector<std::tuple<Types...>> rows;
55
56 // go through file line by line
57 std::string current;
58 while (std::getline(in, current)) {
59 // skip lines ignore empty and comment lines
60 if (current.empty())
61 continue;
62 if (current[0] == '#')
63 continue;
64
65 if (skipLines > 0) {
66 skipLines--;
67 continue;
68 }
69
70 std::vector<std::string> field_list;
71
72 std::istringstream row_stream(current);
73 std::string field;
74 // brake up line in fields
75 while (std::getline(row_stream, field, ',')) {
76 // trim fields
77 const char *whitespaces = " \t\r\n";
78
79 auto start = field.find_first_not_of(whitespaces);
80 if (start == std::string::npos) {
81 field_list.push_back("");
82 continue;
83 };
84 auto end = field.find_last_not_of(whitespaces);
85
86 // push trimmed field to field list
87 field_list.push_back(field.substr(start, end - start + 1));
88 }
89
90 // row is done, push to array
91 rows.push_back(castLine<Types...>(field_list));
92
93 // stop early if a row limit is set
94 if (maxRows > 0 && rows.size() >= maxRows)
95 break;
96 }
97
98 return rows;
99 }
100
101 private:
102 // using this as a consversion from string to T, not ideal but works for base types
103 template <typename T> static T convert(const std::string str) {
104 std::istringstream stream(str);
105 T val;
106 stream >> val;
107 return val;
108 }
109
110 // using variadic templates with a recursive implementation to have a generic csv reader
111
112 // base to catch last type
113 template <typename Last> static std::tuple<Last> castLine(std::vector<std::string> string_row) {
114 if (string_row.size() < 1)
115 throw std::runtime_error("Couldn't parse line, too few cells in row");
116
117 return std::make_tuple(convert<Last>(string_row[0]));
118 }
119
120 // work through each type one by one
121 template <typename First, typename... Types>
122 requires(sizeof...(Types) != 0)
123 static std::tuple<First, Types...> castLine(std::vector<std::string> string_row) {
124 if (string_row.size() < 1)
125 throw std::runtime_error("Couldn't parse line, too few cells in row");
126
127 std::vector<std::string> sub;
128 sub.assign(string_row.begin() + 1, string_row.end());
129
130 auto rest = castLine<Types...>(sub);
131
132 // attach new element to tuple
133 return std::tuple_cat(std::make_tuple(convert<First>(string_row[0])), rest);
134 }
135};
Definition Csv.h:26
static std::vector< std::tuple< Types... > > getRows(std::string filename, std::uint32_t skipLines, std::uint32_t maxRows=0)
Definition Csv.h:48
static void write(t_real i_dxy, t_idx i_nx, t_idx i_ny, t_idx i_stride, t_real const *i_h, t_real const *i_hu, t_real const *i_hv, std::ostream &io_stream)
Definition Csv.cpp:9
Definition constants.h:12
float t_real
floating point type
Definition constants.h:17
std::size_t t_idx
integral type for cell-ids, pointer arithmetic, etc.
Definition constants.h:14