- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

pointer.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28
33
34 #ifndef __INCLUDE_MIST_POINTER_H__
35 #define __INCLUDE_MIST_POINTER_H__
36
37
38 #ifndef __INCLUDE_MIST_CONF_H__
39 #include "mist_conf.h"
40 #endif
41
42 #include <iostream>
43 #include <map>
44
45
46 // mist名前空間の始まり
47 _MIST_BEGIN
48
49
50
51
52 namespace __shared_memory__
53 {
54 template < class T >
55 struct shared_base
56 {
57 private:
58 typedef T* pointer;
59
60 struct shared_memory_conter
61 {
62 typedef T* pointer;
63 pointer ptr;
64 size_t ref_count;
65 size_t ref_weak_count;
66
67 shared_memory_conter( ) : ptr( NULL ), ref_count( 0 ), ref_weak_count( 0 ){ }
68 shared_memory_conter( pointer p, size_t rc, size_t rwc ) : ptr( p ), ref_count( rc ), ref_weak_count( rwc ){ }
69 };
70
71 typedef shared_memory_conter counter_type;
72 typedef std::map< pointer, counter_type > ref_table_type;
73 typedef typename ref_table_type::iterator ref_table_iterator;
74
75 protected:
76 static ref_table_type &get_ref_table( )
77 {
78 static ref_table_type ref_table_singleton_;
79 return( ref_table_singleton_ );
80 }
81
82 static ref_table_iterator get_ref_iterator( pointer p )
83 {
84 ref_table_type &ref_table_ = get_ref_table( );
85
86 if( p == NULL )
87 {
88 return( get_null_reference( ) );
89 }
90 else
91 {
92 ref_table_iterator ite = ref_table_.find( p );
93
94 if( ite == ref_table_.end( ) )
95 {
96 // 最初の追加のため，テーブルを初期化する
97 ite = ref_table_.insert( typename ref_table_type::value_type( p, counter_type( p, 0, 0 ) ) ).first;
98 }
99 return( ite );
100 }
101 }
102
103 static ref_table_iterator get_null_reference( )
104 {
105 ref_table_type &ref_table_ = get_ref_table( );
106 // NULL参照用のデータをあらかじめ挿入しておく
107 static ref_table_iterator null_ite_ = ref_table_.insert( typename ref_table_type::value_type( NULL, counter_type( NULL, 0, 0 ) ) ).first;
108 return( null_ite_ );
109 }
110
111 ref_table_iterator ref_ite_;
112
113 shared_base( ) : ref_ite_( get_null_reference( ) ){ }
114 shared_base( const shared_base &b ) : ref_ite_( b.ref_ite_ ){}
115
116 pointer get_pointer( ) const { return( ref_ite_->second.ptr ); }
117
118 protected:
119 // null 参照に設定する
120 void null_ref( )
121 {
122 ref_ite_ = get_null_reference( );
123 }
124
125 // 参照用の参照カウントを増加させる
126 void add_ref( )
127 {
128 // 参照カウントを増やす
129 ref_ite_->second.ref_count++;
130 }
131
132 // 参照用の参照カウントを増加させる
133 void add_ref( pointer p )
134 {
135 ref_ite_ = get_ref_iterator( p );
136
137 // 参照カウントを増やす
138 ref_ite_->second.ref_count++;
139 }
140
141 // 参照用の参照カウントを増加させる
142 void add_ref( const shared_base &p )
143 {
144 ref_ite_ = p.ref_ite_;
145
146 // 参照カウントを増やす
147 ref_ite_->second.ref_count++;
148 }
149
150 // 弱参照用の参照カウントを増加させる
151 void add_weak_ref( )
152 {
153 // 参照カウントを増やす
154 ref_ite_->second.ref_weak_count++;
155 }
156
157 // 弱参照用の参照カウントを増加させる
158 void add_weak_ref( pointer p )
159 {
160 ref_ite_ = get_ref_iterator( p );
161
162 // 参照カウントを増やす
163 ref_ite_->second.ref_weak_count++;
164 }
165
166 // 弱参照用の参照カウントを増加させる
167 void add_weak_ref( const shared_base &p )
168 {
169 ref_ite_ = p.ref_ite_;
170
171 // 参照カウントを増やす
172 ref_ite_->second.ref_weak_count++;
173 }
174
175 void release( bool isArray )
176 {
177 counter_type &c = ref_ite_->second;
178 if( c.ptr != NULL )
179 {
180 // 参照カウントを減らす
181 c.ref_count--;
182
183 // 参照カウントによって，メモリの開放を行う
184 if( c.ref_count == 0 )
185 {
186 // 参照カウントが 0 になったので，メモリを開放しテーブルから削除する
187 if( isArray )
188 {
189 delete [] c.ptr;
190 }
191 else
192 {
193 delete c.ptr;
194 }
195
196 // ポインタに対する弱参照が存在しない場合は，NULLを代入する
197 if( c.ref_weak_count == 0 )
198 {
199 ref_table_type &table = get_ref_table( );
200 table.erase( ref_ite_ );
201 }
202 else
203 {
204 c.ptr = NULL;
205 }
206 }
207 }
208 }
209
210 void release_weak( )
211 {
212 counter_type &c = ref_ite_->second;
213
214 if( c.ptr != NULL )
215 {
216 // 弱参照カウントを減らす
217 c.ref_weak_count--;
218
219 if( c.ref_weak_count == 0 && c.ref_count == 0 )
220 {
221 // ポインタに対する参照と弱参照が存在しない場合は，テーブルから削除する
222 ref_table_type &table = get_ref_table( );
223 table.erase( ref_ite_ );
224 }
225 }
226 }
227 };
228 }
229
230
231
239
240
253 template < class T >
254 class scoped_ptr
255 {
256 public:
257 typedef size_t size_type;
258 typedef ptrdiff_t difference_type;
259 typedef T value_type;
260 typedef T* pointer;
261 typedef T& reference;
262 typedef const T& const_reference;
263 typedef const T* const_pointer;
264
265 private:
266 pointer ptr_;
267
268 public:
270 scoped_ptr( pointer p ) : ptr_( p ){ }
271
273 ~scoped_ptr( ){ delete ptr_; }
274
275
276 public:
277 reference operator *( ){ return( *ptr_ ); }
278 const_reference operator *( ) const { return( *ptr_ ); }
279
280 pointer operator ->( ){ return( ptr_ ); }
281 const_pointer operator ->( ) const { return( ptr_ ); }
282
283
284 private:
285 scoped_ptr( const scoped_ptr &p );
286 const scoped_ptr &operator =( const scoped_ptr &p );
287 };
288
289
290
307 template < class T >
308 class scoped_array
309 {
310 public:
311 typedef size_t size_type;
312 typedef ptrdiff_t difference_type;
313 typedef T value_type;
314 typedef T* pointer;
315 typedef T& reference;
316 typedef const T& const_reference;
317 typedef const T* const_pointer;
318
319 private:
320 pointer ptr_;
321
322 public:
324 scoped_array( pointer p ) : ptr_( p ){ }
325
326 ~scoped_array( ){ delete [] ptr_; }
327
328
329 public:
330 reference operator *( ){ return( *ptr_ ); }
331 const_reference operator *( ) const { return( *ptr_ ); }
332
333 pointer operator ->( ){ return( ptr_ ); }
334 const_pointer operator ->( ) const { return( ptr_ ); }
335
336 reference operator []( difference_type index ){ return( ptr_[ index ] ); }
337 const_reference operator []( difference_type index ) const { return( ptr_[ index ] ); }
338
339 private:
340 scoped_array( const scoped_array &p );
341 const scoped_array &operator =( const scoped_array &p );
342 };
343
344
345
366 template < class T >
367 class shared_ptr : public __shared_memory__::shared_base< T >
368 {
369 public:
370 typedef size_t size_type;
371 typedef ptrdiff_t difference_type;
372 typedef T value_type;
373 typedef T* pointer;
374 typedef T& reference;
375 typedef const T& const_reference;
376 typedef const T* const_pointer;
377
378 private:
379 typedef __shared_memory__::shared_base< T > base;
380
381
382 public:
384 shared_ptr( ){ }
385
387 shared_ptr( pointer p ){ base::add_ref( p ); }
388
390 shared_ptr( const shared_ptr &p ) : base( p ){ base::add_ref( ); }
391
396 ~shared_ptr( ){ base::release( false ); }
397
398
404 const shared_ptr &operator =( const shared_ptr &p )
405 {
406 if( &p != this )
407 {
408 base::release( false );
409 base::add_ref( p );
410 }
411
412 return( *this );
413 }
414
415 public:
417 reference operator *( ){ return( *base::get_pointer( ) ); }
418
420 const_reference operator *( ) const { return( *base::get_pointer( ) ); }
421
423 pointer operator ->( ){ return( base::get_pointer( ) ); }
424
426 const_pointer operator ->( ) const { return( base::get_pointer( ) ); }
427
428
429
434 void reset( )
435 {
436 base::release( false );
437 base::null_ref( );
438 }
439
440 public:
442 bool operator ==( const shared_ptr &p ) const { return( base::get_pointer( ) == p.get_pointer( ) ); }
443
445 bool operator !=( const shared_ptr &p ) const { return( base::get_pointer( ) != p.get_pointer( ) ); }
446
448 bool operator < ( const shared_ptr &p ) const { return( base::get_pointer( ) < p.get_pointer( ) ); }
449
451 bool operator <=( const shared_ptr &p ) const { return( base::get_pointer( ) <= p.get_pointer( ) ); }
452
454 bool operator > ( const shared_ptr &p ) const { return( base::get_pointer( ) > p.get_pointer( ) ); }
455
457 bool operator >=( const shared_ptr &p ) const { return( base::get_pointer( ) >= p.get_pointer( ) ); }
458
459
461 bool operator ==( const pointer &p ) const { return( base::get_pointer( ) == p ); }
462
464 bool operator !=( const pointer &p ) const { return( base::get_pointer( ) != p ); }
465
467 bool operator < ( const pointer &p ) const { return( base::get_pointer( ) < p ); }
468
470 bool operator <=( const pointer &p ) const { return( base::get_pointer( ) <= p ); }
471
473 bool operator > ( const pointer &p ) const { return( base::get_pointer( ) > p ); }
474
476 bool operator >=( const pointer &p ) const { return( base::get_pointer( ) >= p ); }
477
478 };
479
480 template < class T > inline bool operator ==( const typename shared_ptr< T >::pointer p1, const shared_ptr< T > &p2 ){ return( p2 == p1 ); }
481 template < class T > inline bool operator !=( const typename shared_ptr< T >::pointer p1, const shared_ptr< T > &p2 ){ return( p2 != p1 ); }
482
483 template < class T > inline bool operator < ( const typename shared_ptr< T >::pointer p1, const shared_ptr< T > &p2 ){ return( !( p2 <= p1 ) ); }
484 template < class T > inline bool operator <=( const typename shared_ptr< T >::pointer p1, const shared_ptr< T > &p2 ){ return( !( p2 < p1 ) ); }
485 template < class T > inline bool operator > ( const typename shared_ptr< T >::pointer p1, const shared_ptr< T > &p2 ){ return( !( p2 >= p1 ) ); }
486 template < class T > inline bool operator >=( const typename shared_ptr< T >::pointer p1, const shared_ptr< T > &p2 ){ return( !( p2 > p1 ) ); }
487
488
489
490
515 template < class T >
516 class shared_array : public __shared_memory__::shared_base< T >
517 {
518 public:
519 typedef size_t size_type;
520 typedef ptrdiff_t difference_type;
521 typedef T value_type;
522 typedef T* pointer;
523 typedef T& reference;
524 typedef const T& const_reference;
525 typedef const T* const_pointer;
526
527 private:
528 typedef __shared_memory__::shared_base< T > base;
529
530 public:
532 shared_array( ){ }
533
535 shared_array( pointer p ){ base::add_ref( p ); }
536
538 shared_array( const shared_array &p ) : base( ) { base::add_ref( p ); }
539
544 ~shared_array( ){ base::release( true ); }
545
546
552 const shared_array &operator =( const shared_array &p )
553 {
554 if( &p != this )
555 {
556 base::release( true );
557 base::add_ref( p );
558 }
559
560 return( *this );
561 }
562
563 public:
565 reference operator *( ){ return( *base::get_pointer( ) ); }
566
568 const_reference operator *( ) const { return( *base::get_pointer( ) ); }
569
571 pointer operator ->( ){ return( base::get_pointer( ) ); }
572
574 const_pointer operator ->( ) const { return( base::get_pointer( ) ); }
575
577 reference operator []( difference_type index ){ return( base::get_pointer( )[ index ] ); }
578
580 const_reference operator []( difference_type index ) const { return( base::get_pointer( )[ index ] ); }
581
582
587 void reset( )
588 {
589 base::release( true );
590 base::null_ref( );
591 }
592
593
594 public:
596 bool operator ==( const shared_array &p ) const { return( base::get_pointer( ) == p.get_pointer( ) ); }
597
599 bool operator !=( const shared_array &p ) const { return( base::get_pointer( ) != p.get_pointer( ) ); }
600
602 bool operator < ( const shared_array &p ) const { return( base::get_pointer( ) < p.get_pointer( ) ); }
603
605 bool operator <=( const shared_array &p ) const { return( base::get_pointer( ) <= p.get_pointer( ) ); }
606
608 bool operator > ( const shared_array &p ) const { return( base::get_pointer( ) > p.get_pointer( ) ); }
609
611 bool operator >=( const shared_array &p ) const { return( base::get_pointer( ) >= p.get_pointer( ) ); }
612
613
615 bool operator ==( const pointer &p ) const { return( base::get_pointer( ) == p ); }
616
618 bool operator !=( const pointer &p ) const { return( base::get_pointer( ) != p ); }
619
621 bool operator < ( const pointer &p ) const { return( base::get_pointer( ) < p ); }
622
624 bool operator <=( const pointer &p ) const { return( base::get_pointer( ) <= p ); }
625
627 bool operator > ( const pointer &p ) const { return( base::get_pointer( ) > p ); }
628
630 bool operator >=( const pointer &p ) const { return( base::get_pointer( ) >= p ); }
631
632 };
633
634 template < class T > inline bool operator ==( const typename shared_array< T >::pointer p1, const shared_array< T > &p2 ){ return( p2 == p1 ); }
635 template < class T > inline bool operator !=( const typename shared_array< T >::pointer p1, const shared_array< T > &p2 ){ return( p2 != p1 ); }
636
637 template < class T > inline bool operator < ( const typename shared_array< T >::pointer p1, const shared_array< T > &p2 ){ return( !( p2 <= p1 ) ); }
638 template < class T > inline bool operator <=( const typename shared_array< T >::pointer p1, const shared_array< T > &p2 ){ return( !( p2 < p1 ) ); }
639 template < class T > inline bool operator > ( const typename shared_array< T >::pointer p1, const shared_array< T > &p2 ){ return( !( p2 >= p1 ) ); }
640 template < class T > inline bool operator >=( const typename shared_array< T >::pointer p1, const shared_array< T > &p2 ){ return( !( p2 > p1 ) ); }
641
642
643
668 template < class T >
669 class weak_ptr : public __shared_memory__::shared_base< T >
670 {
671 public:
672 typedef size_t size_type;
673 typedef ptrdiff_t difference_type;
674 typedef T value_type;
675 typedef T* pointer;
676 typedef T& reference;
677 typedef const T& const_reference;
678 typedef const T* const_pointer;
679
680 private:
681 typedef __shared_memory__::shared_base< T > base;
682
683 public:
685 weak_ptr( ){ base::add_weak_ref( NULL ); }
686
688 weak_ptr( shared_ptr< T > &p ){ base::add_weak_ref( p ); }
689
691 weak_ptr( const shared_ptr< T > &p ){ base::add_weak_ref( p ); }
692
694 weak_ptr( shared_array< T > &p ){ base::add_weak_ref( p ); }
695
697 weak_ptr( const shared_array< T > &p ){ base::add_weak_ref( p ); }
698
700 ~weak_ptr( ){ base::release_weak( ); }
701
702
708 const weak_ptr &operator =( const weak_ptr &p )
709 {
710 if( this != &p )
711 {
712 base::release_weak( );
713 base::add_weak_ref( p );
714 }
715
716 return( *this );
717 }
718
724 const weak_ptr &operator =( const shared_ptr< T > &p )
725 {
726 base::release_weak( );
727 base::add_weak_ref( p );
728
729 return( *this );
730 }
731
737 const weak_ptr &operator =( const shared_array< T > &p )
738 {
739 base::release_weak( );
740 base::add_weak_ref( p );
741
742 return( *this );
743 }
744
745
746 public:
748 reference operator *( ){ return( *base::get_pointer( ) ); }
749
751 const_reference operator *( ) const { return( *base::get_pointer( ) ); }
752
754 pointer operator ->( ){ return( base::get_pointer( ) ); }
755
757 const_pointer operator ->( ) const { return( base::get_pointer( ) ); }
758
760 reference operator []( difference_type index ){ return( base::get_pointer( )[ index ] ); }
761
763 const_reference operator []( difference_type index ) const { return( base::get_pointer( )[ index ] ); }
764
765
770 void reset( )
771 {
772 base::release_weak( );
773 base::null_ref( );
774 }
775
776
777 public:
779 bool operator ==( const weak_ptr &p ) const { return( base::get_pointer( ) == p.get_pointer( ) ); }
780
782 bool operator !=( const weak_ptr &p ) const { return( base::get_pointer( ) != p.get_pointer( ) ); }
783
785 bool operator < ( const weak_ptr &p ) const { return( base::get_pointer( ) < p.get_pointer( ) ); }
786
788 bool operator <=( const weak_ptr &p ) const { return( base::get_pointer( ) <= p.get_pointer( ) ); }
789
791 bool operator > ( const weak_ptr &p ) const { return( base::get_pointer( ) > p.get_pointer( ) ); }
792
794 bool operator >=( const weak_ptr &p ) const { return( base::get_pointer( ) >= p.get_pointer( ) ); }
795
796
798 bool operator ==( const pointer &p ) const { return( base::get_pointer( ) == p ); }
799
801 bool operator !=( const pointer &p ) const { return( base::get_pointer( ) != p ); }
802
804 bool operator < ( const pointer &p ) const { return( base::get_pointer( ) < p ); }
805
807 bool operator <=( const pointer &p ) const { return( base::get_pointer( ) <= p ); }
808
810 bool operator > ( const pointer &p ) const { return( base::get_pointer( ) > p ); }
811
813 bool operator >=( const pointer &p ) const { return( base::get_pointer( ) >= p ); }
814
815 };
816
817
818 template < class T > inline bool operator ==( const typename weak_ptr< T >::pointer p1, const weak_ptr< T > &p2 ){ return( p2 == p1 ); }
819 template < class T > inline bool operator !=( const typename weak_ptr< T >::pointer p1, const weak_ptr< T > &p2 ){ return( p2 != p1 ); }
820
821 template < class T > inline bool operator < ( const typename weak_ptr< T >::pointer p1, const weak_ptr< T > &p2 ){ return( !( p2 <= p1 ) ); }
822 template < class T > inline bool operator <=( const typename weak_ptr< T >::pointer p1, const weak_ptr< T > &p2 ){ return( !( p2 < p1 ) ); }
823 template < class T > inline bool operator > ( const typename weak_ptr< T >::pointer p1, const weak_ptr< T > &p2 ){ return( !( p2 >= p1 ) ); }
824 template < class T > inline bool operator >=( const typename weak_ptr< T >::pointer p1, const
825
826 weak_ptr< T > &p2 ){ return( !( p2 > p1 ) ); }
827
828
836 template < class T >
837 inline std::ostream &operator <<( std::ostream &out, const scoped_ptr< T > &p )
838 {
839 out << &( *p );
840 return( out );
841 }
842
843
851 template < class T >
852 inline std::ostream &operator <<( std::ostream &out, const scoped_array< T > &p )
853 {
854 out << &( *p );
855 return( out );
856 }
857
858
866 template < class T >
867 inline std::ostream &operator <<( std::ostream &out, const shared_ptr< T > &p )
868 {
869 out << &( *p );
870 return( out );
871 }
872
880 template < class T >
881 inline std::ostream &operator <<( std::ostream &out, const weak_ptr< T > &p )
882 {
883 out << &( *p );
884 return( out );
885 }
886
888 // メモリ領域の自動開放を行うポインタ
889
890
891
892 // mist名前空間の終わり
893 _MIST_END
894
895
896 #endif // __INCLUDE_MIST_POINTER_H__
897