1 #ifndef GINTENLIB_INCLUDED_BOOL_COMPARABLE_HPP_
2 #define GINTENLIB_INCLUDED_BOOL_COMPARABLE_HPP_
5 bool_comparable : safe_bool¥¤¥Ç¥£¥ª¥àÄó¶¡
8 template<typename Derived>
13 operator unspecified_bool_type() const;
14 // ÇÉÀ¸¤·¤¿¥¯¥é¥¹¤Î¦¤Ç operator! ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢
15 // ÇÉÀ¸¤·¤¿¥¯¥é¥¹¤Î boolean_test() ¥á¥ó¥Ð´Ø¿ô¤¬¤¢¤ì¤Ð¤½¤ÎÈÝÄê¤òÊÖ¤¹¡£
16 // operator!() ¤â boolean_test() ¤â¤Ê¤±¤ì¤Ð¡¢¥¨¥é¡¼
17 bool operator!() const;
19 // bool ¤È¤ÎÈæ³Ó¡£ int ¤Î¤È¤¤ÏÈ¿±þ¤·¤Ê¤¤¤è¤¦¤Ë¤Ê¤Ã¤Æ¤Þ¤¹
20 friend bool operator==( const bool_comparable& lhs, bool rhs );
21 friend bool operator==( bool lhs, const bool_comparable& rhs );
22 friend bool operator!=( const bool_comparable& lhs, bool rhs );
23 friend bool operator!=( bool lhs, const bool_comparable& rhs );
29 }; // class bool_comparable<Derived>
32 // ¾¡¢¸Æ¤Ó½Ð¤µ¤ì¤ë¤È¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼¤Ë¤Ê¤ë operator== ¤È operator!= ¤¬Àë¸À¤µ¤ì¤Æ¤¤¤Þ¤¹
35 boost::operators ¤ß¤¿¤¤¤Ê´¶¤¸¤Ë¡¢´Êñ¤Ë safe_bool ¥¤¥Ç¥£¥ª¥à¤ò¼Â¸½¤·¤Þ¤¹¡£
36 »ÈÍÑË¡¤Ï¡¢bool_comparable ¤Î¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¤ËÀ½ºî¤¹¤ë¥¯¥é¥¹¤Î̾Á°¤òÆþ¤ì¤Æ public ·Ñ¾µ¡£
37 ¤½¤·¤ÆÀ½ºî¤¹¤ë¥¯¥é¥¹¤Ë¡¢
38 bool operator!() const;
40 bool boolean_test() const;
41 ´Ø¿ô¤Î¤É¤Á¤é¤«¤òÄêµÁ¤¹¤ì¤Ð£Ï£Ë¤Ç¤¹¡ÊξÊý¤¢¤ë¾ì¹ç¤Ï operator!() ¤¬Í¥À褵¤ì¤Þ¤¹¡Ë¡£
44 // Îã¤È¤·¤Æ boost::optional Ū¤Ê²¿¤«¤òºî¤ê¤Þ¤·¤ç¤¦
45 #include <boost/scoped_ptr.hpp>
49 : public gintenlib::bool_comparable< my_optional<T> > // ¤³¤Î¤è¤¦¤Ë»È¤¦
51 // ËÜÂÎÉôʬ¤Ï¤Ê¤ó¤éµ¤¤Ë¤»¤º½ñ¤¤¤Æ¤è¤¤
56 typedef const T& const_reference;
58 my_optional() : p() {}
59 my_optional( const T& x ) : p( new T(x) ) {}
61 reference operator*() { return *p; }
62 const_reference operator*() const { return *p; }
64 // operator!() ¤ò³Î¼Â¤Ë¼ÂÁõ¤¹¤ë¤³¤È¤ò˺¤ì¤Ê¤±¤ì¤Ð¡£
65 bool operator!() const
69 // ¤³¤ì¤Ë¤è¤ê¡¢boolÈæ³Ó¤â½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤ë
71 // ¤Á¤Ê¤ß¤Ë operator!() ¤¸¤ã¤Ê¤¯¤Æ
72 // bool boolean_test() const { return p.get(); }
73 // ¤³¤ì¤Ç¤â¤¤¤¤¡Ê¤½¤Î¾ì¹ç¡¢operator! ¤Ï¼«Æ°ÄêµÁ¡Ë
75 // ¤½¤Î¤Û¤«¡¢¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿¤È¤«ÂåÆþ±é»»»Ò¤È¤«¤ÏÌÌÅݤÀ¤«¤é¾Êά
78 // ÌÌÅݤʥݥ¤¥ó¥¿´ÉÍý¤È¤«¤·¤¿¤¯¤Ê¤¤¤Î¤Ç scoped_ptr ¤ò»È¤¦
79 boost::scoped_ptr<T> p;
85 my_optional<int> a, b(1), c(0);
90 assert( !"a is empty." );
93 // && ¤ä || ¤ÈÁȤ߹ç¤ï¤»¤Æ
97 assert( a == 0 && b != 0 && c != 0 );
98 // assert( b == 1 ); // 1 ¤È¤ÏÈæ³Ó¤Ç¤¤Ê¤¤
101 assert( a == false && b == true && c == true );
103 assert( static_cast<bool>(b) == static_cast<bool>(c) );
104 // assert( a != b ); // ¥³¥ì¤Ï¥À¥á¡Ê¤â¤· b ¤È c ¤òÈæ³Ó¤·¤¿¤é¡©¡Ë
107 ¡¦boost::enable_if ¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£¸Å¤¤¥³¥ó¥Ñ¥¤¥é¤Ç¤ÏÆ°¤¤Þ¤»¤ó¡£
108 ¡¦¤½¤ì¤¬·ù¤Ê¤é GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF ¥Þ¥¯¥í¤òÄêµÁ¤¹¤ì¤Ð£Ï£Ë¤Ç¤¹¡£
109 ¡¦¤¿¤À¤·¡¢¤½¤Î¾ì¹ç¡¢¾å¤ÎÎã¤Ç¤Î¡Öb == 1¡×Ū¤Êɽ¸½¤¬¥³¥ó¥Ñ¥¤¥ëÄ̤äƤ·¤Þ¤¤¤Þ¤¹¡£
111 ¡¦¡Ö a == b ¡×¤Î¤è¤¦¤Ê¡¢ÇÉÀ¸Àè¤Î¥¯¥é¥¹Æ±»Î¤Ç¤ÎÈæ³Ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼¤Ë¤Ê¤ê¤Þ¤¹¡£
112 ¡¦¤Ç¤¹¤¬¡¢ÅöÁ³¡¢ÇÉÀ¸Àè¤Ç operator== ¤òÄêµÁ¤·¤Æ¤ª¤±¤Ð¡¢¤¤Á¤ó¤ÈÈæ³Ó¤Ç¤¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
113 ¡¦¤¿¤À¤·¡¢ÇÉÀ¸Àè¤Î¥¯¥é¥¹¤¬¡Ö 0 ¤«¤é°ÅÌÛÊÑ´¹²Äǽ¡×¤Ç¤¢¤ê¡Öoperator==¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡×¾ì¹ç¤Ï¡¢
114 ¡Ö x == 0 ¡×¤Î¤è¤¦¤ÊÈæ³Ó¤¬¡¢¥¼¥í¤È¤ÎÈæ³Ó¤Ë¸Â¤ê¤Ç¤¹¤¬¡¢½ÐÍè¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹:
115 struct convertible_from_int
116 : gintenlib::bool_comparable<convertible_from_int>,
117 private boost::equality_comparable<convertible_from_int>
120 convertible_from_int( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¤È¡¦¡¦¡¦
122 bool operator!() const { return value == 0; }
124 // operator== ¤Ë¤è¤ëÈæ³Ó¤¬½ÐÍè¤ë¾ì¹ç
125 friend bool operator==( const convertible_from_int& lhs, const convertible_from_int& rhs )
127 return lhs.value == rhs.value;
134 convertible_from_int x, y = 2;
135 assert( !x ); // ¤³¤¦¤¤¤¦¤Î¤ÏÉáÄ̤˽ÐÍè¤ë¤¬
137 assert( x == false );
140 // assert( x == 0 ); // ¥³¥ì¤¬¼Â¹Ô¤Ç¤¤Ê¤¤¡ÊÛ£Ëæ¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¡Ë
141 // assert( y != 0 ); // ÅöÁ³¤³¤ì¤â¥À¥á
143 assert( y == 2 ); // ¤Ç¤â¥³¥ì¤Ï£Ï£Ë
144 assert( x != 1 ); // ¥³¥ì¤â£Ï£Ë
147 ¡¦¤½¤Î¾ì¹ç¤Ï int ¤È¤ÎÈæ³Ó¤òÊ̸ÄÄêµÁ¤·¤Æ¤ä¤ì¤Ð£Ï£Ë¤Ç¤¹¡§
148 struct convertible_from_int
149 : gintenlib::bool_comparable<convertible_from_int>,
150 private boost::equality_comparable<convertible_from_int>,
151 private boost::equality_comparable<convertible_from_int, int>
154 convertible_from_int( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¾ì¹ç¤Ç¤â
156 bool boolean_test() const { return value; } // boolean_test ¤ò»È¤Ã¤Æ¤ß¤ë¡£
158 friend bool operator==( const piyo& lhs, const piyo& rhs )
160 return lhs.value == rhs.value;
162 // int ¤È¤ÎÈæ³Ó¤òÌÀ¼¨Åª¤ËÄêµÁ¤µ¤¨¤¹¤ì¤Ð
163 friend bool operator==( const convertible_from_int& lhs, int rhs )
165 return lhs.value == rhs;
172 convertible_from_int x, y(2)
173 assert( x == 0 ); // £Ï£Ë
179 #ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
180 #include "enable_if.hpp"
181 #include <boost/type_traits/is_same.hpp>
187 struct bool_comparable_helper
189 // operator bool_type() ¤ÎÌá¤êÃͤȤ·¤Æ»È¤ï¤ì¤ëÃÍ
190 void bool_value() const {}
193 // ¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼¤òµ¯¤³¤¹¤¿¤á¤Î private ´Ø¿ô
194 bool this_type_does_not_support_comparisons_();
199 template<typename Derived>
200 class bool_comparable
202 // safe-bool ¤Ë»È¤¦·¿¡Ê¥á¥ó¥Ð´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¡Ë
203 typedef void (bool_comparable::*bool_type)() const;
205 // ÇÉÀ¸¤·¤¿¥¯¥é¥¹¤òÆÀ¤ë´Ø¿ô
206 const Derived& derived() const { return *static_cast<const Derived*>(this); }
207 Derived& derived() { return *static_cast< Derived*>(this); }
209 // ¾¤Î¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤â derived ¤Ï»È¤¤¤¿¤¤¤¼
210 template<typename U> friend class bool_comparable;
214 operator bool_type() const
216 return bool_test_() ? bool_value_() : 0;
217 // bool_test_, bool_value_ ¤Ï¸å¤ÇÄêµÁ¤¹¤ë
222 #ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
224 // enable_if ¤Ç bool ¤ÈÈæ³Ó¤¹¤ë»þ¤À¤±Í¸ú¤Ë¤¹¤ë¤³¤È¤Ç¡¢x == 1 ¤Î¤è¤¦¤ÊÈæ³Ó¤ò̵Îϲ½¤¹¤ë
225 // todo: g++ °Ê³°¤Î¥³¥ó¥Ñ¥¤¥é¤Ç¤ÎÆ°ºî¥Á¥§¥Ã¥¯
229 friend typename enable_if<boost::is_same<U, bool>, bool>::type
230 operator==( const Derived& lhs, U rhs )
232 return static_cast<bool>(lhs) == rhs;
235 friend typename enable_if<boost::is_same<U, bool>, bool>::type
236 operator==( U lhs, const Derived& rhs )
238 return lhs == static_cast<bool>(rhs);
241 friend typename enable_if<boost::is_same<U, bool>, bool>::type
242 operator!=( const Derived& lhs, U rhs )
244 return static_cast<bool>(lhs) != rhs;
247 friend typename enable_if<boost::is_same<U, bool>, bool>::type
248 operator!=( U lhs, const Derived& rhs )
250 return lhs != static_cast<bool>(rhs);
253 #else // #ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
255 // °ì±þ enable_if ¤ò»È¤ï¤Ê¤¤ÈǤâÍÑ°Õ
256 // ¤³¤Î¾ì¹ç¡¢ x == 1 ¤Î¤è¤¦¤Êɽ¸½¤¬Ä̤äƤ·¤Þ¤¦¤¬»ÅÊý¤Ê¤¤¤Í
257 friend bool operator==( const Derived& lhs, bool rhs )
259 return static_cast<bool>(lhs) == rhs;
261 friend bool operator==( bool lhs, const Derived& rhs )
263 return lhs == static_cast<bool>(rhs);
265 friend bool operator!=( const Derived& lhs, bool rhs )
267 return static_cast<bool>(lhs) != rhs;
269 friend bool operator!=( bool lhs, const Derived& rhs )
271 return lhs != static_cast<bool>(rhs);
274 #endif // #ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
278 // bool_type ¤È¤·¤ÆÊÖ¤¹ÃÍ
279 static bool_type bool_value_()
281 // ´Ø¿ô¤ò̵Â̤˺î¤é¤»¤Ê¤¤¹©Éס£¤É¤¦¤» bool_type ¤ÎÃͤϻȤï¤Ê¤¤¤·
282 return reinterpret_cast<bool_type>( &bool_comparable_helper::bool_value );
286 // ¤Þ¤º Derived::operator!() ¤ò¸«¤Ë¹Ô¤¯
287 bool bool_test_() const
289 return !( !derived() );
293 // Derived ¦¤Ç operator!() ¤¬ÄêµÁ¤µ¤ì¤Æ̵¤¤¤Ê¤é
294 // Derived::boolean_test() ´Ø¿ô¤¬¤Ê¤¤¤«Ãµ¤·¡¢Ìµ¤±¤ì¤Ð¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼
295 bool operator!() const
297 return !( derived().boolean_test() );
299 // friend ´Ø¿ôÈÇ¡£Â¸ºß¤¹¤ë°ÕÌ£¤ÏÆäË̵¤¤¡£
300 friend bool boolean_test( const bool_comparable& x )
302 return x.bool_test_();
305 // Èæ³Ó¤Ï¥¨¥é¡¼¤Ë¤Ê¤ë¡Ê Derived ¦¤ÇÆÃÊ̤ËÄêµÁ¤¹¤ì¤Ð£Ï£Ë¡Ë
308 friend bool operator==( const bool_comparable& lhs, const bool_comparable& rhs )
310 return bool_comparable_helper().this_type_does_not_support_comparisons_();
313 friend bool operator!=( const bool_comparable& lhs, const bool_comparable& rhs )
315 return bool_comparable_helper().this_type_does_not_support_comparisons_();
319 // ÇÉÀ¸¥¯¥é¥¹°Ê³°¤«¤é¤Î¹½Ã۶ػß
321 ~bool_comparable() {}
323 }; // class bool_comparable<Derived>
325 } // namespace gintenlib
327 #endif // #ifndef GINTENLIB_INCLUDED_BOOL_COMPARABLE_HPP_