reSIProcate/rutil  9694
Inserter.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_INSERTER_HXX)
00002 #define RESIP_INSERTER_HXX 
00003 
00004 #include <iostream>
00005 #include <utility>
00006 #include <map>
00007 #include <set>
00008 #include <list>
00009 #include <vector>
00010 #include <deque>
00011 #include <cassert>
00012 
00013 #include "HashMap.hxx"
00014 #include "rutil/compat.hxx"
00015 #include "rutil/resipfaststreams.hxx"
00016 
00017 /* 
00018 Example of use Inserter
00019 
00020 int
00021 main(int argc, char** argv)
00022 {
00023    std::vector<std::string> v;
00024    
00025    v.push_back("foo");
00026    v.push_back("bar");
00027    v.push_back("baz");
00028 
00029    std::cerr << Inserter(v) << std::endl;
00030    std::cerr << Inserter("nnn") << std::endl; // though you wouldn't bother
00031 }
00032 
00033 Example of use InserterP
00034 InserterP - allows processing of collections with pointers to items
00035 
00036 int
00037 main(int argc, char** argv)
00038 {
00039    std::vector<std::string*> v;
00040    
00041    v.push_back(new std::string("foo"));
00042    v.push_back(new std::string("bar"));
00043    v.push_back(new std::string("baz"));
00044 
00045    std::cerr << InserterP(v) << std::endl;
00046 }
00047 */
00048 
00049 namespace resip
00050 {
00051 
00052 static const char* leftanglebracket("<");
00053 static const char* rightanglebracket(">");
00054 static const char* leftsqbracket("[");
00055 static const char* rightsqbracket("]");
00056 static const char* sparrowsp(" -> ");
00057 static const char* commaspace(", ");
00058 
00060 #ifdef REASONABLE_TEMPLATES
00061 template <class T>
00062 EncodeStream&
00063 insert(EncodeStream& s, const T& t)
00064 {
00065    // use native <<
00066    s << t;
00067    return s;
00068 }
00069 #endif
00070 
00071 // specific collections, sigh
00072 template <class T>
00073 EncodeStream&
00074 insert(EncodeStream& s, const std::vector <T>& c)
00075 {
00076    s << leftsqbracket;
00077    for (typename std::vector <T>::const_iterator i = c.begin();
00078         i != c.end(); i++) 
00079    {
00080       if (i != c.begin()) 
00081       {
00082          s << commaspace;
00083       }
00084       // recurse
00085       insert(s, *i);
00086    }
00087    s << rightsqbracket;
00088    return s;
00089 }
00090 
00091 template <class T>
00092 EncodeStream&
00093 insert(EncodeStream& s, const std::deque<T>& c)
00094 {
00095    s << leftsqbracket;
00096    for (typename std::deque <T>::const_iterator i = c.begin();
00097         i != c.end(); i++) 
00098    {
00099       if (i != c.begin()) 
00100       {
00101          s << commaspace;
00102       }
00103       // recurse
00104       insert(s, *i);
00105    }
00106    s << rightsqbracket;
00107    return s;
00108 }
00109 
00110 template <class T>
00111 EncodeStream&
00112 insert(EncodeStream& s, const std::list <T>& c)
00113 {
00114    s << leftsqbracket;
00115    for (typename std::list <T>::const_iterator i = c.begin();
00116         i != c.end(); i++) 
00117    {
00118       if (i != c.begin()) 
00119       {
00120          s << commaspace;
00121       }
00122       // recurse
00123       insert(s, *i);
00124    }
00125    s << rightsqbracket;
00126    return s;
00127 }
00128 
00129 #if !defined(__INTEL_COMPILER)
00130 template <class K, class C>
00131 EncodeStream&
00132 insert(EncodeStream& s, const std::set <K, C>& c)
00133 {
00134    s << leftsqbracket;
00135    for (typename std::set <K, C>::const_iterator i = c.begin();
00136         i != c.end(); i++) 
00137    {
00138       if (i != c.begin()) 
00139       {
00140          s << commaspace;
00141       }
00142       insert(s, *i);
00143    }
00144    s << rightsqbracket;
00145    return s;
00146 }
00147 #endif
00148 
00149 #if !defined(__INTEL_COMPILER)
00150 template <class K, class C>
00151 EncodeStream&
00152 insert(EncodeStream& s, const std::multiset <K, C>& c)
00153 {
00154    s << leftsqbracket;
00155    for (typename std::multiset <K, C>::const_iterator i = c.begin();
00156         i != c.end(); i++) 
00157    {
00158       if (i != c.begin()) 
00159       {
00160          s << commaspace;
00161       }
00162       insert(s, *i);
00163    }
00164    s << rightsqbracket;
00165    return s;
00166 }
00167 #endif
00168 
00169 // HashMap
00170 #if defined(HASH_MAP_NAMESPACE)
00171 template <class K, class V, class H>
00172 EncodeStream&
00173 insert(EncodeStream& s, const HashMap<K,V,H>& c)
00174 {
00175    s << leftsqbracket;
00176    for (typename HashMap<K,V,H>::const_iterator i = c.begin();
00177         i != c.end(); i++) 
00178    {
00179       if (i != c.begin()) 
00180       {
00181          s << commaspace;
00182       }
00183       insert(s, i->first);
00184       s << sparrowsp;
00185       insert(s, i->second);      
00186    }
00187    s << rightsqbracket;
00188    return s;
00189 }
00190 #endif
00191 
00192 #if defined(HASH_MAP_NAMESPACE)
00193 template <class V, class H>
00194 EncodeStream&
00195 insert(EncodeStream& s, const HashSet<V,H>& c)
00196 {
00197    s << leftsqbracket;
00198    for (typename HashSet<V,H>::const_iterator i = c.begin();
00199         i != c.end(); i++) 
00200    {
00201       if (i != c.begin()) 
00202       {
00203          s << commaspace;
00204       }
00205       insert(s, *i);
00206    }
00207    s << rightsqbracket;
00208    return s;
00209 }
00210 #endif
00211 
00212 // map
00213 template <class K, class V, class H>
00214 EncodeStream&
00215 insert(EncodeStream& s, const std::map <K, V, H>& c)
00216 {
00217    s << leftsqbracket;
00218    for (typename std::map<K,V, H>::const_iterator i = c.begin();
00219         i != c.end(); i++) 
00220    {
00221       if (i != c.begin()) 
00222       {
00223          s << commaspace;
00224       }
00225       insert(s, i->first);
00226       s << sparrowsp;
00227       insert(s, i->second);  
00228    }
00229    s << rightsqbracket;
00230    return s;
00231 }
00232 
00233 // special case for basic_string container
00234 template <class T>
00235 EncodeStream&
00236 insert(EncodeStream& s, const std::basic_string<T>& str)
00237 {
00238    // use native <<
00239    s << str;
00240    return s;
00241 }
00242 
00243 // special case for pair
00244 template <class T, class U>
00245 EncodeStream&
00246 insert(EncodeStream& s, const std::pair<T, U>& p)
00247 {
00248    // use native <<
00249    s << leftanglebracket << p.first << commaspace << p.second << rightanglebracket;
00250    return s;
00251 }
00252 
00269 template <class T>
00270 class InserterClass
00271 {
00272    public:
00273       InserterClass(const T& t)
00274          : _t(t)
00275       {}
00276       
00277       const T& _t;
00278 };
00279 
00281 template <class T>
00282 EncodeStream&
00283 operator<<(EncodeStream& s, const InserterClass<T>& inserter)
00284 {
00285 #if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310)
00286         assert(0); // CJ - really need to fix this
00287         return s;
00288 #else
00289    return insert(s, inserter._t);
00290 #endif
00291 }
00292 
00296 template <class T>
00297 InserterClass<T>
00298 Inserter(const T& t)
00299 {
00300    return InserterClass<T>(t);
00301 }
00302 
00303 
00304 
00309 
00310 
00311 
00313 #ifdef REASONABLE_TEMPLATES
00314 template <class T>
00315 EncodeStream&
00316 insertP(EncodeStream& s, const T& t)
00317 {
00318    // use native <<
00319    s << *t;
00320    return s;
00321 }
00322 #endif
00323 
00324 // specific collections, sigh
00325 template <class T>
00326 EncodeStream&
00327 insertP(EncodeStream& s, const std::vector <T>& c)
00328 {
00329    s << leftsqbracket;
00330    for (typename std::vector <T>::const_iterator i = c.begin();
00331         i != c.end(); i++) 
00332    {
00333       if (i != c.begin()) 
00334       {
00335          s << commaspace;
00336       }
00337       // recurse
00338       insert(s, *(*i));
00339    }
00340    s << rightsqbracket;
00341    return s;
00342 }
00343 
00344 template <class T>
00345 EncodeStream&
00346 insertP(EncodeStream& s, const std::deque<T>& c)
00347 {
00348    s << leftsqbracket;
00349    for (typename std::deque <T>::const_iterator i = c.begin();
00350         i != c.end(); i++) 
00351    {
00352       if (i != c.begin()) 
00353       {
00354          s << commaspace;
00355       }
00356       // recurse
00357       insert(s, *(*i));
00358    }
00359    s << rightsqbracket;
00360    return s;
00361 }
00362 
00363 template <class T>
00364 EncodeStream&
00365 insertP(EncodeStream& s, const std::list <T>& c)
00366 {
00367    s << leftsqbracket;
00368    for (typename std::list <T>::const_iterator i = c.begin();
00369         i != c.end(); i++) 
00370    {
00371       if (i != c.begin()) 
00372       {
00373          s << commaspace;
00374       }
00375       // recurse
00376       insert(s, *(*i));
00377    }
00378    s << rightsqbracket;
00379    return s;
00380 }
00381 
00382 #if !defined(__INTEL_COMPILER)
00383 template <class K, class C>
00384 EncodeStream&
00385 insertP(EncodeStream& s, const std::set <K, C>& c)
00386 {
00387    s << leftsqbracket;
00388    for (typename std::set <K, C>::const_iterator i = c.begin();
00389         i != c.end(); i++) 
00390    {
00391       if (i != c.begin()) 
00392       {
00393          s << commaspace;
00394       }
00395       insert(s, *(*i));
00396    }
00397    s << rightsqbracket;
00398    return s;
00399 }
00400 #endif
00401 
00402 #if !defined(__INTEL_COMPILER)
00403 template <class K, class C>
00404 EncodeStream&
00405 insertP(EncodeStream& s, const std::multiset <K, C>& c)
00406 {
00407    s << leftsqbracket;
00408    for (typename std::multiset <K, C>::const_iterator i = c.begin();
00409         i != c.end(); i++) 
00410    {
00411       if (i != c.begin()) 
00412       {
00413          s << commaspace;
00414       }
00415       insert(s, *(*i));
00416    }
00417    s << rightsqbracket;
00418    return s;
00419 }
00420 #endif
00421 
00422 // HashMap
00423 #if defined(HASH_MAP_NAMESPACE)
00424 template <class K, class V, class H>
00425 EncodeStream&
00426 insertP(EncodeStream& s, const HashMap<K,V,H>& c)
00427 {
00428    s << leftsqbracket;
00429    for (typename HashMap<K,V,H>::const_iterator i = c.begin();
00430         i != c.end(); i++) 
00431    {
00432       if (i != c.begin()) 
00433       {
00434          s << commaspace;
00435       }
00436       insert(s, i->first);
00437       s << sparrowsp;
00438       insert(s, *i->second);      
00439    }
00440    s << rightsqbracket;
00441    return s;
00442 }
00443 #endif
00444 
00445 #if defined(HASH_MAP_NAMESPACE)
00446 template <class V, class H>
00447 EncodeStream&
00448 insertP(EncodeStream& s, const HashSet<V,H>& c)
00449 {
00450    s << leftsqbracket;
00451    for (typename HashSet<V,H>::const_iterator i = c.begin();
00452         i != c.end(); i++) 
00453    {
00454       if (i != c.begin()) 
00455       {
00456          s << commaspace;
00457       }
00458       insert(s, *(*i));
00459    }
00460    s << rightsqbracket;
00461    return s;
00462 }
00463 #endif
00464 
00465 // map
00466 template <class K, class V, class H>
00467 EncodeStream&
00468 insertP(EncodeStream& s, const std::map <K, V, H>& c)
00469 {
00470    s << leftsqbracket;
00471    for (typename std::map<K,V, H>::const_iterator i = c.begin();
00472         i != c.end(); i++) 
00473    {
00474       if (i != c.begin()) 
00475       {
00476          s << commaspace;
00477       }
00478       insert(s, i->first);
00479       s << sparrowsp;
00480       insert(s, *i->second);  
00481    }
00482    s << rightsqbracket;
00483    return s;
00484 }
00485 
00486 // special case for basic_string container
00487 template <class T>
00488 EncodeStream&
00489 insertP(EncodeStream& s, const std::basic_string<T>& str)
00490 {
00491    // use native <<
00492    s << str;
00493    return s;
00494 }
00495 
00496 // special case for pair
00497 template <class T, class U>
00498 EncodeStream&
00499 insertP(EncodeStream& s, const std::pair<T, U>& p)
00500 {
00501    // use native <<
00502    s << leftanglebracket << *p.first << commaspace << *p.second << rightanglebracket;
00503    return s;
00504 }
00505 
00522 template <class T>
00523 class InserterPClass
00524 {
00525    public:
00526       InserterPClass(const T& t)
00527          : _t(t)
00528       {}
00529       
00530       const T& _t;
00531 };
00532 
00534 template <class T>
00535 EncodeStream&
00536 operator<<(EncodeStream& s, const InserterPClass<T>& inserter)
00537 {
00538 #if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310)
00539         assert(0); // CJ - really need to fix this
00540         return s;
00541 #else
00542    return insertP(s, inserter._t);
00543 #endif
00544 }
00545 
00549 template <class T>
00550 InserterPClass<T>
00551 InserterP(const T& t)
00552 {
00553    return InserterPClass<T>(t);
00554 }
00555  
00556 } // resip
00557 
00558 #endif
00559 
00560 /* ====================================================================
00561  * The Vovida Software License, Version 1.0 
00562  * 
00563  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00564  * 
00565  * Redistribution and use in source and binary forms, with or without
00566  * modification, are permitted provided that the following conditions
00567  * are met:
00568  * 
00569  * 1. Redistributions of source code must retain the above copyright
00570  *    notice, this list of conditions and the following disclaimer.
00571  * 
00572  * 2. Redistributions in binary form must reproduce the above copyright
00573  *    notice, this list of conditions and the following disclaimer in
00574  *    the documentation and/or other materials provided with the
00575  *    distribution.
00576  * 
00577  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00578  *    and "Vovida Open Communication Application Library (VOCAL)" must
00579  *    not be used to endorse or promote products derived from this
00580  *    software without prior written permission. For written
00581  *    permission, please contact vocal@vovida.org.
00582  *
00583  * 4. Products derived from this software may not be called "VOCAL", nor
00584  *    may "VOCAL" appear in their name, without prior written
00585  *    permission of Vovida Networks, Inc.
00586  * 
00587  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00588  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00589  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00590  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00591  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00592  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00593  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00594  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00595  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00596  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00597  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00598  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00599  * DAMAGE.
00600  * 
00601  * ====================================================================
00602  * 
00603  * This software consists of voluntary contributions made by Vovida
00604  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00605  * Inc.  For more information on Vovida Networks, Inc., please see
00606  * <http://www.vovida.org/>.
00607  *
00608  */