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