/* mbed Microcontroller Library * Copyright (c) 2006-2013 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BLE_API_SAFE_BOOL_H_ #define BLE_API_SAFE_BOOL_H_ /* Safe bool idiom, see: http://www.artima.com/cppsource/safebool.html */ /** * @file * @addtogroup ble * @{ * @addtogroup common * @{ */ /** * Private namespace used to host details of the SafeBool implementation. */ namespace SafeBool_ { /** * Base class of all SafeBool instances. * * This nontemplate base class exists to reduce the number of instantiation of * the trueTag function. */ class base { template friend class SafeBool; protected: /** * The bool type is a pointer to method that can be used in boolean context. */ typedef void (base::*BoolType_t)() const; /** * Nonimplemented call, use to disallow conversion between unrelated types. */ void invalidTag() const; /** * Special member function that indicates a true value. */ void trueTag() const {} }; } /** * Safe conversion of objects in boolean context. * * Classes wanting evaluation of their instances in boolean context must derive * publicly from this class rather than implementing the easy to misuse * operator bool(). * * Descendant classes must implement the function bool toBool() const to enable * the safe conversion in boolean context. * * @tparam T Type of the derived class * * @code * * class A : public SafeBool { * public: * * // boolean conversion * bool toBool() const { * * } * }; * * class B : public SafeBool { * public: * * // boolean conversion * bool toBool() const { * * } * }; * * A a; * B b; * * // will compile * if(a) { * * } * * // compilation error * if(a == b) { * * } * @endcode */ template class SafeBool : public SafeBool_::base { public: /** * Bool operator implementation, derived class must provide a bool * toBool() const function. */ operator BoolType_t() const { return (static_cast(this))->toBool() ? &SafeBool::trueTag : 0; } }; /** * Avoid conversion to bool between different classes. * * @attention Will generate a compile time error if instantiated. */ template void operator==(const SafeBool& lhs,const SafeBool& rhs) { lhs.invalidTag(); // return false; } /** * Avoid conversion to bool between different classes. * * @attention Will generate a compile time error if instantiated. */ template void operator!=(const SafeBool& lhs,const SafeBool& rhs) { lhs.invalidTag(); // return false; } /** * @} * @} */ #endif /* BLE_API_SAFE_BOOL_H_ */