reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
Inserter.hxx
Go to the documentation of this file.
1#if !defined(RESIP_INSERTER_HXX)
2#define RESIP_INSERTER_HXX
3
4#include <iostream>
5#include <utility>
6#include <map>
7#include <set>
8#include <list>
9#include <unordered_map>
10#include <unordered_set>
11#include <vector>
12#include <deque>
13#include "rutil/ResipAssert.h"
14
15#include "rutil/compat.hxx"
18
19/*
20Example of use Inserter
21
22int
23main(int argc, char** argv)
24{
25 std::vector<std::string> v;
26
27 v.push_back("foo");
28 v.push_back("bar");
29 v.push_back("baz");
30
31 std::cerr << Inserter(v) << std::endl;
32 std::cerr << Inserter("nnn") << std::endl; // though you wouldn't bother
33}
34
35Example of use InserterP
36InserterP - allows processing of collections with pointers to items
37
38int
39main(int argc, char** argv)
40{
41 std::vector<std::string*> v;
42
43 v.push_back(new std::string("foo"));
44 v.push_back(new std::string("bar"));
45 v.push_back(new std::string("baz"));
46
47 std::cerr << InserterP(v) << std::endl;
48}
49*/
50
51namespace resip
52{
53
54static const char* leftanglebracket("<");
55static const char* rightanglebracket(">");
56static const char* leftsqbracket("[");
57static const char* rightsqbracket("]");
58static const char* sparrowsp(" -> ");
59static const char* commaspace(", ");
60
62#ifdef REASONABLE_TEMPLATES
63template <class T>
65insert(EncodeStream& s, const T& t)
66{
67 // use native <<
68 s << t;
69 return s;
70}
71#endif
72
73// specific collections, sigh
74template <class T>
76insert(EncodeStream& s, const std::vector <T>& c)
77{
78 s << leftsqbracket;
79 for (typename std::vector <T>::const_iterator i = c.begin();
80 i != c.end(); i++)
81 {
82 if (i != c.begin())
83 {
84 s << commaspace;
85 }
86 // recurse
87 insert(s, *i);
88 }
89 s << rightsqbracket;
90 return s;
91}
92
93template <class T>
95insert(EncodeStream& s, const std::deque<T>& c)
96{
97 s << leftsqbracket;
98 for (typename std::deque <T>::const_iterator i = c.begin();
99 i != c.end(); i++)
100 {
101 if (i != c.begin())
102 {
103 s << commaspace;
104 }
105 // recurse
106 insert(s, *i);
107 }
108 s << rightsqbracket;
109 return s;
110}
111
112template <class T>
114insert(EncodeStream& s, const std::list <T>& c)
115{
116 s << leftsqbracket;
117 for (typename std::list <T>::const_iterator i = c.begin();
118 i != c.end(); i++)
119 {
120 if (i != c.begin())
121 {
122 s << commaspace;
123 }
124 // recurse
125 insert(s, *i);
126 }
127 s << rightsqbracket;
128 return s;
129}
130
131#if !defined(__INTEL_COMPILER)
132template <class K, class C>
134insert(EncodeStream& s, const std::set <K, C>& c)
135{
136 s << leftsqbracket;
137 for (typename std::set <K, C>::const_iterator i = c.begin();
138 i != c.end(); i++)
139 {
140 if (i != c.begin())
141 {
142 s << commaspace;
143 }
144 insert(s, *i);
145 }
146 s << rightsqbracket;
147 return s;
148}
149#endif
150
151#if !defined(__INTEL_COMPILER)
152template <class K, class C>
154insert(EncodeStream& s, const std::multiset <K, C>& c)
155{
156 s << leftsqbracket;
157 for (typename std::multiset <K, C>::const_iterator i = c.begin();
158 i != c.end(); i++)
159 {
160 if (i != c.begin())
161 {
162 s << commaspace;
163 }
164 insert(s, *i);
165 }
166 s << rightsqbracket;
167 return s;
168}
169#endif
170
171template <class K, class V, class H>
173insert(EncodeStream& s, const std::unordered_map<K,V,H>& c)
174{
175 s << leftsqbracket;
176 for (auto i = c.begin(); i != c.end(); i++)
177 {
178 if (i != c.begin())
179 {
180 s << commaspace;
181 }
182 insert(s, i->first);
183 s << sparrowsp;
184 insert(s, i->second);
185 }
186 s << rightsqbracket;
187 return s;
188}
189
190template <class V, class H>
192insert(EncodeStream& s, const std::unordered_set<V,H>& c)
193{
194 s << leftsqbracket;
195 for (auto i = c.begin(); i != c.end(); i++)
196 {
197 if (i != c.begin())
198 {
199 s << commaspace;
200 }
201 insert(s, *i);
202 }
203 s << rightsqbracket;
204 return s;
205}
206
207template <class K, class V, class H, class P>
210{
211 s << leftsqbracket;
212 for (auto i = c.begin(); i != c.end(); i++)
213 {
214 if (i != c.begin())
215 {
216 s << commaspace;
217 }
218 insert(s, i->first);
219 s << sparrowsp;
220 insert(s, i->second);
221 }
222 s << rightsqbracket;
223 return s;
224}
225
226// map
227template <class K, class V, class H>
229insert(EncodeStream& s, const std::map <K, V, H>& c)
230{
231 s << leftsqbracket;
232 for (typename std::map<K,V, H>::const_iterator i = c.begin();
233 i != c.end(); i++)
234 {
235 if (i != c.begin())
236 {
237 s << commaspace;
238 }
239 insert(s, i->first);
240 s << sparrowsp;
241 insert(s, i->second);
242 }
243 s << rightsqbracket;
244 return s;
245}
246
247// special case for basic_string container
248template <class T>
250insert(EncodeStream& s, const std::basic_string<T>& str)
251{
252 // use native <<
253 s << str;
254 return s;
255}
256
257// special case for pair
258template <class T, class U>
260insert(EncodeStream& s, const std::pair<T, U>& p)
261{
262 // use native <<
263 s << leftanglebracket << p.first << commaspace << p.second << rightanglebracket;
264 return s;
265}
266
283template <class T>
285{
286 public:
287 InserterClass(const T& t)
288 : _t(t)
289 {}
290
291 const T& _t;
292};
293
295template <class T>
297operator<<(EncodeStream& s, const InserterClass<T>& inserter)
298{
299#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310)
300 resip_assert(0); // CJ - really need to fix this
301 return s;
302#else
303 return insert(s, inserter._t);
304#endif
305}
306
310template <class T>
311InserterClass<T>
312Inserter(const T& t)
313{
314 return InserterClass<T>(t);
315}
316
317
318
323
324
325
327#ifdef REASONABLE_TEMPLATES
328template <class T>
330insertP(EncodeStream& s, const T& t)
331{
332 // use native <<
333 s << *t;
334 return s;
335}
336#endif
337
338// specific collections, sigh
339template <class T>
341insertP(EncodeStream& s, const std::vector <T>& c)
342{
343 s << leftsqbracket;
344 for (typename std::vector <T>::const_iterator i = c.begin();
345 i != c.end(); i++)
346 {
347 if (i != c.begin())
348 {
349 s << commaspace;
350 }
351 // recurse
352 insert(s, *(*i));
353 }
354 s << rightsqbracket;
355 return s;
356}
357
358template <class T>
360insertP(EncodeStream& s, const std::deque<T>& c)
361{
362 s << leftsqbracket;
363 for (typename std::deque <T>::const_iterator i = c.begin();
364 i != c.end(); i++)
365 {
366 if (i != c.begin())
367 {
368 s << commaspace;
369 }
370 // recurse
371 insert(s, *(*i));
372 }
373 s << rightsqbracket;
374 return s;
375}
376
377template <class T>
379insertP(EncodeStream& s, const std::list <T>& c)
380{
381 s << leftsqbracket;
382 for (typename std::list <T>::const_iterator i = c.begin();
383 i != c.end(); i++)
384 {
385 if (i != c.begin())
386 {
387 s << commaspace;
388 }
389 // recurse
390 insert(s, *(*i));
391 }
392 s << rightsqbracket;
393 return s;
394}
395
396#if !defined(__INTEL_COMPILER)
397template <class K, class C>
399insertP(EncodeStream& s, const std::set <K, C>& c)
400{
401 s << leftsqbracket;
402 for (typename std::set <K, C>::const_iterator i = c.begin();
403 i != c.end(); i++)
404 {
405 if (i != c.begin())
406 {
407 s << commaspace;
408 }
409 insert(s, *(*i));
410 }
411 s << rightsqbracket;
412 return s;
413}
414#endif
415
416#if !defined(__INTEL_COMPILER)
417template <class K, class C>
419insertP(EncodeStream& s, const std::multiset <K, C>& c)
420{
421 s << leftsqbracket;
422 for (typename std::multiset <K, C>::const_iterator i = c.begin();
423 i != c.end(); i++)
424 {
425 if (i != c.begin())
426 {
427 s << commaspace;
428 }
429 insert(s, *(*i));
430 }
431 s << rightsqbracket;
432 return s;
433}
434#endif
435
436template <class K, class V, class H>
438insertP(EncodeStream& s, const std::unordered_map<K,V,H>& c)
439{
440 s << leftsqbracket;
441 for (auto i = c.begin(); i != c.end(); i++)
442 {
443 if (i != c.begin())
444 {
445 s << commaspace;
446 }
447 insert(s, i->first);
448 s << sparrowsp;
449 insert(s, *i->second);
450 }
451 s << rightsqbracket;
452 return s;
453}
454
455template <class V, class H>
457insertP(EncodeStream& s, const std::unordered_set<V,H>& c)
458{
459 s << leftsqbracket;
460 for (auto i = c.begin(); i != c.end(); i++)
461 {
462 if (i != c.begin())
463 {
464 s << commaspace;
465 }
466 insert(s, *(*i));
467 }
468 s << rightsqbracket;
469 return s;
470}
471
472// map
473template <class K, class V, class H>
475insertP(EncodeStream& s, const std::map <K, V, H>& c)
476{
477 s << leftsqbracket;
478 for (typename std::map<K,V, H>::const_iterator i = c.begin();
479 i != c.end(); i++)
480 {
481 if (i != c.begin())
482 {
483 s << commaspace;
484 }
485 insert(s, i->first);
486 s << sparrowsp;
487 insert(s, *i->second);
488 }
489 s << rightsqbracket;
490 return s;
491}
492
493// special case for basic_string container
494template <class T>
496insertP(EncodeStream& s, const std::basic_string<T>& str)
497{
498 // use native <<
499 s << str;
500 return s;
501}
502
503// special case for pair
504template <class T, class U>
506insertP(EncodeStream& s, const std::pair<T, U>& p)
507{
508 // use native <<
509 s << leftanglebracket << *p.first << commaspace << *p.second << rightanglebracket;
510 return s;
511}
512
529template <class T>
531{
532 public:
533 InserterPClass(const T& t)
534 : _t(t)
535 {}
536
537 const T& _t;
538};
539
541template <class T>
543operator<<(EncodeStream& s, const InserterPClass<T>& inserter)
544{
545#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310)
546 resip_assert(0); // CJ - really need to fix this
547 return s;
548#else
549 return insertP(s, inserter._t);
550#endif
551}
552
556template <class T>
557InserterPClass<T>
558InserterP(const T& t)
559{
560 return InserterPClass<T>(t);
561}
562
563} // resip
564
565#endif
566
567/* ====================================================================
568 * The Vovida Software License, Version 1.0
569 *
570 * Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
571 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
572 *
573 * Redistribution and use in source and binary forms, with or without
574 * modification, are permitted provided that the following conditions
575 * are met:
576 *
577 * 1. Redistributions of source code must retain the above copyright
578 * notice, this list of conditions and the following disclaimer.
579 *
580 * 2. Redistributions in binary form must reproduce the above copyright
581 * notice, this list of conditions and the following disclaimer in
582 * the documentation and/or other materials provided with the
583 * distribution.
584 *
585 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
586 * and "Vovida Open Communication Application Library (VOCAL)" must
587 * not be used to endorse or promote products derived from this
588 * software without prior written permission. For written
589 * permission, please contact vocal@vovida.org.
590 *
591 * 4. Products derived from this software may not be called "VOCAL", nor
592 * may "VOCAL" appear in their name, without prior written
593 * permission of Vovida Networks, Inc.
594 *
595 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
596 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
597 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
598 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
599 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
600 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
601 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
602 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
603 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
604 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
605 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
606 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
607 * DAMAGE.
608 *
609 * ====================================================================
610 *
611 * This software consists of voluntary contributions made by Vovida
612 * Networks, Inc. and many individuals on behalf of Vovida Networks,
613 * Inc. For more information on Vovida Networks, Inc., please see
614 * <http://www.vovida.org/>.
615 *
616 */
#define resip_assert(x)
This file needs to work for both C and C++ code.
Allows a (possibly recursive) container of anything with operator<< to be dumped to a stream.
Definition Inserter.hxx:285
InserterClass(const T &t)
Definition Inserter.hxx:287
Allows a (possibly recursive) container of anything with operator<< to be dumped to a stream.
Definition Inserter.hxx:531
InserterPClass(const T &t)
Definition Inserter.hxx:533
A hash map that iterates in insertion order, so a container filled while parsing (eg.
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
dcm! – add UnusedChecking(_enum) below;
static const char * sparrowsp(" -> ")
EncodeStream & insert(EncodeStream &s, const std::vector< T > &c)
Completely generic insert function.
Definition Inserter.hxx:76
InserterClass< T > Inserter(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
Definition Inserter.hxx:312
static const char * leftsqbracket("[")
static const char * commaspace(", ")
static const char * leftanglebracket("<")
static const char * rightsqbracket("]")
InserterPClass< T > InserterP(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
Definition Inserter.hxx:558
EncodeStream & insertP(EncodeStream &s, const std::vector< T > &c)
The following functions are more or less the same as the above, but add P to the naming and treat dat...
Definition Inserter.hxx:341
static const char * rightanglebracket(">")
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
Replaces STL streams for general encoding purposes.
#define EncodeStream