1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 // A wrapper that uses RAII to ensure that a class invariant is checked
8 // before and after any public function is called
10 #ifndef CHECKINVARIANTWRAPPER_H_
11 #define CHECKINVARIANTWRAPPER_H_
13 #include "mozilla/Attributes.h"
19 // Wraps an object of type T and allows access to its public API by
20 // deferencing it using the pointer syntax "->".
22 // Using that operator will return a temporary RAII object that
23 // calls a method named "CheckInvariant" in its constructor, calls the
24 // requested method, and then calls "CheckInvariant" again in its
27 // The only thing your class requires is a method with the following signature:
29 // void CheckInvariant() const;
32 class CheckInvariantWrapper
{
36 explicit Wrapper(T
& aObject
) : mObject(aObject
) {
37 mObject
.CheckInvariant();
39 ~Wrapper() { mObject
.CheckInvariant(); }
41 T
* operator->() { return &mObject
; }
49 explicit ConstWrapper(const T
& aObject
) : mObject(aObject
) {
50 mObject
.CheckInvariant();
52 ~ConstWrapper() { mObject
.CheckInvariant(); }
54 const T
* operator->() const { return &mObject
; }
60 CheckInvariantWrapper() = default;
62 MOZ_IMPLICIT
CheckInvariantWrapper(T aObject
) : mObject(std::move(aObject
)) {}
64 template <typename
... Args
>
65 explicit CheckInvariantWrapper(std::in_place_t
, Args
&&... args
)
66 : mObject(std::forward
<Args
>(args
)...) {}
68 const ConstWrapper
operator->() const { return ConstWrapper(mObject
); }
70 Wrapper
operator->() { return Wrapper(mObject
); }
76 } // namespace mozilla
78 #endif // CHECKINVARIANTWRAPPER_H_