/[resiprocate]/main/resip/stack/test/testTypedef.cxx
ViewVC logotype

Contents of /main/resip/stack/test/testTypedef.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8425 - (show annotations) (download)
Mon Mar 2 23:20:11 2009 UTC (10 years, 8 months ago) by adam
File MIME type: text/plain
File size: 19823 byte(s)
Made to compile and link with SunPro toolchain through skillful application of a crowbar. Untested -- and the compilation is rife with warnings (some quite dire) that need to be addressed.

1 #include <cassert>
2 #include <iostream>
3
4 using namespace std;
5
6 namespace resip
7 {
8
9 template <class P>
10 class IntrusiveListElement
11 {
12 public:
13 IntrusiveListElement()
14 : mNext(0),
15 mPrev(0)
16 {}
17
18 virtual ~IntrusiveListElement()
19 {
20 remove();
21 }
22
23 // make this element an empty list
24 static P makeList(P elem)
25 {
26 assert(!elem->IntrusiveListElement::mNext);
27
28 elem->IntrusiveListElement::mPrev = elem;
29 elem->IntrusiveListElement::mNext = elem;
30
31 return elem;
32 }
33
34 bool empty() const
35 {
36 assert(mPrev);
37 assert(mNext);
38
39 return mNext == static_cast<P>(const_cast<IntrusiveListElement<P>*>(this));
40 }
41
42 // .dlb. add reverse_iterator?
43
44 class iterator
45 {
46 public:
47 explicit iterator(const P start)
48 : mPos(start)
49 {}
50
51 iterator& operator=(const iterator& rhs)
52 {
53 mPos = rhs.mPos;
54 return *this;
55 }
56
57 iterator& operator++()
58 {
59 mPos = mPos->IntrusiveListElement::mNext;
60 return *this;
61 }
62
63 bool operator==(const iterator& rhs)
64 {
65 return mPos == rhs.mPos;
66 }
67
68 bool operator!=(const iterator& rhs)
69 {
70 return mPos != rhs.mPos;
71 }
72
73 P operator*()
74 {
75 return mPos;
76 }
77
78 private:
79 P mPos;
80 };
81
82 iterator begin()
83 {
84 assert(mPrev);
85 assert(mNext);
86 return iterator(mNext);
87 }
88
89 iterator end()
90 {
91 assert(mPrev);
92 assert(mNext);
93 return iterator(static_cast<P>(this));
94 }
95
96 friend class iterator;
97
98 // pushing an element onto the same list twice is undefined
99 void push_front(P elem)
100 {
101 assert(mPrev);
102 assert(mNext);
103
104 elem->IntrusiveListElement::mNext = mNext;
105 elem->IntrusiveListElement::mPrev = static_cast<P>(this);
106
107 elem->IntrusiveListElement::mNext->IntrusiveListElement::mPrev = elem;
108 elem->IntrusiveListElement::mPrev->IntrusiveListElement::mNext = elem;
109 }
110
111 // putting an element onto the same list twice is undefined
112 void push_back(P elem)
113 {
114 assert(mPrev);
115 assert(mNext);
116
117 elem->IntrusiveListElement::mPrev = mPrev;
118 elem->IntrusiveListElement::mNext = static_cast<P>(this);
119
120 elem->IntrusiveListElement::mPrev->IntrusiveListElement::mNext = elem;
121 elem->IntrusiveListElement::mNext->IntrusiveListElement::mPrev = elem;
122 }
123
124 void remove()
125 {
126 if (mNext)
127 {
128 // prev -> this -> next
129 // <- <-
130 //
131 // prev -> next
132 // <-
133 mNext->IntrusiveListElement::mPrev = mPrev;
134 mPrev->IntrusiveListElement::mNext = mNext;
135 }
136
137 mNext = 0;
138 mPrev = 0;
139 }
140
141 protected:
142 mutable P mNext;
143 mutable P mPrev;
144 };
145
146 template <class P>
147 class IntrusiveListElement1
148 {
149 public:
150 IntrusiveListElement1()
151 : mNext(0),
152 mPrev(0)
153 {}
154
155 virtual ~IntrusiveListElement1()
156 {
157 remove();
158 }
159
160 // make this element an empty list
161 static P makeList(P elem)
162 {
163 assert(!elem->IntrusiveListElement1::mNext);
164
165 elem->IntrusiveListElement1::mPrev = elem;
166 elem->IntrusiveListElement1::mNext = elem;
167
168 return elem;
169 }
170
171 bool empty() const
172 {
173 assert(mPrev);
174 assert(mNext);
175
176 return mNext == static_cast<P>(const_cast<IntrusiveListElement1<P>*>(this));
177 }
178
179 // .dlb. add reverse_iterator?
180
181 class iterator
182 {
183 public:
184 explicit iterator(const P start)
185 : mPos(start)
186 {}
187
188 iterator& operator=(const iterator& rhs)
189 {
190 mPos = rhs.mPos;
191 return *this;
192 }
193
194 iterator& operator++()
195 {
196 mPos = mPos->IntrusiveListElement1::mNext;
197 return *this;
198 }
199
200 bool operator==(const iterator& rhs)
201 {
202 return mPos == rhs.mPos;
203 }
204
205 bool operator!=(const iterator& rhs)
206 {
207 return mPos != rhs.mPos;
208 }
209
210 P operator*()
211 {
212 return mPos;
213 }
214
215 private:
216 P mPos;
217 };
218
219 iterator begin()
220 {
221 assert(mPrev);
222 assert(mNext);
223 return iterator(mNext);
224 }
225
226 iterator end()
227 {
228 assert(mPrev);
229 assert(mNext);
230 return iterator(static_cast<P>(this));
231 }
232
233 friend class iterator;
234
235 // pushing an element onto the same list twice is undefined
236 void push_front(P elem)
237 {
238 assert(mPrev);
239 assert(mNext);
240
241 elem->IntrusiveListElement1::mNext = mNext;
242 elem->IntrusiveListElement1::mPrev = static_cast<P>(this);
243
244 elem->IntrusiveListElement1::mNext->IntrusiveListElement1::mPrev = elem;
245 elem->IntrusiveListElement1::mPrev->IntrusiveListElement1::mNext = elem;
246 }
247
248 // putting an element onto the same list twice is undefined
249 void push_back(P elem)
250 {
251 assert(mPrev);
252 assert(mNext);
253
254 elem->IntrusiveListElement1::mPrev = mPrev;
255 elem->IntrusiveListElement1::mNext = static_cast<P>(this);
256
257 elem->IntrusiveListElement1::mPrev->IntrusiveListElement1::mNext = elem;
258 elem->IntrusiveListElement1::mNext->IntrusiveListElement1::mPrev = elem;
259 }
260
261 void remove()
262 {
263 if (mNext)
264 {
265 // prev -> this -> next
266 // <- <-
267 //
268 // prev -> next
269 // <-
270 mNext->IntrusiveListElement1::mPrev = mPrev;
271 mPrev->IntrusiveListElement1::mNext = mNext;
272 }
273
274 mNext = 0;
275 mPrev = 0;
276 }
277
278 protected:
279 mutable P mNext;
280 mutable P mPrev;
281 };
282
283 template <class P>
284 class IntrusiveListElement2
285 {
286 public:
287 IntrusiveListElement2()
288 : mNext(0),
289 mPrev(0)
290 {}
291
292 virtual ~IntrusiveListElement2()
293 {
294 remove();
295 }
296
297 // make this element an empty list
298 static P makeList(P elem)
299 {
300 assert(!elem->IntrusiveListElement2::mNext);
301
302 elem->IntrusiveListElement2::mPrev = elem;
303 elem->IntrusiveListElement2::mNext = elem;
304
305 return elem;
306 }
307
308 bool empty() const
309 {
310 assert(mPrev);
311 assert(mNext);
312
313 return mNext == static_cast<P>(const_cast<IntrusiveListElement2<P>*>(this));
314 }
315
316 // .dlb. add reverse_iterator?
317
318 class iterator
319 {
320 public:
321 explicit iterator(const P start)
322 : mPos(start)
323 {}
324
325 iterator& operator=(const iterator& rhs)
326 {
327 mPos = rhs.mPos;
328 return *this;
329 }
330
331 iterator& operator++()
332 {
333 mPos = mPos->IntrusiveListElement2::mNext;
334 return *this;
335 }
336
337 bool operator==(const iterator& rhs)
338 {
339 return mPos == rhs.mPos;
340 }
341
342 bool operator!=(const iterator& rhs)
343 {
344 return mPos != rhs.mPos;
345 }
346
347 P operator*()
348 {
349 return mPos;
350 }
351
352 private:
353 P mPos;
354 };
355
356 iterator begin()
357 {
358 assert(mPrev);
359 assert(mNext);
360 return iterator(mNext);
361 }
362
363 iterator end()
364 {
365 assert(mPrev);
366 assert(mNext);
367 return iterator(static_cast<P>(this));
368 }
369
370 friend class iterator;
371
372 // pushing an element onto the same list twice is undefined
373 void push_front(P elem)
374 {
375 assert(mPrev);
376 assert(mNext);
377
378 elem->IntrusiveListElement2::mNext = mNext;
379 elem->IntrusiveListElement2::mPrev = static_cast<P>(this);
380
381 elem->IntrusiveListElement2::mNext->IntrusiveListElement2::mPrev = elem;
382 elem->IntrusiveListElement2::mPrev->IntrusiveListElement2::mNext = elem;
383 }
384
385 // putting an element onto the same list twice is undefined
386 void push_back(P elem)
387 {
388 assert(mPrev);
389 assert(mNext);
390
391 elem->IntrusiveListElement2::mPrev = mPrev;
392 elem->IntrusiveListElement2::mNext = static_cast<P>(this);
393
394 elem->IntrusiveListElement2::mPrev->IntrusiveListElement2::mNext = elem;
395 elem->IntrusiveListElement2::mNext->IntrusiveListElement2::mPrev = elem;
396 }
397
398 void remove()
399 {
400 if (mNext)
401 {
402 // prev -> this -> next
403 // <- <-
404 //
405 // prev -> next
406 // <-
407 mNext->IntrusiveListElement2::mPrev = mPrev;
408 mPrev->IntrusiveListElement2::mNext = mNext;
409 }
410
411 mNext = 0;
412 mPrev = 0;
413 }
414
415 protected:
416 mutable P mNext;
417 mutable P mPrev;
418 };
419
420 } // end namespace resip
421
422 using namespace resip;
423
424 class Foo : public IntrusiveListElement<Foo*>
425 {
426 public:
427 Foo(int v) : va1(v) {}
428 int va1;
429 int va2;
430 };
431
432 class FooFoo : public IntrusiveListElement<FooFoo*>, public IntrusiveListElement1<FooFoo*>
433 {
434 public:
435 typedef IntrusiveListElement<FooFoo*> read;
436 typedef IntrusiveListElement1<FooFoo*> write;
437
438 FooFoo(int v) : va1(v) {}
439
440 int va1;
441 int va2;
442 };
443
444 int
445 main(int argc, char* argv[])
446 {
447 {
448 Foo* fooHead = new Foo(-1);
449 Foo* foo1 = new Foo(1);
450 Foo* foo2 = new Foo(2);
451 Foo* foo3 = new Foo(3);
452 Foo* foo4 = new Foo(4);
453
454 Foo::makeList(fooHead);
455 assert(fooHead->empty());
456 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
457 {
458 cerr << (*f)->va1 << endl;
459 }
460
461 fooHead->push_front(foo1);
462 assert(!fooHead->empty());
463 cerr << endl << "first" << endl;
464 assert((*fooHead->begin())->va1 == 1);
465 assert((*fooHead->end())->va1 == -1);
466
467 Foo::iterator j = fooHead->begin();
468 ++j;
469 cerr << (*j)->va1 << endl;
470 assert((*j)->va1 == -1);
471 assert(*j == *fooHead->end());
472
473 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
474 {
475 cerr << (*f)->va1 << endl;
476 }
477
478 fooHead->push_front(foo2);
479 cerr << endl << "second" << endl;
480 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
481 {
482 cerr << (*f)->va1 << endl;
483 }
484
485 fooHead->push_front(foo3);
486 cerr << endl << "third" << endl;
487 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
488 {
489 cerr << (*f)->va1 << endl;
490 }
491
492 cerr << endl << "deleted second" << endl;
493 delete foo2;
494 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
495 {
496 cerr << (*f)->va1 << endl;
497 }
498
499 cerr << endl << "fourth" << endl;
500 fooHead->push_front(foo4);
501 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
502 {
503 cerr << (*f)->va1 << endl;
504 }
505
506 cerr << endl << "deleted fourth, first" << endl;
507 delete foo1;
508 delete foo4;
509 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
510 {
511 cerr << (*f)->va1 << endl;
512 }
513
514 cerr << endl << "deleted third (empty)" << endl;
515 delete foo3;
516 for (Foo::iterator f = fooHead->begin(); f != fooHead->end(); ++f)
517 {
518 cerr << (*f)->va1 << endl;
519 }
520 }
521
522 // .abr. Yes, this really is necessary just to get things to compile. Don't ask
523 // why -- it's clearly a compiler bug. But you would be well advised not to
524 // comment it out unless you're actually using the SunPRO compiler, and have
525 // found an alternate workaround.
526 #if defined(__SUNPRO_CC)
527 typedef IntrusiveListElement<FooFoo*> read;
528 typedef IntrusiveListElement1<FooFoo*> write;
529 #endif
530
531 //=============================================================================
532 // Read version
533 //=============================================================================
534 cerr << endl << "READ VERSION" << endl;
535 {
536 FooFoo* fooFooHead = new FooFoo(-1);
537 FooFoo* fooFoo1 = new FooFoo(1);
538 FooFoo* fooFoo2 = new FooFoo(2);
539 FooFoo* fooFoo3 = new FooFoo(3);
540 FooFoo* fooFoo4 = new FooFoo(4);
541
542 FooFoo::read::makeList(fooFooHead);
543 FooFoo::write::makeList(fooFooHead);
544 assert(fooFooHead->read::empty());
545 assert(fooFooHead->write::empty());
546 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
547 {
548 cerr << (*f)->va1 << endl;
549 }
550
551 fooFooHead->read::push_front(fooFoo1);
552 assert(!fooFooHead->read::empty());
553 assert(fooFooHead->write::empty());
554 cerr << endl << "first" << endl;
555 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
556 {
557 cerr << (*f)->va1 << endl;
558 }
559
560 fooFooHead->read::push_front(fooFoo2);
561 cerr << endl << "second" << endl;
562 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
563 {
564 cerr << (*f)->va1 << endl;
565 }
566
567 fooFooHead->read::push_front(fooFoo3);
568 cerr << endl << "third" << endl;
569 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
570 {
571 cerr << (*f)->va1 << endl;
572 }
573
574 cerr << endl << "deleted second" << endl;
575 delete fooFoo2;
576 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
577 {
578 cerr << (*f)->va1 << endl;
579 }
580
581 cerr << endl << "fourth" << endl;
582 fooFooHead->read::push_front(fooFoo4);
583 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
584 {
585 cerr << (*f)->va1 << endl;
586 }
587
588 cerr << endl << "deleted fourth, first" << endl;
589 delete fooFoo1;
590 delete fooFoo4;
591 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
592 {
593 cerr << (*f)->va1 << endl;
594 }
595
596 cerr << endl << "deleted third (empty)" << endl;
597 delete fooFoo3;
598 for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); ++f)
599 {
600 cerr << (*f)->va1 << endl;
601 }
602 }
603
604 //=============================================================================
605 // Write version
606 //=============================================================================
607 cerr << endl << "WRITE VERSION" << endl;
608 {
609 FooFoo* fooFooHead = new FooFoo(-1);
610 FooFoo* fooFoo1 = new FooFoo(1);
611 FooFoo* fooFoo2 = new FooFoo(2);
612 FooFoo* fooFoo3 = new FooFoo(3);
613 FooFoo* fooFoo4 = new FooFoo(4);
614
615 FooFoo::write::makeList(fooFooHead);
616 FooFoo::read::makeList(fooFooHead);
617 assert(fooFooHead->write::empty());
618 assert(fooFooHead->read::empty());
619 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
620 {
621 cerr << (*f)->va1 << endl;
622 }
623
624 fooFooHead->write::push_front(fooFoo1);
625 assert(!fooFooHead->write::empty());
626 assert(fooFooHead->read::empty());
627 cerr << endl << "first" << endl;
628 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
629 {
630 cerr << (*f)->va1 << endl;
631 }
632
633 fooFooHead->write::push_front(fooFoo2);
634 cerr << endl << "second" << endl;
635 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
636 {
637 cerr << (*f)->va1 << endl;
638 }
639
640 fooFooHead->write::push_front(fooFoo3);
641 cerr << endl << "third" << endl;
642 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
643 {
644 cerr << (*f)->va1 << endl;
645 }
646
647 cerr << endl << "deleted second" << endl;
648 delete fooFoo2;
649 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
650 {
651 cerr << (*f)->va1 << endl;
652 }
653
654 cerr << endl << "fourth" << endl;
655 fooFooHead->write::push_front(fooFoo4);
656 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
657 {
658 cerr << (*f)->va1 << endl;
659 }
660
661 cerr << endl << "deleted fourth, first" << endl;
662 delete fooFoo1;
663 delete fooFoo4;
664 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
665 {
666 cerr << (*f)->va1 << endl;
667 }
668
669 cerr << endl << "deleted third (empty)" << endl;
670 delete fooFoo3;
671 for (FooFoo::write::iterator f = fooFooHead->write::begin(); f != fooFooHead->write::end(); ++f)
672 {
673 cerr << (*f)->va1 << endl;
674 }
675 }
676
677 return 0;
678 }
679
680 /* ====================================================================
681 * The Vovida Software License, Version 1.0
682 *
683 * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved.
684 *
685 * Redistribution and use in source and binary forms, with or without
686 * modification, are permitted provided that the following conditions
687 * are met:
688 *
689 * 1. Redistributions of source code must retain the above copyright
690 * notice, this list of conditions and the following disclaimer.
691 *
692 * 2. Redistributions in binary form must reproduce the above copyright
693 * notice, this list of conditions and the following disclaimer in
694 * the documentation and/or other materials provided with the
695 * distribution.
696 *
697 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
698 * and "Vovida Open Communication Application Library (VOCAL)" must
699 * not be used to endorse or promote products derived from this
700 * software without prior written permission. For written
701 * permission, please contact vocal@vovida.org.
702 *
703 * 4. Products derived from this software may not be called "VOCAL", nor
704 * may "VOCAL" appear in their name, without prior written
705 * permission of Vovida Networks, Inc.
706 *
707 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
708 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
709 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
710 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
711 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
712 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
713 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
714 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
715 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
716 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
717 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
718 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
719 * DAMAGE.
720 *
721 * ====================================================================
722 *
723 * This software consists of voluntary contributions made by Vovida
724 * Networks, Inc. and many individuals on behalf of Vovida Networks,
725 * Inc. For more information on Vovida Networks, Inc., please see
726 * <http://www.vovida.org/>.
727 *
728 */

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27