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
|