LCOV - code coverage report
Current view: top level - DCPS - SafeBool_T.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 12 13 92.3 %
Date: 2023-04-30 01:32:43 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /**
       2             :  * \file
       3             :  * Implements the "Safe Bool" idiom, which is a safer alternative to operator
       4             :  * bool. Based on:
       5             :  *   https://www.artima.com/articles/the-safe-bool-idiom
       6             :  * TLDR: We may want to be able to use `operator bool()` to check an object's
       7             :  * abstract truthfulness using `if (object) {...}`, but that opens up implicit
       8             :  * casting and comparisons that come with the bool type that are almost
       9             :  * certainly not desired, like `int count = object`. This is achieved via the
      10             :  * BoolType function pointer which isn't actually called, but is the only
      11             :  * boolean-ish thing the type can be implicitly converted to using the BoolType
      12             :  * operator.
      13             :  *
      14             :  * If you want the boolean test function to be virtual, implement it as:
      15             :  *   virtual bool boolean_test() const;
      16             :  * and derive the class from SafeBool_T with no template argument:
      17             :  *   class YourClass : public SafeBool_T<>.
      18             :  *
      19             :  * If you do NOT want the boolean test function to be virtual, implement it as:
      20             :  *   bool boolean_test() const;
      21             :  * and derive the class from SafeBool_T with the class as the template argument:
      22             :  *   class YourClass : public SafeBool_T<YourClass>.
      23             :  */
      24             : 
      25             : #ifndef OPENDDS_DCPS_SAFE_BOOL_T_H
      26             : #define OPENDDS_DCPS_SAFE_BOOL_T_H
      27             : 
      28             : #include <dds/Versioned_Namespace.h>
      29             : 
      30             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      31             : 
      32             : namespace OpenDDS {
      33             : namespace DCPS {
      34             : 
      35             : class SafeBoolBase {
      36             : public:
      37             :   typedef void (SafeBoolBase::*BoolType)() const;
      38           0 :   void this_type_does_not_support_comparisons() const {}
      39             : 
      40             : protected:
      41        2904 :   SafeBoolBase() {}
      42         870 :   SafeBoolBase(const SafeBoolBase&) {}
      43         764 :   SafeBoolBase& operator=(const SafeBoolBase&) {return *this;}
      44        3774 :   ~SafeBoolBase() {}
      45             : };
      46             : 
      47             : template <typename DerivedNonVirtual = void>
      48             : class SafeBool_T : public SafeBoolBase {
      49             : public:
      50          93 :   operator BoolType() const
      51             :   {
      52          93 :     return (static_cast<const DerivedNonVirtual*>(this))->boolean_test()
      53          93 :       ? &SafeBoolBase::this_type_does_not_support_comparisons : 0;
      54             :   }
      55             : 
      56             : protected:
      57        3772 :   ~SafeBool_T() {}
      58             : };
      59             : 
      60             : template<>
      61             : class SafeBool_T<void> : public SafeBoolBase {
      62             : public:
      63           3 :   operator BoolType() const
      64             :   {
      65           3 :     return boolean_test() ?
      66           3 :       &SafeBoolBase::this_type_does_not_support_comparisons : 0;
      67             :   }
      68             : 
      69             : protected:
      70             :   virtual bool boolean_test() const = 0;
      71           2 :   virtual ~SafeBool_T() {}
      72             : };
      73             : 
      74             : template <typename X, typename Y>
      75             : bool operator==(const SafeBool_T<X>& x, const SafeBool_T<Y>&)
      76             : {
      77             :   x.this_type_does_not_support_comparisons();
      78             :   return false;
      79             : }
      80             : 
      81             : template <typename X, typename Y>
      82             : bool operator!=(const SafeBool_T<X>& x, const SafeBool_T<Y>&)
      83             : {
      84             :   x.this_type_does_not_support_comparisons();
      85             :   return false;
      86             : }
      87             : 
      88             : } // namespace DCPS
      89             : } // namespace OpenDDS
      90             : 
      91             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
      92             : 
      93             : #endif

Generated by: LCOV version 1.16