Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields  

stltools.Vector.h

00001 /*----------------------------------------------------------------------------
00002   SWORD 2000 - Software With Objects for Rapid Development
00003   Copyright (C) 2003 Eric NICOLAS
00004   ----------------------------------------------------------------------------
00005   SWORD is free software; you can redistribute it and/or modify
00006   it under the terms of the GNU Lesser General Public License as published by
00007   the Free Software Foundation; either version 2 of the License, or
00008   (at your option) any later version.
00009 
00010   SWORD is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013   GNU Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public License
00016   along with SWORD; if not, write to the Free Software
00017   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018   --------------------------------------------------------------------------*/
00019 #ifndef _SWORD_STLTOOLS_VECTOR_
00020 #define _SWORD_STLTOOLS_VECTOR_
00021 
00022 #include <vector>
00023 #include <algorithm>
00024 #include "sword/streams.IStream.h"
00025 #include "sword/streams.OStream.h"
00026 
00027 namespace std {
00028 
00029         template <class T>
00030         T sum(const std::vector<T>& vect)
00031         {
00032                 T s = 0;
00033 
00034                 for(std::vector<T>::const_iterator i = vect.begin(); i != vect.end(); ++i)
00035                         s += *i;
00036 
00037                 return s;
00038         }
00039 
00040   // -- Traits for changing the way types are streamed to/from text
00041 
00042   // Generic traits
00043   template<class T>
00044   class stdStreamHelperTrait {
00045   public:
00046     static void send(std::ostream& oss, const T& t) { oss << t; }
00047     static void recv(std::istream& iss, T& t) { iss >> t; }
00048   };
00049 
00050   // Specialization for std::string with quotes
00051   template<>
00052   class stdStreamHelperTrait<std::string> {
00053   public:
00054     static void send(std::ostream& oss, const std::string& t) 
00055     { 
00056       oss << "\"";
00057       for(std::string::const_iterator i=t.begin(); i!=t.end(); ++i)
00058       {
00059         if (*i == '\"')
00060           oss << "\\\"";
00061         else
00062           oss << *i;
00063       }
00064       oss << "\"";
00065     }
00066     static void recv(std::istream& iss, std::string& t)
00067     { 
00068       char c = iss.get();
00069       if (c != '\"')
00070       {
00071         sword::estream << "When reading a string : opening \" expected";
00072         throw sword::Exception();
00073       }
00074 
00075       std::ostringstream oss;
00076 
00077       for(;;)
00078       {
00079         if (!iss)
00080         {
00081           sword::estream << "end of stream found while reading a string";
00082           throw sword::Exception();
00083         }
00084         c = iss.get();
00085         if (c == '\"')
00086         {
00087           // found the end quote we're done
00088           break;
00089         }
00090         else if (c == '\\')
00091         {
00092           char c1 = iss.get();
00093           if (c1 == '\"')
00094           {
00095             oss << c1;
00096           }
00097           else
00098           {
00099             oss << c << c1;
00100           }
00101         }
00102         else
00103           oss << c;
00104       }
00105 
00106       t = oss.str();
00107     }
00108   };
00109 
00110         // -- Implementation for : "cout << vector<T>"
00111 
00112         template<class T>
00113   std::ostream& operator<<(std::ostream& lhs, const std::vector<T>& rhs)
00114         {
00115                 if (rhs.empty()) lhs << "<empty>";
00116                 else
00117                 {
00118                         lhs << "<";
00119                         for(std::vector<T>::const_iterator i=rhs.begin();i!=rhs.end();++i)
00120                         {
00121                                 if (i!=rhs.begin()) lhs << ", ";
00122         stdStreamHelperTrait<T>::send(lhs, *i);
00123                         }
00124                         lhs << ">";
00125                 }
00126                 return lhs;
00127         }
00128 
00129   // -- Implementation for : "cin >> vector<T>"
00130 
00131   // eat whitespace
00132   // returns false if the end of stream has been found
00133   // returns true otherwise
00134   inline bool eatSpace_(std::istream& iss)
00135   {
00136     char c;
00137     do
00138     {
00139       c = iss.get();
00140       if (!iss) return false;
00141     }  while(isspace(c));
00142     iss.putback(c);
00143 
00144     return true;
00145   }
00146 
00147   template<class T>
00148   std::istream& operator>>(std::istream& lhs, std::vector<T>& rhs)
00149   {
00150     rhs.clear();
00151     
00152     // read the '<'
00153     {
00154       if (!eatSpace_(lhs)) return lhs;
00155       char c  = lhs.get();
00156       if (c != '<') return lhs;
00157     }
00158 
00159     // read the vector content until the '>'
00160     for(;;)
00161     {
00162       if (!eatSpace_(lhs)) return lhs;
00163       char c = lhs.get();
00164       if (c == '>') return lhs;
00165       lhs.putback(c);
00166 
00167       T t;
00168       stdStreamHelperTrait<T>::recv(lhs, t);
00169 
00170       rhs.push_back(t);
00171 
00172       if (!eatSpace_(lhs)) return lhs;
00173       c = lhs.get();
00174       if (c == '>') return lhs;
00175       if (c != ',') return lhs;
00176     }
00177 
00178     return lhs;
00179   }
00180 
00181         // Implementation for : "OStream << vector<T>"
00182 
00183         template<class T>
00184         sword::OStream& operator<<(sword::OStream& lhs, const std::vector<T>& rhs)
00185         {
00186                 lhs << rhs.size();
00187                 for(std::vector<T>::const_iterator i=rhs.begin(); i!=rhs.end(); ++i)
00188                 {
00189                         lhs << *i;
00190                 }
00191                 return lhs;
00192         }
00193 
00194         // Implementation for : "IStream >> vector<T>"
00195 
00196         template<class T>
00197         sword::IStream& operator>>(sword::IStream& lhs, std::vector<T>& rhs)
00198         {
00199                 size_t size;
00200                 lhs >> size;
00201                 rhs.resize(size);
00202                 for(size_t i=0; i<size; ++i)
00203                 {
00204                         lhs >> rhs[i];
00205                 }
00206                 return lhs;
00207         }
00208 
00209   // in<> on std::vector
00210 
00211         template<class T>
00212   bool in(const T& value, const std::vector<T>& v)
00213   {
00214     return std::find(v.begin(), v.end(), value) != v.end();
00215   }
00216 
00217 } // namespace std
00218 
00219 #endif // _SWORD_STLTOOLS_VECTOR_

Generated on Tue Dec 23 20:08:56 2003 for SWORD by doxygen1.3-rc2