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:
41 static void write(
42 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,
43 t_real const *i_hv, t_real const *i_bm, std::ostream &io_stream
44 );
45
46 // completely in header file for template reasons
47 template <typename... Types>
48 static std::vector<std::tuple<Types...>>
49 getRows(std::string filename, std::uint32_t skipLines, std::uint32_t maxRows = 0) {
50 // read file as stream
51 std::ifstream in(filename);
52 if (!in)
53 throw std::runtime_error("Couldn't open file: " + filename);
54
55 std::vector<std::tuple<Types...>> rows;
56
57 // go through file line by line
58 std::string current;
59 while (std::getline(in, current)) {
60 // skip lines ignore empty and comment lines
61 if (current.empty())
62 continue;
63 if (current[0] == '#')
64 continue;
65
66 if (skipLines > 0) {
67 skipLines--;
68 continue;
69 }
70
71 std::vector<std::string> field_list;
72
73 std::istringstream row_stream(current);
74 std::string field;
75 // brake up line in fields
76 while (std::getline(row_stream, field, ',')) {
77 // trim fields
78 const char *whitespaces = " \t\r\n";
79
80 auto start = field.find_first_not_of(whitespaces);
81 if (start == std::string::npos) {
82 field_list.push_back("");
83 continue;
84 };
85 auto end = field.find_last_not_of(whitespaces);
86
87 // push trimmed field to field list
88 field_list.push_back(field.substr(start, end - start + 1));
89 }
90
91 // row is done, push to array
92 rows.push_back(castLine<Types...>(field_list));
93
94 // stop early if a row limit is set
95 if (maxRows > 0 && rows.size() >= maxRows)
96 break;
97 }
98
99 return rows;
100 }
101
102 private:
103 // using this as a consversion from string to T, not ideal but works for base types
104 template <typename T> static T convert(const std::string str) {
105 std::istringstream stream(str);
106 T val;
107 stream >> val;
108 return val;
109 }
110
111 // using variadic templates with a recursive implementation to have a generic csv reader
112
113 // base to catch last type
114 template <typename Last> static std::tuple<Last> castLine(std::vector<std::string> string_row) {
115 if (string_row.size() < 1)
116 throw std::runtime_error("Couldn't parse line, too few cells in row");
117
118 return std::make_tuple(convert<Last>(string_row[0]));
119 }
120
121 // work through each type one by one
122 template <typename First, typename... Types>
123 requires(sizeof...(Types) != 0)
124 static std::tuple<First, Types...> castLine(std::vector<std::string> string_row) {
125 if (string_row.size() < 1)
126 throw std::runtime_error("Couldn't parse line, too few cells in row");
127
128 std::vector<std::string> sub;
129 sub.assign(string_row.begin() + 1, string_row.end());
130
131 auto rest = castLine<Types...>(sub);
132
133 // attach new element to tuple
134 return std::tuple_cat(std::make_tuple(convert<First>(string_row[0])), rest);
135 }
136};
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:49
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, t_real const *i_bm, 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