switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / safe_bool.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief safe_bool public header */
30
31 #ifndef HH_SENF_Utils_safe_bool_
32 #define HH_SENF_Utils_safe_bool_ 1
33
34 // Custom includes
35
36 //#include "safe_bool.mpp"
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38
39 namespace senf {
40
41     /** \brief internal safe_bool base class
42         \internal
43
44         \see safe_bool
45      */
46     class safe_bool_base
47     {
48     protected:
49         typedef void (safe_bool_base::*bool_type)() const;
50         void this_type_does_not_support_comparisons() const;
51
52         // Just here to make them protected ...
53
54         safe_bool_base();
55         safe_bool_base(const safe_bool_base&);
56         safe_bool_base& operator=(const safe_bool_base&);
57         ~safe_bool_base();
58     };
59
60     /** \brief Mixin class for safe bool conversion support (comparable classes)
61
62         \see safe_bool
63      */
64     template <typename T>
65     class comparable_safe_bool
66         : public safe_bool_base
67     {
68     public:
69         operator bool_type() const;
70         bool operator !() const;
71
72     protected:
73         ~comparable_safe_bool();
74     };
75
76     /** \brief Mixin class for safe boolean conversion support
77
78         This is a direct yet simplified copy of a safe bool solution by Bjorn Karlsson from
79         http://www.artima.com/cppsource/safebool.html
80
81         This mixin provides the client class with safe boolean testing. It is a safe replacement for
82         <tt>operator bool</tt>. <tt>operator bool</tt> is problematic since \c bool is an integer
83         type. This conversion operator makes the class usable in any numeric context, which can be
84         quite dangerous. The <tt>operator void *</tt> solution is much better in this respect but
85         still allows two instances of any class having such a <tt>void *</tt> conversion to be
86         compared for equality. This again will produce absolutely unexpected results since it will
87         not check whether the objects are identical, it will only check, that both return the same
88         boolean state.
89
90         This solutions solves all these problems by returning a pointer-to-member which cannot be
91         converted to any other type. By providing explicit implementations of \c operator== and \c
92         operator!= which fail in an obvious way at compile time, this hazard is removed.
93
94         To make a class boolean testable, just inherit from the mixin and implement \c boolean_test:
95
96         \code
97         class Testable
98             : public safe_bool<Testable>
99         {
100         public:
101             bool boolean_test() const
102             {
103                 // Perform Boolean logic here
104             }
105         };
106
107         Testable t = ...;
108
109         if (t) {
110            ...
111         }
112         \endcode
113
114         If the class to be made using senf::safe_bool is itself comparable via it's own \c
115         operator==, you must use comparable_safe_bool instead of safe_bool to not loose this
116         capability.
117
118         \see comparable_safe_bool
119      */
120     template <typename T>
121     class safe_bool : public comparable_safe_bool<T> {};
122
123     template <typename T, typename U>
124     void operator==(const safe_bool<T>& lhs,const safe_bool<U>& rhs);
125
126     template <typename T,typename U>
127     void operator!=(const safe_bool<T>& lhs,const safe_bool<U>& rhs);
128
129 }
130
131 //-/////////////////////////////////////////////////////////////////////////////////////////////////
132 #include "safe_bool.cci"
133 //#include "safe_bool.ct"
134 #include "safe_bool.cti"
135 //#include "safe_bool.mpp"
136 #endif
137
138 \f
139 // Local Variables:
140 // mode: c++
141 // fill-column: 100
142 // c-file-style: "senf"
143 // indent-tabs-mode: nil
144 // ispell-local-dictionary: "american"
145 // compile-command: "scons -u test"
146 // comment-column: 40
147 // End: