I've already asked this question on github (about a month ago), without any answer so I'm asking here now.
I'm using Cereal as a serialization library in my project. I've tried to add serialization functionality for std::string_view
(which is basically copy & paste from the std::string
implementation). However, Cereal throws a compiler error:
cereal could not find any output serialization functions for the provided type and archive combination.
Here is my implementation (I disabled deserialization here, but I've also tried a dummy function which gave me the same result):
#pragma once
#include "../cereal.hpp"
#include <string_view>
namespace cereal
{
//! Serialization for basic_string_view types, if binary data is supported
template <class Archive, class CharT, class Traits>
typename std::enable_if<traits::is_output_serializable<BinaryData<CharT>, Archive>::value, void>::type
CEREAL_SAVE_FUNCTION_NAME(Archive& ar, std::basic_string_view<CharT, Traits> const& str)
{
// Save number of chars + the data
ar(make_size_tag(static_cast<size_type>(str.size())));
ar(binary_data(str.data(), str.size() * sizeof(CharT)));
}
//! Deserialization into std::basic_string_view is forbidden due to its properties as a view.
//! However std::basic_string_view can be deserialized into a std::basic_string.
// template <class Archive, class CharT, class Traits>
// void CEREAL_LOAD_FUNCTION_NAME(Archive& ar, std::basic_string_view<CharT, Traits> & str);
}
Minimal example:
#include <iostream>
#include <cereal/string_view>
int main()
{
/*
* Working archive types are:
* - BinaryOutputArchive
* - PortableBinaryOutputArchive
*
* Compiler errors for:
* - JSONOutputArchive
* - XMLOutputArchive
*/
using OutputArchive = cereal::JSONOutputArchive;
std::string_view str = "Hello World!";
{
OutputArchive oar(std::cout);
oar(str);
}
return 0;
}
The test successfully compiles and passes for binary archives, but not for XML and JSON serialization.
I assume this has something to do with the trait in the enable_if
condition is_output_serializable<BinaryData<CharT>, Archive>
, but the trait is also present in the std::string
implementation and works perfectly fine. I also couldn't find a second definition or specialization for std::string
.
Why do I get that compiler error for XML and JSON archives?
As std::string
support for JSON and XML serializer is built it, it cannot be found in cereal/types/string.hpp
header.
You have to manually add support for string data just as you did for binary data.
I am not experienced in cereal library, but in docs there is example for archive specializations for std::map<std::string, std::string>
: http://uscilab.github.io/cereal/archive_specialization.html
It uses a little bit different SFINAE technique and cereal specific traits (is_text_archive
, check bottom of the very same article).
Given that, for your code it gives:
namespace cereal
{
template <class Archive, class CharT, class Traits,
traits::EnableIf<traits::is_text_archive<Archive>::value> = traits::sfinae> inline
void save( Archive & ar, std::basic_string_view<CharT, Traits> const & str )
{
/// ...
}
}
Note: docs use cereal::traits::DisableIf<cereal::traits::is_text_archive<Archive>::value>
to specify binary output specialization. It would be more consistent to use it in place of is_output_serializable<BinaryData<CharT>,...>