diff --git a/include/boost/serialization/shared_ptr_helper.hpp b/include/boost/serialization/shared_ptr_helper.hpp index 8974ef38d..a0d37af88 100644 --- a/include/boost/serialization/shared_ptr_helper.hpp +++ b/include/boost/serialization/shared_ptr_helper.hpp @@ -38,15 +38,6 @@ namespace boost_132 { namespace boost { namespace serialization { -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -template class SPT > -void load( - Archive & ar, - SPT< class U > &t, - const unsigned int file_version -); -#endif - /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // a common class for holding various types of shared pointers @@ -68,18 +59,7 @@ class shared_ptr_helper { void operator()(void const *) const {} }; -#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ -|| defined(BOOST_MSVC) \ -|| defined(__SUNPRO_CC) public: -#else - template - friend void boost::serialization::load( - Archive & ar, - SPT< U > &t, - const unsigned int file_version - ); -#endif #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP // list of loaded pointers. This is used to be sure that the pointers diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b0ed98126..dc4213c77 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -119,6 +119,7 @@ test-suite "serialization" : [ test-bsl-run_files test_variant : A ] [ test-bsl-run_files test_vector : A ] [ test-bsl-run_files test_shared_ptr ] + [ test-bsl-run_files test_shared_ptr_coexistence ] [ test-bsl-run_files test_shared_ptr_multi_base ] [ test-bsl-run_files test_shared_ptr_132 : : : [ requires auto_ptr ] ] # BOOST_NO_AUTO_PTR diff --git a/test/test_shared_ptr_coexistence.cpp b/test/test_shared_ptr_coexistence.cpp new file mode 100644 index 000000000..5535ecba9 --- /dev/null +++ b/test/test_shared_ptr_coexistence.cpp @@ -0,0 +1,107 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// test_shared_ptr_coexistence.cpp + +// Copyright 2026 Gennaro Prota. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// Including shared_ptr.hpp must leave the serialization of every other type +// alone. A declaration in shared_ptr_helper.hpp used to add an overload to +// boost::serialization::load matching any class template taking one type +// argument, so that a std::optional or a std::vector serialized in the same +// translation unit no longer compiled. + +// Reported by sowle in +// https://github.com/boostorg/serialization/issues/319, with a reduced +// example that took considerable effort to arrive at. correaa pinned the +// failure down to the exact declaration, and olologin contributed the +// std::vector case, which is covered here as well. Thanks to all three. + +#include +#include +#include +#include + +#include +#ifndef BOOST_NO_CXX17_HDR_OPTIONAL +#include +#endif + +#include +#include +#include +#include + +#include "test_tools.hpp" + +// Included last on purpose: the original report reached the failure with +// this header sitting after everything else. +#include + +struct payload { + int m_x; + payload() : m_x(0) {} + explicit payload(int x) : m_x(x) {} + template + void serialize(Archive & ar, const unsigned int /* version */){ + ar & boost::serialization::make_nvp("x", m_x); + } + bool operator==(const payload & rhs) const { + return m_x == rhs.m_x; + } +}; + +int +test_main(int /* argc */, char * /* argv */ []) +{ + const char * testfile = boost::archive::tmpnam(NULL); + BOOST_REQUIRE(NULL != testfile); + + const std::vector v(3, 7); + const boost::optional bo(payload(11)); + const boost::shared_ptr sp = boost::make_shared(13); + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL + const std::optional so(payload(17)); + #endif + { + test_ostream os(testfile, TEST_STREAM_FLAGS); + test_oarchive oa(os, TEST_ARCHIVE_FLAGS); + oa << boost::serialization::make_nvp("v", v); + oa << boost::serialization::make_nvp("bo", bo); + oa << boost::serialization::make_nvp("sp", sp); + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL + oa << boost::serialization::make_nvp("so", so); + #endif + } + + std::vector v2; + boost::optional bo2; + boost::shared_ptr sp2; + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL + std::optional so2; + #endif + { + test_istream is(testfile, TEST_STREAM_FLAGS); + test_iarchive ia(is, TEST_ARCHIVE_FLAGS); + ia >> boost::serialization::make_nvp("v", v2); + ia >> boost::serialization::make_nvp("bo", bo2); + ia >> boost::serialization::make_nvp("sp", sp2); + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL + ia >> boost::serialization::make_nvp("so", so2); + #endif + } + + BOOST_CHECK(v == v2); + BOOST_CHECK(bo == bo2); + BOOST_REQUIRE(NULL != sp2.get()); + BOOST_CHECK(*sp == *sp2); + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL + BOOST_CHECK(so == so2); + #endif + + std::remove(testfile); + return EXIT_SUCCESS; +}