Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation for std::string_view causes compiler error for XML and JSON archives #558

Open
Dimension4 opened this issue Apr 11, 2019 · 1 comment

Comments

@Dimension4
Copy link

I've implemented a custom save function for std::basic_string_view following the implementation from std::basic_string. Using binary and portable binary archives work without problems (even the tests pass), but when I try to test for the XML and JSON archives I get an compiler error telling me

cereal could not find any output serialization functions for the provided type and archive combination.

I'm using Visual Studio 2019 (16.0.1) with C++17 and x64 config.

My string_view.hpp (basically copy & paste):

#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);
}

and my test file (I use catch2 instead of boost):

#include "../include/cereal/types/string.hpp"
#include "../include/cereal/types/string_view.hpp"
#include "../include/cereal/archives/binary.hpp"
#include "../include/cereal/archives/portable_binary.hpp"
#include "../include/cereal/archives/xml.hpp"
#include "../include/cereal/archives/json.hpp"

#include <catch2/catch.hpp>

#include <sstream>


template <class IArchive, class OArchive>
void test_string_view()
{
    std::string_view out1 = "Some test string\n\t.";
    std::string_view out2 = "";
    std::string_view out3;

    std::ostringstream os;
    {
        OArchive oar(os);
        oar(out1);
        oar(out2);
        oar(out3);
    }

    // deserializing to std::string_view is not allowed, because it's dangerous

    std::string in1;
    std::string in2;
    std::string in3;

    std::istringstream is(os.str());
    {
        IArchive iar(is);
        iar(in1);
        iar(in2);
        iar(in3);
    }

    REQUIRE(out1 == in1);
    REQUIRE(out2 == in2);
    REQUIRE(out3 == in3);
}

TEST_CASE("std::string_view", "[string_view]")
{
    SECTION("to binary")
    {
        test_string_view<cereal::BinaryInputArchive, cereal::BinaryOutputArchive>();
    }

    SECTION("to portable binary")
    {
        test_string_view<cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive>();
    }

    SECTION("to xml")
    {
         test_string_view<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
    }

    SECTION("to json")
    {
         test_string_view<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
    }
}

Do I miss something or why doesn't the code compile?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants