Horizon
csv.hpp
1 #pragma once
2 
3 /*
4  * Specification
5  * 1. Fields are separated by a user specified delimiter (default comma) and
6  * newline.
7  * 2. White space is never touched.
8  * 3. A field may be enclosed in double-quote characters "...".
9  * 4. A quoted field may contain commas.
10  * 5. A sequence of "" inside a quoted field is interpreted as a single '"'.
11  * 6. Fields may be empty; "" and an empty string both represent an empty field.
12  *
13  * Another description for quote mode (3., 4., 5. above):
14  * - When not in quote mode, a double-quote enters quote mode.
15  * - In quote mode, a double-quote not followed by a double-quote exits quote
16  * mode.
17  * - In quote mode, the sequence "" is emitted as a single '"'.
18  * - Delimiters have no special meaning in quote mode.
19  *
20  * Consequences:
21  * - Quote mode does not nest.
22  * - A line should have an even number of double-quote characters.
23  */
24 
25 #include <string>
26 #include <vector>
27 
28 namespace horizon::CSV {
29 
30 class Csv {
31 public:
32  Csv(const std::string &delim = ",");
33  void parseline(const std::string &line);
34  std::size_t size() const;
35  /* Make each line have at least n fields. */
36  void expand(std::size_t n, const std::string &pad = "");
37  const std::vector<std::string> &operator[](std::size_t i) const;
38  std::vector<std::vector<std::string>>::const_iterator begin() const;
39  std::vector<std::vector<std::string>>::const_iterator end() const;
40 
41 private:
42  bool isdelim(char c);
43  std::vector<std::vector<std::string>> val;
44  std::string delim;
45 };
46 
47 std::istream &operator>>(std::istream &is, Csv &obj);
48 
49 } // namespace horizon::CSV