|
reSIProcate/rutil
9694
|
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 */
1.7.5.1