#pragma once
#include "../ds_core/ds_core.h"
namespace snmalloc
{
template<typename T>
SNMALLOC_FAST_PATH auto call_is_initialised(T*, int)
-> decltype(T::is_initialised())
{
return T::is_initialised();
}
template<typename T>
SNMALLOC_FAST_PATH auto call_is_initialised(T*, long)
{
return true;
}
namespace detail
{
template<
SNMALLOC_CONCEPT(IsConfigDomestication) Config,
typename T,
SNMALLOC_CONCEPT(capptr::IsBound) B>
constexpr SNMALLOC_FAST_PATH auto has_domesticate(int) -> stl::enable_if_t<
stl::is_same_v<
decltype(Config::capptr_domesticate(
stl::declval<typename Config::LocalState*>(),
stl::declval<CapPtr<T, B>>())),
CapPtr<
T,
typename B::template with_wildness<
capptr::dimension::Wildness::Tame>>>,
bool>
{
return true;
}
template<
SNMALLOC_CONCEPT(IsConfig) Config,
typename T,
SNMALLOC_CONCEPT(capptr::IsBound) B>
constexpr SNMALLOC_FAST_PATH bool has_domesticate(long)
{
return false;
}
}
template<
SNMALLOC_CONCEPT(IsConfig) Config,
typename T,
SNMALLOC_CONCEPT(capptr::IsBound) B>
SNMALLOC_FAST_PATH_INLINE auto
capptr_domesticate(typename Config::LocalState* ls, CapPtr<T, B> p)
{
static_assert(
!detail::has_domesticate<Config, T, B>(0) ||
Config::Options.HasDomesticate,
"Back end provides domesticate function but opts out of using it ");
static_assert(
detail::has_domesticate<Config, T, B>(0) ||
!Config::Options.HasDomesticate,
"Back end does not provide capptr_domesticate and requests its use");
if constexpr (Config::Options.HasDomesticate)
{
return Config::capptr_domesticate(ls, p);
}
else
{
UNUSED(ls);
return CapPtr<
T,
typename B::template with_wildness<capptr::dimension::Wildness::Tame>>::
unsafe_from(p.unsafe_ptr());
}
}
}