Boost logo

Boost :

From: Neal D. Becker (ndbecker2_at_[hidden])
Date: 2004-09-02 11:49:54


I propose to add the following to mersenne_twister, which will support both
the [proposed] boost::serialization as well as any other use:

Index: mersenne_twister.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/random/mersenne_twister.hpp,v
retrieving revision 1.16
diff -c -r1.16 mersenne_twister.hpp
*** mersenne_twister.hpp 27 Jul 2004 03:43:32 -0000 1.16
--- mersenne_twister.hpp 2 Sep 2004 16:44:07 -0000
***************
*** 133,138 ****
--- 133,145 ----
      return os;
    }
  
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ ar & x;
+ ar & i;
+ }
+
    template<class CharT, class Traits>
    friend std::basic_istream<CharT,Traits>&
    operator>>(std::basic_istream<CharT,Traits>& is, mersenne_twister& mt)

For use with boost::python pickling, I considered 2 approaches.

1) Use boost::serialization. This would require providing an archive format
that would archive via pickling.

2) Use an independent technique, but share the same interface "serialize".

I believe #2 is the best choice. Layering pickling on top of serialization
would result in duplication and inefficiency.

Although #2 is a bit awkward, it is feasible. Here is an example of how to
serialize mersenne_twister via the above interface, using boost::python
pickle. Perhaps this technique could be made more generic.

struct mt_pickle_suite : python::pickle_suite {
  struct Archive {
    struct Save {
      python::list result;
      void operator & (rng_t::result_type x[]) {
        python::list l;
        for (int i = 0; i < 2*rng_t::state_size; i++)
          l.append (x[i]);
        result.append (l);
      }

      template<typename T>
      void operator & (const T& x) {
        result.append (x);
      }
    };
    struct Load {
      python::object entries;
      Load (const python::object& _entries) :
        entries (_entries)
      {}
      void operator & (rng_t::result_type x[]) {
        python::list l = python::extract<python::list> (entries[0]);
        for (int i = 0; i < 2*rng_t::state_size; i++)
          x[i] = python::extract<rng_t::result_type> (l[i]);
      }

      template<typename T>
      void operator & (T& x) {
        x = (python::extract<T>(entries[1]));
      }
    };
  };
    
  static python::object getstate (rng_t& rng) {
    Archive::Save ar;
    rng.serialize (ar, 0);
    return ar.result;
  }

  static void
  setstate(rng_t& rng, python::object entries) {
    Archive::Load ar (entries);
    rng.serialize (ar, 0);
  }
};


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk