Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/boost/archive/basic_archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class version_type {
public:
// should be private - but MPI fails if it's not!!!
version_type(): t(0) {}
explicit version_type(const unsigned int & t_) : t(t_){
explicit version_type(const unsigned int t_) : t(t_){
BOOST_ASSERT(t_ <= boost::integer_traits<base_type>::const_max);
}
version_type(const version_type & t_) :
Expand Down Expand Up @@ -119,7 +119,7 @@ class object_id_type {
object_id_type(): t(0) {}
// note: presumes that size_t >= unsigned int.
// use explicit cast to silence useless warning
explicit object_id_type(const std::size_t & t_) : t(static_cast<base_type>(t_)){
explicit object_id_type(const std::size_t t_) : t(static_cast<base_type>(t_)){
// make quadruple sure that we haven't lost any real integer
// precision
BOOST_ASSERT(t_ <= boost::integer_traits<base_type>::const_max);
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ test-suite "serialization" :
[ test-bsl-run_files test_unique_ptr ]
[ test-bsl-run_files test_valarray ]
[ test-bsl-run_files test_variant : A ]
[ test-bsl-run_files test_version_value_type ]
[ test-bsl-run_files test_vector : A ]
[ test-bsl-run_files test_shared_ptr ]
[ test-bsl-run_files test_shared_ptr_multi_base ]
Expand Down
120 changes: 120 additions & 0 deletions test/test_version_value_type.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// test_version_value_type.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.

// A version trait written by hand has to work whichever integer type it
// names for its value. The library declares the trait as an int, but
// nothing stops a user from writing unsigned int, and doing so used to
// leave the value with no definition to link against: it was passed to
// version_type through a reference, which made a definition necessary.

// Reported by LowLevelMahn in
// https://github.com/boostorg/serialization/issues/311, together with a
// self contained example which linked with one integer type and not with
// the other. Thanks!

// Note that this only ever failed on compilers which do not fold the
// constant away, so it links either way on some of them.

#include <cstddef>
#include <cstdio>
#include <fstream>

#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::remove;
}
#endif

#include <boost/serialization/nvp.hpp>
#include <boost/serialization/version.hpp>

#include "test_tools.hpp"

// the value spelled the way the library spells it
struct signed_version {
int value;
};

// and spelled the way the report did, which is what used to fail
template<typename T, std::size_t N>
struct unsigned_version {
int value;
};

namespace boost {
namespace serialization {

template<>
struct version<signed_version>
{
BOOST_STATIC_CONSTANT(int, value = 1);
};

// a partial specialization, as in the report
template<typename T, std::size_t N>
struct version<unsigned_version<T, N> >
{
BOOST_STATIC_CONSTANT(unsigned int, value = 2);
};

template<class Archive>
void serialize(Archive & ar, signed_version & t, const unsigned int file_version){
BOOST_CHECK(1 == file_version);
ar & BOOST_SERIALIZATION_NVP(t.value);
}

template<class Archive, typename T, std::size_t N>
void serialize(
Archive & ar,
unsigned_version<T, N> & t,
const unsigned int file_version
){
BOOST_CHECK(2 == file_version);
ar & BOOST_SERIALIZATION_NVP(t.value);
}

} // namespace serialization
} // namespace boost

typedef unsigned_version<int, 3> unsigned_version_type;

int
test_main(int /* argc */, char * /* argv */ [])
{
const char * testfile = boost::archive::tmpnam(NULL);
BOOST_REQUIRE(NULL != testfile);

{
signed_version a;
a.value = 11;
unsigned_version_type b;
b.value = 22;
test_ostream os(testfile, TEST_STREAM_FLAGS);
test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
oa << BOOST_SERIALIZATION_NVP(a);
oa << BOOST_SERIALIZATION_NVP(b);
}
{
signed_version a;
a.value = 0;
unsigned_version_type b;
b.value = 0;
test_istream is(testfile, TEST_STREAM_FLAGS);
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
ia >> BOOST_SERIALIZATION_NVP(a);
ia >> BOOST_SERIALIZATION_NVP(b);
BOOST_CHECK(11 == a.value);
BOOST_CHECK(22 == b.value);
}

std::remove(testfile);
return EXIT_SUCCESS;
}