Fixed whitespace in all files (no tabs)
[senf.git] / Utils / SafeBool.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4
5 #ifndef HH_SafeBool_
6 #define HH_SafeBool_ 1
7
8 // Custom includes
9
10 //#include "SafeBool.mpp"
11 ///////////////////////////////hh.p////////////////////////////////////////
12
13 namespace senf {
14
15     /** \brief internal SafeBool base class
16         \internal
17      */
18     class SafeBoolBase
19     {
20     protected:
21         typedef void (SafeBoolBase::*bool_type)() const;
22         void this_type_does_not_support_comparisons() const;
23
24         // Just here to make them protected ...
25
26         SafeBoolBase();
27         SafeBoolBase(const SafeBoolBase&);
28         SafeBoolBase& operator=(const SafeBoolBase&);
29         ~SafeBoolBase();
30     };
31
32     /** \brief Mixin class for safe boolean conversion support
33
34         This is a direct yet simplified copy of a safe bool solution
35         by Bjorn Karlsson from
36         http://www.artima.com/cppsource/safebool.html
37
38         This mixin provides the client class with safe boolean
39         testing. It is a safe replacement for <tt>operator
40         bool</tt>. <tt>operator bool</tt> is problematic since \c bool
41         is an integer type. This conversion operator makes the class
42         usable in any numeric context, which can be quite
43         dangerous. The <tt>operator void *</tt> solution is much
44         better in this respect but still allows two instances of any
45         class having such a <tt>void *</tt> conversion to be compared
46         for equality. This again will produce absolutely unexpected
47         results since it will not check wethere the objects are
48         identical, it will only check, that both return the same
49         boolean state.
50
51         This solutions solves all these problems by returning a
52         pointer-to-member which cannot be converted to any other
53         type. By providing explicit implementations of \c operator==
54         and \c operator!= which fail in an obvious way at compile
55         time, this hazard is removed.
56
57         To make a class boolean testable, just inherit from the mixin
58         and implement \c boolean_test:
59
60         \code
61         class Testable
62             : public SafeBool<Testable>
63         {
64         public:
65             bool boolean_test() const
66             {
67                 // Perform Boolean logic here
68             }
69         };
70
71         Testable t = ...;
72
73         if (t) {
74            ...
75         }
76         \endcode
77
78         \todo Either rename intrusive_refcount to IntrusiveRefcount or
79         SafeBool to safe_bool (I tend to the latter ...)
80      */
81     template <typename T>
82     class SafeBool
83         : public SafeBoolBase
84     {
85     public:
86         operator bool_type() const;
87         bool operator !() const;
88
89     protected:
90         ~SafeBool();
91     };
92
93     template <typename T, typename U>
94     void operator==(const SafeBool<T>& lhs,const SafeBool<U>& rhs);
95
96     template <typename T,typename U>
97     void operator!=(const SafeBool<T>& lhs,const SafeBool<U>& rhs);
98
99 }
100
101 ///////////////////////////////hh.e////////////////////////////////////////
102 #include "SafeBool.cci"
103 //#include "SafeBool.ct"
104 #include "SafeBool.cti"
105 //#include "SafeBool.mpp"
106 #endif
107
108 \f
109 // Local Variables:
110 // mode: c++
111 // fill-column: 100
112 // c-file-style: "senf"
113 // indent-tabs-mode: nil
114 // ispell-local-dictionary: "american"
115 // End: