svn:keywords property set
[senf.git] / Utils / SafeBool.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief SafeBool public header */
23
24 #ifndef HH_SafeBool_
25 #define HH_SafeBool_ 1
26
27 // Custom includes
28
29 //#include "SafeBool.mpp"
30 ///////////////////////////////hh.p////////////////////////////////////////
31
32 namespace senf {
33
34     /** \brief internal SafeBool base class
35         \internal
36      */
37     class SafeBoolBase
38     {
39     protected:
40         typedef void (SafeBoolBase::*bool_type)() const;
41         void this_type_does_not_support_comparisons() const;
42
43         // Just here to make them protected ...
44
45         SafeBoolBase();
46         SafeBoolBase(const SafeBoolBase&);
47         SafeBoolBase& operator=(const SafeBoolBase&);
48         ~SafeBoolBase();
49     };
50
51     /** \brief Mixin class for safe boolean conversion support
52
53         This is a direct yet simplified copy of a safe bool solution
54         by Bjorn Karlsson from
55         http://www.artima.com/cppsource/safebool.html
56
57         This mixin provides the client class with safe boolean
58         testing. It is a safe replacement for <tt>operator
59         bool</tt>. <tt>operator bool</tt> is problematic since \c bool
60         is an integer type. This conversion operator makes the class
61         usable in any numeric context, which can be quite
62         dangerous. The <tt>operator void *</tt> solution is much
63         better in this respect but still allows two instances of any
64         class having such a <tt>void *</tt> conversion to be compared
65         for equality. This again will produce absolutely unexpected
66         results since it will not check whether the objects are
67         identical, it will only check, that both return the same
68         boolean state.
69
70         This solutions solves all these problems by returning a
71         pointer-to-member which cannot be converted to any other
72         type. By providing explicit implementations of \c operator==
73         and \c operator!= which fail in an obvious way at compile
74         time, this hazard is removed.
75
76         To make a class boolean testable, just inherit from the mixin
77         and implement \c boolean_test:
78
79         \code
80         class Testable
81             : public SafeBool<Testable>
82         {
83         public:
84             bool boolean_test() const
85             {
86                 // Perform Boolean logic here
87             }
88         };
89
90         Testable t = ...;
91
92         if (t) {
93            ...
94         }
95         \endcode
96
97         \todo Either rename intrusive_refcount to IntrusiveRefcount or
98         SafeBool to safe_bool (I tend to the latter ...)
99      */
100     template <typename T>
101     class ComparableSafeBool
102         : public SafeBoolBase
103     {
104     public:
105         operator bool_type() const;
106         bool operator !() const;
107
108     protected:
109         ~ComparableSafeBool();
110     };
111
112     template <typename T>
113     class SafeBool : public ComparableSafeBool<T> {};
114
115     template <typename T, typename U>
116     void operator==(const SafeBool<T>& lhs,const SafeBool<U>& rhs);
117
118     template <typename T,typename U>
119     void operator!=(const SafeBool<T>& lhs,const SafeBool<U>& rhs);
120
121 }
122
123 ///////////////////////////////hh.e////////////////////////////////////////
124 #include "SafeBool.cci"
125 //#include "SafeBool.ct"
126 #include "SafeBool.cti"
127 //#include "SafeBool.mpp"
128 #endif
129
130 \f
131 // Local Variables:
132 // mode: c++
133 // fill-column: 100
134 // c-file-style: "senf"
135 // indent-tabs-mode: nil
136 // ispell-local-dictionary: "american"
137 // compile-command: "scons -u test"
138 // comment-column: 40
139 // End: