diff --git a/README.md b/README.md index a0a1940..5d51dc2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ correctness. The code is heavily inspired by [FastDynamicCast](https://github.com/tobspr/FastDynamicCast). This is effectively a -modern C++ implementation of FastDynamicCast. +modern C++ implementation of FastDynamicCast. This is the basic idea in a single image + +![offset](ptroffset.png) # Improvements from FastDynamicCast diff --git a/fastcast.hpp b/fastcast.hpp index c5c27df..9be6c8e 100644 --- a/fastcast.hpp +++ b/fastcast.hpp @@ -18,7 +18,6 @@ #define CONSTEXPR #endif - namespace fastcast { // Core implementation for pointer types @@ -59,12 +58,10 @@ template CONSTEXPR inline To cast_impl(From *ptr) { // slow path auto result = dynamic_cast(ptr); cached_vtable = this_vtable; - if (result) { - offset = reinterpret_cast(result) - - reinterpret_cast(ptr); - } else { - offset = FAILED_OFFSET; - } + offset = static_cast(result) + ? reinterpret_cast(result) - + reinterpret_cast(ptr) + : FAILED_OFFSET; return result; } } @@ -84,25 +81,20 @@ template requires std::is_reference_v constexpr inline To fast_cast(From &ref) { using ToPtr = std::add_pointer_t>; - auto casted_ptr = fast_cast(&ref); - if (!casted_ptr) - throw std::bad_cast{}; - return *casted_ptr; + if (auto casted = fast_cast(&ref)) + return *casted; + throw std::bad_cast{}; } // shared_ptr overload template constexpr inline std::shared_ptr fast_dynamic_pointer_cast(const std::shared_ptr &ptr) { - return std::shared_ptr(ptr, fast_cast(ptr.get())); + if (auto raw = fast_cast(ptr.get())) + return std::shared_ptr(ptr, std::move(raw)); + return nullptr; } -// Identity cast (same type) -template - requires std::is_same_v, std::remove_cv_t> -constexpr inline To fast_cast(To ptr) { - return ptr; -} } // namespace fastcast using fastcast::fast_cast; diff --git a/ptroffset.png b/ptroffset.png new file mode 100644 index 0000000..ebc45e5 Binary files /dev/null and b/ptroffset.png differ