os/ossrv/ossrv_pub/boost_apis/boost/numeric/ublas/io.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 //
     2 //  Copyright (c) 2000-2002
     3 //  Joerg Walter, Mathias Koch
     4 //
     5 //  Permission to use, copy, modify, distribute and sell this software
     6 //  and its documentation for any purpose is hereby granted without fee,
     7 //  provided that the above copyright notice appear in all copies and
     8 //  that both that copyright notice and this permission notice appear
     9 //  in supporting documentation.  The authors make no representations
    10 //  about the suitability of this software for any purpose.
    11 //  It is provided "as is" without express or implied warranty.
    12 //
    13 //  The authors gratefully acknowledge the support of
    14 //  GeNeSys mbH & Co. KG in producing this work.
    15 //
    16 
    17 #ifndef _BOOST_UBLAS_IO_
    18 #define _BOOST_UBLAS_IO_
    19 
    20 // Only forward definition required to define stream operations
    21 #include <iosfwd>
    22 #include <boost/numeric/ublas/matrix_expression.hpp>
    23 
    24 
    25 namespace boost { namespace numeric { namespace ublas {
    26 
    27     template<class E, class T, class VE>
    28     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    29     std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
    30                                            const vector_expression<VE> &v) {
    31         typedef typename VE::size_type size_type;
    32         size_type size = v ().size ();
    33         std::basic_ostringstream<E, T, std::allocator<E> > s;
    34         s.flags (os.flags ());
    35         s.imbue (os.getloc ());
    36         s.precision (os.precision ());
    37         s << '[' << size << "](";
    38         if (size > 0)
    39             s << v () (0);
    40         for (size_type i = 1; i < size; ++ i)
    41             s << ',' << v () (i);
    42         s << ')';
    43         return os << s.str ().c_str ();
    44     }
    45 
    46     template<class E, class T, class VT, class VA>
    47     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    48     std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
    49                                            vector<VT, VA> &v) {
    50         typedef typename vector<VT, VA>::size_type size_type;
    51         E ch;
    52         size_type size;
    53         if (is >> ch && ch != '[') {
    54             is.putback (ch);
    55             is.setstate (std::ios_base::failbit);
    56         } else if (is >> size >> ch && ch != ']') {
    57             is.putback (ch);
    58             is.setstate (std::ios_base::failbit);
    59         } else if (! is.fail ()) {
    60             vector<VT, VA> s (size);
    61             if (is >> ch && ch != '(') {
    62                 is.putback (ch);
    63                 is.setstate (std::ios_base::failbit);
    64             } else if (! is.fail ()) {
    65                 for (size_type i = 0; i < size; i ++) {
    66                     if (is >> s (i) >> ch && ch != ',') {
    67                         is.putback (ch);
    68                         if (i < size - 1)
    69                             is.setstate (std::ios_base::failbit);
    70                         break;
    71                     }
    72                 }
    73                 if (is >> ch && ch != ')') {
    74                     is.putback (ch);
    75                     is.setstate (std::ios_base::failbit);
    76                 }
    77             }
    78             if (! is.fail ())
    79                 v.swap (s);
    80         }
    81         return is;
    82     }
    83 
    84     template<class E, class T, class ME>
    85     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    86     std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
    87                                            const matrix_expression<ME> &m) {
    88         typedef typename ME::size_type size_type;
    89         size_type size1 = m ().size1 ();
    90         size_type size2 = m ().size2 ();
    91         std::basic_ostringstream<E, T, std::allocator<E> > s;
    92         s.flags (os.flags ());
    93         s.imbue (os.getloc ());
    94         s.precision (os.precision ());
    95         s << '[' << size1 << ',' << size2 << "](";
    96         if (size1 > 0) {
    97             s << '(' ;
    98             if (size2 > 0)
    99                 s << m () (0, 0);
   100             for (size_type j = 1; j < size2; ++ j)
   101                 s << ',' << m () (0, j);
   102             s << ')';
   103         }
   104         for (size_type i = 1; i < size1; ++ i) {
   105             s << ",(" ;
   106             if (size2 > 0)
   107                 s << m () (i, 0);
   108             for (size_type j = 1; j < size2; ++ j)
   109                 s << ',' << m () (i, j);
   110             s << ')';
   111         }
   112         s << ')';
   113         return os << s.str ().c_str ();
   114     }
   115 
   116     template<class E, class T, class MT, class MF, class MA>
   117     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
   118     std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
   119                                            matrix<MT, MF, MA> &m) {
   120         typedef typename matrix<MT, MF, MA>::size_type size_type;
   121         E ch;
   122         size_type size1, size2;
   123         if (is >> ch && ch != '[') {
   124             is.putback (ch);
   125             is.setstate (std::ios_base::failbit);
   126         } else if (is >> size1 >> ch && ch != ',') {
   127             is.putback (ch);
   128             is.setstate (std::ios_base::failbit);
   129         } else if (is >> size2 >> ch && ch != ']') {
   130             is.putback (ch);
   131             is.setstate (std::ios_base::failbit);
   132         } else if (! is.fail ()) {
   133             matrix<MT, MF, MA> s (size1, size2);
   134             if (is >> ch && ch != '(') {
   135                 is.putback (ch);
   136                 is.setstate (std::ios_base::failbit);
   137             } else if (! is.fail ()) {
   138                 for (size_type i = 0; i < size1; i ++) {
   139                     if (is >> ch && ch != '(') {
   140                         is.putback (ch);
   141                         is.setstate (std::ios_base::failbit);
   142                         break;
   143                     }
   144                     for (size_type j = 0; j < size2; j ++) {
   145                         if (is >> s (i, j) >> ch && ch != ',') {
   146                             is.putback (ch);
   147                             if (j < size2 - 1) {
   148                                 is.setstate (std::ios_base::failbit);
   149                                 break;
   150                             }
   151                         }
   152                     }
   153                     if (is >> ch && ch != ')') {
   154                         is.putback (ch);
   155                         is.setstate (std::ios_base::failbit);
   156                         break;
   157                     }
   158                     if (is >> ch && ch != ',') {
   159                        is.putback (ch);
   160                        if (i < size1 - 1) {
   161                             is.setstate (std::ios_base::failbit);
   162                             break;
   163                        }
   164                     }
   165                 }
   166                 if (is >> ch && ch != ')') {
   167                     is.putback (ch);
   168                     is.setstate (std::ios_base::failbit);
   169                 }
   170             }
   171             if (! is.fail ())
   172                 m.swap (s);
   173         }
   174         return is;
   175     }
   176 
   177     // Special input operator for symmetrix_matrix
   178     template<class E, class T, class MT, class MF1, class MF2, class MA>
   179     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
   180     std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
   181                                            symmetric_matrix<MT, MF1, MF2, MA> &m) {
   182         typedef typename symmetric_matrix<MT, MF1, MF2, MA>::size_type size_type;
   183         E ch;
   184         size_type size1, size2;
   185         MT value;
   186         if (is >> ch && ch != '[') {
   187             is.putback (ch);
   188             is.setstate (std::ios_base::failbit);
   189         } else if (is >> size1 >> ch && ch != ',') {
   190             is.putback (ch);
   191             is.setstate (std::ios_base::failbit);
   192         } else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square
   193             is.putback (ch);
   194             is.setstate (std::ios_base::failbit);
   195         } else if (! is.fail ()) {
   196             symmetric_matrix<MT, MF1, MF2, MA> s (size1, size2);
   197             if (is >> ch && ch != '(') {
   198                 is.putback (ch);
   199                 is.setstate (std::ios_base::failbit);
   200              } else if (! is.fail ()) {
   201                 for (size_type i = 0; i < size1; i ++) {
   202                     if (is >> ch && ch != '(') {
   203                         is.putback (ch);
   204                         is.setstate (std::ios_base::failbit);
   205                         break;
   206                     }
   207                     for (size_type j = 0; j < size2; j ++) {
   208                         if (is >> value >> ch && ch != ',') {
   209                             is.putback (ch);
   210                             if (j < size2 - 1) {
   211                                 is.setstate (std::ios_base::failbit);
   212                                 break;
   213                             }
   214                         }
   215                         if (i <= j) { 
   216                              // this is the first time we read this element - set the value
   217                             s(i,j) = value;
   218                         }
   219                         else if ( s(i,j) != value ) {
   220                             // matrix is not symmetric
   221                             is.setstate (std::ios_base::failbit);
   222                             break;
   223                         }
   224                      }
   225                      if (is >> ch && ch != ')') {
   226                          is.putback (ch);
   227                          is.setstate (std::ios_base::failbit);
   228                          break;
   229                      }
   230                      if (is >> ch && ch != ',') {
   231                         is.putback (ch);
   232                         if (i < size1 - 1) {
   233                              is.setstate (std::ios_base::failbit);
   234                              break;
   235                         }
   236                      }
   237                 }
   238                 if (is >> ch && ch != ')') {
   239                     is.putback (ch);
   240                     is.setstate (std::ios_base::failbit);
   241                 }
   242             }
   243             if (! is.fail ())
   244                 m.swap (s);
   245         }
   246         return is;
   247     }
   248  
   249 
   250 }}}
   251 
   252 #endif