f1786964c525d197449283e00c107feaee87a4ce
[senf.git] / senf / Utils / safe_bool.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
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 safe_bool public header */
25
26 #ifndef HH_SENF_Utils_safe_bool_
27 #define HH_SENF_Utils_safe_bool_ 1
28
29 // Custom includes
30
31 //#include "safe_bool.mpp"
32 ///////////////////////////////hh.p////////////////////////////////////////
33
34 namespace senf {
35
36     /** \brief internal safe_bool base class
37         \internal
38
39         \see safe_bool
40      */
41     class safe_bool_base
42     {
43     protected:
44         typedef void (safe_bool_base::*bool_type)() const;
45         void this_type_does_not_support_comparisons() const;
46
47         // Just here to make them protected ...
48
49         safe_bool_base();
50         safe_bool_base(const safe_bool_base&);
51         safe_bool_base& operator=(const safe_bool_base&);
52         ~safe_bool_base();
53     };
54
55     /** \brief Mixin class for safe bool conversion support (comparable classes)
56
57         \see safe_bool
58      */
59     template <typename T>
60     class comparable_safe_bool
61         : public safe_bool_base
62     {
63     public:
64         operator bool_type() const;
65         bool operator !() const;
66
67     protected:
68         ~comparable_safe_bool();
69     };
70
71     /** \brief Mixin class for safe boolean conversion support
72
73         This is a direct yet simplified copy of a safe bool solution by Bjorn Karlsson from
74         http://www.artima.com/cppsource/safebool.html
75
76         This mixin provides the client class with safe boolean testing. It is a safe replacement for
77         <tt>operator bool</tt>. <tt>operator bool</tt> is problematic since \c bool is an integer
78         type. This conversion operator makes the class usable in any numeric context, which can be
79         quite dangerous. The <tt>operator void *</tt> solution is much better in this respect but
80         still allows two instances of any class having such a <tt>void *</tt> conversion to be
81         compared for equality. This again will produce absolutely unexpected results since it will
82         not check whether the objects are identical, it will only check, that both return the same
83         boolean state.
84
85         This solutions solves all these problems by returning a pointer-to-member which cannot be
86         converted to any other type. By providing explicit implementations of \c operator== and \c
87         operator!= which fail in an obvious way at compile time, this hazard is removed.
88
89         To make a class boolean testable, just inherit from the mixin and implement \c boolean_test:
90
91         \code
92         class Testable
93             : public safe_bool<Testable>
94         {
95         public:
96             bool boolean_test() const
97             {
98                 // Perform Boolean logic here
99             }
100         };
101
102         Testable t = ...;
103
104         if (t) {
105            ...
106         }
107         \endcode
108
109         If the class to be made using senf::safe_bool is itself comparable via it's own \c
110         operator==, you must use comparable_safe_bool instead of safe_bool to not loose this
111         capability.
112
113         \see comparable_safe_bool
114      */
115     template <typename T>
116     class safe_bool : public comparable_safe_bool<T> {};
117
118     template <typename T, typename U>
119     void operator==(const safe_bool<T>& lhs,const safe_bool<U>& rhs);
120
121     template <typename T,typename U>
122     void operator!=(const safe_bool<T>& lhs,const safe_bool<U>& rhs);
123
124 }
125
126 ///////////////////////////////hh.e////////////////////////////////////////
127 #include "safe_bool.cci"
128 //#include "safe_bool.ct"
129 #include "safe_bool.cti"
130 //#include "safe_bool.mpp"
131 #endif
132
133 \f
134 // Local Variables:
135 // mode: c++
136 // fill-column: 100
137 // c-file-style: "senf"
138 // indent-tabs-mode: nil
139 // ispell-local-dictionary: "american"
140 // compile-command: "scons -u test"
141 // comment-column: 40
142 // End: