#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_UTIL_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_UTIL_H_
#include <type_traits>
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
namespace mojo {
namespace internal {
template <typename T, typename U, typename SFINAE = void>
struct HasIsNullMethod : std::false_type {
static_assert(sizeof(T), "T must be a complete type.");
};
template <typename T, typename U>
struct HasIsNullMethod<
T,
U,
std::void_t<decltype(T::IsNull(std::declval<const U&>()))>>
: std::true_type {};
template <typename Traits, typename UserType>
bool CallIsNullIfExists(const UserType& input) {
if constexpr (HasIsNullMethod<Traits, UserType>::value) {
return Traits::IsNull(input);
} else {
return false;
}
}
template <typename T, typename U, typename SFINAE = void>
struct HasSetToNullMethod : std::false_type {
static_assert(sizeof(T), "T must be a complete type.");
};
template <typename T, typename U>
struct HasSetToNullMethod<
T,
U,
std::void_t<decltype(T::SetToNull(std::declval<U*>()))>> : std::true_type {
};
template <typename Traits, typename UserType>
bool CallSetToNullIfExists(UserType* output) {
if constexpr (HasSetToNullMethod<Traits, UserType>::value) {
Traits::SetToNull(output);
}
return true;
}
template <typename MojomType, typename UserType, typename = void>
struct TraitsFinder {
using Traits = StructTraits<MojomType, UserType>;
};
template <typename MojomType, typename UserType>
struct TraitsFinder<
MojomType,
UserType,
std::enable_if_t<BelongsTo<MojomType, MojomTypeCategory::kUnion>::value>> {
using Traits = UnionTraits<MojomType, UserType>;
};
template <typename UserType>
struct TraitsFinder<StringDataView, UserType> {
using Traits = StringTraits<UserType>;
};
template <typename UserType, typename ElementType>
struct TraitsFinder<ArrayDataView<ElementType>, UserType> {
using Traits = ArrayTraits<UserType>;
};
template <typename UserType, typename KeyType, typename ValueType>
struct TraitsFinder<MapDataView<KeyType, ValueType>, UserType> {
using Traits = MapTraits<UserType>;
};
template <typename MojomType, typename UserType>
constexpr bool IsValidUserTypeForOptionalValue() {
if constexpr (IsStdOptional<UserType>::value) {
return true;
} else {
using Traits = typename TraitsFinder<MojomType, UserType>::Traits;
return HasSetToNullMethod<Traits, UserType>::value;
}
}
template <typename T, typename U, typename SFINAE = void>
struct HasGetBeginMethod : std::false_type {
static_assert(sizeof(T), "T must be a complete type.");
};
template <typename T, typename U>
struct HasGetBeginMethod<T,
U,
std::void_t<decltype(T::GetBegin(std::declval<U&>()))>>
: std::true_type {};
template <typename T, typename U, typename SFINAE = void>
struct HasGetDataMethod : std::false_type {
static_assert(sizeof(T), "T must be a complete type.");
};
template <typename T, typename U>
struct HasGetDataMethod<T,
U,
std::void_t<decltype(&T::GetData(std::declval<U&>()))>>
: std::true_type {};
}
}
#endif