~hikiko/nux/arb-srgba-shader

« back to all changes in this revision

Viewing changes to NuxCore/SmartPtr/GenericSmartPointer.h

  • Committer: Travis Watkins
  • Date: 2011-08-03 10:34:36 UTC
  • mfrom: (409 nux-logger-fix)
  • mto: (454.5.1 nux-gles)
  • mto: This revision was merged to the branch mainline in revision 501.
  • Revision ID: travis.watkins@linaro.org-20110803103436-biz9c9930l2refsi
merge with lp:nux

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2010 Inalogic® Inc.
3
 
 *
4
 
 * This program is free software: you can redistribute it and/or modify it
5
 
 * under the terms of the GNU Lesser General Public License, as
6
 
 * published by the  Free Software Foundation; either version 2.1 or 3.0
7
 
 * of the License.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful, but
10
 
 * WITHOUT ANY WARRANTY; without even the implied warranties of
11
 
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12
 
 * PURPOSE.  See the applicable version of the GNU Lesser General Public
13
 
 * License for more details.
14
 
 *
15
 
 * You should have received a copy of both the GNU Lesser General Public
16
 
 * License along with this program. If not, see <http://www.gnu.org/licenses/>
17
 
 *
18
 
 * Authored by: Jay Taoko <jaytaoko@inalogic.com>
19
 
 *
20
 
 */
21
 
 
22
 
 
23
 
#ifndef WIDGETSMARTPOINTER_H
24
 
#define WIDGETSMARTPOINTER_H
25
 
 
26
 
namespace nux
27
 
{
28
 
 
29
 
  struct RefCounts
30
 
  {
31
 
    RefCounts () : totalRefs_ (1), strongRefs_ (1)
32
 
    {
33
 
    }
34
 
 
35
 
    NThreadSafeCounter totalRefs_;
36
 
    NThreadSafeCounter strongRefs_;
37
 
  };
38
 
 
39
 
  enum Null
40
 
  {
41
 
    null = 0
42
 
  };
43
 
 
44
 
///////////////////////////////////////////////////////
45
 
// forward definitions
46
 
 
47
 
  template <typename T>
48
 
  class GenericWeakSP;
49
 
 
50
 
  template <typename T>
51
 
  class GenericSP;
52
 
 
53
 
//! A smart pointer class. Implemented as an intrusive smart pointer.
54
 
  template <typename T>
55
 
  class GenericSP
56
 
  {
57
 
  public:
58
 
    //! Constructor
59
 
    GenericSP()
60
 
      :   ptr_ (0)
61
 
      , refCounts_ (0)
62
 
      , deletewhenrefcounthitzero_ (true)
63
 
    {
64
 
    }
65
 
 
66
 
    //! Copy constructor
67
 
    GenericSP (const GenericSP<T>& other)
68
 
      :   ptr_ (0)
69
 
      , refCounts_ (0)
70
 
      , deletewhenrefcounthitzero_ (true)
71
 
    {
72
 
      ptr_ = other.ptr_;
73
 
      refCounts_ = other.refCounts_;
74
 
      deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_;
75
 
 
76
 
      if (ptr_ != 0)
77
 
      {
78
 
        refCounts_->strongRefs_.Increment();
79
 
        refCounts_->totalRefs_.Increment();
80
 
      }
81
 
    }
82
 
 
83
 
    //! Copy constructor
84
 
    /*!
85
 
        @param other Parameter with a type derived from T.
86
 
    */
87
 
    template <typename O>
88
 
    GenericSP (const GenericSP<O>& other)
89
 
      :   ptr_ (0)
90
 
      , refCounts_ (0)
91
 
      , deletewhenrefcounthitzero_ (true)
92
 
    {
93
 
      if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) )
94
 
      {
95
 
        ptr_ = (T *) other.ptr_;
96
 
        refCounts_ = other.refCounts_;
97
 
        deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_;
98
 
      }
99
 
 
100
 
      if (ptr_ != 0)
101
 
      {
102
 
        refCounts_->strongRefs_.Increment();
103
 
        refCounts_->totalRefs_.Increment();
104
 
      }
105
 
    }
106
 
 
107
 
    //! Construction with a base pointer of type T.
108
 
    /*!
109
 
        @param ptr Start maintaining a reference count of the passed pointer.
110
 
        @param deletewhenrefcounthitzero if True, the pointer is deleted when the ref count reach 0 (to be deprecated).
111
 
    */
112
 
    explicit GenericSP (T *ptr, bool deletewhenrefcounthitzero = true)
113
 
      :   ptr_ (0)
114
 
      ,   refCounts_ (0)
115
 
      ,   deletewhenrefcounthitzero_ (true)
116
 
    {
117
 
      if (ptr != 0)
118
 
      {
119
 
        ptr_ = ptr;
120
 
        refCounts_ = new RefCounts;
121
 
        deletewhenrefcounthitzero_ = deletewhenrefcounthitzero;;
122
 
      }
123
 
    }
124
 
 
125
 
    //! Construction with a base pointer of type O that inherits from type T.
126
 
    /*!
127
 
        @param ptr Start maintaining a reference count of the passed pointer.
128
 
        @param deletewhenrefcounthitzero if True, the pointer is deleted when the ref count reach 0 (to be deprecated).
129
 
    */
130
 
    template <typename O>
131
 
    explicit GenericSP (O *ptr, bool deletewhenrefcounthitzero = true)
132
 
      :   ptr_ (0)
133
 
      , refCounts_ (0)
134
 
      , deletewhenrefcounthitzero_ (true)
135
 
    {
136
 
      if (ptr != 0)
137
 
      {
138
 
        if (ptr->Type().IsDerivedFromType (T::StaticObjectType) )
139
 
        {
140
 
          ptr_ = (T *) ptr;
141
 
          refCounts_ = new RefCounts;
142
 
          deletewhenrefcounthitzero_ = deletewhenrefcounthitzero;
143
 
        }
144
 
        else
145
 
        {
146
 
          // This is possible but check why!
147
 
          // It can happen when doing something like this:
148
 
          //      Layout* layout = this;
149
 
          // where this is a Baseobject.
150
 
          nuxAssert (0);
151
 
        }
152
 
      }
153
 
    }
154
 
 
155
 
    //! Assignment of a smart pointer of type T.
156
 
    /*!
157
 
        @param other Smart pointer of type T.
158
 
    */
159
 
    GenericSP &operator = (const GenericSP<T>& other)
160
 
    {
161
 
      if (ptr_ != other.ptr_)
162
 
      {
163
 
        ReleaseReference ();
164
 
 
165
 
        ptr_ = other.ptr_;
166
 
        refCounts_ = other.refCounts_;
167
 
        deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_;
168
 
 
169
 
        if (ptr_ != 0)
170
 
        {
171
 
          refCounts_->strongRefs_.Increment();
172
 
          refCounts_->totalRefs_.Increment();
173
 
        }
174
 
      }
175
 
 
176
 
      return *this;
177
 
    }
178
 
 
179
 
    //! Assignment of a smart pointer of type O that inherits from type T.
180
 
    /*!
181
 
        @param other Smart pointer of type O.
182
 
    */
183
 
    template <typename O>
184
 
    GenericSP &operator = (const GenericSP<O>& other)
185
 
    {
186
 
      if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) )
187
 
      {
188
 
        if (ptr_ != other.ptr_)
189
 
        {
190
 
          ReleaseReference ();
191
 
 
192
 
          ptr_ = other.ptr_;
193
 
          refCounts_ = other.refCounts_;
194
 
          deletewhenrefcounthitzero_ = other.deletewhenrefcounthitzero_;
195
 
 
196
 
          if (ptr_ != 0)
197
 
          {
198
 
            refCounts_->strongRefs_.Increment();
199
 
            refCounts_->totalRefs_.Increment();
200
 
          }
201
 
        }
202
 
      }
203
 
      else
204
 
      {
205
 
        ReleaseReference ();
206
 
      }
207
 
 
208
 
      return *this;
209
 
    }
210
 
 
211
 
    ~GenericSP ()
212
 
    {
213
 
      ReleaseReference ();
214
 
    }
215
 
 
216
 
    T &operator * () const
217
 
    {
218
 
      nuxAssert (ptr_ != 0);
219
 
      return *ptr_;
220
 
    }
221
 
 
222
 
    T *operator -> () const
223
 
    {
224
 
      nuxAssert (ptr_ != 0);
225
 
      return ptr_;
226
 
    }
227
 
 
228
 
    //! Swap the content of 2 smart pointers.
229
 
    /*!
230
 
        @param other Smart pointer to swap with.
231
 
    */
232
 
    void Swap (GenericSP<T>& other)
233
 
    {
234
 
      std::swap (ptr_, other.ptr_);
235
 
      std::swap (refCounts_, other.refCounts_);
236
 
    }
237
 
 
238
 
    //! Test validity of the smart pointer.
239
 
    /*!
240
 
        Return True if the internal pointer is not null.
241
 
    */
242
 
    bool operator () () const
243
 
    {
244
 
      return ptr_ != 0;
245
 
    }
246
 
 
247
 
    //! Test validity of the smart pointer.
248
 
    /*!
249
 
        Return True if the internal pointer is null.
250
 
    */
251
 
    bool IsNull() const
252
 
    {
253
 
      if (ptr_ == 0)
254
 
        return true;
255
 
 
256
 
      return false;
257
 
    }
258
 
 
259
 
    //! Test validity of the smart pointer.
260
 
    /*!
261
 
        Return True if the internal pointer is not null.
262
 
    */
263
 
    bool IsValid() const
264
 
    {
265
 
      if (ptr_ != 0)
266
 
        return true;
267
 
 
268
 
      return false;
269
 
    }
270
 
 
271
 
    bool operator < (T *ptr) const
272
 
    {
273
 
      return (ptr_ < ptr);
274
 
    }
275
 
 
276
 
    bool operator > (T *ptr) const
277
 
    {
278
 
      return (ptr_ > ptr);
279
 
    }
280
 
 
281
 
    bool operator < (GenericSP<T> other) const
282
 
    {
283
 
      return (ptr_ < other.ptr_);
284
 
    }
285
 
 
286
 
    bool operator > (GenericSP<T> other) const
287
 
    {
288
 
      return (ptr_ > other.ptr_);
289
 
    }
290
 
 
291
 
    bool operator != (T *ptr) const
292
 
    {
293
 
      return (ptr_ != ptr);
294
 
    }
295
 
 
296
 
    bool operator == (T *ptr) const
297
 
    {
298
 
      return (ptr_ == ptr);
299
 
    }
300
 
 
301
 
    template<typename U>
302
 
    bool operator != (U *ptr) const
303
 
    {
304
 
      if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) )
305
 
        return false;
306
 
 
307
 
      return (ptr_ != ptr);
308
 
    }
309
 
 
310
 
    template<typename U>
311
 
    bool operator == (U *ptr) const
312
 
    {
313
 
      if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) )
314
 
        return false;
315
 
 
316
 
      return (ptr_ == ptr);
317
 
    }
318
 
 
319
 
    template<typename U>
320
 
    bool operator != (const GenericSP<U>& other) const
321
 
    {
322
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
323
 
        return false;
324
 
 
325
 
      return ptr_ != other.ptr_;
326
 
    }
327
 
 
328
 
    template<typename U>
329
 
    bool operator == (const GenericSP<U>& other) const
330
 
    {
331
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
332
 
        return false;
333
 
 
334
 
      return ptr_ == other.ptr_;
335
 
    }
336
 
 
337
 
    template<typename U>
338
 
    bool operator != (const GenericWeakSP<U>& other) const
339
 
    {
340
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
341
 
        return false;
342
 
 
343
 
      return ptr_ != other.ptr_;
344
 
    }
345
 
 
346
 
    template<typename U>
347
 
    bool operator == (const GenericWeakSP<U>& other) const
348
 
    {
349
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
350
 
        return false;
351
 
 
352
 
      return ptr_ == other.ptr_;
353
 
    }
354
 
 
355
 
    void Release()
356
 
    {
357
 
      ReleaseReference();
358
 
    }
359
 
 
360
 
  private:
361
 
    GenericSP (T *ptr, RefCounts *refCounts) : ptr_ (ptr), refCounts_ (refCounts)
362
 
    {
363
 
    }
364
 
 
365
 
    void ReleaseReference()
366
 
    {
367
 
      if (ptr_ == 0)
368
 
      {
369
 
        return;
370
 
      }
371
 
 
372
 
      {
373
 
        refCounts_->strongRefs_.Decrement();
374
 
        bool release = refCounts_->strongRefs_ == 0;
375
 
 
376
 
        if (release && deletewhenrefcounthitzero_)
377
 
        {
378
 
          delete ptr_;
379
 
        }
380
 
 
381
 
        ptr_ = 0;
382
 
      }
383
 
 
384
 
      {
385
 
        refCounts_->totalRefs_.Decrement();
386
 
        bool release = refCounts_->totalRefs_ == 0;
387
 
 
388
 
        if (release)
389
 
        {
390
 
          delete refCounts_;
391
 
        }
392
 
 
393
 
        refCounts_ = 0;
394
 
      }
395
 
    }
396
 
 
397
 
    T *ptr_;
398
 
    RefCounts *refCounts_;
399
 
    bool deletewhenrefcounthitzero_;
400
 
 
401
 
    template <typename U>
402
 
    friend GenericSP<U> Create ();
403
 
 
404
 
    template <typename U, typename P1>
405
 
    friend GenericSP<U> Create (P1 p1);
406
 
 
407
 
    template <typename U, typename P1, typename P2>
408
 
    friend GenericSP<U> Create (P1 p1, P2 p2);
409
 
 
410
 
    template <typename U, typename P1, typename P2, typename P3>
411
 
    friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3);
412
 
 
413
 
    template <typename U, typename P1, typename P2, typename P3, typename P4>
414
 
    friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4);
415
 
 
416
 
    template <typename U, typename P1, typename P2, typename P3, typename P4, typename P5>
417
 
    friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5);
418
 
 
419
 
    template <typename U, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
420
 
    friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6);
421
 
 
422
 
    template <typename U, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
423
 
    friend GenericSP<U> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7);
424
 
 
425
 
    template <typename U>
426
 
    friend GenericSP<U> WrapWSPtr (U *u);
427
 
 
428
 
    template <typename O>
429
 
    friend class GenericSP;
430
 
 
431
 
    template <typename O>
432
 
    friend class GenericWeakSP;
433
 
 
434
 
    //     template<typename T, typename U>
435
 
    //     friend bool operator == (const GenericSP<T>& a, const GenericSP<U>& b);
436
 
 
437
 
    //     template<typename T, typename U>
438
 
    //     friend bool operator != (const GenericSP<T>& a, const GenericSP<U>& b);
439
 
 
440
 
    //     template<typename T>
441
 
    //     friend bool operator == (const GenericSP<T>& a, T*);
442
 
 
443
 
    template<typename U>
444
 
    friend bool operator == (U *, const GenericSP<U>& a);
445
 
 
446
 
    //     template<typename T>
447
 
    //     friend bool operator != (const GenericSP<T>& a, T*);
448
 
 
449
 
    template<typename U>
450
 
    friend bool operator != (U *, const GenericSP<U>& a);
451
 
 
452
 
    //     template<typename T, typename U>
453
 
    //     friend bool operator == (const GenericSP<T>& a, const GenericWeakSP<U>& b);
454
 
 
455
 
    //     template<typename T, typename U>
456
 
    //     friend bool operator == (const GenericWeakSP<T>& a, const GenericSP<U>& b);
457
 
    //
458
 
    //     template<typename T, typename U>
459
 
    //     friend bool operator != (const GenericSP<T>& a, const GenericWeakSP<U>& b);
460
 
    //
461
 
    //     template<typename T, typename U>
462
 
    //     friend bool operator != (const GenericWeakSP<T>& a, const GenericSP<U>& b);
463
 
 
464
 
    template <typename U, typename F>
465
 
    friend GenericSP<U> staticCast (const GenericSP<F>& from);
466
 
 
467
 
    template <typename U, typename F>
468
 
    friend GenericSP<U> constCast (const GenericSP<F>& from);
469
 
 
470
 
    template <typename U, typename F>
471
 
    friend GenericSP<U> dynamicCast (const GenericSP<F>& from);
472
 
 
473
 
    template <typename U, typename F>
474
 
    friend GenericSP<U> checkedCast (const GenericSP<F>& from);
475
 
 
476
 
    template <typename U, typename F>
477
 
    friend GenericSP<U> queryCast (const GenericSP<F>& from);
478
 
  };
479
 
 
480
 
 
481
 
//! A weak smart pointer class. Implemented as an intrusive smart pointer.
482
 
  /*!
483
 
      A weak smart pointer is built from a smart pointer or another weak smart pointer. It increments and decrements
484
 
      the total reference count of an pointer. Even is the original pointer is destroyed, weak smart pointers still point
485
 
      to the RefCounts pointers of the original pointer and can use it to check if the pointer is still valid or not.
486
 
  */
487
 
  template <typename T>
488
 
  class GenericWeakSP
489
 
  {
490
 
  public:
491
 
    //! Constructor
492
 
    GenericWeakSP () : ptr_ (0), refCounts_ (0)
493
 
    {
494
 
    }
495
 
 
496
 
    //! Copy constructor
497
 
    /*!
498
 
        @param other Parameter with type T.
499
 
    */
500
 
    GenericWeakSP (const GenericWeakSP<T>& other)
501
 
    {
502
 
      ptr_ = other.ptr_;
503
 
      refCounts_ = other.refCounts_;
504
 
 
505
 
      if (ptr_ != 0)
506
 
      {
507
 
        refCounts_->totalRefs_.Increment();
508
 
      }
509
 
    }
510
 
 
511
 
    //! Copy constructor
512
 
    /*!
513
 
        @param other Parameter with a type derived from T.
514
 
    */
515
 
    template <typename O>
516
 
    GenericWeakSP (const GenericWeakSP<O>& other)
517
 
      :   ptr_ (0)
518
 
      ,   refCounts_ (0)
519
 
    {
520
 
      if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) )
521
 
      {
522
 
        ptr_ = other.ptr_;
523
 
        refCounts_ = other.refCounts_;
524
 
 
525
 
        if (ptr_ != 0)
526
 
        {
527
 
          refCounts_->totalRefs_.Increment();
528
 
        }
529
 
      }
530
 
    }
531
 
 
532
 
//     //! Construction from a smart pointer of type T.
533
 
//     /*!
534
 
//         @param other Maintains a weak smart pointer reference to this parameter.
535
 
//     */
536
 
//     GenericWeakSP (const GenericSP<T>& other)
537
 
//         :   ptr_(0)
538
 
//         ,   refCounts_(0)
539
 
//     {
540
 
//         if(other.ptr_)
541
 
//         {
542
 
//             ptr_ = other.ptr_;
543
 
//             refCounts_ = other.refCounts_;
544
 
//
545
 
//             if (ptr_ != 0)
546
 
//             {
547
 
//                 refCounts_->totalRefs_.Increment();
548
 
//             }
549
 
//         }
550
 
//     }
551
 
 
552
 
    //! Construction from a smart pointer of type O that inherits from type T.
553
 
    /*!
554
 
        @param other Maintains a weak smart pointer reference to this parameter.
555
 
    */
556
 
    template <typename O>
557
 
    GenericWeakSP (const GenericSP<O>& other)
558
 
      :   ptr_ (0)
559
 
      ,   refCounts_ (0)
560
 
    {
561
 
      if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) )
562
 
      {
563
 
        ptr_ = other.ptr_;
564
 
        refCounts_ = other.refCounts_;
565
 
 
566
 
        if (ptr_ != 0)
567
 
        {
568
 
          refCounts_->totalRefs_.Increment();
569
 
        }
570
 
      }
571
 
    }
572
 
 
573
 
    //! Assignment of a weak smart pointer of type T.
574
 
    /*!
575
 
        @param other Weak smart pointer of type T.
576
 
    */
577
 
    GenericWeakSP &operator = (const GenericWeakSP<T>& other)
578
 
    {
579
 
      if (get () != other.get () )
580
 
      {
581
 
        ReleaseReference ();
582
 
 
583
 
        ptr_ = other.ptr_;
584
 
        refCounts_ = other.refCounts_;
585
 
 
586
 
        if (ptr_ != 0)
587
 
        {
588
 
          refCounts_->totalRefs_.Increment();
589
 
        }
590
 
      }
591
 
 
592
 
      return *this;
593
 
    }
594
 
 
595
 
    //! Assignment of a weak smart pointer of Type O that inherits from type T.
596
 
    /*!
597
 
        @param other Weak smart pointer of type O.
598
 
    */
599
 
    template <typename O>
600
 
    GenericWeakSP &operator = (const GenericWeakSP<O>& other)
601
 
    {
602
 
      if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) )
603
 
      {
604
 
        if (get () != other.get () )
605
 
        {
606
 
          ReleaseReference ();
607
 
 
608
 
          ptr_ = other.ptr_;
609
 
          refCounts_ = other.refCounts_;
610
 
 
611
 
          if (ptr_ != 0)
612
 
          {
613
 
            refCounts_->totalRefs_.Increment();
614
 
          }
615
 
        }
616
 
      }
617
 
      else
618
 
      {
619
 
        ReleaseReference();
620
 
      }
621
 
 
622
 
      return *this;
623
 
    }
624
 
 
625
 
    //! Assignment of a smart pointer of Type O that inherits from type T.
626
 
    /*!
627
 
        @param other Maintains a weak smart pointer reference to this parameter.
628
 
    */
629
 
    template <typename O>
630
 
    GenericWeakSP &operator = (const GenericSP<O>& other)
631
 
    {
632
 
      if (other.ptr_ && other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) )
633
 
      {
634
 
        if (get () != other.ptr_)
635
 
        {
636
 
          ReleaseReference ();
637
 
 
638
 
          ptr_ = other.ptr_;
639
 
          refCounts_ = other.refCounts_;
640
 
 
641
 
          if (ptr_ != 0)
642
 
          {
643
 
            refCounts_->totalRefs_.Increment();
644
 
          }
645
 
        }
646
 
      }
647
 
      else
648
 
      {
649
 
        ReleaseReference();
650
 
      }
651
 
 
652
 
      return *this;
653
 
    }
654
 
 
655
 
    ~GenericWeakSP ()
656
 
    {
657
 
      ReleaseReference ();
658
 
    }
659
 
 
660
 
    T &operator * () const
661
 
    {
662
 
      nuxAssert ( (refCounts_->strongRefs_.GetValue() != 0) && (ptr_ != 0) );
663
 
 
664
 
      return *get ();
665
 
    }
666
 
 
667
 
    T *operator -> () const
668
 
    {
669
 
      nuxAssert ( (refCounts_->strongRefs_.GetValue() != 0) && (ptr_ != 0) );
670
 
 
671
 
      return get ();
672
 
    }
673
 
 
674
 
    void Swap (GenericWeakSP<T>& other)
675
 
    {
676
 
      std::swap (ptr_, other.ptr_);
677
 
      std::swap (refCounts_, other.refCounts_);
678
 
    }
679
 
 
680
 
    bool operator < (T *ptr) const
681
 
    {
682
 
      return (ptr_ < ptr);
683
 
    }
684
 
 
685
 
    bool operator > (T *ptr) const
686
 
    {
687
 
      return (ptr_ > ptr);
688
 
    }
689
 
 
690
 
    bool operator < (GenericWeakSP<T> other) const
691
 
    {
692
 
      return (ptr_ < other.ptr_);
693
 
    }
694
 
 
695
 
    bool operator > (GenericWeakSP<T> other) const
696
 
    {
697
 
      return (ptr_ > other.ptr_);
698
 
    }
699
 
 
700
 
    bool operator != (T *ptr) const
701
 
    {
702
 
      return (ptr_ != ptr);
703
 
    }
704
 
 
705
 
    bool operator == (T *ptr) const
706
 
    {
707
 
      return (ptr_ == ptr);
708
 
    }
709
 
 
710
 
    template<typename U>
711
 
    bool operator != (U *ptr) const
712
 
    {
713
 
      if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) )
714
 
        return false;
715
 
 
716
 
      return (ptr_ != ptr);
717
 
    }
718
 
 
719
 
    template<typename U>
720
 
    bool operator == (U *ptr) const
721
 
    {
722
 
      if (ptr && (!ptr->Type().IsDerivedFromType (T::StaticObjectType) ) )
723
 
        return false;
724
 
 
725
 
      return (ptr_ == ptr);
726
 
    }
727
 
 
728
 
    template<typename U>
729
 
    bool operator != (const GenericWeakSP<U>& other) const
730
 
    {
731
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
732
 
        return false;
733
 
 
734
 
      return ptr_ != other.ptr_;
735
 
    }
736
 
 
737
 
    template<typename U>
738
 
    bool operator == (const GenericWeakSP<U>& other) const
739
 
    {
740
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
741
 
        return false;
742
 
 
743
 
      return ptr_ == other.ptr_;
744
 
    }
745
 
 
746
 
    template<typename U>
747
 
    bool operator != (const GenericSP<U>& other) const
748
 
    {
749
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
750
 
        return false;
751
 
 
752
 
      return ptr_ != other.ptr_;
753
 
    }
754
 
 
755
 
    template<typename U>
756
 
    bool operator == (const GenericSP<U>& other) const
757
 
    {
758
 
      if (other.ptr_ && (!other.ptr_->Type().IsDerivedFromType (T::StaticObjectType) ) )
759
 
        return false;
760
 
 
761
 
      return ptr_ == other.ptr_;
762
 
    }
763
 
 
764
 
    bool IsNull () const
765
 
    {
766
 
      return get () == 0;
767
 
    }
768
 
 
769
 
    bool IsValid () const
770
 
    {
771
 
      return get () != 0;
772
 
    }
773
 
 
774
 
    void Release()
775
 
    {
776
 
      ReleaseReference();
777
 
    }
778
 
 
779
 
  private:
780
 
    GenericWeakSP (T *ptr, RefCounts *refCounts) : ptr_ (ptr), refCounts_ (refCounts)
781
 
    {
782
 
    }
783
 
 
784
 
    T *get () const
785
 
    {
786
 
      if (refCounts_ == 0 || (refCounts_->strongRefs_ == 0) )
787
 
      {
788
 
        return 0;
789
 
      }
790
 
 
791
 
      return ptr_;
792
 
    }
793
 
 
794
 
//     bool isNull () const
795
 
//     {
796
 
//         return get () == 0;
797
 
//     }
798
 
 
799
 
    void ReleaseReference ()
800
 
    {
801
 
      if (ptr_ == 0)
802
 
      {
803
 
        return;
804
 
      }
805
 
 
806
 
      refCounts_->totalRefs_.Decrement();
807
 
      bool release = refCounts_->totalRefs_ == 0;
808
 
 
809
 
      if (release)
810
 
      {
811
 
        delete refCounts_;
812
 
      }
813
 
 
814
 
      refCounts_ = 0;
815
 
      ptr_ = 0;
816
 
    }
817
 
 
818
 
    T *ptr_;
819
 
    RefCounts *refCounts_;
820
 
 
821
 
    template <typename O>
822
 
    friend class GenericWeakSP;
823
 
 
824
 
    template <typename O>
825
 
    friend class SmartPtr;
826
 
 
827
 
    //     template<typename T, typename U>
828
 
    //     friend bool operator == (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b);
829
 
 
830
 
    //     template<typename T, typename U>
831
 
    //     friend bool operator != (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b);
832
 
 
833
 
    //     template<typename T>
834
 
    //     friend bool operator == (const GenericWeakSP<T>& a, T*);
835
 
 
836
 
    template<typename U>
837
 
    friend bool operator == (U *, const GenericWeakSP<U>& a);
838
 
 
839
 
    //     template<typename T>
840
 
    //     friend bool operator != (const GenericWeakSP<T>& a, T*);
841
 
 
842
 
    template<typename U>
843
 
    friend bool operator != (U *, const GenericWeakSP<U>& a);
844
 
 
845
 
    //     template<typename T, typename U>
846
 
    //     friend bool operator == (const GenericSP<T>& a, const GenericWeakSP<U>& b);
847
 
    //
848
 
    //     template<typename T, typename U>
849
 
    //     friend bool operator == (const GenericWeakSP<T>& a, const GenericSP<U>& b);
850
 
    //
851
 
    //     template<typename T, typename U>
852
 
    //     friend bool operator != (const GenericSP<T>& a, const GenericWeakSP<U>& b);
853
 
    //
854
 
    //     template<typename T, typename U>
855
 
    //     friend bool operator != (const GenericWeakSP<T>& a, const GenericSP<U>& b);
856
 
 
857
 
    template <typename U, typename F>
858
 
    friend GenericWeakSP<U> staticCast (const GenericWeakSP<F>& from);
859
 
 
860
 
    template <typename U, typename F>
861
 
    friend GenericWeakSP<U> constCast (const GenericWeakSP<F>& from);
862
 
 
863
 
    template <typename U, typename F>
864
 
    friend GenericWeakSP<U> dynamicCast (const GenericWeakSP<F>& from);
865
 
 
866
 
    template <typename U, typename F>
867
 
    friend GenericWeakSP<U> checkedCast (const GenericWeakSP<F>& from);
868
 
 
869
 
    template <typename U, typename F>
870
 
    friend GenericWeakSP<U> queryCast (const GenericWeakSP<F>& from);
871
 
  };
872
 
 
873
 
///////////////////////////////////////////////////////
874
 
// globals
875
 
 
876
 
// template<typename T, typename U>
877
 
// inline bool operator == (const GenericSP<T>& a, const GenericSP<U>& b)
878
 
// {
879
 
//     return a.ptr_ == b.ptr_;
880
 
// }
881
 
//
882
 
// template<typename T, typename U>
883
 
// inline bool operator == (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b)
884
 
// {
885
 
//     return a.get () == b.get ();
886
 
// }
887
 
//
888
 
// template<typename T, typename U>
889
 
// inline bool operator == (const GenericSP<T>& a, const GenericWeakSP<U>& b)
890
 
// {
891
 
//     return a.ptr_ == b.get ();
892
 
// }
893
 
//
894
 
// template<typename T, typename U>
895
 
// inline bool operator == (const GenericWeakSP<T>& a, const GenericSP<U>& b)
896
 
// {
897
 
//     return a.get () == b.ptr_;
898
 
// }
899
 
//
900
 
// template<typename T, typename U>
901
 
// inline bool operator != (const GenericSP<T>& a, const GenericSP<U>& b)
902
 
// {
903
 
//     return a.ptr_ != b.ptr_;
904
 
// }
905
 
//
906
 
// template<typename T, typename U>
907
 
// inline bool operator != (const GenericWeakSP<T>& a, const GenericWeakSP<U>& b)
908
 
// {
909
 
//     return a.get () != b.get ();
910
 
// }
911
 
//
912
 
// template<typename T, typename U>
913
 
// inline bool operator != (const GenericSP<T>& a, const GenericWeakSP<U>& b)
914
 
// {
915
 
//     return a.ptr_ != b.get ();
916
 
// }
917
 
//
918
 
// template<typename T, typename U>
919
 
// inline bool operator != (const GenericWeakSP<T>& a, const GenericSP<U>& b)
920
 
// {
921
 
//     return a.get () != b.ptr_;
922
 
// }
923
 
 
924
 
// template<typename T>
925
 
// inline bool operator == (const GenericSP<T>& a, T* ptr)
926
 
// {
927
 
//     return a.ptr_ == ptr;
928
 
// }
929
 
 
930
 
  template<typename T>
931
 
  inline bool operator == (T *ptr, const GenericSP<T>& a)
932
 
  {
933
 
    return a.ptr_ == ptr;
934
 
  }
935
 
 
936
 
// template<typename T>
937
 
// inline bool operator != (const GenericSP<T>& a, T* ptr)
938
 
// {
939
 
//     return a.ptr_ != ptr;
940
 
// }
941
 
 
942
 
  template<typename T>
943
 
  inline bool operator != (T *ptr, const GenericSP<T>& a)
944
 
  {
945
 
    return a.ptr_ != ptr;
946
 
  }
947
 
 
948
 
// template<typename T>
949
 
// inline bool operator == (const GenericWeakSP<T>& a, T* ptr)
950
 
// {
951
 
//     return a.ptr_ == ptr;
952
 
// }
953
 
 
954
 
  template<typename T>
955
 
  inline bool operator == (T *ptr, const GenericWeakSP<T>& a)
956
 
  {
957
 
    return a.ptr_ == ptr;
958
 
  }
959
 
 
960
 
// template<typename T>
961
 
// inline bool operator != (const GenericWeakSP<T>& a, T* ptr)
962
 
// {
963
 
//     return a.ptr_ != ptr;
964
 
// }
965
 
 
966
 
  template<typename T>
967
 
  inline bool operator != (T *ptr, const GenericWeakSP<T>& a)
968
 
  {
969
 
    return a.ptr_ != ptr;
970
 
  }
971
 
 
972
 
///////////////////////////////////////////////////////
973
 
// creation functions
974
 
 
975
 
  template <typename T>
976
 
  GenericSP<T> Create ()
977
 
  {
978
 
    RefCounts *rc = new RefCounts;
979
 
 
980
 
    try
981
 
    {
982
 
      T *t = new T;
983
 
      return GenericSP<T> (t, rc);
984
 
    }
985
 
    catch (...)
986
 
    {
987
 
      delete rc;
988
 
      throw;
989
 
    }
990
 
  }
991
 
 
992
 
  template <typename T, typename P1>
993
 
  GenericSP<T> Create (P1 p1)
994
 
  {
995
 
    RefCounts *rc = new RefCounts;
996
 
 
997
 
    try
998
 
    {
999
 
      T *t = new T (p1);
1000
 
      return GenericSP<T> (t, rc);
1001
 
    }
1002
 
    catch (...)
1003
 
    {
1004
 
      delete rc;
1005
 
      throw;
1006
 
    }
1007
 
  }
1008
 
 
1009
 
  template <typename T, typename P1, typename P2>
1010
 
  GenericSP<T> Create (P1 p1, P2 p2)
1011
 
  {
1012
 
    RefCounts *rc = new RefCounts;
1013
 
 
1014
 
    try
1015
 
    {
1016
 
      T *t = new T (p1, p2);
1017
 
      return GenericSP<T> (t, rc);
1018
 
    }
1019
 
    catch (...)
1020
 
    {
1021
 
      delete rc;
1022
 
      throw;
1023
 
    }
1024
 
  }
1025
 
 
1026
 
  template <typename T, typename P1, typename P2, typename P3>
1027
 
  GenericSP<T> Create (P1 p1, P2 p2, P3 p3)
1028
 
  {
1029
 
    RefCounts *rc = new RefCounts;
1030
 
 
1031
 
    try
1032
 
    {
1033
 
      T *t = new T (p1, p2, p3);
1034
 
      return GenericSP<T> (t, rc);
1035
 
    }
1036
 
    catch (...)
1037
 
    {
1038
 
      delete rc;
1039
 
      throw;
1040
 
    }
1041
 
  }
1042
 
 
1043
 
  template <typename T, typename P1, typename P2, typename P3, typename P4>
1044
 
  GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4)
1045
 
  {
1046
 
    RefCounts *rc = new RefCounts;
1047
 
 
1048
 
    try
1049
 
    {
1050
 
      T *t = new T (p1, p2, p3, p4);
1051
 
      return GenericSP<T> (t, rc);
1052
 
    }
1053
 
    catch (...)
1054
 
    {
1055
 
      delete rc;
1056
 
      throw;
1057
 
    }
1058
 
  }
1059
 
 
1060
 
  template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5>
1061
 
  GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
1062
 
  {
1063
 
    RefCounts *rc = new RefCounts;
1064
 
 
1065
 
    try
1066
 
    {
1067
 
      T *t = new T (p1, p2, p3, p4, p5);
1068
 
      return GenericSP<T> (t, rc);
1069
 
    }
1070
 
    catch (...)
1071
 
    {
1072
 
      delete rc;
1073
 
      throw;
1074
 
    }
1075
 
  }
1076
 
 
1077
 
  template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
1078
 
  GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
1079
 
  {
1080
 
    RefCounts *rc = new RefCounts;
1081
 
 
1082
 
    try
1083
 
    {
1084
 
      T *t = new T (p1, p2, p3, p4, p5, p6);
1085
 
      return GenericSP<T> (t, rc);
1086
 
    }
1087
 
    catch (...)
1088
 
    {
1089
 
      delete rc;
1090
 
      throw;
1091
 
    }
1092
 
  }
1093
 
 
1094
 
  template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
1095
 
  GenericSP<T> Create (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
1096
 
  {
1097
 
    RefCounts *rc = new RefCounts;
1098
 
 
1099
 
    try
1100
 
    {
1101
 
      T *t = new T (p1, p2, p3, p4, p5, p6, p7);
1102
 
      return GenericSP<T> (t, rc);
1103
 
    }
1104
 
    catch (...)
1105
 
    {
1106
 
      delete rc;
1107
 
      throw;
1108
 
    }
1109
 
  }
1110
 
 
1111
 
  template <typename T>
1112
 
  GenericSP<T> WrapWSPtr (T *t)
1113
 
  {
1114
 
    if (t == 0)
1115
 
    {
1116
 
      return GenericSP<T> ();
1117
 
    }
1118
 
 
1119
 
    try
1120
 
    {
1121
 
      RefCounts *rc = new RefCounts;
1122
 
 
1123
 
      return GenericSP<T> (t, rc);
1124
 
    }
1125
 
    catch (...)
1126
 
    {
1127
 
      delete t;
1128
 
      throw;
1129
 
    }
1130
 
  }
1131
 
 
1132
 
///////////////////////////////////////////////////////
1133
 
// casts
1134
 
 
1135
 
  template <typename U, typename F>
1136
 
  GenericSP<U> staticCast (const GenericSP<F>& from)
1137
 
  {
1138
 
    if (from.ptr_ == 0)
1139
 
    {
1140
 
      return GenericSP<U>();
1141
 
    }
1142
 
 
1143
 
    U *ptr = static_cast <U *> (from.ptr_);
1144
 
    RefCounts *refCounts = from.refCounts_;
1145
 
 
1146
 
    if (ptr != 0)
1147
 
    {
1148
 
      refCounts->strongRefs_.Increment();
1149
 
      refCounts->totalRefs_.Increment();
1150
 
    }
1151
 
 
1152
 
    return GenericSP<U> (ptr, refCounts);
1153
 
  }
1154
 
 
1155
 
  template <typename T, typename F>
1156
 
  GenericSP<T> constCast (const GenericSP<F>& from)
1157
 
  {
1158
 
    if (from.ptr_ == 0)
1159
 
    {
1160
 
      return GenericSP<T>();
1161
 
    }
1162
 
 
1163
 
    T *ptr = const_cast <T *> (from.ptr_);
1164
 
    RefCounts *refCounts = from.refCounts_;
1165
 
 
1166
 
    if (ptr != 0)
1167
 
    {
1168
 
      refCounts->strongRefs_.Increment();
1169
 
      refCounts->totalRefs_.Increment();
1170
 
    }
1171
 
 
1172
 
    return GenericSP<T> (ptr, refCounts);
1173
 
  }
1174
 
 
1175
 
  template <typename T, typename F>
1176
 
  GenericSP<T> dynamicCast (const GenericSP<F>& from)
1177
 
  {
1178
 
    if (from.ptr_ == 0)
1179
 
    {
1180
 
      return GenericSP<T>();
1181
 
    }
1182
 
 
1183
 
    T *ptr = &dynamic_cast <T &> (*from.ptr_);
1184
 
    RefCounts *refCounts = from.refCounts_;
1185
 
 
1186
 
    if (ptr != 0)
1187
 
    {
1188
 
      refCounts->strongRefs_.Increment();
1189
 
      refCounts->totalRefs_.Increment();
1190
 
    }
1191
 
 
1192
 
    return GenericSP<T> (ptr, refCounts);
1193
 
  }
1194
 
 
1195
 
  template <typename T, typename F>
1196
 
  GenericSP<T> queryCast (const GenericSP<F>& from)
1197
 
  {
1198
 
    T *ptr = dynamic_cast <T *> (from.ptr_);
1199
 
 
1200
 
    if (ptr == 0)
1201
 
    {
1202
 
      return GenericSP<T>();
1203
 
    }
1204
 
 
1205
 
    RefCounts *refCounts = from.refCounts_;
1206
 
 
1207
 
    if (ptr != 0)
1208
 
    {
1209
 
      refCounts->strongRefs_.Increment();
1210
 
      refCounts->totalRefs_.Increment();
1211
 
    }
1212
 
 
1213
 
    return GenericSP<T> (ptr, refCounts);
1214
 
  }
1215
 
 
1216
 
  template <typename T, typename F>
1217
 
  GenericSP<T> checkedCast (const GenericSP<F>& from)
1218
 
  {
1219
 
    if (from.ptr_ == 0)
1220
 
    {
1221
 
      return GenericSP<T>();
1222
 
    }
1223
 
 
1224
 
    nuxAssert (dynamic_cast<T *> (from.ptr_) != 0);
1225
 
 
1226
 
    T *ptr = static_cast <T *> (from.ptr_);
1227
 
    RefCounts *refCounts = from.refCounts_;
1228
 
 
1229
 
    if (ptr != 0)
1230
 
    {
1231
 
      refCounts->strongRefs_.Increment();
1232
 
      refCounts->totalRefs_.Increment();
1233
 
    }
1234
 
 
1235
 
    return GenericSP<T> (ptr, refCounts);
1236
 
  }
1237
 
 
1238
 
  template <typename U, typename F>
1239
 
  GenericWeakSP<U> staticCast (const GenericWeakSP<F>& from)
1240
 
  {
1241
 
    if (from.get () == 0)
1242
 
    {
1243
 
      return GenericWeakSP<U>();
1244
 
    }
1245
 
 
1246
 
    U *ptr = static_cast <U *> (from.ptr_);
1247
 
    RefCounts *refCounts = from.refCounts_;
1248
 
 
1249
 
    if (ptr != 0)
1250
 
    {
1251
 
      refCounts->totalRefs_.Increment();
1252
 
    }
1253
 
 
1254
 
    return GenericWeakSP<U> (ptr, refCounts);
1255
 
  }
1256
 
 
1257
 
  template <typename T, typename F>
1258
 
  GenericWeakSP<T> constCast (const GenericWeakSP<F>& from)
1259
 
  {
1260
 
    if (from.get () == 0)
1261
 
    {
1262
 
      return GenericWeakSP<T>();
1263
 
    }
1264
 
 
1265
 
    T *ptr = const_cast <T *> (from.ptr_);
1266
 
    RefCounts *refCounts = from.refCounts_;
1267
 
 
1268
 
    if (ptr != 0)
1269
 
    {
1270
 
      refCounts->totalRefs_.Increment();
1271
 
    }
1272
 
 
1273
 
    return GenericWeakSP<T> (ptr, refCounts);
1274
 
  }
1275
 
 
1276
 
  template <typename T, typename F>
1277
 
  GenericWeakSP<T> dynamicCast (const GenericWeakSP<F>& from)
1278
 
  {
1279
 
    if (from.get () == 0)
1280
 
    {
1281
 
      return GenericWeakSP<T>();
1282
 
    }
1283
 
 
1284
 
    T *ptr = &dynamic_cast <T &> (*from.ptr_);
1285
 
    RefCounts *refCounts = from.refCounts_;
1286
 
 
1287
 
    if (ptr != 0)
1288
 
    {
1289
 
      refCounts->totalRefs_.Increment();
1290
 
    }
1291
 
 
1292
 
    return GenericWeakSP<T> (ptr, refCounts);
1293
 
  }
1294
 
 
1295
 
  template <typename T, typename F>
1296
 
  GenericWeakSP<T> queryCast (const GenericWeakSP<F>& from)
1297
 
  {
1298
 
    T *ptr = dynamic_cast <T *> (from.get () );
1299
 
 
1300
 
    if (ptr == 0)
1301
 
    {
1302
 
      return GenericWeakSP<T>();
1303
 
    }
1304
 
 
1305
 
    RefCounts *refCounts = from.refCounts_;
1306
 
 
1307
 
    if (ptr != 0)
1308
 
    {
1309
 
      refCounts->totalRefs_.Increment();
1310
 
    }
1311
 
 
1312
 
    return GenericWeakSP<T> (ptr, refCounts);
1313
 
  }
1314
 
 
1315
 
  template <typename T, typename F>
1316
 
  GenericWeakSP<T> checkedCast (const GenericWeakSP<F>& from)
1317
 
  {
1318
 
    if (from.get () == 0)
1319
 
    {
1320
 
      return GenericWeakSP<T>();
1321
 
    }
1322
 
 
1323
 
    nuxAssert (dynamic_cast<T *> (from.ptr_) != 0);
1324
 
 
1325
 
    T *ptr = static_cast <T *> (from.ptr_);
1326
 
    RefCounts *refCounts = from.refCounts_;
1327
 
 
1328
 
    if (ptr != 0)
1329
 
    {
1330
 
      refCounts->totalRefs_.Increment();
1331
 
    }
1332
 
 
1333
 
    return GenericWeakSP<T> (ptr, refCounts);
1334
 
  }
1335
 
 
1336
 
///////////////////////////////////////////////////////
1337
 
// std specializations
1338
 
 
1339
 
  template <typename T>
1340
 
  inline void swap (GenericSP<T>& t1, GenericSP<T>& t2)
1341
 
  {
1342
 
    t1.swap (t2);
1343
 
  }
1344
 
 
1345
 
  template <typename T>
1346
 
  inline void swap (GenericWeakSP<T>& t1, GenericWeakSP<T>& t2)
1347
 
  {
1348
 
    t1.swap (t2);
1349
 
  }
1350
 
 
1351
 
}
1352
 
 
1353
 
#endif // WIDGETSMARTPOINTER_H