Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Cast.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Debug_Cast_h_
5#define _Stroika_Foundation_Debug_Cast_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <memory>
10
12
13/**
14 * \file
15 *
16 */
17
18namespace Stroika::Foundation::Debug {
19
20 /**
21 * \brief return the same value as dynamic_cast<T> would have, except instead of checking nullptr,
22 * only check in DEBUG builds, and there ASSERT != null (if original pointer not null)
23 *
24 * \pre arg != nullptr
25 *
26 * Use where you would want to check Assert (dynamic_cast<const T*> (&ir) != nullptr) and then do static_cast<> instead;)
27 *
28 * AssertMember (&ir, IteratorRep_);
29 * auto& mir = static_cast<const IteratorRep_&> (ir);
30 *
31 * The purpose of this function is to gain the performance of static_cast<> but the safety / checking of dynamic_cast (in debug builds).
32 *
33 * \par Example Usage
34 * \code
35 * auto& mir = Debug::UncheckedDynamicCast<const IteratorRep_&> (i.ConstGetRep ());
36 * \endcode
37 *
38 *
39 * \par Example Usage
40 * \code
41 * virtual bool Equals (const IRep* rhs) const override
42 * {
43 * RequireNotNull (rhs);
44 * RequireMember (rhs, MyIterRep_);
45 * const MyIterRep_* rrhs = Debug::UncheckedDynamicCast<const MyIterRep_*> (rhs);
46 * return fData_.data () == rrhs->fData_.data () and fIdx_ == rrhs->fIdx_;
47 * }
48 * \endcode
49 *
50 * \see https://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast
51 *
52 * \note this does NOT work (should be checked somehow/assert/type info @todo) - with virtual inheritance.
53 */
54 template <typename T, typename T1>
55 T UncheckedDynamicCast (T1&& arg) noexcept;
56
57 /**
58 * \brief Produce the same result as dynamic_pointer_cast if the successful case (non-null) - with better performance.
59 *
60 * \pre arg != nullptr
61 * \pre dynamic_pointer_cast<T> (arg) != nullptr
62 *
63 * \see UncheckedDynamicCast and dynamic_pointer_cast
64 *
65 * @todo CONSIDER USING SAME NAME - UncheckedDynamicCast - and overload. Done this way cuz std c++ does it that way, but not sure thats a good reason here.
66 */
67 template <typename T, typename T1>
68 std::shared_ptr<T> UncheckedDynamicPointerCast (const std::shared_ptr<T1>& arg) noexcept;
69
70}
71
72/*
73 ********************************************************************************
74 ***************************** Implementation Details ***************************
75 ********************************************************************************
76 */
77#include "Cast.inl"
78
79#endif /*_Stroika_Foundation_Debug_Cast_h_*/
T UncheckedDynamicCast(T1 &&arg) noexcept
return the same value as dynamic_cast<T> would have, except instead of checking nullptr,...
Definition Cast.inl:13
std::shared_ptr< T > UncheckedDynamicPointerCast(const std::shared_ptr< T1 > &arg) noexcept
Produce the same result as dynamic_pointer_cast if the successful case (non-null) - with better perfo...
Definition Cast.inl:42