How to serialize boost::dynamic_bitset?

后端 未结 2 957
南旧
南旧 2020-12-06 14:17

How to serialize a class with a boost::dynamic_bitset member?

#include 
#include 

        
相关标签:
2条回答
  • 2020-12-06 14:39

    dynamic_bitset<> is not serializable, as you've found out (std::bitset<N> is different type).

    Not to worry, though, you can add it without too much effort:

    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);
            }
    
    } }
    

    This works e.g. 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);
        }
    }
    

    Note that if you can't afford to copy the blocks vector, it's equally easy to add serialization directly on the m_bits level, but that requires intrusive changes (friend access required at a minimum).

    Such a thing would easily be added to boost in a pull request.

    Update added that pull request

    0 讨论(0)
  • 2020-12-06 14:53

    I went ahead and filed the pull request to add Serialization support to 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.

    0 讨论(0)
提交回复
热议问题