如何序列化boost::dynamic_bitset?
How to serialize boost::dynamic_bitset?
如何用 boost::dynamic_bitset 成员序列化 class?
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/serialization/bitset.hpp>
#include <sstream>
class A
{
friend class boost::serialization::access;
boost::dynamic_bitset<> x;
template<class Archive>
void serialize(Archive & ar, const unsigned int){
ar & x;
}
};
int main()
{
A a;
std::stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << a;
return 0;
}
编译报错(boost 1.57)
In file included from /usr/include/boost/serialization/extended_type_info_typeid.hpp:37:0,
from /usr/include/boost/archive/detail/oserializer.hpp:38,
from /usr/include/boost/archive/detail/interface_oarchive.hpp:23,
from /usr/include/boost/archive/detail/common_oarchive.hpp:22,
from /usr/include/boost/archive/basic_text_oarchive.hpp:32,
from /usr/include/boost/archive/text_oarchive.hpp:31,
from dynamic_bitset_setial.cpp:1:
/usr/include/boost/serialization/access.hpp: In static member function ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’:
/usr/include/boost/serialization/serialization.hpp:69:5: instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
/usr/include/boost/serialization/serialization.hpp:128:9: instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
/usr/include/boost/archive/detail/oserializer.hpp:148:5: instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
dynamic_bitset_setial.cpp:25:1: instantiated from here
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class boost::dynamic_bitset<>’ has no member named ‘serialize’
正如您所发现的,dynamic_bitset<>
不可序列化(std::bitset<N>
是不同的类型)。
不过不用担心,您可以毫不费力地添加它:
namespace boost { namespace serialization {
template <typename Ar, typename Block, typename Alloc>
void save(Ar& ar, dynamic_bitset<Block, Alloc> const& bs, unsigned) {
size_t num_bits = bs.size();
std::vector<Block> blocks(bs.num_blocks());
to_block_range(bs, blocks.begin());
ar & num_bits & blocks;
}
template <typename Ar, typename Block, typename Alloc>
void load(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned) {
size_t num_bits;
std::vector<Block> blocks;
ar & num_bits & blocks;
bs.resize(num_bits);
from_block_range(blocks.begin(), blocks.end(), bs);
bs.resize(num_bits);
}
template <typename Ar, typename Block, typename Alloc>
void serialize(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned version) {
split_free(ar, bs, version);
}
} }
这有效,例如Live On Coliru
int main() {
A a;
for (int i=0; i<128; ++i)
a.x.resize(11*i, i%2);
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
oa << a;
}
std::cout << ss.str();
{
boost::archive::text_iarchive ia(ss);
A b;
ia >> b;
assert(a.x == b.x);
}
}
请注意,如果您无力复制块向量,直接在 m_bits
级别添加序列化同样容易,但这需要进行侵入性更改(至少需要好友访问权限)。
这样的东西很容易被添加到拉取请求中。
更新
我继续 filed the pull request 为 Boost Dynamic Bitset 添加序列化支持
Serialization using the public interface isn't optimal as to_block_range()
/from_block_range()
require copying of m_bits
(and subsequent resize()
).
I added a generic implementation to Boost Dynamic Bitset. The changes merge cleanly against develop or master (1_58_0).
Changes
Implementation added with
- minimal intrusiveness, only a nested friend (
class serialization_impl;
) has been forward declared to "key-hole" the required friend access through
- This class, as well as the actual ADL hook for Boost Serialization are implemented in a separate header (
dynamic_bitset/serialization.hpp
, similar to other boost libraries with serialization support).
- This means that zero dependencies on Boost Serialization stuff exists unless
boost/dynamic_bitset/serialization.hpp
is actually included
- Zero copy is achieved (leveraging
std::vector<Block>
's builtin support in Boost Serialization)
Tests
The second commit in the pull request adds tests for this feature. I'm not sure how to add the dyn_bitset_unit_tests5.cpp
to the Jamfile. I suppose something else must be done to ensure linking to Boost System and Boost Serialization. I have run the tests myself using a simple wrapper:
#include <modular-boost/libs/dynamic_bitset/dyn_bitset_unit_tests5.cpp>
int main() {
test_main(0, nullptr);
}
Which can then be compiled and run with e.g.
g++ main.cpp -lboost_system -lboost_serialization && ./a.out
No output means no errors.
如何用 boost::dynamic_bitset 成员序列化 class?
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/serialization/bitset.hpp>
#include <sstream>
class A
{
friend class boost::serialization::access;
boost::dynamic_bitset<> x;
template<class Archive>
void serialize(Archive & ar, const unsigned int){
ar & x;
}
};
int main()
{
A a;
std::stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << a;
return 0;
}
编译报错(boost 1.57)
In file included from /usr/include/boost/serialization/extended_type_info_typeid.hpp:37:0,
from /usr/include/boost/archive/detail/oserializer.hpp:38,
from /usr/include/boost/archive/detail/interface_oarchive.hpp:23,
from /usr/include/boost/archive/detail/common_oarchive.hpp:22,
from /usr/include/boost/archive/basic_text_oarchive.hpp:32,
from /usr/include/boost/archive/text_oarchive.hpp:31,
from dynamic_bitset_setial.cpp:1:
/usr/include/boost/serialization/access.hpp: In static member function ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’:
/usr/include/boost/serialization/serialization.hpp:69:5: instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
/usr/include/boost/serialization/serialization.hpp:128:9: instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
/usr/include/boost/archive/detail/oserializer.hpp:148:5: instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
dynamic_bitset_setial.cpp:25:1: instantiated from here
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class boost::dynamic_bitset<>’ has no member named ‘serialize’
dynamic_bitset<>
不可序列化(std::bitset<N>
是不同的类型)。
不过不用担心,您可以毫不费力地添加它:
namespace boost { namespace serialization {
template <typename Ar, typename Block, typename Alloc>
void save(Ar& ar, dynamic_bitset<Block, Alloc> const& bs, unsigned) {
size_t num_bits = bs.size();
std::vector<Block> blocks(bs.num_blocks());
to_block_range(bs, blocks.begin());
ar & num_bits & blocks;
}
template <typename Ar, typename Block, typename Alloc>
void load(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned) {
size_t num_bits;
std::vector<Block> blocks;
ar & num_bits & blocks;
bs.resize(num_bits);
from_block_range(blocks.begin(), blocks.end(), bs);
bs.resize(num_bits);
}
template <typename Ar, typename Block, typename Alloc>
void serialize(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned version) {
split_free(ar, bs, version);
}
} }
这有效,例如Live On Coliru
int main() {
A a;
for (int i=0; i<128; ++i)
a.x.resize(11*i, i%2);
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
oa << a;
}
std::cout << ss.str();
{
boost::archive::text_iarchive ia(ss);
A b;
ia >> b;
assert(a.x == b.x);
}
}
请注意,如果您无力复制块向量,直接在 m_bits
级别添加序列化同样容易,但这需要进行侵入性更改(至少需要好友访问权限)。
这样的东西很容易被添加到拉取请求中。
更新
我继续 filed the pull request 为 Boost Dynamic Bitset 添加序列化支持
Serialization using the public interface isn't optimal as
to_block_range()
/from_block_range()
require copying ofm_bits
(and subsequentresize()
).I added a generic implementation to Boost Dynamic Bitset. The changes merge cleanly against develop or master (1_58_0).
Changes
Implementation added with
- minimal intrusiveness, only a nested friend (
class serialization_impl;
) has been forward declared to "key-hole" the required friend access through- This class, as well as the actual ADL hook for Boost Serialization are implemented in a separate header (
dynamic_bitset/serialization.hpp
, similar to other boost libraries with serialization support).- This means that zero dependencies on Boost Serialization stuff exists unless
boost/dynamic_bitset/serialization.hpp
is actually included- Zero copy is achieved (leveraging
std::vector<Block>
's builtin support in Boost Serialization)Tests
The second commit in the pull request adds tests for this feature. I'm not sure how to add the
dyn_bitset_unit_tests5.cpp
to the Jamfile. I suppose something else must be done to ensure linking to Boost System and Boost Serialization. I have run the tests myself using a simple wrapper:#include <modular-boost/libs/dynamic_bitset/dyn_bitset_unit_tests5.cpp> int main() { test_main(0, nullptr); }
Which can then be compiled and run with e.g.
g++ main.cpp -lboost_system -lboost_serialization && ./a.out
No output means no errors.