fmatvec 0.0.0

stream_impl.h
1 /* Copyright (C) 2003-2005 Martin Förg
2
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 *
17 * Contact:
18 * martin.o.foerg@googlemail.com
19 *
20 */
21
22 #ifndef stream_impl_h
23 #define stream_impl_h
24
25 #include "stream.h"
26 #include <cassert>
27 #include <fstream>
28 #include <sstream>
29 #include <iomanip>
30 #include <stdexcept>
31 #include <limits>
32 #include <boost/scope_exit.hpp>
33 #include "range.h"
34 #include "types.h"
35 #include <boost/spirit/include/qi.hpp>
36 #include <boost/phoenix/bind/bind_function.hpp>
37 #include <boost/spirit/include/phoenix_operator.hpp>
38 #include <boost/spirit/include/support_istream_iterator.hpp>
39 #include <boost/spirit/include/karma_real.hpp>
40 #include <boost/spirit/include/karma.hpp>
41
42 namespace {
43 template<class AT>
44 std::vector<std::vector<AT>> scalarToVecVec(const AT& x) {
45 return std::vector<std::vector<AT>>(1, std::vector<AT>(1, x));
46 }
47 }
48
49 namespace fmatvec {
50
58 template <class Type, class Row, class Col, class AT> std::istream& operator>>(std::istream &s, Matrix<Type,Row,Col,AT> &A) {
59 namespace qi = boost::spirit::qi;
60 namespace phx = boost::phoenix;
61 using It = boost::spirit::istream_iterator;
62
63 qi::rule<It, std::vector<std::vector<AT>>()> scalar;
64 qi::rule<It, std::vector<AT>()> row;
65 qi::rule<It, std::vector<std::vector<AT>>()> matrix;
66 qi::rule<It, std::vector<std::vector<AT>>()> scalarOrMatrix;
67
68 qi::rule<It, AT()> &atomicType = getBoostSpiritQiRule<AT>();
69 scalar = *qi::space >> atomicType[qi::_val=phx::bind(&scalarToVecVec<AT>, qi::_1)];
70 row = atomicType % (+qi::blank | (*qi::blank >> ',' >> *qi::blank));
71 matrix = *qi::space >> '[' >> *qi::space >>
72 -(row % (*qi::blank >> (';' | qi::eol) >> *qi::blank))[qi::_val=qi::_1] >>
73 *qi::space >> ']';
74 scalarOrMatrix = scalar | matrix;
75
76 auto savedFlags=s.flags();
77 s.unsetf(std::ios::skipws);
78 BOOST_SCOPE_EXIT_TPL(&s, &savedFlags) {
79 s.flags(savedFlags);
80 } BOOST_SCOPE_EXIT_END
81
82 std::vector<std::vector<AT>> Avecvec;
83 if(!qi::parse(It(s), It(), scalarOrMatrix, Avecvec))
84 throw std::runtime_error("The stream does not contain a valid scalar, vector or matrix expression. Not parsed content of stream:\n"+
85 std::string(std::istreambuf_iterator<char>(s), std::istreambuf_iterator<char>()));
86 A<<=Matrix<Type,Row,Col,AT>(Avecvec);
87 return s;
88 }
89
97 template <class Type, class Row, class Col, class AT> std::ostream& operator<<(std::ostream &os, const Matrix<Type,Row,Col,AT> &A) {
98 namespace karma = boost::spirit::karma;
99 using It = std::ostream_iterator<char>;
100
101 static boost::spirit::karma::rule<It, std::vector<std::vector<AT>>()> matrix;
102 static bool init=false;
103 if(!init) {
104 static karma::rule<It, std::vector<AT>()> row;
105
106 auto &atomicType=getBoostSpiritKarmaRule<AT>();
107
108 row = -(atomicType % ", ")[karma::_1=karma::_val];
109 matrix = '[' << -(row % "; ")[karma::_1=karma::_val] << ']';
110 }
111
112 auto Avecvec=static_cast<std::vector<std::vector<AT>>>(A);
113 if(!karma::generate(It(os), matrix, Avecvec))
114 throw std::runtime_error("Failed to write matrix to stream");
115 return os;
116 }
117
118 }
119
120 #endif
fmatvec::Matrix
This is the basic matrix class for arbitrary matrices.
Definition: fmatvec.h:42
boost::spirit::basic_istream_iterator
Definition: stream.h:32
fmatvec
Namespace fmatvec.
Definition: _memory.cc:28
fmatvec::operator<<
ostream & operator<<(ostream &s, const SymbolicExpression &se)
Write a SymbolicExpression to a stream using serialization.
Definition: ast.cc:190