File: matrix_parser.hh

package info (click to toggle)
dynare 5.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 77,852 kB
  • sloc: cpp: 94,481; ansic: 28,551; pascal: 14,532; sh: 5,453; objc: 4,671; yacc: 4,442; makefile: 2,923; lex: 1,612; python: 677; ruby: 469; lisp: 156; xml: 22
file content (150 lines) | stat: -rw-r--r-- 4,628 bytes parent folder | download
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
/*
 * Copyright © 2006 Ondra Kamenik
 * Copyright © 2019 Dynare Team
 *
 * This file is part of Dynare.
 *
 * Dynare is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Dynare is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef OGP_MATRIX_PARSER
#define OGP_MATRIX_PARSER

#include <vector>
#include <string>

namespace ogp
{
  using std::vector;

  /** This class reads the given string and parses it as a
   * matrix. The matrix is read row by row. The row delimiter is
   * either a newline character or semicolon (first newline
   * character after the semicolon is ignored), the column delimiter
   * is either blank character or comma. A different number of items
   * in the row is not reconciliated, we do not construct a matrix
   * here. The class provides only an iterator to go through all
   * read items, the iterator provides information on row number and
   * column number of the item. */
  class MPIterator;
  class MatrixParser
  {
    friend class MPIterator;
  protected:
    /** Raw data as they were read. */
    vector<double> data;
    /** Number of items in each row. */
    vector<int> row_lengths;
    /** Maximum number of row lengths. */
    int nc{0};
  public:
    MatrixParser() = default;
    MatrixParser(const MatrixParser &mp) = default;
    virtual ~MatrixParser() = default;
    /** Return a number of read rows. */
    int
    nrows() const
    {
      return static_cast<int>(row_lengths.size());
    }
    /** Return a maximum number of items in the rows. */
    int
    ncols() const
    {
      return nc;
    }
    /** Parses a given data. This initializes the object data. */
    void parse(const std::string &stream);
    /** Adds newly read item. This should be called from bison
     * parser. */
    void add_item(double v);
    /** Starts a new row. This should be called from bison
     * parser. */
    void start_row();
    /** Process a parse error from the parser. */
    void error(std::string mes) const;
    /** Return begin iterator. */
    MPIterator begin() const;
    /** Return end iterator. */
    MPIterator end() const;
  protected:
    /** Returns an index of the first non-empty row starting at
     * start. If the start row is non-empty, returns the start. If
     * there is no other non-empty row, returns
     * row_lengths.size(). */
    int find_first_non_empty_row(int start = 0) const;
  };

  /** This is an iterator intended to iterate through a matrix parsed
   * by MatrixParser. The iterator provides only read-only access. */
  class MPIterator
  {
    friend class MatrixParser;
  protected:
    /** Reference to the matrix parser. */
    const MatrixParser *p{nullptr};
    /** The index of the pointed item in the matrix parser. */
    unsigned int i{0};
    /** The column number of the pointed item starting from zero. */
    int c{0};
    /** The row number of the pointed item starting from zero. */
    int r{0};

  public:
    MPIterator() = default;
    /** Constructs an iterator pointing to the beginning of the
     * parsed matrix. */
    MPIterator(const MatrixParser &mp);
    /** Constructs an iterator pointing to the past-the-end of the
     * parsed matrix. */
    MPIterator(const MatrixParser &mp, const char *dummy);
    /** Return read-only reference to the pointed item. */
    const double &
    operator*() const
    {
      return p->data[i];
    }
    /** Return a row index of the pointed item. */
    int
    row() const
    {
      return r;
    }
    /** Return a column index of the pointed item. */
    int
    col() const
    {
      return c;
    }
    /** Assignment operator. */
    MPIterator &operator=(const MPIterator &it) = default;
    /** Return true if the iterators are the same, this is if they
     * have the same underlying object and the same item index. */
    bool
    operator==(const MPIterator &it) const
    {
      return it.p == p && it.i == i;
    }
    /** Negative of the operator==. */
    bool
    operator!=(const MPIterator &it) const
    {
      return !(it == *this);
    }
    /** Increment operator. */
    MPIterator &operator++();
  };
};

#endif