From 8168dd904d3682305114e371814bc41fbb70ada3 Mon Sep 17 00:00:00 2001 From: Avril Date: Sat, 12 Mar 2022 20:19:51 +0000 Subject: [PATCH] Added opaque_handle::ptr_cast(): Use `try_cast()` for complete types, and `unsafe_cast()` for incomplete types. This is used *only* for `operator [const] T*()`, since this is intended for C interop. `operator->` and `operator*` will only work with complete types, as they should. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for opaque_handle's current commit: Curse − 凶 --- include/opaque.hh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/include/opaque.hh b/include/opaque.hh index 77cef48..7b3e7c3 100644 --- a/include/opaque.hh +++ b/include/opaque.hh @@ -100,6 +100,19 @@ struct opaque_handle final { template constexpr T* try_cast() noexcept { return _impl ? _impl->try_cast() : nullptr; } + + /// ptr_cast(): use try_cast() for complete types, and unsafe_cast() for incomplete types. + template + constexpr T* ptr_cast() noexcept { + if constexpr(opaque_is_incomplete) return unsafe_cast(); + else return try_cast(); + } + template + constexpr const T* ptr_cast() const noexcept { + if constexpr(opaque_is_incomplete) return unsafe_cast(); + else return try_cast(); + } + template inline const T& cast() const { if constexpr(Kind >= CAST_UNSAFE) @@ -118,6 +131,8 @@ struct opaque_handle final { constexpr bool has_value() const noexcept { return bool(_impl); } constexpr explicit operator bool() const noexcept { return has_value(); } + // XXX: NOTE: operator-> and operator* do not, and SHOULD NOT, work for incomplete types. only `ptr_cast()` and `operator [const] T*()` should consider the completeness of the type. + //TODO: Test these, we may need to do the same thing we did for `operator*`, but with a shim that has `operator T*` and `operator->` instead of `operator T&`. template constexpr const T* operator->() const noexcept(std::is_void_v) { @@ -147,13 +162,11 @@ struct opaque_handle final { */ template constexpr operator T*() noexcept { - if constexpr(opaque_is_incomplete) return unsafe_cast(); - else return try_cast(); + return ptr_cast(); } template constexpr operator const T*() const noexcept { - if constexpr(opaque_is_incomplete) return unsafe_cast(); - else return try_cast(); + return ptr_cast(); } private: