mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-02-15 19:55:53 +00:00
101 lines
3.0 KiB
C++
101 lines
3.0 KiB
C++
|
//
|
||
|
// Copyright © 2020 Arm Ltd. All rights reserved.
|
||
|
// SPDX-License-Identifier: MIT
|
||
|
//
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "Assert.hpp"
|
||
|
|
||
|
#include <armnn/Exceptions.hpp>
|
||
|
|
||
|
#include <memory>
|
||
|
#include <type_traits>
|
||
|
|
||
|
namespace armnn
|
||
|
{
|
||
|
|
||
|
// If we are testing then throw an exception, otherwise regular assert
|
||
|
#if defined(ARMNN_POLYMORPHIC_CAST_TESTABLE)
|
||
|
# define ARMNN_POLYMORPHIC_CAST_CHECK_METHOD(cond) ConditionalThrow<std::bad_cast>(cond)
|
||
|
#else
|
||
|
# define ARMNN_POLYMORPHIC_CAST_CHECK_METHOD(cond) ARMNN_ASSERT(cond)
|
||
|
#endif
|
||
|
|
||
|
//Only check the condition if debug build or during testing
|
||
|
#if !defined(NDEBUG) || defined(ARMNN_POLYMORPHIC_CAST_TESTABLE)
|
||
|
# define ARMNN_POLYMORPHIC_CAST_CHECK(cond) ARMNN_POLYMORPHIC_CAST_CHECK_METHOD(cond)
|
||
|
#else
|
||
|
# define ARMNN_POLYMORPHIC_CAST_CHECK(cond) // release builds dont check the cast
|
||
|
#endif
|
||
|
|
||
|
|
||
|
namespace utility
|
||
|
{
|
||
|
// static_pointer_cast overload for std::shared_ptr
|
||
|
template <class T1, class T2>
|
||
|
std::shared_ptr<T1> StaticPointerCast (const std::shared_ptr<T2>& sp)
|
||
|
{
|
||
|
return std::static_pointer_cast<T1>(sp);
|
||
|
}
|
||
|
|
||
|
// dynamic_pointer_cast overload for std::shared_ptr
|
||
|
template <class T1, class T2>
|
||
|
std::shared_ptr<T1> DynamicPointerCast (const std::shared_ptr<T2>& sp)
|
||
|
{
|
||
|
return std::dynamic_pointer_cast<T1>(sp);
|
||
|
}
|
||
|
|
||
|
// static_pointer_cast overload for raw pointers
|
||
|
template<class T1, class T2>
|
||
|
inline T1* StaticPointerCast(T2* ptr)
|
||
|
{
|
||
|
return static_cast<T1*>(ptr);
|
||
|
}
|
||
|
|
||
|
// dynamic_pointer_cast overload for raw pointers
|
||
|
template<class T1, class T2>
|
||
|
inline T1* DynamicPointerCast(T2* ptr)
|
||
|
{
|
||
|
return dynamic_cast<T1*>(ptr);
|
||
|
}
|
||
|
|
||
|
} // namespace utility
|
||
|
|
||
|
/// Polymorphic downcast for build in pointers only
|
||
|
///
|
||
|
/// Usage: Child* pChild = PolymorphicDowncast<Child*>(pBase);
|
||
|
///
|
||
|
/// \tparam DestType Pointer type to the target object (Child pointer type)
|
||
|
/// \tparam SourceType Pointer type to the source object (Base pointer type)
|
||
|
/// \param value Pointer to the source object
|
||
|
/// \return Pointer of type DestType (Pointer of type child)
|
||
|
template<typename DestType, typename SourceType>
|
||
|
DestType PolymorphicDowncast(SourceType* value)
|
||
|
{
|
||
|
static_assert(std::is_pointer<DestType>::value,
|
||
|
"PolymorphicDowncast only works with pointer types.");
|
||
|
|
||
|
ARMNN_POLYMORPHIC_CAST_CHECK(dynamic_cast<DestType>(value) == value);
|
||
|
return static_cast<DestType>(value);
|
||
|
}
|
||
|
|
||
|
|
||
|
/// Polymorphic downcast for shared pointers and build in pointers
|
||
|
///
|
||
|
/// Usage: auto pChild = PolymorphicPointerDowncast<Child>(pBase)
|
||
|
///
|
||
|
/// \tparam DestType Type of the target object (Child type)
|
||
|
/// \tparam SourceType Pointer type to the source object (Base (shared) pointer type)
|
||
|
/// \param value Pointer to the source object
|
||
|
/// \return Pointer of type DestType ((Shared) pointer of type child)
|
||
|
template<typename DestType, typename SourceType>
|
||
|
auto PolymorphicPointerDowncast(const SourceType& value)
|
||
|
{
|
||
|
ARMNN_POLYMORPHIC_CAST_CHECK(utility::DynamicPointerCast<DestType>(value)
|
||
|
== value);
|
||
|
return utility::StaticPointerCast<DestType>(value);
|
||
|
}
|
||
|
|
||
|
} //namespace armnn
|