From 462e86286c967092b5c116d9d936cc6f0f7295c1 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Thu, 19 May 2022 12:22:29 -0400 Subject: [PATCH] bt2::internal::BorrowedObj: add static assertions for generic copy ops. This patch adds static assertions to `borrowed-obj.hpp` so as to make compiler errors more readable when assigning a const wrapper to a non-const wrapper, for example: bt2::Value v = bt2::ConstMapValue {somePtr}; Signed-off-by: Philippe Proulx Change-Id: Ib23d91c6660a478e0ad663abbd141b0a90eaa92d Reviewed-on: https://review.lttng.org/c/babeltrace/+/8091 Reviewed-on: https://review.lttng.org/c/babeltrace/+/10802 Tested-by: jenkins --- src/cpp-common/bt2/internal/borrowed-obj.hpp | 36 +++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/cpp-common/bt2/internal/borrowed-obj.hpp b/src/cpp-common/bt2/internal/borrowed-obj.hpp index 9b68af96..24c52cd1 100644 --- a/src/cpp-common/bt2/internal/borrowed-obj.hpp +++ b/src/cpp-common/bt2/internal/borrowed-obj.hpp @@ -46,6 +46,33 @@ class BorrowedObj template friend class BorrowedObj; +private: + /* + * Provides `val` which indicates whether or not you can assign this + * object from a borrowed object of type `OtherLibObjT`. + */ + template + struct _AssignableFromConst final + { + /* + * If `LibObjT` is const (for example, `const bt_value`), then + * you may always assign from its non-const equivalent (for + * example, `bt_value`). In C (correct): + * + * bt_value * const meow = bt_value_bool_create_init(BT_TRUE); + * const bt_value * const mix = meow; + * + * If `LibObjT` is non-const, then you may not assign from its + * const equivalent. In C (not correct): + * + * const bt_value * const meow = + * bt_value_array_borrow_element_by_index_const(some_val, 17); + * bt_value * const mix = meow; + */ + static constexpr bool val = + std::is_const::value || !std::is_const::value; + }; + protected: /* libbabeltrace2 object pointer */ using _LibObjPtr = LibObjT *; @@ -83,6 +110,8 @@ protected: template BorrowedObj(const BorrowedObj& other) noexcept : BorrowedObj {other._mLibObjPtr} { + static_assert(_AssignableFromConst::val, + "Don't assign a non-const wrapper from a const wrapper."); } /* @@ -95,11 +124,16 @@ protected: * * This makes it possible for a `BorrowedObj` * instance to get assigned an instance of - * `BorrowedObj`. C++ forbids the other way around. + * `BorrowedObj`. C++ forbids the other way around, + * therefore we use `_EnableIfAssignableT` to show a more relevant + * context in the compiler error message. */ template _ThisBorrowedObj& operator=(const BorrowedObj& other) noexcept { + static_assert(_AssignableFromConst::val, + "Don't assign a non-const wrapper from a const wrapper."); + _mLibObjPtr = other._mLibObjPtr; return *this; } -- 2.34.1