Skip to content

Deserialization of XML archive fails with std::pmr::string #267

Open
@schorsch1976

Description

@schorsch1976

Expected Behaviour: Serialization and deserialization of std::pmr::string works like std::string

Observed Behaviour: Exception is thrown at the deserialization of a std::pmr::string. The string is expected to be: "D1" but it is "D1</value>".

Reproduction Steps:

// STL Archive + Stuff
#include <boost/serialization/export.hpp>

// PMR Strings
#include <boost/config.hpp>
#include <boost/serialization/level.hpp>
#include <string>
#include <memory_resource>
BOOST_CLASS_IMPLEMENTATION(std::pmr::string, boost::serialization::primitive_type)
BOOST_CLASS_IMPLEMENTATION(std::pmr::wstring, boost::serialization::primitive_type)

// include headers that implement a archive in xml format
#include <boost/archive/archive_exception.hpp>


#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

using OArchive = boost::archive::xml_oarchive;
using IArchive = boost::archive::xml_iarchive;

#include <sstream>
using ArchiveIStringStream = std::istringstream;
using ArchiveOStringStream = std::ostringstream;

// -----------------------------------
#include <compare>
#include <cassert>

#if 1
// Trigger the Bug with that typedef
using String = std::pmr::string;
#else
// This Typedef works
using String = std::string;
#endif
struct Data
{
    friend class boost::serialization::access;

    // When the class Archive corresponds to an output archive, the
    // & operator is defined similar to <<.  Likewise, when the class Archive
    // is a type of input archive the & operator is defined similar to >>.
    template<class Archive>
    void serialize(Archive& ar, const unsigned int version)
    {
        ar& BOOST_SERIALIZATION_NVP(value);
        ar& BOOST_SERIALIZATION_NVP(test);
    }

    auto operator<=>(const Data& rhs) const = default;
    String value = "default";
    int test = 1;
};
BOOST_CLASS_VERSION(Data, 0)

std::string ToString(const Data& data)
{
    ArchiveOStringStream oss(std::ios::binary);

    {
        OArchive oa(oss);
        oa << BOOST_SERIALIZATION_NVP(data);
    }

    return oss.str();
}

Data FromString(std::string& s)
{
    Data data;
    ArchiveIStringStream iss(s, std::ios::binary);
    {
        IArchive ia(iss);
        ia >> BOOST_SERIALIZATION_NVP(data);
    }
    return data;
}

#include <iostream>

int main()
{
    try
    {
        Data d1;
        d1.value = "D1";
        d1.test = 1;

        auto s1 = ToString(d1);
        auto r1 = FromString(s1);

        assert(d1 == r1);

        std::cout << "Success: Is Equal: " << (d1 == r1) << "\n";
        return d1 == r1 ? EXIT_SUCCESS : EXIT_FAILURE;
    }
    catch (const std::exception& ex)
    {
        std::cerr << "Should not happen: " << ex.what() << "\n";
    }
    catch (...)
    {
        std::cerr << "Should not happen: unknown exception\n";
    }
    return EXIT_FAILURE;
}

OS: Windows 10 21H2 x64
Compiler: MSVC 2019 (16.11.9)
Boost: 1.80.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions