OSDN Git Service

removed .svn
[gintenlib/gintenlib.git] / gintenlib / pointer_facade.hpp
1 #ifndef GINTENLIB_INCLUDED_POINTER_FACADE_HPP_
2 #define GINTENLIB_INCLUDED_POINTER_FACADE_HPP_
3
4 /*
5
6       <gintenlib/pointer_facade.hpp>
7
8   pointer_facade ¡§ ´Ê°×¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿À½ºî
9
10   Àë¸À¡§
11     template< class Derived, typename T, typename Category = Derived >
12     struct pointer_facade
13     {
14       typedef T  element_type;
15       typedef T  value_type;
16       typedef T* pointer;
17       typedef T& reference;
18       
19       // »²¾È³°¤·¤È¥Ý¥¤¥ó¥¿¼èÆÀ
20       reference operator*() const;
21       pointer operator->() const;
22       friend pointer get_pointer( const Derived& target );
23       
24       // bool Èæ³Ó
25       operator unspecified_bool_type() const;
26       bool operator!() const;
27     
28     };
29     
30     // ¥Æ¥ó¥×¥ì¡¼¥ÈÈÇÁê¸ßÈæ³Ó
31     // ¥«¥Æ¥´¥ê¤¬Æ±¤¸¤â¤Î¤Ê¤éÁê¸ßÈæ³Ó£Ï£Ë
32     template<typename T, typename U, typename D1, typename D2, typename C>
33     inline bool operator==
34       ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs );
35       
36     template<typename T, typename U, typename D1, typename D2, typename C>
37     inline bool operator!=
38       ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs );
39     
40     template<typename T, typename U, typename D1, typename D2, typename C>
41     inline bool operator<
42       ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs );
43   
44   µ¡Ç½¡§
45     get() ¤µ¤¨¼ÂÁõ¤¹¤ì¤Ð¡¢¤½¤ì¤ò¸µ¤Ë¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤È¤·¤ÆɬÍפʤâ¤Î¤òÀ¸À®¤¹¤ë¥¯¥é¥¹¤Ç¤¹¡£
46     ¼ÂÁõ¤·¤Æ¤¯¤ì¤ë¤â¤Î¤Ï°Ê²¼¤ÎÄ̤ꡧ
47     ¡¡¡¦element_type, value_type, pointer, reference ¤Î·¿ÄêµÁ
48     ¡¡¡¦operator*, operator->, get_pointer() ¤Ë¤è¤ë¥Ý¥¤¥ó¥¿¼èÆÀ
49     ¡¡¡¦boolÃͤȤÎÈæ³Ó¡¢¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÈæ³Ó
50     ¡¡¡¦°Û¤Ê¤ë·¿¤ò¼¨¤¹¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÈæ³Ó¡ÊƱ¤¸¥«¥Æ¥´¥ê¤Ë°¤¹¤ë¤â¤Î¤Î¤ß¡Ë
51     
52     »È¤¤Êý¤Ï bool_comparable ¤ÈƱ¤¸¡¢¡Ö¥Æ¥ó¥×¥ì¡¼¥È¤Ë¼«Ê¬¼«¿È¤Î·¿Ì¾¤òÆþ¤ì¤Æ·Ñ¾µ¡×¡£
53     ÂèÆó°ú¿ô¤Ï¥Ý¥¤¥ó¥¿¤ò³ÊǼ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î·¿¤ò¼¨¤·¤Þ¤¹¡£
54     ¾Êά²Äǽ¤ÊÂè»°°ú¿ô¤Ï¥Ý¥¤¥ó¥¿¤Î¥«¥Æ¥´¥ê¡¢Âè»°°ú¿ô¤¬Æ±¤¸¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÏÁê¸ßÈæ³Ó¤Ç¤­¤Þ¤¹¡£
55     ¾Êά¤·¤¿¾ì¹ç¡¢Â¾¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤È¤ÏÈæ³Ó¤¬½ÐÍè¤Þ¤»¤ó¡Ê¤Ç¤âÄ̾ï¤ÏÈæ³Ó¤Ç¤­¤¿Êý¤¬Îɤ¤¤Ç¤¹¤è¡©¡Ë¡£
56     ¤µ¤é¤Ë¾Ü¤·¤¯¤Ï¡¢²¼¤ÎÍó¤ä¡¢¶äÅ·¥é¥¤¥Ö¥é¥ê¤ÇÄêµÁ¤µ¤ì¤¿¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Î¼ÂÁõ¤ò¤´Í÷¤¯¤À¤µ¤¤¡£
57     
58   »È¤¤Êý¡§
59     // Ã±½ã¤Ê¥Ý¥¤¥ó¥¿¤Ø¤Î¥é¥Ã¥Ñ
60     
61     // ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤òºî¤ë¾ì¹ç¡¢¤Þ¤º¥«¥Æ¥´¥ê¥¯¥é¥¹¤òÄêµÁ¤¹¤ë¡£
62     // Æ±¤¸¼ïÎà¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Ç¡¢Æ±¤¸¥«¥Æ¥´¥ê¤ò¶¦Í­¤¹¤ë¤³¤È¤Ç¡¢
63     // ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÁê¸ßÈæ³Ó¤¬¡ÊƱ¤¸¼ïÎà¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Ë¸Â¤ê¡Ë²Äǽ¤Ë¤Ê¤ë¡£
64     struct trivial_ptr_category {}; // ¥«¥Æ¥´¥ê¥¯¥é¥¹¤Ï¥¿¥°¤Ê¤Î¤ÇŬÅö¤Ë
65     
66     // ËÜÂΠ
67     template<typename T>
68     class trivial_ptr :
69       public gintenlib::pointer_facade< trivial_ptr<T>, T, trivial_ptr_category > // ¤³¤¦»È¤¦
70     {
71      public:
72       trivial_ptr() : p(0) {}
73       explicit trivial_ptr( T* ptr ) : p( ptr ) {}
74       
75       // ²òÊü½èÍý¤È¤«¹Ô¤ï¤Ê¤¤
76       // ~trivial_ptr() throw () {}
77       
78       // get() ¤µ¤¨¤¢¤ì¤ÐOK
79       T* get() const { return p; }
80       
81       // reset ¤È¤« swap ¤â¤¢¤ë¤ÈÎɤ¤¤±¤É¡¢´ðËܤϤ³¤ì¤Ç½ªÎ»¡ª
82       
83      private:
84       T* p;
85       
86     };
87     
88     int main()
89     {
90       trivial_ptr<int> p1( new int() );
91       
92       // ¿§¡¹¤È¼«Æ°ÄêµÁ¤·¤Æ¤¯¤ì¤ë¤Î¤Ç
93       // ¤³¤ó¤Ê´¶¤¸¤Ë½ñ¤±¤ë
94       if( p1 )  // OK
95       {
96         cout << *p1 << endl; // OK
97       }
98       
99       trivial_ptr<vector<int> > p2( new vector<int>() );
100       cout << p2->size() << endl; // OK
101       
102       trivial_ptr<void> p0; // void ¤Ø¤Î¥Ý¥¤¥ó¥¿¤âŬÀڤ˿¶¤êʬ¤±¤Æ¤¯¤ì¤ë
103       assert( p0 != p1 ); // ¤â¤Á¤í¤óÈæ³Ó¤Ç¤­¤ë
104       
105       // todo: delete
106     }
107   
108   Ãí°Õ»ö¹à¡§
109     ¥Ý¥¤¥ó¥¿¤ËɬÍפʵ¡Ç½¤Ï¤¢¤é¤«¤¿ÍÑ°Õ¤·¤Æ¤¯¤ì¤ëÊØÍø¥¯¥é¥¹¤Ç¤¹¤¬¡¢
110     static_pointer_cast ¤ä¤é swap ¤ä¤é reset ¤ä¤é¤ÏÄêµÁ¤·¤Æ¤¯¤ì¤Þ¤»¤ó¡£Ëº¤ì¤Ê¤¤¤è¤¦¤Ë¡£
111     ¤Ê¤ª¡¢ friend ´Ø¿ô¤Î get_pointer ¤ä operator== ¤Ê¤ó¤«¤Ï¡¢gintenlib Ì¾Á°¶õ´ÖÆâ¤ËÄêµÁ¤µ¤ì¤Þ¤¹¡£
112     Ä̾ï¤Ï ADL ¤Ë¤è¤Ã¤Æ°Õ¼±¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¤¬¡¢¸Å¤¤¥³¥ó¥Ñ¥¤¥é¤Ç¤Ï°ú¤Ã¤«¤«¤ë¤«¤â¡£
113
114 */
115
116 #include "bool_comparable.hpp"
117
118 #include <cassert>
119 #include <boost/type_traits/add_reference.hpp>
120
121 namespace gintenlib
122 {
123   template< typename Derived, typename T, typename Category = Derived >
124   struct pointer_facade
125     : bool_comparable< pointer_facade< Derived, T, Category > >
126   {
127     // ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤È¤·¤ÆɬÍפʤ¢¤ì¤³¤ì
128     typedef T  element_type;
129     typedef T  value_type;
130     typedef T* pointer;
131     // reference ¤Ï void ·¿¤Ø¤ÎÂбþ¤Î¤¿¤áÆüì
132     typedef typename boost::add_reference<T>::type reference;
133     
134     // »²¾È³°¤·¤È¥Ý¥¤¥ó¥¿¼èÆÀ
135     reference operator*() const
136     {
137       using namespace std;
138       assert( get_() != 0 );
139       return *get_();
140     }
141     pointer operator->() const
142     {
143       using namespace std;
144       assert( get_() != 0 );
145       return get_();
146     }
147     // for boost::mem_fn
148     friend pointer get_pointer( const Derived& target )
149     {
150       return target.get();
151     }
152     
153     // bool ¤È¤ÎÈæ³Ó
154     bool operator!() const
155     {
156       return !get_();
157     }
158     // operator safe_bool ¤Ï bool_comparable ¤Î´É³í
159     
160     // ÅùÃÍÈæ³Ó¤Ê¤É¤Ï³°Éô¤Î¥Æ¥ó¥×¥ì¡¼¥È¤Ç¼ÂÁõ
161   
162    private:
163     template<typename D, typename U, typename C>
164     friend class pointer_facade;
165     
166     // ÇÉÀ¸¥¯¥é¥¹¤Î get() ¤ò¸Æ¤Ó½Ð¤¹
167     pointer get_() const
168     {
169       return static_cast<const Derived*>(this)->get();
170     }
171     
172    protected:
173      pointer_facade(){}
174     ~pointer_facade(){}
175   
176   };  // pointer_facade<Derived, T, Category>
177   
178   // ¥Æ¥ó¥×¥ì¡¼¥ÈÈÇÁê¸ßÈæ³Ó
179   // ¥«¥Æ¥´¥ê¤¬Æ±¤¸¤â¤Î¤Ê¤éÁê¸ßÈæ³Ó£Ï£Ë
180   template<typename T, typename U, typename D1, typename D2, typename C>
181   inline bool operator==( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs )
182   {
183     return static_cast<const D1&>(lhs).get() == static_cast<const D2&>(rhs).get();
184   }
185   template<typename T, typename U, typename D1, typename D2, typename C>
186   inline bool operator!=( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs )
187   {
188     return static_cast<const D1&>(lhs).get() != static_cast<const D2&>(rhs).get();
189   }
190   template<typename T, typename U, typename D1, typename D2, typename C>
191   inline bool operator< ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs )
192   {
193     // °Û¤Ê¤ë¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÈæ³Ó¤Ï¡¢
194     // boost::shared_ptr ¤Ç < ¤ò»È¤Ã¤Æ¤ë¤Î¤Ç¡¢¤³¤³¤Ç¤â < ¤ÇÈæ³Ó¤¹¤ë
195     return static_cast<const D1&>(lhs).get() < static_cast<const D2&>(rhs).get();
196   }
197
198 }   // namespace gintenlib
199
200
201 #endif  // #ifndef GINTENLIB_INCLUDED_POINTER_FACADE_HPP_