I wrote my own based on some static asserts I found in Cereal. I have a base case with a bunch of specialisations I need for my own code. The specialisations are needed as the base case is true for std::shared_ptr<T>
even if T isn't itself serialisable.
/// Meta programming constant, can you serialise the type T to the Cereal archive ARCHIVE?
template<typename ARCHIVE, typename T>
static constexpr bool kHasCerealOutputArchiver
= not std::is_pointer<T>::value and cereal::traits::detail::count_output_serializers<T, ARCHIVE>::value != 0;
// specialisation for vectors
template<typename ARCHIVE, typename T, typename A>
static constexpr bool kHasCerealOutputArchiver<ARCHIVE, std::vector<T, A>> = kHasCerealOutputArchiver<ARCHIVE, T>;
// specialisation for shared_ptrs
template<typename ARCHIVE, typename T>
static constexpr bool kHasCerealOutputArchiver<ARCHIVE, std::shared_ptr<T>> = kHasCerealOutputArchiver<ARCHIVE, T>;
// specialisation for shared_ptrs to const
template<typename ARCHIVE, typename T>
static constexpr bool kHasCerealOutputArchiver<ARCHIVE, std::shared_ptr<const T>> = kHasCerealOutputArchiver<ARCHIVE, T>;
/// Meta programming constant, can you serialise the type T from the Cereal archive ARCHIVE?
template<typename ARCHIVE, typename T>
static constexpr bool kHasCerealInputArchiver
= not std::is_pointer<T>::value and cereal::traits::detail::count_input_serializers<T, ARCHIVE>::value != 0;
// specialisation for vectors
template<typename ARCHIVE, typename T, typename A>
static constexpr bool kHasCerealInputArchiver<ARCHIVE, std::vector<T, A>> = kHasCerealInputArchiver<ARCHIVE, T>;
// specialisation for shared_ptrs
template<typename ARCHIVE, typename T>
static constexpr bool kHasCerealInputArchiver<ARCHIVE, std::shared_ptr<T>> = kHasCerealInputArchiver<ARCHIVE, T>;
// specialisation for shared_ptrs to const
template<typename ARCHIVE, typename T>
static constexpr bool kHasCerealInputArchiver<ARCHIVE, std::shared_ptr<const T>> = kHasCerealInputArchiver<ARCHIVE, T>;