X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FSafeBool.hh;h=c0b7163f0983f319da540e0a8b56fc4452d6964d;hb=9a988902090d28007578e93bffd809f6bd913155;hp=5bde302818a4f03e2f13e095185792b7a99b0682;hpb=9248350bdd5a59799e603936d98241a1bb4591f9;p=senf.git diff --git a/Utils/SafeBool.hh b/Utils/SafeBool.hh index 5bde302..c0b7163 100644 --- a/Utils/SafeBool.hh +++ b/Utils/SafeBool.hh @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2006 +// Copyright (C) 2006 #ifndef HH_SafeBool_ #define HH_SafeBool_ 1 @@ -10,64 +10,93 @@ //#include "SafeBool.mpp" ///////////////////////////////hh.p//////////////////////////////////////// -namespace satcom { -namespace lib { - - // This is a direct copy of a safe bool solution by Bjorn Karlsson - // from http://www.artima.com/cppsource/safebool.html - // - // Usage: - // class TestableWithVirtual - // : public safe_bool<> - // { - // protected: - // bool boolean_test() const - // { - // // Perform Boolean logic here - // } - // }; - // - // class TestableWithoutVirtual - // : public safe_bool - // { - // public: - // bool boolean_test() const - // { - // // Perform Boolean logic here - // } - // }; - - class SafeBoolBase +namespace senf { + + /** \brief internal SafeBool base class + \internal + */ + class SafeBoolBase { protected: - typedef void (SafeBoolBase::*bool_type)() const; - void this_type_does_not_support_comparisons() const; + typedef void (SafeBoolBase::*bool_type)() const; + void this_type_does_not_support_comparisons() const; + + // Just here to make them protected ... - SafeBoolBase(); - SafeBoolBase(const SafeBoolBase&); - SafeBoolBase& operator=(const SafeBoolBase&); - ~SafeBoolBase(); + SafeBoolBase(); + SafeBoolBase(const SafeBoolBase&); + SafeBoolBase& operator=(const SafeBoolBase&); + ~SafeBoolBase(); }; - template - class SafeBool - : public SafeBoolBase + /** \brief Mixin class for safe boolean conversion support + + This is a direct yet simplified copy of a safe bool solution + by Bjorn Karlsson from + http://www.artima.com/cppsource/safebool.html + + This mixin provides the client class with safe boolean + testing. It is a safe replacement for operator + bool. operator bool is problematic since \c bool + is an integer type. This conversion operator makes the class + usable in any numeric context, which can be quite + dangerous. The operator void * solution is much + better in this respect but still allows two instances of any + class having such a void * conversion to be compared + for equality. This again will produce absolutely unexpected + results since it will not check whether the objects are + identical, it will only check, that both return the same + boolean state. + + This solutions solves all these problems by returning a + pointer-to-member which cannot be converted to any other + type. By providing explicit implementations of \c operator== + and \c operator!= which fail in an obvious way at compile + time, this hazard is removed. + + To make a class boolean testable, just inherit from the mixin + and implement \c boolean_test: + + \code + class Testable + : public SafeBool + { + public: + bool boolean_test() const + { + // Perform Boolean logic here + } + }; + + Testable t = ...; + + if (t) { + ... + } + \endcode + + \todo Either rename intrusive_refcount to IntrusiveRefcount or + SafeBool to safe_bool (I tend to the latter ...) + */ + template + class SafeBool + : public SafeBoolBase { public: - operator bool_type() const; - bool operator !() const; + operator bool_type() const; + bool operator !() const; protected: - ~SafeBool(); + ~SafeBool(); }; - template + template void operator==(const SafeBool& lhs,const SafeBool& rhs); - template + template void operator!=(const SafeBool& lhs,const SafeBool& rhs); -}} +} ///////////////////////////////hh.e//////////////////////////////////////// #include "SafeBool.cci" @@ -79,4 +108,8 @@ namespace lib { // Local Variables: // mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" // End: