cpp-common/bt2: `bt2::internal::SharedObj` -> `bt2::SharedObj`
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 13 Nov 2023 18:52:39 +0000 (13:52 -0500)
committerSimon Marchi <simon.marchi@efficios.com>
Thu, 14 Dec 2023 15:57:04 +0000 (10:57 -0500)
`SharedObj` is not completely internal: it offers public methods,
including creation methods.

Also, we don't need to hide anything from the end user in this file.

Therefore make this class not internal.

Also apply to specific shared object aliases, for example
`bt2::SharedValue`.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I8bf1718a95de87b7c506ffab4868e63bc57a7391
Reviewed-on: https://review.lttng.org/c/babeltrace/+/11367
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
src/Makefile.am
src/cpp-common/bt2/clock-class.hpp
src/cpp-common/bt2/field-class.hpp
src/cpp-common/bt2/field-path.hpp
src/cpp-common/bt2/integer-range-set.hpp
src/cpp-common/bt2/internal/shared-obj.hpp [deleted file]
src/cpp-common/bt2/message.hpp
src/cpp-common/bt2/shared-obj.hpp [new file with mode: 0644]
src/cpp-common/bt2/trace-ir.hpp
src/cpp-common/bt2/value.hpp

index 523274bf0319b158c202243dc6d61e3c0d2b92bc..2154e5ac6c2d13ea83ef4956e20a225034cfdff0 100644 (file)
@@ -22,10 +22,10 @@ noinst_HEADERS = \
        cpp-common/bt2/field-path.hpp \
        cpp-common/bt2/integer-range.hpp \
        cpp-common/bt2/integer-range-set.hpp \
-       cpp-common/bt2/internal/shared-obj.hpp \
        cpp-common/bt2/internal/utils.hpp \
        cpp-common/bt2/logging.hpp \
        cpp-common/bt2/message.hpp \
+       cpp-common/bt2/shared-obj.hpp \
        cpp-common/bt2/trace-ir.hpp \
        cpp-common/bt2/type-traits.hpp \
        cpp-common/bt2/value.hpp \
index 16bfd23b3678c5afa2bece05dbd8c7ae93c601e0..1aac1459b94c5d4b47f3e19bc48d96bca3bdea9c 100644 (file)
@@ -19,8 +19,8 @@
 
 #include "borrowed-object.hpp"
 #include "exc.hpp"
-#include "internal/shared-obj.hpp"
 #include "internal/utils.hpp"
+#include "shared-obj.hpp"
 #include "value.hpp"
 
 namespace bt2 {
@@ -100,8 +100,7 @@ private:
     using _ThisCommonClockClass = CommonClockClass<LibObjT>;
 
 public:
-    using Shared =
-        internal::SharedObj<_ThisCommonClockClass, LibObjT, internal::ClockClassRefFuncs>;
+    using Shared = SharedObj<_ThisCommonClockClass, LibObjT, internal::ClockClassRefFuncs>;
 
     using UserAttributes =
         typename std::conditional<std::is_const<LibObjT>::value, ConstMapValue, MapValue>::type;
index 67bf9e8a5d5b8b13651feaff90c4be0f21e72328..f8f3d850a0276242e85c977fa057386e27df1999 100644 (file)
@@ -21,8 +21,8 @@
 #include "exc.hpp"
 #include "field-path.hpp"
 #include "integer-range-set.hpp"
-#include "internal/shared-obj.hpp"
 #include "internal/utils.hpp"
+#include "shared-obj.hpp"
 #include "value.hpp"
 
 namespace bt2 {
@@ -41,9 +41,6 @@ struct FieldClassRefFuncs final
     }
 };
 
-template <typename ObjT, typename LibObjT>
-using SharedFieldClass = internal::SharedObj<ObjT, LibObjT, internal::FieldClassRefFuncs>;
-
 template <typename LibObjT>
 struct CommonFieldClassSpec;
 
@@ -69,6 +66,9 @@ struct CommonFieldClassSpec<const bt_field_class> final
 
 } /* namespace internal */
 
+template <typename ObjT, typename LibObjT>
+using SharedFieldClass = SharedObj<ObjT, LibObjT, internal::FieldClassRefFuncs>;
+
 template <typename LibObjT>
 class CommonBitArrayFieldClass;
 
@@ -194,7 +194,7 @@ protected:
     using _ThisCommonFieldClass = CommonFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonFieldClass<LibObjT>, LibObjT>;
 
     using UserAttributes =
         typename std::conditional<std::is_const<LibObjT>::value, ConstMapValue, MapValue>::type;
@@ -483,7 +483,7 @@ private:
     using typename CommonFieldClass<LibObjT>::_ThisCommonFieldClass;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonBitArrayFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonBitArrayFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonBitArrayFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonFieldClass {libObjPtr}
@@ -558,7 +558,7 @@ protected:
     using _ThisCommonIntegerFieldClass = CommonIntegerFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonIntegerFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonIntegerFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonIntegerFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonFieldClass {libObjPtr}
@@ -791,7 +791,7 @@ protected:
     using _ThisCommonBaseEnumerationFieldClass = CommonBaseEnumerationFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<_ThisCommonBaseEnumerationFieldClass, LibObjT>;
+    using Shared = SharedFieldClass<_ThisCommonBaseEnumerationFieldClass, LibObjT>;
 
     explicit CommonBaseEnumerationFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonIntegerFieldClass {libObjPtr}
@@ -834,7 +834,7 @@ private:
     using _ThisCommonEnumerationFieldClass = CommonEnumerationFieldClass<LibObjT, MappingT>;
 
 public:
-    using Shared = internal::SharedFieldClass<_ThisCommonEnumerationFieldClass, LibObjT>;
+    using Shared = SharedFieldClass<_ThisCommonEnumerationFieldClass, LibObjT>;
     using Iterator = CommonIterator<CommonEnumerationFieldClass, MappingT>;
     using Mapping = MappingT;
 
@@ -1143,7 +1143,7 @@ private:
     using typename CommonFieldClass<LibObjT>::_ThisCommonFieldClass;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonStructureFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonStructureFieldClass<LibObjT>, LibObjT>;
     using Member =
         typename std::conditional<std::is_const<LibObjT>::value, ConstStructureFieldClassMember,
                                   StructureFieldClassMember>::type;
@@ -1317,7 +1317,7 @@ protected:
     using _ThisCommonArrayFieldClass = CommonArrayFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonArrayFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonArrayFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonArrayFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonFieldClass {libObjPtr}
@@ -1388,7 +1388,7 @@ private:
     using typename CommonFieldClass<LibObjT>::_LibObjPtr;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonStaticArrayFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonStaticArrayFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonStaticArrayFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonArrayFieldClass {libObjPtr}
@@ -1452,8 +1452,7 @@ private:
     using typename CommonFieldClass<LibObjT>::_LibObjPtr;
 
 public:
-    using Shared =
-        internal::SharedFieldClass<CommonDynamicArrayWithLengthFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonDynamicArrayWithLengthFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonDynamicArrayWithLengthFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonArrayFieldClass {libObjPtr}
@@ -1553,7 +1552,7 @@ protected:
     using _ThisCommonOptionFieldClass = CommonOptionFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonOptionFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonOptionFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonOptionFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonFieldClass {libObjPtr}
@@ -1627,7 +1626,7 @@ protected:
     using _ThisCommonOptionWithSelectorFieldClass = CommonOptionWithSelectorFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonOptionWithSelectorFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonOptionWithSelectorFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonOptionWithSelectorFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonOptionFieldClass {libObjPtr}
@@ -1696,8 +1695,7 @@ private:
         LibObjT>::_ThisCommonOptionWithSelectorFieldClass;
 
 public:
-    using Shared =
-        internal::SharedFieldClass<CommonOptionWithBoolSelectorFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonOptionWithBoolSelectorFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonOptionWithBoolSelectorFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonOptionWithSelectorFieldClass {libObjPtr}
@@ -1799,8 +1797,7 @@ private:
         CommonOptionWithIntegerSelectorFieldClass<LibObjT, RangeSetT>;
 
 public:
-    using Shared =
-        internal::SharedFieldClass<_ThisCommonOptionWithIntegerSelectorFieldClass, LibObjT>;
+    using Shared = SharedFieldClass<_ThisCommonOptionWithIntegerSelectorFieldClass, LibObjT>;
 
     using RangeSet = RangeSetT;
 
@@ -2191,7 +2188,7 @@ protected:
     using _ThisCommonVariantFieldClass = CommonVariantFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<CommonVariantFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonVariantFieldClass<LibObjT>, LibObjT>;
 
     using Option =
         typename std::conditional<std::is_const<LibObjT>::value, ConstVariantFieldClassOption,
@@ -2320,8 +2317,7 @@ private:
     using typename CommonFieldClass<LibObjT>::_LibObjPtr;
 
 public:
-    using Shared =
-        internal::SharedFieldClass<CommonVariantWithoutSelectorFieldClass<LibObjT>, LibObjT>;
+    using Shared = SharedFieldClass<CommonVariantWithoutSelectorFieldClass<LibObjT>, LibObjT>;
 
     explicit CommonVariantWithoutSelectorFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonVariantFieldClass {libObjPtr}
@@ -2468,7 +2464,7 @@ protected:
     using _ThisCommonVariantWithSelectorFieldClass = CommonVariantWithSelectorFieldClass<LibObjT>;
 
 public:
-    using Shared = internal::SharedFieldClass<_ThisCommonVariantWithSelectorFieldClass, LibObjT>;
+    using Shared = SharedFieldClass<_ThisCommonVariantWithSelectorFieldClass, LibObjT>;
 
     explicit CommonVariantWithSelectorFieldClass(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonVariantFieldClass {libObjPtr}
@@ -2522,8 +2518,7 @@ private:
     using _Spec = internal::CommonVariantWithIntegerSelectorFieldClassSpec<OptionT>;
 
 public:
-    using Shared =
-        internal::SharedFieldClass<_ThisCommonVariantWithIntegerSelectorFieldClass, LibObjT>;
+    using Shared = SharedFieldClass<_ThisCommonVariantWithIntegerSelectorFieldClass, LibObjT>;
 
     using Option = OptionT;
     using Iterator =
index 0416b00a5409090f3a599cd10bbb9fe162cfa57d..caf1de001da9865985ffc7ef740a854e4140b4a5 100644 (file)
@@ -15,7 +15,7 @@
 
 #include "borrowed-object.hpp"
 #include "common-iter.hpp"
-#include "internal/shared-obj.hpp"
+#include "shared-obj.hpp"
 
 namespace bt2 {
 
@@ -127,8 +127,7 @@ struct FieldPathRefFuncs final
 class ConstFieldPath final : public BorrowedObject<const bt_field_path>
 {
 public:
-    using Shared =
-        internal::SharedObj<ConstFieldPath, const bt_field_path, internal::FieldPathRefFuncs>;
+    using Shared = SharedObj<ConstFieldPath, const bt_field_path, internal::FieldPathRefFuncs>;
 
     using Iterator = CommonIterator<ConstFieldPath, ConstFieldPathItem>;
 
index eb10992138d6e122a68e5fb41dc1bb7596dfcc10..3a05e1d3b8bc29df0dd58463481619ea4b986086 100644 (file)
@@ -17,6 +17,7 @@
 #include "exc.hpp"
 #include "integer-range.hpp"
 #include "internal/utils.hpp"
+#include "shared-obj.hpp"
 
 namespace bt2 {
 
@@ -172,7 +173,7 @@ private:
     using _ThisCommonIntegerRangeSet = CommonIntegerRangeSet<LibObjT>;
 
 public:
-    using Shared = internal::SharedObj<_ThisCommonIntegerRangeSet, LibObjT, _RefFuncs>;
+    using Shared = SharedObj<_ThisCommonIntegerRangeSet, LibObjT, _RefFuncs>;
 
     using Range = typename std::conditional<
         std::is_same<_ConstLibObjT, const bt_integer_range_set_unsigned>::value,
diff --git a/src/cpp-common/bt2/internal/shared-obj.hpp b/src/cpp-common/bt2/internal/shared-obj.hpp
deleted file mode 100644 (file)
index 7846b32..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2019-2020 Philippe Proulx <pproulx@efficios.com>
- *
- * SPDX-License-Identifier: MIT
- */
-
-#ifndef BABELTRACE_CPP_COMMON_BT2_INTERNAL_SHARED_OBJ_HPP
-#define BABELTRACE_CPP_COMMON_BT2_INTERNAL_SHARED_OBJ_HPP
-
-#include "common/assert.h"
-#include "cpp-common/optional.hpp"
-
-namespace bt2 {
-namespace internal {
-
-/*
- * An instance of this class wraps an optional instance of `ObjT` and
- * manages the reference counting of the underlying libbabeltrace2
- * object.
- *
- * When you move a shared object, it becomes invalid, in that
- * operator*() and operator->() will either fail to assert in debug mode
- * or trigger a segmentation fault.
- *
- * `LibObjT` is the direct libbabeltrace2 object type, for example
- * `bt_stream_class` or `const bt_value`.
- *
- * RefFuncsT::get() must accept a `const LibObjT *` value and increment
- * its reference count.
- *
- * RefFuncsT::put() must accept a `const LibObjT *` value and decrement
- * its reference count.
- */
-template <typename ObjT, typename LibObjT, typename RefFuncsT>
-class SharedObj final
-{
-    /*
-     * This makes it possible for a
-     * `SharedObj<Something, bt_something, ...>` instance to get
-     * assigned an instance of
-     * `SharedObj<SpecificSomething, bt_something, ...>` (copy/move
-     * constructors and assignment operators), given that
-     * `SpecificSomething` inherits `Something`.
-     */
-    template <typename, typename, typename>
-    friend class SharedObj;
-
-private:
-    /*
-     * Builds a shared object from `obj` without getting a reference.
-     */
-    explicit SharedObj(const ObjT& obj) noexcept : _mObj {obj}
-    {
-    }
-
-    /*
-     * Common generic "copy" constructor.
-     *
-     * This constructor is meant to be delegated to by the copy
-     * constructor and the generic "copy" constructor.
-     *
-     * The second parameter, of type `int`, makes it possible to
-     * delegate by deduction as you can't explicit the template
-     * parameters when delegating to a constructor template.
-     */
-    template <typename OtherObjT, typename OtherLibObjT>
-    SharedObj(const SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>& other, int) noexcept :
-        _mObj {other._mObj}
-    {
-        this->_getRef();
-    }
-
-    /*
-     * Common generic "move" constructor.
-     *
-     * See the comment of the common generic "copy" constructor above.
-     */
-    template <typename OtherObjT, typename OtherLibObjT>
-    SharedObj(SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>&& other, int) noexcept :
-        _mObj {other._mObj}
-    {
-        /* Reset moved-from object */
-        other._reset();
-    }
-
-public:
-    /*
-     * Builds a shared object from `obj` without getting a reference.
-     */
-    static SharedObj createWithoutRef(const ObjT& obj) noexcept
-    {
-        return SharedObj {obj};
-    }
-
-    /*
-     * Builds a shared object from `libObjPtr` without getting a
-     * reference.
-     */
-    static SharedObj createWithoutRef(LibObjT * const libObjPtr) noexcept
-    {
-        return SharedObj::createWithoutRef(ObjT {libObjPtr});
-    }
-
-    /*
-     * Builds a shared object from `obj`, immediately getting a new
-     * reference.
-     */
-    static SharedObj createWithRef(const ObjT& obj) noexcept
-    {
-        SharedObj sharedObj {obj};
-
-        sharedObj._getRef();
-        return sharedObj;
-    }
-
-    /*
-     * Builds a shared object from `libObjPtr`, immediately getting a new
-     * reference.
-     */
-    static SharedObj createWithRef(LibObjT * const libObjPtr) noexcept
-    {
-        return SharedObj::createWithRef(ObjT {libObjPtr});
-    }
-
-    /*
-     * Copy constructor.
-     */
-    SharedObj(const SharedObj& other) noexcept : SharedObj {other, 0}
-    {
-    }
-
-    /*
-     * Move constructor.
-     */
-    SharedObj(SharedObj&& other) noexcept : SharedObj {std::move(other), 0}
-    {
-    }
-
-    /*
-     * Copy assignment operator.
-     */
-    SharedObj& operator=(const SharedObj& other) noexcept
-    {
-        /* Use generic "copy" assignment operator */
-        return this->operator=<ObjT, LibObjT>(other);
-    }
-
-    /*
-     * Move assignment operator.
-     */
-    SharedObj& operator=(SharedObj&& other) noexcept
-    {
-        /* Use generic "move" assignment operator */
-        return this->operator=<ObjT, LibObjT>(std::move(other));
-    }
-
-    /*
-     * Generic "copy" constructor.
-     *
-     * See the `friend class SharedObj` comment above.
-     */
-    template <typename OtherObjT, typename OtherLibObjT>
-    SharedObj(const SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept :
-        SharedObj {other, 0}
-    {
-    }
-
-    /*
-     * Generic "move" constructor.
-     *
-     * See the `friend class SharedObj` comment above.
-     */
-    template <typename OtherObjT, typename OtherLibObjT>
-    SharedObj(SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept :
-        SharedObj {std::move(other), 0}
-    {
-    }
-
-    /*
-     * Generic "copy" assignment operator.
-     *
-     * See the `friend class SharedObj` comment above.
-     */
-    template <typename OtherObjT, typename OtherLibObjT>
-    SharedObj& operator=(const SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept
-    {
-        /* Put current object's reference */
-        this->_putRef();
-
-        /* Set new current object and get a reference */
-        _mObj = other._mObj;
-        this->_getRef();
-
-        return *this;
-    }
-
-    /*
-     * Generic "move" assignment operator.
-     *
-     * See the `friend class SharedObj` comment above.
-     */
-    template <typename OtherObjT, typename OtherLibObjT>
-    SharedObj& operator=(SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept
-    {
-        /* Put current object's reference */
-        this->_putRef();
-
-        /* Set new current object */
-        _mObj = other._mObj;
-
-        /* Reset moved-from object */
-        other._reset();
-
-        return *this;
-    }
-
-    ~SharedObj()
-    {
-        this->_putRef();
-    }
-
-    ObjT& operator*() noexcept
-    {
-        BT_ASSERT_DBG(_mObj);
-        return *_mObj;
-    }
-
-    const ObjT& operator*() const noexcept
-    {
-        BT_ASSERT_DBG(_mObj);
-        return *_mObj;
-    }
-
-    ObjT *operator->() noexcept
-    {
-        BT_ASSERT_DBG(_mObj);
-        return &*_mObj;
-    }
-
-    const ObjT *operator->() const noexcept
-    {
-        BT_ASSERT_DBG(_mObj);
-        return &*_mObj;
-    }
-
-    /*
-     * Transfers the reference of the object which this shared object
-     * wrapper manages and returns it, making the caller become an active
-     * owner.
-     *
-     * This method makes this object invalid.
-     */
-    ObjT release() noexcept
-    {
-        BT_ASSERT_DBG(_mObj);
-        const auto obj = *_mObj;
-        this->_reset();
-        return obj;
-    }
-
-private:
-    /*
-     * Resets this shared object.
-     *
-     * To be used when moving it.
-     */
-    void _reset() noexcept
-    {
-        _mObj.reset();
-    }
-
-    /*
-     * Gets a new reference using the configured libbabeltrace2
-     * reference incrementation function.
-     */
-    void _getRef() const noexcept
-    {
-        if (_mObj) {
-            RefFuncsT::get(_mObj->libObjPtr());
-        }
-    }
-
-    /*
-     * Puts a reference using the configured libbabeltrace2 reference
-     * decrementation function.
-     */
-    void _putRef() const noexcept
-    {
-        if (_mObj) {
-            RefFuncsT::put(_mObj->libObjPtr());
-        }
-    }
-
-    nonstd::optional<ObjT> _mObj;
-};
-
-} /* namespace internal */
-} /* namespace bt2 */
-
-#endif /* BABELTRACE_CPP_COMMON_BT2_INTERNAL_SHARED_OBJ_HPP */
index e284afe2720fe0e5406e5d27e7a73dd6f705036b..aee0e7c98a59d9e90988d99ca14e683f17ed27f0 100644 (file)
@@ -18,8 +18,8 @@
 #include "cpp-common/optional.hpp"
 
 #include "borrowed-object.hpp"
-#include "internal/shared-obj.hpp"
 #include "internal/utils.hpp"
+#include "shared-obj.hpp"
 
 namespace bt2 {
 namespace internal {
@@ -37,11 +37,11 @@ struct MessageRefFuncs final
     }
 };
 
-template <typename ObjT, typename LibObjT>
-using SharedMessage = internal::SharedObj<ObjT, LibObjT, internal::MessageRefFuncs>;
-
 } /* namespace internal */
 
+template <typename ObjT, typename LibObjT>
+using SharedMessage = SharedObj<ObjT, LibObjT, internal::MessageRefFuncs>;
+
 template <typename LibObjT>
 class CommonStreamBeginningMessage;
 
@@ -89,7 +89,7 @@ protected:
     using _ThisCommonMessage = CommonMessage<LibObjT>;
 
 public:
-    using Shared = internal::SharedMessage<CommonMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonMessage<LibObjT>, LibObjT>;
 
     explicit CommonMessage(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
     {
@@ -231,7 +231,7 @@ private:
                                   CommonStream<bt_stream>>::type;
 
 public:
-    using Shared = internal::SharedMessage<CommonStreamBeginningMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonStreamBeginningMessage<LibObjT>, LibObjT>;
 
     explicit CommonStreamBeginningMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
@@ -349,7 +349,7 @@ private:
                                   CommonStream<bt_stream>>::type;
 
 public:
-    using Shared = internal::SharedMessage<CommonStreamEndMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonStreamEndMessage<LibObjT>, LibObjT>;
 
     explicit CommonStreamEndMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
@@ -466,7 +466,7 @@ private:
                                   CommonPacket<bt_packet>>::type;
 
 public:
-    using Shared = internal::SharedMessage<CommonPacketBeginningMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonPacketBeginningMessage<LibObjT>, LibObjT>;
 
     explicit CommonPacketBeginningMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
@@ -579,7 +579,7 @@ private:
                                   CommonPacket<bt_packet>>::type;
 
 public:
-    using Shared = internal::SharedMessage<CommonPacketEndMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonPacketEndMessage<LibObjT>, LibObjT>;
 
     explicit CommonPacketEndMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
@@ -691,7 +691,7 @@ private:
                                   CommonEvent<bt_event>>::type;
 
 public:
-    using Shared = internal::SharedMessage<CommonEventMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonEventMessage<LibObjT>, LibObjT>;
 
     explicit CommonEventMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
@@ -795,7 +795,7 @@ private:
                                   CommonStream<bt_stream>>::type;
 
 public:
-    using Shared = internal::SharedMessage<CommonDiscardedEventsMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonDiscardedEventsMessage<LibObjT>, LibObjT>;
 
     explicit CommonDiscardedEventsMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
@@ -929,7 +929,7 @@ private:
                                   CommonStream<bt_stream>>::type;
 
 public:
-    using Shared = internal::SharedMessage<CommonDiscardedPacketsMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonDiscardedPacketsMessage<LibObjT>, LibObjT>;
 
     explicit CommonDiscardedPacketsMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
@@ -1036,8 +1036,7 @@ private:
     using typename CommonMessage<LibObjT>::_ThisCommonMessage;
 
 public:
-    using Shared =
-        internal::SharedMessage<CommonMessageIteratorInactivityMessage<LibObjT>, LibObjT>;
+    using Shared = SharedMessage<CommonMessageIteratorInactivityMessage<LibObjT>, LibObjT>;
 
     explicit CommonMessageIteratorInactivityMessage(const _LibObjPtr libObjPtr) noexcept :
         _ThisCommonMessage {libObjPtr}
diff --git a/src/cpp-common/bt2/shared-obj.hpp b/src/cpp-common/bt2/shared-obj.hpp
new file mode 100644 (file)
index 0000000..d0a2d7f
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2019-2020 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BABELTRACE_CPP_COMMON_BT2_SHARED_OBJ_HPP
+#define BABELTRACE_CPP_COMMON_BT2_SHARED_OBJ_HPP
+
+#include "common/assert.h"
+#include "cpp-common/optional.hpp"
+
+namespace bt2 {
+
+/*
+ * An instance of this class wraps an optional instance of `ObjT` and
+ * manages the reference counting of the underlying libbabeltrace2
+ * object.
+ *
+ * When you move a shared object, it becomes invalid, in that
+ * operator*() and operator->() will either fail to assert in debug mode
+ * or trigger a segmentation fault.
+ *
+ * `LibObjT` is the direct libbabeltrace2 object type, for example
+ * `bt_stream_class` or `const bt_value`.
+ *
+ * RefFuncsT::get() must accept a `const LibObjT *` value and increment
+ * its reference count.
+ *
+ * RefFuncsT::put() must accept a `const LibObjT *` value and decrement
+ * its reference count.
+ */
+template <typename ObjT, typename LibObjT, typename RefFuncsT>
+class SharedObj final
+{
+    /*
+     * This makes it possible for a
+     * `SharedObj<Something, bt_something, ...>` instance to get
+     * assigned an instance of
+     * `SharedObj<SpecificSomething, bt_something, ...>` (copy/move
+     * constructors and assignment operators), given that
+     * `SpecificSomething` inherits `Something`.
+     */
+    template <typename, typename, typename>
+    friend class SharedObj;
+
+private:
+    /*
+     * Builds a shared object from `obj` without getting a reference.
+     */
+    explicit SharedObj(const ObjT& obj) noexcept : _mObj {obj}
+    {
+    }
+
+    /*
+     * Common generic "copy" constructor.
+     *
+     * This constructor is meant to be delegated to by the copy
+     * constructor and the generic "copy" constructor.
+     *
+     * The second parameter, of type `int`, makes it possible to
+     * delegate by deduction as you can't explicit the template
+     * parameters when delegating to a constructor template.
+     */
+    template <typename OtherObjT, typename OtherLibObjT>
+    SharedObj(const SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>& other, int) noexcept :
+        _mObj {other._mObj}
+    {
+        this->_getRef();
+    }
+
+    /*
+     * Common generic "move" constructor.
+     *
+     * See the comment of the common generic "copy" constructor above.
+     */
+    template <typename OtherObjT, typename OtherLibObjT>
+    SharedObj(SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>&& other, int) noexcept :
+        _mObj {other._mObj}
+    {
+        /* Reset moved-from object */
+        other._reset();
+    }
+
+public:
+    /*
+     * Builds a shared object from `obj` without getting a reference.
+     */
+    static SharedObj createWithoutRef(const ObjT& obj) noexcept
+    {
+        return SharedObj {obj};
+    }
+
+    /*
+     * Builds a shared object from `libObjPtr` without getting a
+     * reference.
+     */
+    static SharedObj createWithoutRef(LibObjT * const libObjPtr) noexcept
+    {
+        return SharedObj::createWithoutRef(ObjT {libObjPtr});
+    }
+
+    /*
+     * Builds a shared object from `obj`, immediately getting a new
+     * reference.
+     */
+    static SharedObj createWithRef(const ObjT& obj) noexcept
+    {
+        SharedObj sharedObj {obj};
+
+        sharedObj._getRef();
+        return sharedObj;
+    }
+
+    /*
+     * Builds a shared object from `libObjPtr`, immediately getting a new
+     * reference.
+     */
+    static SharedObj createWithRef(LibObjT * const libObjPtr) noexcept
+    {
+        return SharedObj::createWithRef(ObjT {libObjPtr});
+    }
+
+    /*
+     * Copy constructor.
+     */
+    SharedObj(const SharedObj& other) noexcept : SharedObj {other, 0}
+    {
+    }
+
+    /*
+     * Move constructor.
+     */
+    SharedObj(SharedObj&& other) noexcept : SharedObj {std::move(other), 0}
+    {
+    }
+
+    /*
+     * Copy assignment operator.
+     */
+    SharedObj& operator=(const SharedObj& other) noexcept
+    {
+        /* Use generic "copy" assignment operator */
+        return this->operator=<ObjT, LibObjT>(other);
+    }
+
+    /*
+     * Move assignment operator.
+     */
+    SharedObj& operator=(SharedObj&& other) noexcept
+    {
+        /* Use generic "move" assignment operator */
+        return this->operator=<ObjT, LibObjT>(std::move(other));
+    }
+
+    /*
+     * Generic "copy" constructor.
+     *
+     * See the `friend class SharedObj` comment above.
+     */
+    template <typename OtherObjT, typename OtherLibObjT>
+    SharedObj(const SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept :
+        SharedObj {other, 0}
+    {
+    }
+
+    /*
+     * Generic "move" constructor.
+     *
+     * See the `friend class SharedObj` comment above.
+     */
+    template <typename OtherObjT, typename OtherLibObjT>
+    SharedObj(SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept :
+        SharedObj {std::move(other), 0}
+    {
+    }
+
+    /*
+     * Generic "copy" assignment operator.
+     *
+     * See the `friend class SharedObj` comment above.
+     */
+    template <typename OtherObjT, typename OtherLibObjT>
+    SharedObj& operator=(const SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept
+    {
+        /* Put current object's reference */
+        this->_putRef();
+
+        /* Set new current object and get a reference */
+        _mObj = other._mObj;
+        this->_getRef();
+
+        return *this;
+    }
+
+    /*
+     * Generic "move" assignment operator.
+     *
+     * See the `friend class SharedObj` comment above.
+     */
+    template <typename OtherObjT, typename OtherLibObjT>
+    SharedObj& operator=(SharedObj<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept
+    {
+        /* Put current object's reference */
+        this->_putRef();
+
+        /* Set new current object */
+        _mObj = other._mObj;
+
+        /* Reset moved-from object */
+        other._reset();
+
+        return *this;
+    }
+
+    ~SharedObj()
+    {
+        this->_putRef();
+    }
+
+    ObjT& operator*() noexcept
+    {
+        BT_ASSERT_DBG(_mObj);
+        return *_mObj;
+    }
+
+    const ObjT& operator*() const noexcept
+    {
+        BT_ASSERT_DBG(_mObj);
+        return *_mObj;
+    }
+
+    ObjT *operator->() noexcept
+    {
+        BT_ASSERT_DBG(_mObj);
+        return &*_mObj;
+    }
+
+    const ObjT *operator->() const noexcept
+    {
+        BT_ASSERT_DBG(_mObj);
+        return &*_mObj;
+    }
+
+    /*
+     * Transfers the reference of the object which this shared object
+     * wrapper manages and returns it, making the caller become an active
+     * owner.
+     *
+     * This method makes this object invalid.
+     */
+    ObjT release() noexcept
+    {
+        BT_ASSERT_DBG(_mObj);
+        const auto obj = *_mObj;
+        this->_reset();
+        return obj;
+    }
+
+private:
+    /*
+     * Resets this shared object.
+     *
+     * To be used when moving it.
+     */
+    void _reset() noexcept
+    {
+        _mObj.reset();
+    }
+
+    /*
+     * Gets a new reference using the configured libbabeltrace2
+     * reference incrementation function.
+     */
+    void _getRef() const noexcept
+    {
+        if (_mObj) {
+            RefFuncsT::get(_mObj->libObjPtr());
+        }
+    }
+
+    /*
+     * Puts a reference using the configured libbabeltrace2 reference
+     * decrementation function.
+     */
+    void _putRef() const noexcept
+    {
+        if (_mObj) {
+            RefFuncsT::put(_mObj->libObjPtr());
+        }
+    }
+
+    nonstd::optional<ObjT> _mObj;
+};
+
+} /* namespace bt2 */
+
+#endif /* BABELTRACE_CPP_COMMON_BT2_SHARED_OBJ_HPP */
index 88ac7b0fb07c2e3f7a117cfb6f488a07fbf07e1d..293e99546afa2098b837d1a3d3ae30cedd1f14fd 100644 (file)
@@ -20,6 +20,7 @@
 #include "field-class.hpp"
 #include "field.hpp"
 #include "internal/utils.hpp"
+#include "shared-obj.hpp"
 #include "value.hpp"
 
 namespace bt2 {
@@ -324,7 +325,7 @@ private:
                                                       ConstStructureField, StructureField>::type;
 
 public:
-    using Shared = internal::SharedObj<_ThisCommonPacket, LibObjT, internal::PacketRefFuncs>;
+    using Shared = SharedObj<_ThisCommonPacket, LibObjT, internal::PacketRefFuncs>;
 
     explicit CommonPacket(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
     {
@@ -495,7 +496,7 @@ private:
                                   CommonTrace<bt_trace>>::type;
 
 public:
-    using Shared = internal::SharedObj<_ThisCommonStream, LibObjT, internal::StreamRefFuncs>;
+    using Shared = SharedObj<_ThisCommonStream, LibObjT, internal::StreamRefFuncs>;
 
     using Class = typename std::conditional<std::is_const<LibObjT>::value,
                                             CommonStreamClass<const bt_stream_class>,
@@ -728,7 +729,7 @@ private:
                                   CommonStream<bt_stream>>::type;
 
 public:
-    using Shared = internal::SharedObj<_ThisCommonTrace, LibObjT, internal::TraceRefFuncs>;
+    using Shared = SharedObj<_ThisCommonTrace, LibObjT, internal::TraceRefFuncs>;
 
     using Class = typename std::conditional<std::is_const<LibObjT>::value,
                                             CommonTraceClass<const bt_trace_class>,
@@ -1065,8 +1066,7 @@ private:
                                   StructureFieldClass>::type;
 
 public:
-    using Shared =
-        internal::SharedObj<_ThisCommonEventClass, LibObjT, internal::EventClassRefFuncs>;
+    using Shared = SharedObj<_ThisCommonEventClass, LibObjT, internal::EventClassRefFuncs>;
 
     using UserAttributes =
         typename std::conditional<std::is_const<LibObjT>::value, ConstMapValue, MapValue>::type;
@@ -1448,8 +1448,7 @@ private:
         typename std::conditional<std::is_const<LibObjT>::value, ConstClockClass, ClockClass>::type;
 
 public:
-    using Shared =
-        internal::SharedObj<_ThisCommonStreamClass, LibObjT, internal::StreamClassRefFuncs>;
+    using Shared = SharedObj<_ThisCommonStreamClass, LibObjT, internal::StreamClassRefFuncs>;
 
     using UserAttributes =
         typename std::conditional<std::is_const<LibObjT>::value, ConstMapValue, MapValue>::type;
@@ -1931,8 +1930,7 @@ private:
                                                    CommonStreamClass<bt_stream_class>>::type;
 
 public:
-    using Shared =
-        internal::SharedObj<_ThisCommonTraceClass, LibObjT, internal::TraceClassRefFuncs>;
+    using Shared = SharedObj<_ThisCommonTraceClass, LibObjT, internal::TraceClassRefFuncs>;
 
     using UserAttributes =
         typename std::conditional<std::is_const<LibObjT>::value, ConstMapValue, MapValue>::type;
index c78b5701785935e803e22b3d09e5075844c12b64..19bc357df5656576b0a8dfc3e6382a913a9af7b3 100644 (file)
@@ -21,8 +21,8 @@
 #include "borrowed-object.hpp"
 #include "common-iter.hpp"
 #include "exc.hpp"
-#include "internal/shared-obj.hpp"
 #include "internal/utils.hpp"
+#include "shared-obj.hpp"
 
 namespace bt2 {
 namespace internal {
@@ -40,11 +40,11 @@ struct ValueRefFuncs final
     }
 };
 
-template <typename ObjT, typename LibObjT>
-using SharedValue = internal::SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
-
 } /* namespace internal */
 
+template <typename ObjT, typename LibObjT>
+using SharedValue = SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
+
 template <typename LibObjT>
 class CommonNullValue;
 
@@ -128,7 +128,7 @@ protected:
     using _ThisCommonValue = CommonValue<LibObjT>;
 
 public:
-    using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
 
     explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
     {
@@ -265,7 +265,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
 
     CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
     {
@@ -320,7 +320,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
     using Value = bool;
 
     explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
@@ -403,7 +403,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
     using Value = std::uint64_t;
 
     explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
@@ -489,7 +489,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
     using Value = std::int64_t;
 
     explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
@@ -575,7 +575,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
     using Value = double;
 
     explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
@@ -658,7 +658,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
 
     explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
     {
@@ -774,7 +774,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
     using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
 
     explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
@@ -1085,7 +1085,7 @@ private:
     using typename CommonValue<LibObjT>::_ThisCommonValue;
 
 public:
-    using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
+    using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
 
     explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
     {
This page took 0.04086 seconds and 4 git commands to generate.