LCOV - app.info - objdir/dist/include/mozilla/GuardObjects.h

LCOV - code coverage report
| Current view: | directory - objdir/dist/include/mozilla - GuardObjects.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 15 | 15 | 100.0 %
| Date: | 2012-04-07 | Functions: | 6 | 6 | 100.0 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
           2                 : /* vim: set ts=8 sw=4 et tw=99 ft=cpp: */
           3                 : /* ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is mozilla.org code.
          17                 :  *
          18                 :  * The Initial Developer of the Original Code is
          19                 :  * the Mozilla Foundation.
          20                 :  * Portions created by the Initial Developer are Copyright (C) 2010
          21                 :  * the Initial Developer. All Rights Reserved.
          22                 :  *
          23                 :  * Contributor(s):
          24                 :  *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation (original author)
          25                 :  *   Ms2ger <ms2ger@gmail.com>
          26                 :  *
          27                 :  * Alternatively, the contents of this file may be used under the terms of
          28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          31                 :  * of those above. If you wish to allow use of your version of this file only
          32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          33                 :  * use your version of this file under the terms of the MPL, indicate your
          34                 :  * decision by deleting the provisions above and replace them with the notice
          35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          36                 :  * the provisions above, a recipient may use your version of this file under
          37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          38                 :  *
          39                 :  * ***** END LICENSE BLOCK ***** */
          40                 :
          41                 : /* Implementation of macros to ensure correct use of RAII Auto* objects. */
          42                 :
          43                 : #ifndef mozilla_GuardObjects_h
          44                 : #define mozilla_GuardObjects_h
          45                 :
          46                 : #include "mozilla/Assertions.h"
          47                 : #include "mozilla/Types.h"
          48                 :
          49                 : #ifdef __cplusplus
          50                 :
          51                 : #ifdef DEBUG
          52                 :
          53                 : namespace mozilla {
          54                 : namespace detail {
          55                 : /*
          56                 :  * The following classes are designed to cause assertions to detect
          57                 :  * inadvertent use of guard objects as temporaries. In other words,
          58                 :  * when we have a guard object whose only purpose is its constructor and
          59                 :  * destructor (and is never otherwise referenced), the intended use
          60                 :  * might be:
          61                 :  *
          62                 :  *     AutoRestore savePainting(mIsPainting);
          63                 :  *
          64                 :  * but is is easy to accidentally write:
          65                 :  *
          66                 :  *     AutoRestore(mIsPainting);
          67                 :  *
          68                 :  * which compiles just fine, but runs the destructor well before the
          69                 :  * intended time.
          70                 :  *
          71                 :  * They work by adding (#ifdef DEBUG) an additional parameter to the
          72                 :  * guard object's constructor, with a default value, so that users of
          73                 :  * the guard object's API do not need to do anything. The default value
          74                 :  * of this parameter is a temporary object. C++ (ISO/IEC 14882:1998),
          75                 :  * section 12.2 [class.temporary], clauses 4 and 5 seem to assume a
          76                 :  * guarantee that temporaries are destroyed in the reverse of their
          77                 :  * construction order, but I actually can't find a statement that that
          78                 :  * is true in the general case (beyond the two specific cases mentioned
          79                 :  * there). However, it seems to be true.
          80                 :  *
          81                 :  * These classes are intended to be used only via the macros immediately
          82                 :  * below them:
          83                 :  *
          84                 :  *   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER declares (ifdef DEBUG) a member
          85                 :  *     variable, and should be put where a declaration of a private
          86                 :  *     member variable would be placed.
          87                 :  *   MOZ_GUARD_OBJECT_NOTIFIER_PARAM should be placed at the end of the
          88                 :  *     parameters to each constructor of the guard object; it declares
          89                 :  *     (ifdef DEBUG) an additional parameter. (But use the *_ONLY_PARAM
          90                 :  *     variant for constructors that take no other parameters.)
          91                 :  *   MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL should likewise be used in
          92                 :  *     the implementation of such constructors when they are not inline.
          93                 :  *   MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT should be used in
          94                 :  *     the implementation of such constructors to pass the parameter to
          95                 :  *     a base class that also uses these macros
          96                 :  *   MOZ_GUARD_OBJECT_NOTIFIER_INIT is a statement that belongs in each
          97                 :  *     constructor. It uses the parameter declared by
          98                 :  *     MOZ_GUARD_OBJECT_NOTIFIER_PARAM.
          99                 :  *
         100                 :  * For more details, and examples of using these macros, see
         101                 :  * https://developer.mozilla.org/en/Using_RAII_classes_in_Mozilla
         102                 :  */
         103                 : class MOZ_EXPORT_API(GuardObjectNotifier)
         104                 : {
         105                 :   private:
         106                 :     bool* statementDone;
         107                 :
         108                 :   public:
         109         3748465 :     GuardObjectNotifier() : statementDone(NULL) {}
         110                 :
         111         3748443 :     ~GuardObjectNotifier() {
         112         3748443 :         *statementDone = true;
         113         3748443 :     }
         114                 :
         115         3748445 :     void setStatementDone(bool* statementIsDone) {
         116         3748445 :         statementDone = statementIsDone;
         117         3748445 :     }
         118                 : };
         119                 :
         120                 : class MOZ_EXPORT_API(GuardObjectNotificationReceiver)
         121                 : {
         122                 :   private:
         123                 :     bool statementDone;
         124                 :
         125                 :   public:
         126         3748461 :     GuardObjectNotificationReceiver() : statementDone(false) {}
         127                 :
         128         3748472 :     ~GuardObjectNotificationReceiver() {
         129                 :         /*
         130                 :          * Assert that the guard object was not used as a temporary.
         131                 :          * (Note that this assert might also fire if init is not called
         132                 :          * because the guard object's implementation is not using the
         133                 :          * above macros correctly.)
         134                 :          */
         135         3748472 :         MOZ_ASSERT(statementDone);
         136         3748472 :     }
         137                 :
         138         3748435 :     void init(const GuardObjectNotifier& constNotifier) {
         139                 :         /*
         140                 :          * constNotifier is passed as a const reference so that we can pass a
         141                 :          * temporary, but we really intend it as non-const.
         142                 :          */
         143         3748435 :         GuardObjectNotifier& notifier = const_cast<GuardObjectNotifier&>(constNotifier);
         144         3748435 :         notifier.setStatementDone(&statementDone);
         145         3748436 :     }
         146                 : };
         147                 :
         148                 : } /* namespace detail */
         149                 : } /* namespace mozilla */
         150                 :
         151                 : #endif /* DEBUG */
         152                 :
         153                 : #ifdef DEBUG
         154                 : #  define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER \
         155                 :      mozilla::detail::GuardObjectNotificationReceiver _mCheckNotUsedAsTemporary;
         156                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_PARAM \
         157                 :      , const mozilla::detail::GuardObjectNotifier& _notifier = \
         158                 :          mozilla::detail::GuardObjectNotifier()
         159                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM \
         160                 :      const mozilla::detail::GuardObjectNotifier& _notifier = \
         161                 :          mozilla::detail::GuardObjectNotifier()
         162                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL \
         163                 :      , const mozilla::detail::GuardObjectNotifier& _notifier
         164                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT \
         165                 :      , _notifier
         166                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT \
         167                 :        _notifier
         168                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_INIT \
         169                 :      do { _mCheckNotUsedAsTemporary.init(_notifier); } while (0)
         170                 : #else
         171                 : #  define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
         172                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_PARAM
         173                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM
         174                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL
         175                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT
         176                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT
         177                 : #  define MOZ_GUARD_OBJECT_NOTIFIER_INIT do { } while (0)
         178                 : #endif
         179                 :
         180                 : #endif /* __cplusplus */
         181                 :
         182                 : #endif /* mozilla_GuardObjects_h */

Generated by: LCOV version 1.7