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名前空間の始まり
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 >
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 >
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:
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:
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 

Generated on Wed Nov 12 2014 19:44:22 for MIST by doxygen 1.8.1.2