...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
00001 // 00002 // Copyright (c) 2000-2010 00003 // Joerg Walter, Mathias Koch, David Bellot 00004 // 00005 // Distributed under the Boost Software License, Version 1.0. (See 00006 // accompanying file LICENSE_1_0.txt or copy at 00007 // http://www.boost.org/LICENSE_1_0.txt) 00008 // 00009 // The authors gratefully acknowledge the support of 00010 // GeNeSys mbH & Co. KG in producing this work. 00011 // 00012 00013 #ifndef _BOOST_UBLAS_IO_ 00014 #define _BOOST_UBLAS_IO_ 00015 00016 // Only forward definition required to define stream operations 00017 #include <iosfwd> 00018 #include <sstream> 00019 #include <boost/numeric/ublas/matrix_expression.hpp> 00020 00021 00022 namespace boost { namespace numeric { namespace ublas { 00023 00046 template<class E, class T, class VE> 00047 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. 00048 std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os, 00049 const vector_expression<VE> &v) { 00050 typedef typename VE::size_type size_type; 00051 size_type size = v ().size (); 00052 std::basic_ostringstream<E, T, std::allocator<E> > s; 00053 s.flags (os.flags ()); 00054 s.imbue (os.getloc ()); 00055 s.precision (os.precision ()); 00056 s << '[' << size << "]("; 00057 if (size > 0) 00058 s << v () (0); 00059 for (size_type i = 1; i < size; ++ i) 00060 s << ',' << v () (i); 00061 s << ')'; 00062 return os << s.str ().c_str (); 00063 } 00064 00087 template<class E, class T, class VT, class VA> 00088 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. 00089 std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is, 00090 vector<VT, VA> &v) { 00091 typedef typename vector<VT, VA>::size_type size_type; 00092 E ch; 00093 size_type size; 00094 if (is >> ch && ch != '[') { 00095 is.putback (ch); 00096 is.setstate (std::ios_base::failbit); 00097 } else if (is >> size >> ch && ch != ']') { 00098 is.putback (ch); 00099 is.setstate (std::ios_base::failbit); 00100 } else if (! is.fail ()) { 00101 vector<VT, VA> s (size); 00102 if (is >> ch && ch != '(') { 00103 is.putback (ch); 00104 is.setstate (std::ios_base::failbit); 00105 } else if (! is.fail ()) { 00106 for (size_type i = 0; i < size; i ++) { 00107 if (is >> s (i) >> ch && ch != ',') { 00108 is.putback (ch); 00109 if (i < size - 1) 00110 is.setstate (std::ios_base::failbit); 00111 break; 00112 } 00113 } 00114 if (is >> ch && ch != ')') { 00115 is.putback (ch); 00116 is.setstate (std::ios_base::failbit); 00117 } 00118 } 00119 if (! is.fail ()) 00120 v.swap (s); 00121 } 00122 return is; 00123 } 00124 00148 template<class E, class T, class ME> 00149 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. 00150 std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os, 00151 const matrix_expression<ME> &m) { 00152 typedef typename ME::size_type size_type; 00153 size_type size1 = m ().size1 (); 00154 size_type size2 = m ().size2 (); 00155 std::basic_ostringstream<E, T, std::allocator<E> > s; 00156 s.flags (os.flags ()); 00157 s.imbue (os.getloc ()); 00158 s.precision (os.precision ()); 00159 s << '[' << size1 << ',' << size2 << "]("; 00160 if (size1 > 0) { 00161 s << '(' ; 00162 if (size2 > 0) 00163 s << m () (0, 0); 00164 for (size_type j = 1; j < size2; ++ j) 00165 s << ',' << m () (0, j); 00166 s << ')'; 00167 } 00168 for (size_type i = 1; i < size1; ++ i) { 00169 s << ",(" ; 00170 if (size2 > 0) 00171 s << m () (i, 0); 00172 for (size_type j = 1; j < size2; ++ j) 00173 s << ',' << m () (i, j); 00174 s << ')'; 00175 } 00176 s << ')'; 00177 return os << s.str ().c_str (); 00178 } 00179 00199 template<class E, class T, class MT, class MF, class MA> 00200 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. 00201 std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is, 00202 matrix<MT, MF, MA> &m) { 00203 typedef typename matrix<MT, MF, MA>::size_type size_type; 00204 E ch; 00205 size_type size1, size2; 00206 if (is >> ch && ch != '[') { 00207 is.putback (ch); 00208 is.setstate (std::ios_base::failbit); 00209 } else if (is >> size1 >> ch && ch != ',') { 00210 is.putback (ch); 00211 is.setstate (std::ios_base::failbit); 00212 } else if (is >> size2 >> ch && ch != ']') { 00213 is.putback (ch); 00214 is.setstate (std::ios_base::failbit); 00215 } else if (! is.fail ()) { 00216 matrix<MT, MF, MA> s (size1, size2); 00217 if (is >> ch && ch != '(') { 00218 is.putback (ch); 00219 is.setstate (std::ios_base::failbit); 00220 } else if (! is.fail ()) { 00221 for (size_type i = 0; i < size1; i ++) { 00222 if (is >> ch && ch != '(') { 00223 is.putback (ch); 00224 is.setstate (std::ios_base::failbit); 00225 break; 00226 } 00227 for (size_type j = 0; j < size2; j ++) { 00228 if (is >> s (i, j) >> ch && ch != ',') { 00229 is.putback (ch); 00230 if (j < size2 - 1) { 00231 is.setstate (std::ios_base::failbit); 00232 break; 00233 } 00234 } 00235 } 00236 if (is >> ch && ch != ')') { 00237 is.putback (ch); 00238 is.setstate (std::ios_base::failbit); 00239 break; 00240 } 00241 if (is >> ch && ch != ',') { 00242 is.putback (ch); 00243 if (i < size1 - 1) { 00244 is.setstate (std::ios_base::failbit); 00245 break; 00246 } 00247 } 00248 } 00249 if (is >> ch && ch != ')') { 00250 is.putback (ch); 00251 is.setstate (std::ios_base::failbit); 00252 } 00253 } 00254 if (! is.fail ()) 00255 m.swap (s); 00256 } 00257 return is; 00258 } 00259 00281 template<class E, class T, class MT, class MF1, class MF2, class MA> 00282 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. 00283 std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is, 00284 symmetric_matrix<MT, MF1, MF2, MA> &m) { 00285 typedef typename symmetric_matrix<MT, MF1, MF2, MA>::size_type size_type; 00286 E ch; 00287 size_type size1, size2; 00288 MT value; 00289 if (is >> ch && ch != '[') { 00290 is.putback (ch); 00291 is.setstate (std::ios_base::failbit); 00292 } else if (is >> size1 >> ch && ch != ',') { 00293 is.putback (ch); 00294 is.setstate (std::ios_base::failbit); 00295 } else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square 00296 is.putback (ch); 00297 is.setstate (std::ios_base::failbit); 00298 } else if (! is.fail ()) { 00299 symmetric_matrix<MT, MF1, MF2, MA> s (size1, size2); 00300 if (is >> ch && ch != '(') { 00301 is.putback (ch); 00302 is.setstate (std::ios_base::failbit); 00303 } else if (! is.fail ()) { 00304 for (size_type i = 0; i < size1; i ++) { 00305 if (is >> ch && ch != '(') { 00306 is.putback (ch); 00307 is.setstate (std::ios_base::failbit); 00308 break; 00309 } 00310 for (size_type j = 0; j < size2; j ++) { 00311 if (is >> value >> ch && ch != ',') { 00312 is.putback (ch); 00313 if (j < size2 - 1) { 00314 is.setstate (std::ios_base::failbit); 00315 break; 00316 } 00317 } 00318 if (i <= j) { 00319 // this is the first time we read this element - set the value 00320 s(i,j) = value; 00321 } 00322 else if ( s(i,j) != value ) { 00323 // matrix is not symmetric 00324 is.setstate (std::ios_base::failbit); 00325 break; 00326 } 00327 } 00328 if (is >> ch && ch != ')') { 00329 is.putback (ch); 00330 is.setstate (std::ios_base::failbit); 00331 break; 00332 } 00333 if (is >> ch && ch != ',') { 00334 is.putback (ch); 00335 if (i < size1 - 1) { 00336 is.setstate (std::ios_base::failbit); 00337 break; 00338 } 00339 } 00340 } 00341 if (is >> ch && ch != ')') { 00342 is.putback (ch); 00343 is.setstate (std::ios_base::failbit); 00344 } 00345 } 00346 if (! is.fail ()) 00347 m.swap (s); 00348 } 00349 return is; 00350 } 00351 00352 00353 }}} 00354 00355 #endif