#pragma once
#include <CoreFoundation/CoreFoundation.h>
#include <wtf/Assertions.h>
#ifndef CF_BRIDGED_TYPE
#define CF_BRIDGED_TYPE(T)
#endif
namespace WTF {
template <typename> struct CFTypeTrait;
#define WTF_DECLARE_CF_TYPE_TRAIT(ClassName) \
template <> \
struct WTF::CFTypeTrait<ClassName##Ref> { \
static inline CFTypeID typeID(void) { return ClassName##GetTypeID(); } \
};
WTF_DECLARE_CF_TYPE_TRAIT(CFArray);
WTF_DECLARE_CF_TYPE_TRAIT(CFBoolean);
WTF_DECLARE_CF_TYPE_TRAIT(CFData);
WTF_DECLARE_CF_TYPE_TRAIT(CFDictionary);
WTF_DECLARE_CF_TYPE_TRAIT(CFNumber);
WTF_DECLARE_CF_TYPE_TRAIT(CFString);
#define WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(ClassName, MutableClassName) \
template <> \
struct WTF::CFTypeTrait<MutableClassName##Ref> { \
static inline CFTypeID typeID(void) { return ClassName##GetTypeID(); } \
};
WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(CFArray, CFMutableArray);
WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(CFData, CFMutableData);
WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(CFDictionary, CFMutableDictionary);
WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(CFString, CFMutableString);
#undef WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT
template<typename T> T dynamic_cf_cast(CFTypeRef object)
{
if (!object)
return nullptr;
ASSERT_WITH_SECURITY_IMPLICATION(CFGetTypeID(object) == CFTypeTrait<T>::typeID());
if (CFGetTypeID(object) != CFTypeTrait<T>::typeID())
return nullptr;
return static_cast<T>(const_cast<CF_BRIDGED_TYPE(id) void*>(object));
}
template<typename T> T checked_cf_cast(CFTypeRef object)
{
if (!object)
return nullptr;
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(CFGetTypeID(object) == CFTypeTrait<T>::typeID());
return static_cast<T>(const_cast<CF_BRIDGED_TYPE(id) void*>(object));
}
}
using WTF::checked_cf_cast;
using WTF::dynamic_cf_cast;