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
15 changes: 11 additions & 4 deletions include/boost/archive/basic_archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ BOOST_ARCHIVE_VERSION();
typedef boost::serialization::library_version_type library_version_type;

class version_type {
private:
public:
// The wrapped type is part of the interface, since the conversion
// operators below return it and user code has no other way to name
// it. See issue #326. The same goes for the classes which follow.
typedef uint_least32_t base_type;
private:
base_type t;
public:
// should be private - but MPI fails if it's not!!!
Expand Down Expand Up @@ -73,8 +77,9 @@ class version_type {
};

class class_id_type {
private:
public:
typedef int_least16_t base_type;
private:
base_type t;
public:
// should be private - but then can't use BOOST_STRONG_TYPE below
Expand Down Expand Up @@ -112,8 +117,9 @@ class class_id_type {
#define BOOST_SERIALIZATION_NULL_POINTER_TAG boost::archive::class_id_type(-1)

class object_id_type {
private:
public:
typedef uint_least32_t base_type;
private:
base_type t;
public:
object_id_type(): t(0) {}
Expand Down Expand Up @@ -152,7 +158,8 @@ class object_id_type {
#endif

struct tracking_type {
bool t;
typedef bool base_type;
base_type t;
explicit tracking_type(const bool t_ = false)
: t(t_)
{}
Expand Down
6 changes: 5 additions & 1 deletion include/boost/serialization/collection_size_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ namespace serialization {
//BOOST_STRONG_TYPEDEF(std::size_t, collection_size_type)

class collection_size_type {
private:
public:
// The wrapped type is part of the interface, since the conversion
// operators below return it and user code has no other way to name
// it. See issue #326.
typedef std::size_t base_type;
private:
base_type t;
public:
collection_size_type(): t(0) {}
Expand Down
6 changes: 5 additions & 1 deletion include/boost/serialization/item_version_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ namespace serialization {
#endif

class item_version_type {
private:
public:
// The wrapped type is part of the interface, since the conversion
// operators below return it and user code has no other way to name
// it. See issue #326.
typedef unsigned int base_type;
private:
base_type t;
public:
// should be private - but MPI fails if it's not!!!
Expand Down
6 changes: 5 additions & 1 deletion include/boost/serialization/library_version_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ namespace serialization {
* binary archives won't be readable !!!
*/
class library_version_type {
private:
public:
// The wrapped type is part of the interface, since the conversion
// operators below return it and user code has no other way to name
// it. See issue #326.
typedef uint_least16_t base_type;
private:
base_type t;
public:
library_version_type(): t(0) {}
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ test-suite "serialization" :
[ test-bsl-run_polymorphic_files test_exported : polymorphic_base polymorphic_derived1 polymorphic_derived2 ]

# should compile
[ compile test_public_base_type.cpp ]
[ compile test_strong_typedef.cpp ]
;

Expand Down
67 changes: 67 additions & 0 deletions test/test_public_base_type.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// test_public_base_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.

// The classes an archive uses for versions, identifiers, counts and flags
// each wrap a single value and convert to it. Generic code reading such a
// value has to name the wrapped type, so every one of them publishes it as
// base_type.

// Requested by smuzaffar in
// https://github.com/boostorg/serialization/issues/326. With the typedef
// out of reach, generic code had to guess the wrapped type, and a
// static_cast to a wrong guess does not compile at all. A C style cast
// does, by reinterpreting the object rather than converting it, which is
// what GCC 14 warned about, and rightly so. Thanks for the report.

#include <boost/archive/basic_archive.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/item_version_type.hpp>
#include <boost/serialization/library_version_type.hpp>

// What a generic reader wants to write. A static_cast selects the
// conversion operator, so nothing is reinterpreted.
template<class T>
void check(T & t){
typename T::base_type & r = static_cast<typename T::base_type &>(t);
(void) r;
}

// And the same for a generic writer, through the const conversion.
template<class T>
void check_const(const T & t){
const typename T::base_type v = static_cast<typename T::base_type>(t);
(void) v;
}

template<class T>
void check_both(T & t){
check(t);
check_const(t);
}

int main(){
boost::archive::version_type version(0);
boost::archive::class_id_type class_id(0);
boost::archive::object_id_type object_id(std::size_t(0));
boost::archive::tracking_type tracking(false);
boost::serialization::collection_size_type collection_size(0);
boost::serialization::item_version_type item_version(0);
boost::serialization::library_version_type library_version(0);

check_both(version);
check_both(class_id);
check_both(object_id);
check_both(tracking);
check_both(collection_size);
check_both(item_version);
check_both(library_version);

return 0;
}