diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/serialization/example | |
parent | Initial commit. (diff) | |
download | ceph-upstream/16.2.11+ds.tar.xz ceph-upstream/16.2.11+ds.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/serialization/example')
41 files changed, 4747 insertions, 0 deletions
diff --git a/src/boost/libs/serialization/example/Jamfile.v2 b/src/boost/libs/serialization/example/Jamfile.v2 new file mode 100644 index 000000000..cce6ee65f --- /dev/null +++ b/src/boost/libs/serialization/example/Jamfile.v2 @@ -0,0 +1,42 @@ +# Boost serialization Library Build Jamfile +# (C) Copyright Robert Ramey 2002-2004. +# Use, modification, and distribution are subject to 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/libs/serialization for the library home page. + +project libs/serialization/example + : id serialization_example + : requirements <library>../build//boost_serialization + ; + +import ../util/test : + run-template + run-invoke + run-winvoke + test-bsl-run-no-lib + test-bsl-run + test-bsl-run_archive + test-bsl-run_files + test-bsl-run_polymorphic_archive +; + +test-suite "demo-suite" : + # demos + [ test-bsl-run demo ] + [ test-bsl-run demo_auto_ptr ] + [ test-bsl-run demo_exception ] + [ test-bsl-run demo_fast_archive ] + [ test-bsl-run demo_log : log_archive ] + [ test-bsl-run demo_pimpl : demo_pimpl_A ] + [ test-bsl-run demo_polymorphic : demo_polymorphic_A ] + [ test-bsl-run demo_portable_archive : portable_binary_iarchive portable_binary_oarchive ] + [ test-bsl-run demo_shared_ptr ] + [ test-bsl-run demo_simple_log ] + [ test-bsl-run demo_trivial_archive ] + [ test-bsl-run demo_xml ] + [ test-bsl-run demo_xml_save ] + [ test-bsl-run demo_xml_load : : : <dependency>demo_xml_save ] +; + diff --git a/src/boost/libs/serialization/example/demo.cpp b/src/boost/libs/serialization/example/demo.cpp new file mode 100644 index 000000000..cfd212770 --- /dev/null +++ b/src/boost/libs/serialization/example/demo.cpp @@ -0,0 +1,377 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo.cpp +// +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + + +#include <cstddef> // NULL +#include <iomanip> +#include <iostream> +#include <fstream> +#include <string> + +#include <boost/archive/tmpdir.hpp> + +#include <boost/archive/text_iarchive.hpp> +#include <boost/archive/text_oarchive.hpp> + +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/utility.hpp> +#include <boost/serialization/list.hpp> +#include <boost/serialization/assume_abstract.hpp> + +///////////////////////////////////////////////////////////// +// The intent of this program is to serve as a tutorial for +// users of the serialization package. An attempt has been made +// to illustrate most of the facilities of the package. +// +// The intent is to create an example suffciently complete to +// illustrate the usage and utility of the package while +// including a minimum of other code. +// +// This illustration models the bus system of a small city. +// This includes, multiple bus stops, bus routes and schedules. +// There are different kinds of stops. Bus stops in general will +// will appear on multiple routes. A schedule will include +// muliple trips on the same route. + +///////////////////////////////////////////////////////////// +// gps coordinate +// +// llustrates serialization for a simple type +// +class gps_position +{ + friend std::ostream & operator<<(std::ostream &os, const gps_position &gp); + friend class boost::serialization::access; + int degrees; + int minutes; + float seconds; + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & degrees & minutes & seconds; + } +public: + // every serializable class needs a constructor + gps_position(){}; + gps_position(int _d, int _m, float _s) : + degrees(_d), minutes(_m), seconds(_s) + {} +}; +std::ostream & operator<<(std::ostream &os, const gps_position &gp) +{ + return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"'; +} + +///////////////////////////////////////////////////////////// +// One bus stop +// +// illustrates serialization of serializable members +// + +class bus_stop +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp); + virtual std::string description() const = 0; + gps_position latitude; + gps_position longitude; + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & latitude; + ar & longitude; + } +protected: + bus_stop(const gps_position & _lat, const gps_position & _long) : + latitude(_lat), longitude(_long) + {} +public: + bus_stop(){} + virtual ~bus_stop(){} +}; + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop) + +std::ostream & operator<<(std::ostream &os, const bus_stop &bs) +{ + return os << bs.latitude << bs.longitude << ' ' << bs.description(); +} + +///////////////////////////////////////////////////////////// +// Several kinds of bus stops +// +// illustrates serialization of derived types +// +class bus_stop_corner : public bus_stop +{ + friend class boost::serialization::access; + std::string street1; + std::string street2; + virtual std::string description() const + { + return street1 + " and " + street2; + } + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + // save/load base class information + ar & boost::serialization::base_object<bus_stop>(*this); + ar & street1 & street2; + } + +public: + bus_stop_corner(){} + bus_stop_corner(const gps_position & _lat, const gps_position & _long, + const std::string & _s1, const std::string & _s2 + ) : + bus_stop(_lat, _long), street1(_s1), street2(_s2) + { + } +}; + +class bus_stop_destination : public bus_stop +{ + friend class boost::serialization::access; + std::string name; + virtual std::string description() const + { + return name; + } + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & boost::serialization::base_object<bus_stop>(*this) & name; + } +public: + + bus_stop_destination(){} + bus_stop_destination( + const gps_position & _lat, const gps_position & _long, const std::string & _name + ) : + bus_stop(_lat, _long), name(_name) + { + } +}; + +///////////////////////////////////////////////////////////// +// a bus route is a collection of bus stops +// +// illustrates serialization of STL collection templates. +// +// illustrates serialzation of polymorphic pointer (bus stop *); +// +// illustrates storage and recovery of shared pointers is correct +// and efficient. That is objects pointed to by more than one +// pointer are stored only once. In such cases only one such +// object is restored and pointers are restored to point to it +// +class bus_route +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const bus_route &br); + typedef bus_stop * bus_stop_pointer; + std::list<bus_stop_pointer> stops; + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + // in this program, these classes are never serialized directly but rather + // through a pointer to the base class bus_stop. So we need a way to be + // sure that the archive contains information about these derived classes. + //ar.template register_type<bus_stop_corner>(); + ar.register_type(static_cast<bus_stop_corner *>(NULL)); + //ar.template register_type<bus_stop_destination>(); + ar.register_type(static_cast<bus_stop_destination *>(NULL)); + // serialization of stl collections is already defined + // in the header + ar & stops; + } +public: + bus_route(){} + void append(bus_stop *_bs) + { + stops.insert(stops.end(), _bs); + } +}; +std::ostream & operator<<(std::ostream &os, const bus_route &br) +{ + std::list<bus_stop *>::const_iterator it; + // note: we're displaying the pointer to permit verification + // that duplicated pointers are properly restored. + for(it = br.stops.begin(); it != br.stops.end(); it++){ + os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it; + } + return os; +} + +///////////////////////////////////////////////////////////// +// a bus schedule is a collection of routes each with a starting time +// +// Illustrates serialization of STL objects(pair) in a non-intrusive way. +// See definition of operator<< <pair<F, S> >(ar, pair) and others in +// serialization.hpp +// +// illustrates nesting of serializable classes +// +// illustrates use of version number to automatically grandfather older +// versions of the same class. + +class bus_schedule +{ +public: + // note: this structure was made public. because the friend declarations + // didn't seem to work as expected. + struct trip_info + { + template<class Archive> + void serialize(Archive &ar, const unsigned int file_version) + { + // in versions 2 or later + if(file_version >= 2) + // read the drivers name + ar & driver; + // all versions have the follwing info + ar & hour & minute; + } + + // starting time + int hour; + int minute; + // only after system shipped was the driver's name added to the class + std::string driver; + + trip_info(){} + trip_info(int _h, int _m, const std::string &_d) : + hour(_h), minute(_m), driver(_d) + {} + }; +private: + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs); + friend std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti); + std::list<std::pair<trip_info, bus_route *> > schedule; + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & schedule; + } +public: + void append(const std::string &_d, int _h, int _m, bus_route *_br) + { + schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br)); + } + bus_schedule(){} +}; +BOOST_CLASS_VERSION(bus_schedule::trip_info, 2) + +std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti) +{ + return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' '; +} +std::ostream & operator<<(std::ostream &os, const bus_schedule &bs) +{ + std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it; + for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){ + os << it->first << *(it->second); + } + return os; +} + +void save_schedule(const bus_schedule &s, const char * filename){ + // make an archive + std::ofstream ofs(filename); + boost::archive::text_oarchive oa(ofs); + oa << s; +} + +void +restore_schedule(bus_schedule &s, const char * filename) +{ + // open the archive + std::ifstream ifs(filename); + boost::archive::text_iarchive ia(ifs); + + // restore the schedule from the archive + ia >> s; +} + +int main(int argc, char *argv[]) +{ + // make the schedule + bus_schedule original_schedule; + + // fill in the data + // make a few stops + bus_stop *bs0 = new bus_stop_corner( + gps_position(34, 135, 52.560f), + gps_position(134, 22, 78.30f), + "24th Street", "10th Avenue" + ); + bus_stop *bs1 = new bus_stop_corner( + gps_position(35, 137, 23.456f), + gps_position(133, 35, 54.12f), + "State street", "Cathedral Vista Lane" + ); + bus_stop *bs2 = new bus_stop_destination( + gps_position(35, 136, 15.456f), + gps_position(133, 32, 15.300f), + "White House" + ); + bus_stop *bs3 = new bus_stop_destination( + gps_position(35, 134, 48.789f), + gps_position(133, 32, 16.230f), + "Lincoln Memorial" + ); + + // make a routes + bus_route route0; + route0.append(bs0); + route0.append(bs1); + route0.append(bs2); + + // add trips to schedule + original_schedule.append("bob", 6, 24, &route0); + original_schedule.append("bob", 9, 57, &route0); + original_schedule.append("alice", 11, 02, &route0); + + // make aother routes + bus_route route1; + route1.append(bs3); + route1.append(bs2); + route1.append(bs1); + + // add trips to schedule + original_schedule.append("ted", 7, 17, &route1); + original_schedule.append("ted", 9, 38, &route1); + original_schedule.append("alice", 11, 47, &route1); + + // display the complete schedule + std::cout << "original schedule"; + std::cout << original_schedule; + + std::string filename(boost::archive::tmpdir()); + filename += "/demofile.txt"; + + // save the schedule + save_schedule(original_schedule, filename.c_str()); + + // ... some time later + // make a new schedule + bus_schedule new_schedule; + + restore_schedule(new_schedule, filename.c_str()); + + // and display + std::cout << "\nrestored schedule"; + std::cout << new_schedule; + // should be the same as the old one. (except for the pointer values) + + delete bs0; + delete bs1; + delete bs2; + delete bs3; + return 0; +} diff --git a/src/boost/libs/serialization/example/demo_auto_ptr.cpp b/src/boost/libs/serialization/example/demo_auto_ptr.cpp new file mode 100644 index 000000000..ff86ac413 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_auto_ptr.cpp @@ -0,0 +1,135 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_auto_ptr.cpp + +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <list> +#include <memory> +#include <fstream> +#include <string> + +#include <cstdio> // remove, std::autoptr inteface wrong in dinkumware +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::remove; +} +#endif + +#include <boost/archive/tmpdir.hpp> +#include <boost/archive/text_oarchive.hpp> +#include <boost/archive/text_iarchive.hpp> + +#include <boost/serialization/split_free.hpp> + +namespace boost { +namespace serialization { + +///////////////////////////////////////////////////////////// +// implement serialization for auto_ptr< T > +// note: this must be added to the boost namespace in order to +// be called by the library +template<class Archive, class T> +inline void save( + Archive & ar, + const std::auto_ptr< T > &t, + const unsigned int file_version +){ + // only the raw pointer has to be saved + // the ref count is rebuilt automatically on load + const T * const tx = t.get(); + ar << tx; +} + +template<class Archive, class T> +inline void load( + Archive & ar, + std::auto_ptr< T > &t, + const unsigned int file_version +){ + T *pTarget; + ar >> pTarget; + // note that the reset automagically maintains the reference count + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + t.release(); + t = std::auto_ptr< T >(pTarget); + #else + t.reset(pTarget); + #endif +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template<class Archive, class T> +inline void serialize( + Archive & ar, + std::auto_ptr< T > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +///////////////////////////////////////////////////////////// +// test auto_ptr serialization +class A +{ +private: + friend class boost::serialization::access; + int x; + template<class Archive> + void serialize(Archive &ar, const unsigned int /* file_version */){ + ar & x; + } +public: + A(){} // default constructor + ~A(){} // default destructor +}; + +void save(const std::auto_ptr<A> & spa, const char *filename) +{ + std::ofstream ofs(filename); + boost::archive::text_oarchive oa(ofs); + oa << spa; +} + +void load(std::auto_ptr<A> & spa, const char *filename) +{ + // open the archive + std::ifstream ifs(filename); + boost::archive::text_iarchive ia(ifs); + + // restore the schedule from the archive + ia >> spa; +} + +int main(int argc, char *argv[]) +{ + std::string filename = boost::archive::tmpdir(); + filename += "/testfile"; + + // create a new auto pointer to ta new object of type A + std::auto_ptr<A> spa(new A); + // serialize it + save(spa, filename.c_str()); + // reset the auto pointer to NULL + // thereby destroying the object of type A + // note that the reset automagically maintains the reference count + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + spa.release(); + #else + spa.reset(); + #endif + // restore state to one equivalent to the original + // creating a new type A object + load(spa, filename.c_str()); + // obj of type A gets destroyed + // as auto_ptr goes out of scope + std::remove(filename.c_str()); + return 0; +} diff --git a/src/boost/libs/serialization/example/demo_dll_a.hpp b/src/boost/libs/serialization/example/demo_dll_a.hpp new file mode 100644 index 000000000..0dd5ffb93 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_dll_a.hpp @@ -0,0 +1,318 @@ +#ifndef BOOST_SERIALIZATION_TEST_A_HPP +#define BOOST_SERIALIZATION_TEST_A_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// A.hpp simple class test + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <cassert> +#include <cstdlib> // for rand() +#include <cmath> // for fabs() +#include <cstddef> // size_t +#include <boost/math/special_functions/next.hpp> + +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::rand; + using ::fabs; + using ::size_t; +} +#endif + +//#include <boost/test/test_exec_monitor.hpp> +#include <boost/limits.hpp> +#include <boost/cstdint.hpp> + +#include <boost/detail/workaround.hpp> +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include <boost/archive/dinkumware.hpp> +#endif + +#include <boost/serialization/nvp.hpp> +#include <boost/serialization/string.hpp> +#include <boost/serialization/access.hpp> + +class A +{ +private: + friend class boost::serialization::access; + // note: from an aesthetic perspective, I would much prefer to have this + // defined out of line. Unfortunately, this trips a bug in the VC 6.0 + // compiler. So hold our nose and put it her to permit running of tests. + template<class Archive> + void serialize( + Archive &ar, + const unsigned int /* file_version */ + ){ + ar & BOOST_SERIALIZATION_NVP(b); + #ifndef BOOST_NO_INT64_T + ar & BOOST_SERIALIZATION_NVP(f); + ar & BOOST_SERIALIZATION_NVP(g); + #endif + #if BOOST_WORKAROUND(__BORLANDC__, <= 0x551 ) + int i; + if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){ + i = l; + ar & BOOST_SERIALIZATION_NVP(i); + } + else{ + ar & BOOST_SERIALIZATION_NVP(i); + l = i; + } + #else + ar & BOOST_SERIALIZATION_NVP(l); + #endif + ar & BOOST_SERIALIZATION_NVP(m); + ar & BOOST_SERIALIZATION_NVP(n); + ar & BOOST_SERIALIZATION_NVP(o); + ar & BOOST_SERIALIZATION_NVP(p); + ar & BOOST_SERIALIZATION_NVP(q); + #ifndef BOOST_NO_CWCHAR + ar & BOOST_SERIALIZATION_NVP(r); + #endif + ar & BOOST_SERIALIZATION_NVP(c); + ar & BOOST_SERIALIZATION_NVP(s); + ar & BOOST_SERIALIZATION_NVP(t); + ar & BOOST_SERIALIZATION_NVP(u); + ar & BOOST_SERIALIZATION_NVP(v); + ar & BOOST_SERIALIZATION_NVP(w); + ar & BOOST_SERIALIZATION_NVP(x); + ar & BOOST_SERIALIZATION_NVP(y); + #ifndef BOOST_NO_STD_WSTRING + ar & BOOST_SERIALIZATION_NVP(z); + #endif + } + bool b; + #ifndef BOOST_NO_INT64_T + boost::int64_t f; + boost::uint64_t g; + #endif + enum h { + i = 0, + j, + k + } l; + std::size_t m; + signed long n; + unsigned long o; + signed short p; + unsigned short q; + #ifndef BOOST_NO_CWCHAR + wchar_t r; + #endif + char c; + signed char s; + unsigned char t; + signed int u; + unsigned int v; + float w; + double x; + std::string y; + #ifndef BOOST_NO_STD_WSTRING + std::wstring z; + #endif +public: + A(); + bool operator==(const A &rhs) const; + bool operator!=(const A &rhs) const; + bool operator<(const A &rhs) const; // used by less + // hash function for class A + operator std::size_t () const; + friend std::ostream & operator<<(std::ostream & os, A const & a); + friend std::istream & operator>>(std::istream & is, A & a); +}; + +//BOOST_TEST_DONT_PRINT_LOG_VALUE(A); + +template<class S> +void randomize(S &x) +{ + assert(0 == x.size()); + for(;;){ + unsigned int i = std::rand() % 27; + if(0 == i) + break; + x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i); + } +} + +template<class T> +void accumulate(std::size_t & s, const T & t){ + const char * tptr = (const char *)(& t); + unsigned int count = sizeof(t); + while(count-- > 0){ + s += *tptr++; + } +} + +A::operator std::size_t () const { + std::size_t retval = 0; + accumulate(retval, b); + #ifndef BOOST_NO_INT64_T + accumulate(retval, f); + accumulate(retval, g); + #endif + accumulate(retval, l); + accumulate(retval, m); + accumulate(retval, n); + accumulate(retval, o); + accumulate(retval, p); + accumulate(retval, q); + #ifndef BOOST_NO_CWCHAR + accumulate(retval, r); + #endif + accumulate(retval, c); + accumulate(retval, s); + accumulate(retval, t); + accumulate(retval, u); + accumulate(retval, v); + return retval; +} + +inline A::A() : + b(true), + #ifndef BOOST_NO_INT64_T + f(std::rand() * std::rand()), + g(std::rand() * std::rand()), + #endif + l(static_cast<enum h>(std::rand() % 3)), + m(std::rand()), + n(std::rand()), + o(std::rand()), + p(std::rand()), + q(std::rand()), + #ifndef BOOST_NO_CWCHAR + r(std::rand()), + #endif + c(std::rand()), + s(std::rand()), + t(std::rand()), + u(std::rand()), + v(std::rand()), + w((float)std::rand()), + x((double)std::rand()) +{ + randomize(y); + #ifndef BOOST_NO_STD_WSTRING + randomize(z); + #endif +} + +inline bool A::operator==(const A &rhs) const +{ + if(b != rhs.b) + return false; + if(l != rhs.l) + return false; + #ifndef BOOST_NO_INT64_T + if(f != rhs.f) + return false; + if(g != rhs.g) + return false; + #endif + if(m != rhs.m) + return false; + if(n != rhs.n) + return false; + if(o != rhs.o) + return false; + if(p != rhs.p) + return false; + if(q != rhs.q) + return false; + #ifndef BOOST_NO_CWCHAR + if(r != rhs.r) + return false; + #endif + if(c != rhs.c) + return false; + if(s != rhs.s) + return false; + if(t != rhs.t) + return false; + if(u != rhs.u) + return false; + if(v != rhs.v) + return false; + if(std::abs( boost::math::float_distance(w, rhs.w)) > 1) + return false; + if(std::abs( boost::math::float_distance(x, rhs.x)) > 1) + return false; + if(0 != y.compare(rhs.y)) + return false; + #ifndef BOOST_NO_STD_WSTRING + if(0 != z.compare(rhs.z)) + return false; + #endif + return true; +} + +inline bool A::operator!=(const A &rhs) const +{ + return ! (*this == rhs); +} + +inline bool A::operator<(const A &rhs) const +{ + if(b != rhs.b) + return b < rhs.b; + #ifndef BOOST_NO_INT64_T + if(f != rhs.f) + return f < rhs.f; + if(g != rhs.g) + return g < rhs.g; + #endif + if(l != rhs.l ) + return l < rhs.l; + if(m != rhs.m ) + return m < rhs.m; + if(n != rhs.n ) + return n < rhs.n; + if(o != rhs.o ) + return o < rhs.o; + if(p != rhs.p ) + return p < rhs.p; + if(q != rhs.q ) + return q < rhs.q; + #ifndef BOOST_NO_CWCHAR + if(r != rhs.r ) + return r < rhs.r; + #endif + if(c != rhs.c ) + return c < rhs.c; + if(s != rhs.s ) + return s < rhs.s; + if(t != rhs.t ) + return t < rhs.t; + if(u != rhs.u ) + return u < rhs.u; + if(v != rhs.v ) + return v < rhs.v; + if(w != rhs.w ) + return w < rhs.w; + if(x != rhs.x ) + return x < rhs.x; + int i = y.compare(rhs.y); + if(i != 0 ) + return i < 0; + #ifndef BOOST_NO_STD_WSTRING + int j = z.compare(rhs.z); + if(j != 0 ) + return j < 0; + #endif + return false; +} + +#endif // BOOST_SERIALIZATION_TEST_A_HPP diff --git a/src/boost/libs/serialization/example/demo_dll_a.ipp b/src/boost/libs/serialization/example/demo_dll_a.ipp new file mode 100644 index 000000000..99cc9fe61 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_dll_a.ipp @@ -0,0 +1,317 @@ +#ifndef BOOST_SERIALIZATION_TEST_A_HPP +#define BOOST_SERIALIZATION_TEST_A_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// A.hpp simple class test + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <cassert> +#include <cstdlib> // for rand() +#include <cmath> // for fabs() +#include <cstddef> // size_t + +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::rand; + using ::fabs; + using ::size_t; +} +#endif + +//#include <boost/test/test_exec_monitor.hpp> +#include <boost/limits.hpp> +#include <boost/cstdint.hpp> + +#include <boost/detail/workaround.hpp> +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include <boost/archive/dinkumware.hpp> +#endif + +#include <boost/serialization/nvp.hpp> +#include <boost/serialization/string.hpp> +#include <boost/serialization/access.hpp> + +class A +{ +private: + friend class boost::serialization::access; + // note: from an aesthetic perspective, I would much prefer to have this + // defined out of line. Unfortunately, this trips a bug in the VC 6.0 + // compiler. So hold our nose and put it her to permit running of tests. + template<class Archive> + void serialize( + Archive &ar, + const unsigned int /* file_version */ + ){ + ar & BOOST_SERIALIZATION_NVP(b); + #ifndef BOOST_NO_INT64_T + ar & BOOST_SERIALIZATION_NVP(f); + ar & BOOST_SERIALIZATION_NVP(g); + #endif + #if BOOST_WORKAROUND(__BORLANDC__, <= 0x551 ) + int i; + if(BOOST_DEDUCED_TYPENAME Archive::is_saving::value){ + i = l; + ar & BOOST_SERIALIZATION_NVP(i); + } + else{ + ar & BOOST_SERIALIZATION_NVP(i); + l = i; + } + #else + ar & BOOST_SERIALIZATION_NVP(l); + #endif + ar & BOOST_SERIALIZATION_NVP(m); + ar & BOOST_SERIALIZATION_NVP(n); + ar & BOOST_SERIALIZATION_NVP(o); + ar & BOOST_SERIALIZATION_NVP(p); + ar & BOOST_SERIALIZATION_NVP(q); + #ifndef BOOST_NO_CWCHAR + ar & BOOST_SERIALIZATION_NVP(r); + #endif + ar & BOOST_SERIALIZATION_NVP(c); + ar & BOOST_SERIALIZATION_NVP(s); + ar & BOOST_SERIALIZATION_NVP(t); + ar & BOOST_SERIALIZATION_NVP(u); + ar & BOOST_SERIALIZATION_NVP(v); + ar & BOOST_SERIALIZATION_NVP(w); + ar & BOOST_SERIALIZATION_NVP(x); + ar & BOOST_SERIALIZATION_NVP(y); + #ifndef BOOST_NO_STD_WSTRING + ar & BOOST_SERIALIZATION_NVP(z); + #endif + } + bool b; + #ifndef BOOST_NO_INT64_T + boost::int64_t f; + boost::uint64_t g; + #endif + enum h { + i = 0, + j, + k + } l; + std::size_t m; + signed long n; + unsigned long o; + signed short p; + unsigned short q; + #ifndef BOOST_NO_CWCHAR + wchar_t r; + #endif + char c; + signed char s; + unsigned char t; + signed int u; + unsigned int v; + float w; + double x; + std::string y; + #ifndef BOOST_NO_STD_WSTRING + std::wstring z; + #endif +public: + A(); + bool operator==(const A &rhs) const; + bool operator!=(const A &rhs) const; + bool operator<(const A &rhs) const; // used by less + // hash function for class A + operator std::size_t () const; + friend std::ostream & operator<<(std::ostream & os, A const & a); + friend std::istream & operator>>(std::istream & is, A & a); +}; + +//BOOST_TEST_DONT_PRINT_LOG_VALUE(A); + +template<class S> +void randomize(S &x) +{ + assert(0 == x.size()); + for(;;){ + unsigned int i = std::rand() % 27; + if(0 == i) + break; + x += static_cast<BOOST_DEDUCED_TYPENAME S::value_type>('a' - 1 + i); + } +} + +template<class T> +void accumulate(std::size_t & s, const T & t){ + const char * tptr = (const char *)(& t); + unsigned int count = sizeof(t); + while(count-- > 0){ + s += *tptr++; + } +} + +A::operator std::size_t () const { + std::size_t retval = 0; + accumulate(retval, b); + #ifndef BOOST_NO_INT64_T + accumulate(retval, f); + accumulate(retval, g); + #endif + accumulate(retval, l); + accumulate(retval, m); + accumulate(retval, n); + accumulate(retval, o); + accumulate(retval, p); + accumulate(retval, q); + #ifndef BOOST_NO_CWCHAR + accumulate(retval, r); + #endif + accumulate(retval, c); + accumulate(retval, s); + accumulate(retval, t); + accumulate(retval, u); + accumulate(retval, v); + return retval; +} + +inline A::A() : + b(true), + #ifndef BOOST_NO_INT64_T + f(std::rand() * std::rand()), + g(std::rand() * std::rand()), + #endif + l(static_cast<enum h>(std::rand() % 3)), + m(std::rand()), + n(std::rand()), + o(std::rand()), + p(std::rand()), + q(std::rand()), + #ifndef BOOST_NO_CWCHAR + r(std::rand()), + #endif + c(std::rand()), + s(std::rand()), + t(std::rand()), + u(std::rand()), + v(std::rand()), + w((float)std::rand()), + x((double)std::rand()) +{ + randomize(y); + #ifndef BOOST_NO_STD_WSTRING + randomize(z); + #endif +} + +inline bool A::operator==(const A &rhs) const +{ + if(b != rhs.b) + return false; + if(l != rhs.l) + return false; + #ifndef BOOST_NO_INT64_T + if(f != rhs.f) + return false; + if(g != rhs.g) + return false; + #endif + if(m != rhs.m) + return false; + if(n != rhs.n) + return false; + if(o != rhs.o) + return false; + if(p != rhs.p) + return false; + if(q != rhs.q) + return false; + #ifndef BOOST_NO_CWCHAR + if(r != rhs.r) + return false; + #endif + if(c != rhs.c) + return false; + if(s != rhs.s) + return false; + if(t != rhs.t) + return false; + if(u != rhs.u) + return false; + if(v != rhs.v) + return false; + if(std::abs( boost::math::float_distance(w, rhs.w)) > 1) + return false; + if(std::abs( boost::math::float_distance(x, rhs.x)) > 1) + return false; + if(0 != y.compare(rhs.y)) + return false; + #ifndef BOOST_NO_STD_WSTRING + if(0 != z.compare(rhs.z)) + return false; + #endif + return true; +} + +inline bool A::operator!=(const A &rhs) const +{ + return ! (*this == rhs); +} + +inline bool A::operator<(const A &rhs) const +{ + if(b != rhs.b) + return b < rhs.b; + #ifndef BOOST_NO_INT64_T + if(f != rhs.f) + return f < rhs.f; + if(g != rhs.g) + return g < rhs.g; + #endif + if(l != rhs.l ) + return l < rhs.l; + if(m != rhs.m ) + return m < rhs.m; + if(n != rhs.n ) + return n < rhs.n; + if(o != rhs.o ) + return o < rhs.o; + if(p != rhs.p ) + return p < rhs.p; + if(q != rhs.q ) + return q < rhs.q; + #ifndef BOOST_NO_CWCHAR + if(r != rhs.r ) + return r < rhs.r; + #endif + if(c != rhs.c ) + return c < rhs.c; + if(s != rhs.s ) + return s < rhs.s; + if(t != rhs.t ) + return t < rhs.t; + if(u != rhs.u ) + return u < rhs.u; + if(v != rhs.v ) + return v < rhs.v; + if(w != rhs.w ) + return w < rhs.w; + if(x != rhs.x ) + return x < rhs.x; + int i = y.compare(rhs.y); + if(i != 0 ) + return i < 0; + #ifndef BOOST_NO_STD_WSTRING + int j = z.compare(rhs.z); + if(j != 0 ) + return j < 0; + #endif + return false; +} + +#endif // BOOST_SERIALIZATION_TEST_A_HPP diff --git a/src/boost/libs/serialization/example/demo_dll_b.hpp b/src/boost/libs/serialization/example/demo_dll_b.hpp new file mode 100644 index 000000000..3fcfea672 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_dll_b.hpp @@ -0,0 +1,113 @@ +#ifndef BOOST_SERIALIZATION_TEST_B_HPP +#define BOOST_SERIALIZATION_TEST_B_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// B.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <cstdlib> // for rand() +#include <boost/math/special_functions/next.hpp> + +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::rand; +} +#endif + +#include <boost/serialization/version.hpp> +#include <boost/serialization/split_member.hpp> +#include <boost/serialization/base_object.hpp> + +#include "A.hpp" + +/////////////////////////////////////////////////////// +// Derived class test +class B : public A +{ +private: + friend class boost::serialization::access; + template<class Archive> + void save(Archive &ar, const unsigned int /* file_version */) const + { + // write any base class info to the archive + ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); + + // write out members + ar << BOOST_SERIALIZATION_NVP(s); + ar << BOOST_SERIALIZATION_NVP(t); + ar << BOOST_SERIALIZATION_NVP(u); + ar << BOOST_SERIALIZATION_NVP(v); + ar << BOOST_SERIALIZATION_NVP(w); + ar << BOOST_SERIALIZATION_NVP(x); + } + + template<class Archive> + void load(Archive & ar, const unsigned int file_version) + { + // read any base class info to the archive + ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); + switch(file_version){ + case 1: + case 2: + ar >> BOOST_SERIALIZATION_NVP(s); + ar >> BOOST_SERIALIZATION_NVP(t); + ar >> BOOST_SERIALIZATION_NVP(u); + ar >> BOOST_SERIALIZATION_NVP(v); + ar >> BOOST_SERIALIZATION_NVP(w); + ar >> BOOST_SERIALIZATION_NVP(x); + default: + break; + } + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + signed char s; + unsigned char t; + signed int u; + unsigned int v; + float w; + double x; +public: + B(); + virtual ~B(){}; + bool operator==(const B &rhs) const; +}; + +B::B() : + s(std::rand()), + t(std::rand()), + u(std::rand()), + v(std::rand()), + w((float)std::rand() / std::rand()), + x((double)std::rand() / std::rand()) +{ +} + +BOOST_CLASS_VERSION(B, 2) + +inline bool B::operator==(const B &rhs) const +{ + return + A::operator==(rhs) + && s == rhs.s + && t == rhs.t + && u == rhs.u + && v == rhs.v + && std::abs( boost::math::float_distance(w, rhs.w)) < 2 + && std::abs( boost::math::float_distance(x, rhs.x)) < 2 + ; +} + +#endif // BOOST_SERIALIZATION_TEST_B_HPP diff --git a/src/boost/libs/serialization/example/demo_dll_b.ipp b/src/boost/libs/serialization/example/demo_dll_b.ipp new file mode 100644 index 000000000..74d53b794 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_dll_b.ipp @@ -0,0 +1,112 @@ +#ifndef BOOST_SERIALIZATION_TEST_B_HPP +#define BOOST_SERIALIZATION_TEST_B_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// B.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <cstdlib> // for rand() + +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::rand; +} +#endif + +#include <boost/serialization/version.hpp> +#include <boost/serialization/split_member.hpp> +#include <boost/serialization/base_object.hpp> + +#include "A.hpp" + +/////////////////////////////////////////////////////// +// Derived class test +class B : public A +{ +private: + friend class boost::serialization::access; + template<class Archive> + void save(Archive &ar, const unsigned int /* file_version */) const + { + // write any base class info to the archive + ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); + + // write out members + ar << BOOST_SERIALIZATION_NVP(s); + ar << BOOST_SERIALIZATION_NVP(t); + ar << BOOST_SERIALIZATION_NVP(u); + ar << BOOST_SERIALIZATION_NVP(v); + ar << BOOST_SERIALIZATION_NVP(w); + ar << BOOST_SERIALIZATION_NVP(x); + } + + template<class Archive> + void load(Archive & ar, const unsigned int file_version) + { + // read any base class info to the archive + ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); + switch(file_version){ + case 1: + case 2: + ar >> BOOST_SERIALIZATION_NVP(s); + ar >> BOOST_SERIALIZATION_NVP(t); + ar >> BOOST_SERIALIZATION_NVP(u); + ar >> BOOST_SERIALIZATION_NVP(v); + ar >> BOOST_SERIALIZATION_NVP(w); + ar >> BOOST_SERIALIZATION_NVP(x); + default: + break; + } + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + signed char s; + unsigned char t; + signed int u; + unsigned int v; + float w; + double x; +public: + B(); + virtual ~B(){}; + bool operator==(const B &rhs) const; +}; + +B::B() : + s(std::rand()), + t(std::rand()), + u(std::rand()), + v(std::rand()), + w((float)std::rand() / std::rand()), + x((double)std::rand() / std::rand()) +{ +} + +BOOST_CLASS_VERSION(B, 2) + +inline bool B::operator==(const B &rhs) const +{ + return + A::operator==(rhs) + && s == rhs.s + && t == rhs.t + && u == rhs.u + && v == rhs.v + && std::abs( boost::math::float_distance(w, rhs.w)) < 2 + && std::abs( boost::math::float_distance(x, rhs.x)) < 2 + ; +} + +#endif // BOOST_SERIALIZATION_TEST_B_HPP diff --git a/src/boost/libs/serialization/example/demo_exception.cpp b/src/boost/libs/serialization/example/demo_exception.cpp new file mode 100644 index 000000000..84f881f9b --- /dev/null +++ b/src/boost/libs/serialization/example/demo_exception.cpp @@ -0,0 +1,258 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_exception.cpp + +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +// Example of safe exception handling for pointer de-serialization +// +// This example was prepared by Robert Ramey to demonstrate and test +// safe exception handling during the de-serialization of pointers in +// a non-trivial example. +// +// Hopefully, this addresses exception issues raised by +// Vahan Margaryan who spent considerable time and effort +// in the analysis and testing of issues of exception safety +// of the serialization library. + +#include <algorithm> +#include <iostream> +#include <cstddef> // NULL +#include <fstream> +#include <string> + +#include <cstdio> // remove +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::remove; +} +#endif + +#include <boost/archive/tmpdir.hpp> + +#ifndef BOOST_NO_EXCEPTIONS +#include <exception> +#endif + +#include <boost/archive/text_iarchive.hpp> +#include <boost/archive/text_oarchive.hpp> + +#include <boost/serialization/list.hpp> +#include <boost/serialization/split_member.hpp> + +template<class TPTR> +struct deleter +{ + void operator()(TPTR t){ + delete t; + } +}; + +class Course; +class Student; + +class Student +{ +public: + static int count; + Student(){ + count++; + } + ~Student(){ + some_courses.clear(); + count--; + } + std::list<Course *> some_courses; +private: + friend class boost::serialization::access; + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & some_courses; + } +}; + +int Student::count = 0; + +class Course +{ +public: + static int count; + Course(){ + count++; + } + ~Course(){ + // doesnt delete pointers in list + // since it doesn't "own" them + some_students.clear(); + count--; + } + std::list<Student *> some_students; +private: + friend class boost::serialization::access; + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & some_students; + } +}; + +int Course::count = 0; + +class School +{ +public: + ~School(){ + // must delete all the students because + // it "owns" them + std::for_each(all_students.begin(), all_students.end(), deleter<Student *>()); + all_students.clear(); + // as well as courses + std::for_each(all_courses.begin(), all_courses.end(), deleter<Course *>()); + all_courses.clear(); + } + std::list<Student *> all_students; + std::list<Course *> all_courses; +private: + friend class boost::serialization::access; + BOOST_SERIALIZATION_SPLIT_MEMBER() + template<class Archive> + void save(Archive & ar, const unsigned int file_version) const; + template<class Archive> + void load(Archive & ar, const unsigned int file_version); +}; + +#if 0 +// case 1: +template<class Archive> +void School::serialize(Archive & ar, const unsigned int /* file_version */){ + // if an exeception occurs while loading courses + // the structure courses may have some courses each + // with students + ar & all_courses; + // while all_students will have no members. + ar & all_students; // create students that have no courses + // so ~School() will delete all members of courses + // but this will NOT delete any students - see above + // a memory leak will be the result. +} + +// switching the order of serialization doesn't help in this case +// case 2: +template<class Archive> +void School::serialize(Archive & ar, const unsigned int /* file_version */){ + ar & all_students; + ar >> all_courses; // create any courses that have no students +} +#endif + +template<class Archive> +void School::save(Archive & ar, const unsigned int /* file_version */) const { + ar << all_students; + ar << all_courses; +} + +template<class Archive> +void School::load(Archive & ar, const unsigned int /* file_version */){ + // if an exeception occurs while loading courses + // the structure courses may have some courses each + // with students + try{ + // deserialization of a Course * will in general provoke the + // deserialization of Student * which are added to the list of + // students for a class. That is, this process will result + // in the copying of a pointer. + ar >> all_courses; + ar >> all_students; // create students that have no courses + } + catch(std::exception){ + // elminate any dangling references + all_courses.clear(); + all_students.clear(); + throw; + } +} + +void init(School *school){ + Student *bob = new Student(); + Student *ted = new Student(); + Student *carol = new Student(); + Student *alice = new Student(); + + school->all_students.push_back(bob); + school->all_students.push_back(ted); + school->all_students.push_back(carol); + school->all_students.push_back(alice); + + Course *math = new Course(); + Course *history = new Course(); + Course *literature = new Course(); + Course *gym = new Course(); + + school->all_courses.push_back(math); + school->all_courses.push_back(history); + school->all_courses.push_back(literature); + school->all_courses.push_back(gym); + + bob->some_courses.push_back(math); + math->some_students.push_back(bob); + bob->some_courses.push_back(literature); + literature->some_students.push_back(bob); + + ted->some_courses.push_back(math); + math->some_students.push_back(ted); + ted->some_courses.push_back(history); + history->some_students.push_back(ted); + + alice->some_courses.push_back(literature); + literature->some_students.push_back(alice); + alice->some_courses.push_back(history); + history->some_students.push_back(alice); + + // no students signed up for gym + // carol has no courses +} + +void save(const School * const school, const char *filename){ + std::ofstream ofile(filename); + boost::archive::text_oarchive ar(ofile); + ar << school; +} + +void load(School * & school, const char *filename){ + std::ifstream ifile(filename); + boost::archive::text_iarchive ar(ifile); + try{ + ar >> school; + } + catch(std::exception){ + // eliminate dangling reference + school = NULL; + } +} + +int main(int argc, char *argv[]){ + std::string filename(boost::archive::tmpdir()); + filename += "/demofile.txt"; + + School *school = new School(); + std::cout << "1. student count = " << Student::count << std::endl; + std::cout << "2. class count = " << Course::count << std::endl; + init(school); + std::cout << "3. student count = " << Student::count << std::endl; + std::cout << "4. class count = " << Course::count << std::endl; + save(school, filename.c_str()); + delete school; + school = NULL; + std::cout << "5. student count = " << Student::count << std::endl; + std::cout << "6. class count = " << Course::count << std::endl; + load(school, filename.c_str()); + std::cout << "7. student count = " << Student::count << std::endl; + std::cout << "8. class count = " << Course::count << std::endl; + delete school; + std::cout << "9. student count = " << Student::count << std::endl; + std::cout << "10. class count = " << Course::count << std::endl; + std::remove(filename.c_str()); + return Student::count + Course::count; +} diff --git a/src/boost/libs/serialization/example/demo_fast_archive.cpp b/src/boost/libs/serialization/example/demo_fast_archive.cpp new file mode 100644 index 000000000..ca813900e --- /dev/null +++ b/src/boost/libs/serialization/example/demo_fast_archive.cpp @@ -0,0 +1,180 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_fast_binary_archive.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +// should pass compilation and execution +#include <sstream> + +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_array.hpp> + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/binary_oarchive_impl.hpp> +#include <boost/archive/binary_iarchive_impl.hpp> +#include <boost/archive/detail/register_archive.hpp> + +// include template definitions for base classes used. Otherwise +// you'll get link failure with undefined symbols +#include <boost/archive/impl/basic_binary_oprimitive.ipp> +#include <boost/archive/impl/basic_binary_iprimitive.ipp> +#include <boost/archive/impl/basic_binary_oarchive.ipp> +#include <boost/archive/impl/basic_binary_iarchive.ipp> + +using namespace boost::archive; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// "Fast" output binary archive. This is a variation of the native binary +class fast_binary_oarchive : + // don't derive from binary_oarchive !!! + public binary_oarchive_impl< + fast_binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type + > +{ + typedef fast_binary_oarchive derived_t; + typedef binary_oarchive_impl< + fast_binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type + > base_t; +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class boost::archive::detail::interface_oarchive<derived_t>; + friend class basic_binary_oarchive<derived_t>; + friend class basic_binary_oprimitive< + derived_t, + std::ostream::char_type, + std::ostream::traits_type + >; + friend class boost::archive::save_access; +#endif + // add base class to the places considered when matching + // save function to a specific set of arguments. Note, this didn't + // work on my MSVC 7.0 system using + // binary_oarchive_impl<derived_t>::load_override; + // so we use the sure-fire method below. This failed to work as well + template<class T> + void save_override(T & t){ + base_t::save_override(t); + // verify that this program is in fact working by making sure + // that arrays are getting passed here + BOOST_STATIC_ASSERT(! (boost::is_array<T>::value) ); + } + template<int N> + void save_override(const int (& t)[N]){ + save_binary(t, sizeof(t)); + } + template<int N> + void save_override(const unsigned int (& t)[N]){ + save_binary(t, sizeof(t)); + } + template<int N> + void save_override(const long (& t)[N]){ + save_binary(t, sizeof(t)); + } + template<int N> + void save_override(const unsigned long (& t)[N]){ + save_binary(t, sizeof(t)); + } +public: + fast_binary_oarchive(std::ostream & os, unsigned flags = 0) : + base_t(os, flags) + {} + fast_binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) : + base_t(bsb, flags) + {} +}; + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(fast_binary_oarchive) + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// "Fast" input binary archive. This is a variation of the native binary +class fast_binary_iarchive : + // don't derive from binary_oarchive !!! + public binary_iarchive_impl< + fast_binary_iarchive, + std::istream::char_type, + std::istream::traits_type + > +{ + typedef fast_binary_iarchive derived_t; + typedef binary_iarchive_impl< + fast_binary_iarchive, + std::istream::char_type, + std::istream::traits_type + > base_t; +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class boost::archive::detail::interface_iarchive<derived_t>; + friend class basic_binary_iarchive<derived_t>; + friend class basic_binary_iprimitive< + derived_t, + std::ostream::char_type, + std::ostream::traits_type + >; + friend class boost::archive::load_access; +#endif + // add base class to the places considered when matching + // save function to a specific set of arguments. Note, this didn't + // work on my MSVC 7.0 system using + // binary_oarchive_impl<derived_t>::load_override; + // so we use the sure-fire method below. This failed to work as well + template<class T> + void load_override(T & t){ + base_t::load_override(t); + BOOST_STATIC_ASSERT(! (boost::is_array<T>::value) ); + } + template<int N> + void load_override(int (& t)[N]){ + load_binary(t, sizeof(t)); + } + template<int N> + void load_override(unsigned int (& t)[N]){ + load_binary(t, sizeof(t)); + } + template<int N> + void load_override(long (& t)[N]){ + load_binary(t, sizeof(t)); + } + template<int N> + void load_override(unsigned long (& t)[N]){ + load_binary(t, sizeof(t)); + } +public: + fast_binary_iarchive(std::istream & is, unsigned int flags = 0) : + base_t(is, flags) + {} + fast_binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) : + base_t(bsb, flags) + {} +}; + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(fast_binary_iarchive) + +int main( int argc, char* argv[] ) +{ + const int a[3] = {1, 2, 3}; + int a1[3] = {4, 5, 6}; + + std::stringstream ss; + { + fast_binary_oarchive pboa(ss); + pboa << a; + } + { + fast_binary_iarchive pbia(ss); + pbia >> a1; + } + return (a[0] != a1[0]) || (a[1] != a1[1]) || (a[2] != a1[2]); +} + + diff --git a/src/boost/libs/serialization/example/demo_gps.hpp b/src/boost/libs/serialization/example/demo_gps.hpp new file mode 100644 index 000000000..5f39cc041 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_gps.hpp @@ -0,0 +1,284 @@ +#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP +#define BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_gps.hpp +// +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <iomanip> +#include <iostream> +#include <fstream> + +#include <boost/serialization/string.hpp> +#include <boost/serialization/nvp.hpp> +#include <boost/serialization/utility.hpp> +#include <boost/serialization/list.hpp> +#include <boost/serialization/version.hpp> +#include <boost/serialization/assume_abstract.hpp> + +// This illustration models the bus system of a small city. +// This includes, multiple bus stops, bus routes and schedules. +// There are different kinds of stops. Bus stops in general will +// will appear on multiple routes. A schedule will include +// muliple trips on the same route. + +///////////////////////////////////////////////////////////// +// gps coordinate +// +// llustrates serialization for a simple type +// +class gps_position +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const gps_position &gp); + + int degrees; + int minutes; + float seconds; + + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & BOOST_SERIALIZATION_NVP(degrees) + & BOOST_SERIALIZATION_NVP(minutes) + & BOOST_SERIALIZATION_NVP(seconds); + } + +public: + // every serializable class needs a constructor + gps_position(){}; + gps_position(int _d, int _m, float _s) : + degrees(_d), minutes(_m), seconds(_s) + {} +}; + +std::ostream & operator<<(std::ostream &os, const gps_position &gp) +{ + return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"'; +} + +///////////////////////////////////////////////////////////// +// One bus stop +// +// illustrates serialization of serializable members +// + +class bus_stop +{ + friend class boost::serialization::access; + virtual std::string description() const = 0; + gps_position latitude; + gps_position longitude; + + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_NVP(latitude); + ar & BOOST_SERIALIZATION_NVP(longitude); + } + +protected: + bus_stop(const gps_position & _lat, const gps_position & _long) : + latitude(_lat), longitude(_long) + {} +public: + bus_stop(){} + friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp); + virtual ~bus_stop(){} +}; + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop) + +std::ostream & operator<<(std::ostream &os, const bus_stop &bs) +{ + return os << bs.latitude << bs.longitude << ' ' << bs.description(); +} + +///////////////////////////////////////////////////////////// +// Several kinds of bus stops +// +// illustrates serialization of derived types +// +class bus_stop_corner : public bus_stop +{ + friend class boost::serialization::access; + std::string street1; + std::string street2; + virtual std::string description() const + { + return street1 + " and " + street2; + } + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + // save/load base class information + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop); + ar & BOOST_SERIALIZATION_NVP(street1); + ar & BOOST_SERIALIZATION_NVP(street2); + } +public: + bus_stop_corner(){} + bus_stop_corner(const gps_position & _lat, const gps_position & _long, + const std::string & _s1, const std::string & _s2 + ) : + bus_stop(_lat, _long), street1(_s1), street2(_s2) + { + } +}; + +class bus_stop_destination : public bus_stop +{ + friend class boost::serialization::access; + std::string name; + virtual std::string description() const + { + return name; + } + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop) + & BOOST_SERIALIZATION_NVP(name); + } +public: + bus_stop_destination(){} + bus_stop_destination( + const gps_position & _lat, const gps_position & _long, const std::string & _name + ) : + bus_stop(_lat, _long), name(_name) + { + } +}; + +///////////////////////////////////////////////////////////// +// a bus route is a collection of bus stops +// +// illustrates serialization of STL collection templates. +// +// illustrates serialzation of polymorphic pointer (bus stop *); +// +// illustrates storage and recovery of shared pointers is correct +// and efficient. That is objects pointed to by more than one +// pointer are stored only once. In such cases only one such +// object is restored and pointers are restored to point to it +// +class bus_route +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const bus_route &br); + typedef bus_stop * bus_stop_pointer; + std::list<bus_stop_pointer> stops; + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + // in this program, these classes are never serialized directly but rather + // through a pointer to the base class bus_stop. So we need a way to be + // sure that the archive contains information about these derived classes. + //ar.template register_type<bus_stop_corner>(); + ar.register_type(static_cast<bus_stop_corner *>(NULL)); + //ar.template register_type<bus_stop_destination>(); + ar.register_type(static_cast<bus_stop_destination *>(NULL)); + // serialization of stl collections is already defined + // in the header + ar & BOOST_SERIALIZATION_NVP(stops); + } +public: + bus_route(){} + void append(bus_stop *_bs) + { + stops.insert(stops.end(), _bs); + } +}; +std::ostream & operator<<(std::ostream &os, const bus_route &br) +{ + std::list<bus_stop *>::const_iterator it; + // note: we're displaying the pointer to permit verification + // that duplicated pointers are properly restored. + for(it = br.stops.begin(); it != br.stops.end(); it++){ + os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it; + } + return os; +} + +///////////////////////////////////////////////////////////// +// a bus schedule is a collection of routes each with a starting time +// +// Illustrates serialization of STL objects(pair) in a non-intrusive way. +// See definition of operator<< <pair<F, S> >(ar, pair) +// +// illustrates nesting of serializable classes +// +// illustrates use of version number to automatically grandfather older +// versions of the same class. + +class bus_schedule +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs); + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_NVP(schedule); + } + // note: this structure was made public. because the friend declarations + // didn't seem to work as expected. +public: + struct trip_info + { + template<class Archive> + void serialize(Archive &ar, const unsigned int file_version) + { + // in versions 2 or later + if(file_version >= 2) + // read the drivers name + ar & BOOST_SERIALIZATION_NVP(driver); + // all versions have the follwing info + ar & BOOST_SERIALIZATION_NVP(hour) + & BOOST_SERIALIZATION_NVP(minute); + } + + // starting time + int hour; + int minute; + // only after system shipped was the driver's name added to the class + std::string driver; + + trip_info(){} + trip_info(int _h, int _m, const std::string &_d) : + hour(_h), minute(_m), driver(_d) + {} + ~trip_info(){ + } + }; +// friend std::ostream & operator<<(std::ostream &os, const trip_info &ti); +private: + std::list<std::pair<trip_info, bus_route *> > schedule; +public: + void append(const std::string &_d, int _h, int _m, bus_route *_br) + { + schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br)); + } + bus_schedule(){} +}; + +BOOST_CLASS_VERSION(bus_schedule::trip_info, 3) +BOOST_CLASS_VERSION(bus_schedule, 2) + +std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti) +{ + return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' '; +} +std::ostream & operator<<(std::ostream &os, const bus_schedule &bs) +{ + std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it; + for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){ + os << it->first << *(it->second); + } + return os; +} + +#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP diff --git a/src/boost/libs/serialization/example/demo_log.cpp b/src/boost/libs/serialization/example/demo_log.cpp new file mode 100644 index 000000000..eef40ec81 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_log.cpp @@ -0,0 +1,76 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_log.cpp +// +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <iostream> +#include <cstdio> + +#include "demo_gps.hpp" +#include "log_archive.hpp" + +int main(int argc, char *argv[]){ + // make the schedule + bus_schedule schedule; + + // fill in the data + // make a few stops + bus_stop *bs0 = new bus_stop_corner( + gps_position(34, 135, 52.560f), + gps_position(134, 22, 78.30f), + "24th Street", "10th Avenue" + ); + bus_stop *bs1 = new bus_stop_corner( + gps_position(35, 137, 23.456f), + gps_position(133, 35, 54.12f), + "State street", "Cathedral Vista Lane" + ); + bus_stop *bs2 = new bus_stop_destination( + gps_position(35, 136, 15.456f), + gps_position(133, 32, 15.300f), + "White House" + ); + bus_stop *bs3 = new bus_stop_destination( + gps_position(35, 134, 48.789f), + gps_position(133, 32, 16.230f), + "Lincoln Memorial" + ); + + // make a routes + bus_route route0; + route0.append(bs0); + route0.append(bs1); + route0.append(bs2); + + // add trips to schedule + schedule.append("bob", 6, 24, &route0); + schedule.append("bob", 9, 57, &route0); + schedule.append("alice", 11, 02, &route0); + + // make aother routes + bus_route route1; + route1.append(bs3); + route1.append(bs2); + route1.append(bs1); + + // add trips to schedule + schedule.append("ted", 7, 17, &route1); + schedule.append("ted", 9, 38, &route1); + schedule.append("alice", 11, 47, &route1); + + // display the complete schedule + log_archive oa(std::cout); + oa << BOOST_SERIALIZATION_NVP(schedule); + oa << schedule; + + delete bs0; + delete bs1; + delete bs2; + delete bs3; + return 0; +} + diff --git a/src/boost/libs/serialization/example/demo_output.txt b/src/boost/libs/serialization/example/demo_output.txt new file mode 100644 index 000000000..306bdbdc2 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_output.txt @@ -0,0 +1,51 @@ +original schedule +6:24 bob +0x003265C8 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue +0x00326648 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +0x00326768 35º136'15.456" 133º32'15.3" White House +9:57 bob +0x003265C8 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue +0x00326648 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +0x00326768 35º136'15.456" 133º32'15.3" White House +11:2 alice +0x003265C8 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue +0x00326648 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +0x00326768 35º136'15.456" 133º32'15.3" White House +7:17 ted +0x003267D0 35º134'48.789" 133º32'16.23" Lincoln Memorial +0x00326768 35º136'15.456" 133º32'15.3" White House +0x00326648 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +9:38 ted +0x003267D0 35º134'48.789" 133º32'16.23" Lincoln Memorial +0x00326768 35º136'15.456" 133º32'15.3" White House +0x00326648 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +11:47 alice +0x003267D0 35º134'48.789" 133º32'16.23" Lincoln Memorial +0x00326768 35º136'15.456" 133º32'15.3" White House +0x00326648 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +restored schedule +6:24 +0x0032A2F8 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue +0x0032A508 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +0x0032A628 35º136'15.456" 133º32'15.3" White House +9:57 +0x0032A2F8 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue +0x0032A508 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +0x0032A628 35º136'15.456" 133º32'15.3" White House +11:2 +0x0032A2F8 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue +0x0032A508 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +0x0032A628 35º136'15.456" 133º32'15.3" White House +7:17 +0x0032A8C0 35º134'48.789" 133º32'16.23" Lincoln Memorial +0x0032A628 35º136'15.456" 133º32'15.3" White House +0x0032A508 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +9:38 +0x0032A8C0 35º134'48.789" 133º32'16.23" Lincoln Memorial +0x0032A628 35º136'15.456" 133º32'15.3" White House +0x0032A508 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +11:47 +0x0032A8C0 35º134'48.789" 133º32'16.23" Lincoln Memorial +0x0032A628 35º136'15.456" 133º32'15.3" White House +0x0032A508 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane +*** No errors detected diff --git a/src/boost/libs/serialization/example/demo_pimpl.cpp b/src/boost/libs/serialization/example/demo_pimpl.cpp new file mode 100644 index 000000000..629bbcd1f --- /dev/null +++ b/src/boost/libs/serialization/example/demo_pimpl.cpp @@ -0,0 +1,34 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_pimpl.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +// should pass compilation and execution + +#include <sstream> + +#include <boost/archive/text_iarchive.hpp> +#include <boost/archive/text_oarchive.hpp> + +#include "demo_pimpl_A.hpp" + +int main(int argc, char* argv[]) +{ + std::stringstream ss; + + const A a; + { + boost::archive::text_oarchive oa(ss); + oa << a; + } + A a1; + { + boost::archive::text_iarchive ia(ss); + ia >> a1; + } + return 0; +} + diff --git a/src/boost/libs/serialization/example/demo_pimpl_A.cpp b/src/boost/libs/serialization/example/demo_pimpl_A.cpp new file mode 100644 index 000000000..055d02daa --- /dev/null +++ b/src/boost/libs/serialization/example/demo_pimpl_A.cpp @@ -0,0 +1,45 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_pimpl_A.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <boost/archive/text_iarchive.hpp> +#include <boost/archive/text_oarchive.hpp> + +#include "demo_pimpl_A.hpp" + +// "hidden" definition of class B +struct B { + int b; + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & b; + } +}; + +A::A() : + pimpl(new B) +{} +A::~A(){ + delete pimpl; +} +// now we can define the serialization for class A +template<class Archive> +void A::serialize(Archive & ar, const unsigned int /* file_version */){ + ar & pimpl; +} + +// without the explicit instantiations below, the program will +// fail to link for lack of instantiantiation of the above function +// note: the following failed to fix link errors for vc 7.0 ! +template void A::serialize<boost::archive::text_iarchive>( + boost::archive::text_iarchive & ar, + const unsigned int file_version +); +template void A::serialize<boost::archive::text_oarchive>( + boost::archive::text_oarchive & ar, + const unsigned int file_version +); diff --git a/src/boost/libs/serialization/example/demo_pimpl_A.hpp b/src/boost/libs/serialization/example/demo_pimpl_A.hpp new file mode 100644 index 000000000..eff3f1277 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_pimpl_A.hpp @@ -0,0 +1,24 @@ +#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_PIMPL_A_HPP +#define BOOST_SERIALIZATION_EXAMPLE_DEMO_PIMPL_A_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_pimpl_A.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +// class whose declaration is hidden by a pointer +struct B; + +struct A { + // class a contains a pointer to a "hidden" declaration + B *pimpl; + template<class Archive> + void serialize(Archive & ar, const unsigned int file_version); + A(); + ~A(); +}; + +#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_PIMPL_A_HPP diff --git a/src/boost/libs/serialization/example/demo_polymorphic.cpp b/src/boost/libs/serialization/example/demo_polymorphic.cpp new file mode 100644 index 000000000..0a9c85667 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_polymorphic.cpp @@ -0,0 +1,65 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_polymorphic.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +// should pass compilation and execution + +#include <sstream> + +#include <boost/archive/polymorphic_text_iarchive.hpp> +#include <boost/archive/polymorphic_text_oarchive.hpp> + +#include <boost/archive/polymorphic_binary_iarchive.hpp> +#include <boost/archive/polymorphic_binary_oarchive.hpp> + +#include "demo_polymorphic_A.hpp" + +int main(int argc, char* argv[]) +{ + const A a; + A a1; + { + // test with a text archive + std::stringstream ss; + { + // instantiate archive which inhertis polymorphic interface + // and the normal text archive implementation + boost::archive::polymorphic_text_oarchive oa(ss); + boost::archive::polymorphic_oarchive & oa_interface = oa; + // we can just just the interface for saving + oa_interface << a; + } + { + // or we can use the implementation directly + boost::archive::polymorphic_text_iarchive ia(ss); + ia >> a1; + } + } + if(! (a == a1)) + return 1; + { + //test with a binary archive + std::stringstream ss; + { + // instantiate archive which inhertis polymorphic interface + // and the normal binary archive implementation + boost::archive::polymorphic_binary_oarchive oa(ss); + oa << a; + } + { + // see above + boost::archive::polymorphic_binary_iarchive ia(ss); + boost::archive::polymorphic_iarchive & ia_interface = ia; + // use just the polymorphic interface for loading. + ia_interface >> a1; + } + } + if(! (a == a1)) + return 1; + return 0; +} + diff --git a/src/boost/libs/serialization/example/demo_polymorphic_A.cpp b/src/boost/libs/serialization/example/demo_polymorphic_A.cpp new file mode 100644 index 000000000..bf26cb413 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_polymorphic_A.cpp @@ -0,0 +1,26 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_polymorphic_A.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + + +#include <boost/archive/polymorphic_iarchive.hpp> +#include <boost/archive/polymorphic_oarchive.hpp> + +#include "demo_polymorphic_A.hpp" + +// explicitly instantiate templates for polymorphic archives +// used by this demo. +template +void A::serialize<boost::archive::polymorphic_iarchive>( + boost::archive::polymorphic_iarchive &, + const unsigned int +); +template +void A::serialize<boost::archive::polymorphic_oarchive>( + boost::archive::polymorphic_oarchive &, + const unsigned int +); diff --git a/src/boost/libs/serialization/example/demo_polymorphic_A.hpp b/src/boost/libs/serialization/example/demo_polymorphic_A.hpp new file mode 100644 index 000000000..513b633a2 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_polymorphic_A.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP +#define BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// demo_polymorphic_A.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +namespace boost { +namespace archive { + +class polymorphic_iarchive; +class polymorphic_oarchive; + +} // namespace archive +} // namespace boost + +struct A { + // class a contains a pointer to a "hidden" declaration + template<class Archive> + void serialize( + Archive & ar, + const unsigned int file_version + ){ + ar & data; + } + int data; + bool operator==(const A & rhs) const { + return data == rhs.data; + } + A() : + data(0) + {} +}; + +#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_POLYMORPHIC_A_HPP diff --git a/src/boost/libs/serialization/example/demo_portable_archive.cpp b/src/boost/libs/serialization/example/demo_portable_archive.cpp new file mode 100644 index 000000000..ae329618c --- /dev/null +++ b/src/boost/libs/serialization/example/demo_portable_archive.cpp @@ -0,0 +1,104 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_portable_archive.cpp +// +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +// should pass compilation and execution + +// note:: this example can only be built with the static library +// (at least with MSVC - due to conflicts related to import of library +// code and instantiation of templates. +#include <sstream> + +#include "portable_binary_oarchive.hpp" +#include "portable_binary_iarchive.hpp" + +#include <cstdlib> +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::rand; } +#endif + +class A +{ + friend class boost::serialization::access; + char c; + A *pa; + int i; + int i2; // special tricky case to check sign extension + unsigned int ui; + long l; + unsigned long ul; + template<class Archive> + void serialize(Archive & ar, const unsigned int /* version */){ + ar & c & i & i2 & ui & l & ul ; + } +public: + bool operator==(const A & rhs) const { + return + c == rhs.c + && i == rhs.i + && i2 == rhs.i2 + && ui == rhs.ui + && l == rhs.l + && ul == rhs.ul + ; + } + A() : + c(0xFF & std::rand()), + pa(0), + i(std::rand()), + i2(0x80), + ui(std::rand()), + l(std::rand() * std::rand()), + ul(std::rand()) + {} +}; + +int main( int /* argc */, char* /* argv */[] ) +{ + const A a; + A a1; + + std::stringstream ss; + { + portable_binary_oarchive pboa(ss); + pboa << a; + } + { + portable_binary_iarchive pbia(ss); + pbia >> a1; + } + if(! (a == a1)) + return 1; + + ss.clear(); + { + portable_binary_oarchive pboa(ss, endian_big); + pboa << a; + } + { + portable_binary_iarchive pbia(ss, endian_big); + pbia >> a1; + } + if(! (a == a1)) + return 1; + + ss.clear(); + { + portable_binary_oarchive pboa(ss, endian_big); + pboa << a; + } + { + portable_binary_iarchive pbia(ss, endian_big); + pbia >> a1; + } + + return !(a == a1); +} + + diff --git a/src/boost/libs/serialization/example/demo_save.xml b/src/boost/libs/serialization/example/demo_save.xml new file mode 100644 index 000000000..c5a28c8eb --- /dev/null +++ b/src/boost/libs/serialization/example/demo_save.xml @@ -0,0 +1,129 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<!DOCTYPE boost_serialization> +<boost_serialization signature="serialization::archive" version="3"> +<s class_id="0" tracking_level="0" version="2"> + <schedule class_id="1" tracking_level="0"> + <count>6</count> + <item class_id="2" tracking_level="0"> + <first class_id="3" tracking_level="0" version="3"> + <driver>bob</driver> + <hour>6</hour> + <minute>24</minute> + </first> + <second class_id="4" tracking_level="1" object_id="_0"> + <stops class_id="7" tracking_level="0"> + <count>3</count> + <item class_id="5" tracking_level="1" object_id="_1"> + <bus_stop class_id="8" tracking_level="0"> + <latitude class_id="9" tracking_level="0"> + <degrees>34</degrees> + <minutes>135</minutes> + <seconds>52.560001</seconds> + </latitude> + <longitude> + <degrees>134</degrees> + <minutes>22</minutes> + <seconds>78.300003</seconds> + </longitude> + </bus_stop> + <street1>24th Street</street1> + <street2>10th Avenue</street2> + </item> + <item class_id_reference="5" object_id="_2"> + <bus_stop> + <latitude> + <degrees>35</degrees> + <minutes>137</minutes> + <seconds>23.455999</seconds> + </latitude> + <longitude> + <degrees>133</degrees> + <minutes>35</minutes> + <seconds>54.119999</seconds> + </longitude> + </bus_stop> + <street1>State street</street1> + <street2>Cathedral Vista Lane</street2> + </item> + <item class_id="6" tracking_level="1" object_id="_3"> + <bus_stop> + <latitude> + <degrees>35</degrees> + <minutes>136</minutes> + <seconds>15.456</seconds> + </latitude> + <longitude> + <degrees>133</degrees> + <minutes>32</minutes> + <seconds>15.3</seconds> + </longitude> + </bus_stop> + <name>White House</name> + </item> + </stops> + </second> + </item> + <item> + <first> + <driver>bob</driver> + <hour>9</hour> + <minute>57</minute> + </first> + <second class_id_reference="4" object_id_reference="_0"></second> + </item> + <item> + <first> + <driver>alice</driver> + <hour>11</hour> + <minute>2</minute> + </first> + <second class_id_reference="4" object_id_reference="_0"></second> + </item> + <item> + <first> + <driver>ted</driver> + <hour>7</hour> + <minute>17</minute> + </first> + <second class_id_reference="4" object_id="_4"> + <stops> + <count>3</count> + <item class_id_reference="6" object_id="_5"> + <bus_stop> + <latitude> + <degrees>35</degrees> + <minutes>134</minutes> + <seconds>48.789001</seconds> + </latitude> + <longitude> + <degrees>133</degrees> + <minutes>32</minutes> + <seconds>16.23</seconds> + </longitude> + </bus_stop> + <name>Lincoln Memorial</name> + </item> + <item class_id_reference="6" object_id_reference="_3"></item> + <item class_id_reference="5" object_id_reference="_2"></item> + </stops> + </second> + </item> + <item> + <first> + <driver>ted</driver> + <hour>9</hour> + <minute>38</minute> + </first> + <second class_id_reference="4" object_id_reference="_4"></second> + </item> + <item> + <first> + <driver>alice</driver> + <hour>11</hour> + <minute>47</minute> + </first> + <second class_id_reference="4" object_id_reference="_4"></second> + </item> + </schedule> +</s> +</boost_serialization> diff --git a/src/boost/libs/serialization/example/demo_shared_ptr.cpp b/src/boost/libs/serialization/example/demo_shared_ptr.cpp new file mode 100644 index 000000000..63410fc88 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_shared_ptr.cpp @@ -0,0 +1,164 @@ +// demo_shared_ptr.cpp : demonstrates adding serialization to a template + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . Polymorphic +// derived pointer example by David Tonge. + +// Use, modification and distribution is subject to 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. + +#include <iomanip> +#include <iostream> +#include <cstddef> // NULL +#include <fstream> +#include <string> + +#include <cstdio> // remove +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::remove; +} +#endif + +#include <boost/archive/text_oarchive.hpp> +#include <boost/archive/text_iarchive.hpp> +#include <boost/archive/tmpdir.hpp> + +#include <boost/serialization/shared_ptr.hpp> + +/////////////////////////// +// test shared_ptr serialization +class A +{ +private: + friend class boost::serialization::access; + int x; + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & x; + } +public: + static int count; + A(){++count;} // default constructor + virtual ~A(){--count;} // default destructor +}; + +BOOST_SERIALIZATION_SHARED_PTR(A) + +///////////////// +// ADDITION BY DT +class B : public A +{ +private: + friend class boost::serialization::access; + int x; + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & boost::serialization::base_object<A>(*this); + } +public: + static int count; + B() : A() {}; + virtual ~B() {}; +}; + +BOOST_SERIALIZATION_SHARED_PTR(B) + +///////////////// + +int A::count = 0; + +void display(boost::shared_ptr<A> &spa, boost::shared_ptr<A> &spa1) +{ + std::cout << "a = 0x" << std::hex << spa.get() << " "; + if (spa.get()) std::cout << "is a " << typeid(*(spa.get())).name() << "* "; + std::cout << "use count = " << std::dec << spa.use_count() << std::endl; + std::cout << "a1 = 0x" << std::hex << spa1.get() << " "; + if (spa1.get()) std::cout << "is a " << typeid(*(spa1.get())).name() << "* "; + std::cout << "use count = " << std::dec << spa1.use_count() << std::endl; + std::cout << "unique element count = " << A::count << std::endl; +} + +int main(int /* argc */, char * /*argv*/[]) +{ + std::string filename(boost::archive::tmpdir()); + filename += "/testfile"; + + // create a new shared pointer to ta new object of type A + boost::shared_ptr<A> spa(new A); + boost::shared_ptr<A> spa1; + spa1 = spa; + display(spa, spa1); + // serialize it + { + std::ofstream ofs(filename.c_str()); + boost::archive::text_oarchive oa(ofs); + oa << spa; + oa << spa1; + } + // reset the shared pointer to NULL + // thereby destroying the object of type A + spa.reset(); + spa1.reset(); + display(spa, spa1); + // restore state to one equivalent to the original + // creating a new type A object + { + // open the archive + std::ifstream ifs(filename.c_str()); + boost::archive::text_iarchive ia(ifs); + + // restore the schedule from the archive + ia >> spa; + ia >> spa1; + } + display(spa, spa1); + spa.reset(); + spa1.reset(); + + std::cout << std::endl; + std::cout << std::endl; + std::cout << "New tests" << std::endl; + + ///////////////// + // ADDITION BY DT + // create a new shared pointer to ta new object of type A + spa = boost::shared_ptr<A>(new B); + spa1 = spa; + display(spa, spa1); + // serialize it + { + std::ofstream ofs(filename.c_str()); + boost::archive::text_oarchive oa(ofs); + oa.register_type(static_cast<B *>(NULL)); + oa << spa; + oa << spa1; + } + // reset the shared pointer to NULL + // thereby destroying the object of type B + spa.reset(); + spa1.reset(); + display(spa, spa1); + // restore state to one equivalent to the original + // creating a new type B object + { + // open the archive + std::ifstream ifs(filename.c_str()); + boost::archive::text_iarchive ia(ifs); + + // restore the schedule from the archive + ia.register_type(static_cast<B *>(NULL)); + ia >> spa; + ia >> spa1; + } + display(spa, spa1); + /////////////// + std::remove(filename.c_str()); + + // obj of type A gets destroyed + // as smart_ptr goes out of scope + return 0; +} diff --git a/src/boost/libs/serialization/example/demo_simple_log.cpp b/src/boost/libs/serialization/example/demo_simple_log.cpp new file mode 100644 index 000000000..b6963c5b1 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_simple_log.cpp @@ -0,0 +1,75 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_log.cpp +// +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <iostream> +#include <cstdio> + +#include "demo_gps.hpp" +#include "simple_log_archive.hpp" + +int main(int argc, char *argv[]) +{ + // make the schedule + bus_schedule schedule; + + // fill in the data + // make a few stops + bus_stop *bs0 = new bus_stop_corner( + gps_position(34, 135, 52.560f), + gps_position(134, 22, 78.30f), + "24th Street", "10th Avenue" + ); + bus_stop *bs1 = new bus_stop_corner( + gps_position(35, 137, 23.456f), + gps_position(133, 35, 54.12f), + "State street", "Cathedral Vista Lane" + ); + bus_stop *bs2 = new bus_stop_destination( + gps_position(35, 136, 15.456f), + gps_position(133, 32, 15.300f), + "White House" + ); + bus_stop *bs3 = new bus_stop_destination( + gps_position(35, 134, 48.789f), + gps_position(133, 32, 16.230f), + "Lincoln Memorial" + ); + + // make a routes + bus_route route0; + route0.append(bs0); + route0.append(bs1); + route0.append(bs2); + + // add trips to schedule + schedule.append("bob", 6, 24, &route0); + schedule.append("bob", 9, 57, &route0); + schedule.append("alice", 11, 02, &route0); + + // make aother routes + bus_route route1; + route1.append(bs3); + route1.append(bs2); + route1.append(bs1); + + // add trips to schedule + schedule.append("ted", 7, 17, &route1); + schedule.append("ted", 9, 38, &route1); + schedule.append("alice", 11, 47, &route1); + + // display the complete schedule + simple_log_archive log(std::cout); + log << schedule; + + delete bs0; + delete bs1; + delete bs2; + delete bs3; + return 0; +} diff --git a/src/boost/libs/serialization/example/demo_trivial_archive.cpp b/src/boost/libs/serialization/example/demo_trivial_archive.cpp new file mode 100644 index 000000000..b82b13764 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_trivial_archive.cpp @@ -0,0 +1,94 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_trivial_archive.cpp +// +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <cstddef> // std::size_t +#include <boost/mpl/bool.hpp> + +///////////////////////////////////////////////////////////////////////// +// class trivial_oarchive +class trivial_oarchive { + +public: + ////////////////////////////////////////////////////////// + // public interface used by programs that use the + // serialization library + typedef boost::mpl::bool_<true> is_saving; + typedef boost::mpl::bool_<false> is_loading; + template<class T> void register_type(){} + template<class T> trivial_oarchive & operator<<(const T & t){ + return *this; + } + template<class T> trivial_oarchive & operator&(const T & t){ + return *this << t; + } + void save_binary(void *address, std::size_t count){}; +}; + +#include "demo_gps.hpp" + +int main(int argc, char *argv[]) +{ + // make the schedule + bus_schedule schedule; + + // fill in the data + // make a few stops + bus_stop *bs0 = new bus_stop_corner( + gps_position(34, 135, 52.560f), + gps_position(134, 22, 78.30f), + "24th Street", "10th Avenue" + ); + bus_stop *bs1 = new bus_stop_corner( + gps_position(35, 137, 23.456f), + gps_position(133, 35, 54.12f), + "State street", "Cathedral Vista Lane" + ); + bus_stop *bs2 = new bus_stop_destination( + gps_position(35, 136, 15.456f), + gps_position(133, 32, 15.300f), + "White House" + ); + bus_stop *bs3 = new bus_stop_destination( + gps_position(35, 134, 48.789f), + gps_position(133, 32, 16.230f), + "Lincoln Memorial" + ); + + // make a routes + bus_route route0; + route0.append(bs0); + route0.append(bs1); + route0.append(bs2); + + // add trips to schedule + schedule.append("bob", 6, 24, &route0); + schedule.append("bob", 9, 57, &route0); + schedule.append("alice", 11, 02, &route0); + + // make aother routes + bus_route route1; + route1.append(bs3); + route1.append(bs2); + route1.append(bs1); + + // add trips to schedule + schedule.append("ted", 7, 17, &route1); + schedule.append("ted", 9, 38, &route1); + schedule.append("alice", 11, 47, &route1); + + // display the complete schedule + trivial_oarchive ta; + ta << schedule; + + delete bs0; + delete bs1; + delete bs2; + delete bs3; + return 0; +} diff --git a/src/boost/libs/serialization/example/demo_xml.cpp b/src/boost/libs/serialization/example/demo_xml.cpp new file mode 100644 index 000000000..4c8518e99 --- /dev/null +++ b/src/boost/libs/serialization/example/demo_xml.cpp @@ -0,0 +1,127 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_xml.cpp +// +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <iomanip> +#include <iostream> +#include <fstream> +#include <string> + +#include <cstdio> // remove +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::remove; +} +#endif + +#include <boost/archive/tmpdir.hpp> +#include <boost/archive/xml_iarchive.hpp> +#include <boost/archive/xml_oarchive.hpp> + +#include "demo_gps.hpp" + +void save_schedule(const bus_schedule &s, const char * filename){ + // make an archive + std::ofstream ofs(filename); + assert(ofs.good()); + boost::archive::xml_oarchive oa(ofs); + oa << BOOST_SERIALIZATION_NVP(s); +} + +void +restore_schedule(bus_schedule &s, const char * filename) +{ + // open the archive + std::ifstream ifs(filename); + assert(ifs.good()); + boost::archive::xml_iarchive ia(ifs); + + // restore the schedule from the archive + ia >> BOOST_SERIALIZATION_NVP(s); +} + +int main(int argc, char *argv[]) +{ + // make the schedule + bus_schedule original_schedule; + + // fill in the data + // make a few stops + bus_stop *bs0 = new bus_stop_corner( + gps_position(34, 135, 52.560f), + gps_position(134, 22, 78.30f), + "24th Street", "10th Avenue" + ); + bus_stop *bs1 = new bus_stop_corner( + gps_position(35, 137, 23.456f), + gps_position(133, 35, 54.12f), + "State street", "Cathedral Vista Lane" + ); + bus_stop *bs2 = new bus_stop_destination( + gps_position(35, 136, 15.456f), + gps_position(133, 32, 15.300f), + "White House" + ); + bus_stop *bs3 = new bus_stop_destination( + gps_position(35, 134, 48.789f), + gps_position(133, 32, 16.230f), + "Lincoln Memorial" + ); + + // make a routes + bus_route route0; + route0.append(bs0); + route0.append(bs1); + route0.append(bs2); + + // add trips to schedule + original_schedule.append("bob", 6, 24, &route0); + original_schedule.append("bob", 9, 57, &route0); + original_schedule.append("alice", 11, 02, &route0); + + // make aother routes + bus_route route1; + route1.append(bs3); + route1.append(bs2); + route1.append(bs1); + + // add trips to schedule + original_schedule.append("ted", 7, 17, &route1); + original_schedule.append("ted", 9, 38, &route1); + original_schedule.append("alice", 11, 47, &route1); + + // display the complete schedule + std::cout << "original schedule"; + std::cout << original_schedule; + + std::string filename(boost::archive::tmpdir()); + filename += "/demo.xml"; + + // save the schedule + save_schedule(original_schedule, filename.c_str()); + + // ... some time later + // make a new schedule + bus_schedule new_schedule; + + restore_schedule(new_schedule, filename.c_str()); + + // and display + std::cout << "\nrestored schedule"; + std::cout << new_schedule; + // should be the same as the old one. (except for the pointer values) + + std::remove(filename.c_str()); + + delete bs0; + delete bs1; + delete bs2; + delete bs3; + return 0; +} diff --git a/src/boost/libs/serialization/example/demo_xml.hpp b/src/boost/libs/serialization/example/demo_xml.hpp new file mode 100644 index 000000000..86d6c1b4a --- /dev/null +++ b/src/boost/libs/serialization/example/demo_xml.hpp @@ -0,0 +1,284 @@ +#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP +#define BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_xml.hpp +// +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + + +#include <string> +#include <iomanip> +#include <iostream> +#include <fstream> + +#include <boost/serialization/nvp.hpp> +#include <boost/serialization/utility.hpp> +#include <boost/serialization/list.hpp> +#include <boost/serialization/version.hpp> + +// This illustration models the bus system of a small city. +// This includes, multiple bus stops, bus routes and schedules. +// There are different kinds of stops. Bus stops in general will +// will appear on multiple routes. A schedule will include +// muliple trips on the same route. + +///////////////////////////////////////////////////////////// +// gps coordinate +// +// llustrates serialization for a simple type +// +class gps_position +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const gps_position &gp); + + int degrees; + int minutes; + float seconds; + + template<class Archive> + void serialize(Archive & ar, const unsigned int /* file_version */){ + ar & BOOST_SERIALIZATION_NVP(degrees) + & BOOST_SERIALIZATION_NVP(minutes) + & BOOST_SERIALIZATION_NVP(seconds); + } + +public: + // every serializable class needs a constructor + gps_position(){}; + gps_position(int _d, int _m, float _s) : + degrees(_d), minutes(_m), seconds(_s) + {} +}; + +std::ostream & operator<<(std::ostream &os, const gps_position &gp) +{ + return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"'; +} + +///////////////////////////////////////////////////////////// +// One bus stop +// +// illustrates serialization of serializable members +// + +class bus_stop +{ + friend class boost::serialization::access; + virtual std::string description() const = 0; + gps_position latitude; + gps_position longitude; + + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_NVP(latitude); + ar & BOOST_SERIALIZATION_NVP(longitude); + } + +protected: + bus_stop(const gps_position & _lat, const gps_position & _long) : + latitude(_lat), longitude(_long) + {} +public: + bus_stop(){} + friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp); + virtual ~bus_stop(){} +}; + +BOOST_IS_ABSTRACT(bus_stop) + +std::ostream & operator<<(std::ostream &os, const bus_stop &bs) +{ + return os << bs.latitude << bs.longitude << ' ' << bs.description(); +} + +///////////////////////////////////////////////////////////// +// Several kinds of bus stops +// +// illustrates serialization of derived types +// +class bus_stop_corner : public bus_stop +{ + friend class boost::serialization::access; + std::string street1; + std::string street2; + virtual std::string description() const + { + return street1 + " and " + street2; + } + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + // save/load base class information + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop); + ar & BOOST_SERIALIZATION_NVP(street1); + ar & BOOST_SERIALIZATION_NVP(street2); + } +public: + bus_stop_corner(){} + bus_stop_corner(const gps_position & _lat, const gps_position & _long, + const std::string & _s1, const std::string & _s2 + ) : + bus_stop(_lat, _long), street1(_s1), street2(_s2) + { + } +}; + +class bus_stop_destination : public bus_stop +{ + friend class boost::serialization::access; + std::string name; + virtual std::string description() const + { + return name; + } + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop) + & BOOST_SERIALIZATION_NVP(name); + } +public: + bus_stop_destination(){} + bus_stop_destination( + const gps_position & _lat, const gps_position & _long, const std::string & _name + ) : + bus_stop(_lat, _long), name(_name) + { + } +}; + +///////////////////////////////////////////////////////////// +// a bus route is a collection of bus stops +// +// illustrates serialization of STL collection templates. +// +// illustrates serialzation of polymorphic pointer (bus stop *); +// +// illustrates storage and recovery of shared pointers is correct +// and efficient. That is objects pointed to by more than one +// pointer are stored only once. In such cases only one such +// object is restored and pointers are restored to point to it +// +class bus_route +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const bus_route &br); + typedef bus_stop * bus_stop_pointer; + std::list<bus_stop_pointer> stops; + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + // in this program, these classes are never serialized directly but rather + // through a pointer to the base class bus_stop. So we need a way to be + // sure that the archive contains information about these derived classes. + //ar.template register_type<bus_stop_corner>(); + ar.register_type(static_cast<bus_stop_corner *>(NULL)); + //ar.template register_type<bus_stop_destination>(); + ar.register_type(static_cast<bus_stop_destination *>(NULL)); + // serialization of stl collections is already defined + // in the header + ar & BOOST_SERIALIZATION_NVP(stops); + } +public: + bus_route(){} + void append(bus_stop *_bs) + { + stops.insert(stops.end(), _bs); + } +}; +std::ostream & operator<<(std::ostream &os, const bus_route &br) +{ + std::list<bus_stop *>::const_iterator it; + // note: we're displaying the pointer to permit verification + // that duplicated pointers are properly restored. + for(it = br.stops.begin(); it != br.stops.end(); it++){ + os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it; + } + return os; +} + +///////////////////////////////////////////////////////////// +// a bus schedule is a collection of routes each with a starting time +// +// Illustrates serialization of STL objects(pair) in a non-intrusive way. +// See definition of operator<< <pair<F, S> >(ar, pair) +// +// illustrates nesting of serializable classes +// +// illustrates use of version number to automatically grandfather older +// versions of the same class. + +class bus_schedule +{ + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs); + template<class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_NVP(schedule); + } + // note: this structure was made public. because the friend declarations + // didn't seem to work as expected. +public: + struct trip_info + { + template<class Archive> + void serialize(Archive &ar, const unsigned int file_version) + { + // in versions 2 or later + if(file_version >= 2) + // read the drivers name + ar & BOOST_SERIALIZATION_NVP(driver); + // all versions have the follwing info + ar & BOOST_SERIALIZATION_NVP(hour) + & BOOST_SERIALIZATION_NVP(minute); + } + + // starting time + int hour; + int minute; + // only after system shipped was the driver's name added to the class + std::string driver; + + trip_info(){} + trip_info(int _h, int _m, const std::string &_d) : + hour(_h), minute(_m), driver(_d) + {} + ~trip_info(){ + } + }; +// friend std::ostream & operator<<(std::ostream &os, const trip_info &ti); +private: + std::list<std::pair<trip_info, bus_route *> > schedule; +public: + void append(const std::string &_d, int _h, int _m, bus_route *_br) + { + schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br)); + } + bus_schedule(){} +}; + +BOOST_CLASS_VERSION(bus_schedule::trip_info, 3) +BOOST_CLASS_VERSION(bus_schedule, 2) + +std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti) +{ + return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' '; +} +std::ostream & operator<<(std::ostream &os, const bus_schedule &bs) +{ + std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it; + for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){ + os << it->first << *(it->second); + } + return os; +} + +#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP diff --git a/src/boost/libs/serialization/example/demo_xml_load.cpp b/src/boost/libs/serialization/example/demo_xml_load.cpp new file mode 100644 index 000000000..fcbe80bbf --- /dev/null +++ b/src/boost/libs/serialization/example/demo_xml_load.cpp @@ -0,0 +1,45 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_xml_load.cpp +// +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <iostream> +#include <string> +#include <boost/archive/tmpdir.hpp> + +#include <boost/archive/xml_iarchive.hpp> + +#include "demo_gps.hpp" + +void +restore_schedule(bus_schedule &s, const char * filename) +{ + // open the archive + std::ifstream ifs(filename); + assert(ifs.good()); + boost::archive::xml_iarchive ia(ifs); + + // restore the schedule from the archive + ia >> BOOST_SERIALIZATION_NVP(s); +} + +int main(int argc, char *argv[]) +{ + // make a new schedule + bus_schedule new_schedule; + + std::string filename(boost::archive::tmpdir()); + filename += "/demo_save.xml"; + + restore_schedule(new_schedule, filename.c_str()); + + // and display + std::cout << "\nrestored schedule"; + std::cout << new_schedule; + + return 0; +} diff --git a/src/boost/libs/serialization/example/demo_xml_save.cpp b/src/boost/libs/serialization/example/demo_xml_save.cpp new file mode 100644 index 000000000..045d40bab --- /dev/null +++ b/src/boost/libs/serialization/example/demo_xml_save.cpp @@ -0,0 +1,91 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// +// demo_xml_save.cpp +// +// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +#include <iostream> +#include <string> +#include <boost/archive/tmpdir.hpp> + +#include <boost/archive/xml_oarchive.hpp> + +#include "demo_gps.hpp" + +void save_schedule(const bus_schedule &s, const char * filename){ + // make an archive + std::ofstream ofs(filename); + assert(ofs.good()); + boost::archive::xml_oarchive oa(ofs); + oa << BOOST_SERIALIZATION_NVP(s); +} + +int main(int argc, char *argv[]) +{ + // make the schedule + bus_schedule original_schedule; + + // fill in the data + // make a few stops + bus_stop *bs0 = new bus_stop_corner( + gps_position(34, 135, 52.560f), + gps_position(134, 22, 78.30f), + "24th Street", "10th Avenue" + ); + bus_stop *bs1 = new bus_stop_corner( + gps_position(35, 137, 23.456f), + gps_position(133, 35, 54.12f), + "State street", "Cathedral Vista Lane" + ); + bus_stop *bs2 = new bus_stop_destination( + gps_position(35, 136, 15.456f), + gps_position(133, 32, 15.300f), + "White House" + ); + bus_stop *bs3 = new bus_stop_destination( + gps_position(35, 134, 48.789f), + gps_position(133, 32, 16.230f), + "Lincoln Memorial" + ); + + // make a routes + bus_route route0; + route0.append(bs0); + route0.append(bs1); + route0.append(bs2); + + // add trips to schedule + original_schedule.append("bob", 6, 24, &route0); + original_schedule.append("bob", 9, 57, &route0); + original_schedule.append("alice", 11, 02, &route0); + + // make aother routes + bus_route route1; + route1.append(bs3); + route1.append(bs2); + route1.append(bs1); + + // add trips to schedule + original_schedule.append("ted", 7, 17, &route1); + original_schedule.append("ted", 9, 38, &route1); + original_schedule.append("alice", 11, 47, &route1); + + // display the complete schedule + std::cout << "original schedule"; + std::cout << original_schedule; + + std::string filename(boost::archive::tmpdir()); + filename += "/demo_save.xml"; + + // save the schedule + save_schedule(original_schedule, filename.c_str()); + + delete bs0; + delete bs1; + delete bs2; + delete bs3; + return 0; +} diff --git a/src/boost/libs/serialization/example/demofile.txt b/src/boost/libs/serialization/example/demofile.txt new file mode 100644 index 000000000..59ae12f63 --- /dev/null +++ b/src/boost/libs/serialization/example/demofile.txt @@ -0,0 +1,13 @@ +22 serialization::archive 3 0 2 0 0 6 0 0 0 0 6 24 4 1 0 +0 0 0 3 5 1 0 +1 0 0 0 0 34 135 52.560001 134 22 78.300003 11 24th Street 11 10th Avenue 5 +2 35 137 23.455999 133 35 54.119999 12 State street 20 Cathedral Vista Lane 6 1 0 +3 35 136 15.456 133 32 15.3 11 White House 9 57 4 +0 11 2 4 +0 7 17 4 +4 3 6 +5 35 134 48.789001 133 32 16.23 16 Lincoln Memorial 6 +3 5 +2 9 38 4 +4 11 47 4 +4
\ No newline at end of file diff --git a/src/boost/libs/serialization/example/fix_six.cpp b/src/boost/libs/serialization/example/fix_six.cpp new file mode 100644 index 000000000..6526e1292 --- /dev/null +++ b/src/boost/libs/serialization/example/fix_six.cpp @@ -0,0 +1,37 @@ +#include <fstream> +#include <ios> +#include <iostream> +#include <boost/integer_traits.hpp> +#include <boost/archive/binary_iarchive.hpp> + +void usage(const char * program_name){ + std::cout << "usage:"; + std::cout << program_name << " filename" << std::endl; +} + +int main(int argc, char *argv[]){ + if(argc != 2){ + std::cout << "invalid number of arguments" << std::endl; + usage(argv[0]); + return 1; + } + std::filebuf fb; + fb.open( + argv[1], + std::ios_base::binary | std::ios_base::in | std::ios_base::out + ); + if(!fb.is_open()){ + std::cout << argv[1] << " failed to open" << std::endl; + return 1; + } + boost::archive::binary_iarchive ia(fb); + boost::archive::library_version_type lvt = ia.get_library_version(); + if(boost::archive::library_version_type(6) != lvt){ + std::cout << "library version not equal to six" << std::endl; + return 1; + } + lvt = boost::archive::library_version_type(7); + fb.pubseekpos(26, std::ios_base::out); + fb.sputn(reinterpret_cast<const char *>(& lvt), sizeof(lvt)); + fb.close(); +} diff --git a/src/boost/libs/serialization/example/log_archive.cpp b/src/boost/libs/serialization/example/log_archive.cpp new file mode 100644 index 000000000..8b21a008b --- /dev/null +++ b/src/boost/libs/serialization/example/log_archive.cpp @@ -0,0 +1,32 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// log_archive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +//#define BOOST_ARCHIVE_SOURCE +#include "log_archive.hpp" +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of xml stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_xml_oarchive.ipp> +#include <boost/archive/impl/xml_oarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<log_archive>; +template class basic_xml_oarchive<log_archive> ; +template class xml_oarchive_impl<log_archive> ; + +} // namespace archive +} // namespace boost diff --git a/src/boost/libs/serialization/example/log_archive.hpp b/src/boost/libs/serialization/example/log_archive.hpp new file mode 100644 index 000000000..0d7ffdbd2 --- /dev/null +++ b/src/boost/libs/serialization/example/log_archive.hpp @@ -0,0 +1,81 @@ +#ifndef LOG_ARCHIVE_HPP +#define LOG_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// log_archive.hpp + +// (C) Copyright 2010 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <boost/archive/xml_oarchive.hpp> + +namespace boost { + namespace archive { + namespace detail { + template<class Archive> class interface_oarchive; + } // namespace detail + } // namespace archive +} // boost + +///////////////////////////////////////////////////////////////////////// +// log data to an output stream. This illustrates a simpler implemenation +// of text output which is useful for getting a formatted display of +// any serializable class. Intended to be useful as a debugging aid. +class log_archive : + /* protected ? */ + public boost::archive::xml_oarchive_impl<log_archive> +{ + typedef boost::archive::xml_oarchive_impl<log_archive> base; + // give serialization implementation access to this clas + friend class boost::archive::detail::interface_oarchive<log_archive>; + friend class boost::archive::basic_xml_oarchive<log_archive>; + friend class boost::archive::save_access; + + ///////////////////////////////////////////////////////////////////// + // Override functions defined in basic_xml_oarchive + + // Anything not an attribute and not a name-value pair is an + // error and should be trapped here. + template<class T> + void save_override(T & t){ + // make it a name-value pair and pass it on. + // this permits this to be used even with data types which + // are not wrapped with the name + base::save_override(boost::serialization::make_nvp(NULL, t)); + } + template<class T> + void save_override(const boost::serialization::nvp< T > & t){ + // this is here to remove the "const" requirement. Since + // this class is to be used only for output, it's not required. + base::save_override(t); + } + // specific overrides for attributes - not name value pairs so we + // want to trap them before the above "fall through" + // since we don't want to see these in the output - make them no-ops. + void save_override(const boost::archive::object_id_type & t){} + void save_override(const boost::archive::object_reference_type & t){} + void save_override(const boost::archive::version_type & t){} + void save_override(const boost::archive::class_id_type & t){} + void save_override(const boost::archive::class_id_optional_type & t){} + void save_override(const boost::archive::class_id_reference_type & t){} + void save_override(const boost::archive::class_name_type & t){} + void save_override(const boost::archive::tracking_type & t){} +public: + log_archive(std::ostream & os, unsigned int flags = 0) : + boost::archive::xml_oarchive_impl<log_archive>( + os, + flags | boost::archive::no_header + ) + {} +}; + +#endif // LOG_ARCHIVE_HPP diff --git a/src/boost/libs/serialization/example/polymorphic_portable_binary_iarchive.cpp b/src/boost/libs/serialization/example/polymorphic_portable_binary_iarchive.cpp new file mode 100644 index 000000000..2e16262b5 --- /dev/null +++ b/src/boost/libs/serialization/example/polymorphic_portable_binary_iarchive.cpp @@ -0,0 +1,34 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_portable_binary_iarchive.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <istream> + +#define BOOST_ARCHIVE_SOURCE +#include "polymorphic_portable_binary_iarchive.hpp" + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/basic_binary_iarchive.ipp> +#include <boost/archive/impl/archive_pointer_iserializer.ipp> +#include <boost/archive/impl/basic_binary_iprimitive.ipp> + +namespace boost { +namespace archive { + +template class binary_iarchive_impl< + polymorphic_portable_binary_iarchive, + std::istream::char_type, + std::istream::traits_type +>; +template class detail::archive_pointer_iserializer< + polymorphic_portable_binary_iarchive +> ; + +} // namespace archive +} // namespace boost diff --git a/src/boost/libs/serialization/example/polymorphic_portable_binary_iarchive.hpp b/src/boost/libs/serialization/example/polymorphic_portable_binary_iarchive.hpp new file mode 100644 index 000000000..34334c271 --- /dev/null +++ b/src/boost/libs/serialization/example/polymorphic_portable_binary_iarchive.hpp @@ -0,0 +1,35 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_portable_binary_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <boost/archive/detail/polymorphic_iarchive_dispatch.hpp> +#include "portable_binary_iarchive.hpp" + +typedef boost::archive::detail::polymorphic_iarchive_dispatch< + portable_binary_iarchive +> polymorphic_portable_binary_iarchive; + +#include <boost/version.hpp> +#if BOOST_VERSION > 103401 + // required by export + BOOST_SERIALIZATION_REGISTER_ARCHIVE( + polymorphic_portable_binary_iarchive + ) +#endif + +#endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP + diff --git a/src/boost/libs/serialization/example/polymorphic_portable_binary_oarchive.cpp b/src/boost/libs/serialization/example/polymorphic_portable_binary_oarchive.cpp new file mode 100644 index 000000000..dce90c343 --- /dev/null +++ b/src/boost/libs/serialization/example/polymorphic_portable_binary_oarchive.cpp @@ -0,0 +1,35 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_portable_binary_oarchive.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <ostream> + +#define BOOST_ARCHIVE_SOURCE +#include "polymorphic_portable_binary_oarchive.hpp" + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/basic_binary_oarchive.ipp> +#include <boost/archive/impl/archive_pointer_oserializer.ipp> +#include <boost/archive/impl/basic_binary_oprimitive.ipp> + +namespace boost { +namespace archive { + +// explicitly instantiate for this type of binary stream +template class binary_oarchive_impl< + polymorphic_portable_binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type +>; +template class detail::archive_pointer_oserializer< + polymorphic_portable_binary_oarchive +> ; + +} // namespace archive +} // namespace boost diff --git a/src/boost/libs/serialization/example/polymorphic_portable_binary_oarchive.hpp b/src/boost/libs/serialization/example/polymorphic_portable_binary_oarchive.hpp new file mode 100644 index 000000000..f63269a00 --- /dev/null +++ b/src/boost/libs/serialization/example/polymorphic_portable_binary_oarchive.hpp @@ -0,0 +1,34 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_portable_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <boost/archive/detail/polymorphic_oarchive_dispatch.hpp> +#include "portable_binary_oarchive.hpp" + +typedef boost::archive::detail::polymorphic_oarchive_dispatch< + portable_binary_oarchive + > polymorphic_portable_binary_oarchive; + +#include <boost/version.hpp> +#if BOOST_VERSION > 103401 + // required by export + BOOST_SERIALIZATION_REGISTER_ARCHIVE( + polymorphic_portable_binary_oarchive + ) +#endif + +#endif // BOOST_ARCHIVE_POLYMORPHIC_PORTABLE_BINARY_OARCHIVE_HPP diff --git a/src/boost/libs/serialization/example/portable_binary_archive.hpp b/src/boost/libs/serialization/example/portable_binary_archive.hpp new file mode 100644 index 000000000..132eba631 --- /dev/null +++ b/src/boost/libs/serialization/example/portable_binary_archive.hpp @@ -0,0 +1,46 @@ +#ifndef PORTABLE_BINARY_ARCHIVE_HPP +#define PORTABLE_BINARY_ARCHIVE_HPP + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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) + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include <boost/config.hpp> +#include <boost/cstdint.hpp> +#include <boost/static_assert.hpp> + +#include <climits> +#if CHAR_BIT != 8 +#error This code assumes an eight-bit byte. +#endif + +#include <boost/archive/basic_archive.hpp> +#include <boost/predef/other/endian.h> + +enum portable_binary_archive_flags { + endian_big = 0x4000, + endian_little = 0x8000 +}; + +//#if ( endian_big <= boost::archive::flags_last ) +//#error archive flags conflict +//#endif + +inline void +reverse_bytes(char size, char *address){ + char * first = address; + char * last = first + size - 1; + for(;first < last;++first, --last){ + char x = *last; + *last = *first; + *first = x; + } +} + +#endif // PORTABLE_BINARY_ARCHIVE_HPP diff --git a/src/boost/libs/serialization/example/portable_binary_iarchive.cpp b/src/boost/libs/serialization/example/portable_binary_iarchive.cpp new file mode 100644 index 000000000..08f3f20ec --- /dev/null +++ b/src/boost/libs/serialization/example/portable_binary_iarchive.cpp @@ -0,0 +1,131 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// portable_binary_iarchive.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <istream> +#include <string> + +#include <boost/predef/other/endian.h> +#include <boost/serialization/throw_exception.hpp> +#include <boost/archive/archive_exception.hpp> + +#include "portable_binary_iarchive.hpp" + +void +portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){ + char size; + l = 0; + this->primitive_base_t::load(size); + + if(0 == size){ + return; + } + + bool negative = (size < 0); + if(negative) + size = -size; + + if(size > maxsize) + boost::serialization::throw_exception( + portable_binary_iarchive_exception() + ); + + char * cptr = reinterpret_cast<char *>(& l); + #if BOOST_ENDIAN_BIG_BYTE + cptr += (sizeof(boost::intmax_t) - size); + #endif + this->primitive_base_t::load_binary(cptr, size); + + #if BOOST_ENDIAN_BIG_BYTE + if(m_flags & endian_little) + #else + if(m_flags & endian_big) + #endif + reverse_bytes(size, cptr); + + if(negative) + l = -l; +} + +void +portable_binary_iarchive::load_override( + boost::archive::class_name_type & t +){ + std::string cn; + cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); + load_override(cn); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::invalid_class_name) + ); + std::memcpy(t, cn.data(), cn.size()); + // borland tweak + t.t[cn.size()] = '\0'; +} + +void +portable_binary_iarchive::init(unsigned int flags){ + if(0 == (flags & boost::archive::no_header)){ + // read signature in an archive version independent manner + std::string file_signature; + * this >> file_signature; + if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE()) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::invalid_signature + ) + ); + // make sure the version of the reading archive library can + // support the format of the archive being read + boost::archive::library_version_type input_library_version; + * this >> input_library_version; + + // extra little .t is to get around borland quirk + if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unsupported_version + ) + ); + + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->set_library_version(input_library_version); + //#else + //#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + //detail:: + //#endif + boost::archive::detail::basic_iarchive::set_library_version( + input_library_version + ); + #endif + } + unsigned char x; + load(x); + m_flags = x << CHAR_BIT; +} + +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_binary_iprimitive.ipp> + +namespace boost { +namespace archive { + +namespace detail { + template class archive_serializer_map<portable_binary_iarchive>; +} + +template class basic_binary_iprimitive< + portable_binary_iarchive, + std::istream::char_type, + std::istream::traits_type +> ; + +} // namespace archive +} // namespace boost diff --git a/src/boost/libs/serialization/example/portable_binary_iarchive.hpp b/src/boost/libs/serialization/example/portable_binary_iarchive.hpp new file mode 100644 index 000000000..de7f287fb --- /dev/null +++ b/src/boost/libs/serialization/example/portable_binary_iarchive.hpp @@ -0,0 +1,204 @@ +#ifndef PORTABLE_BINARY_IARCHIVE_HPP +#define PORTABLE_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 ) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// portable_binary_iarchive.hpp + +// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <istream> +#include <boost/serialization/string.hpp> +#include <boost/serialization/item_version_type.hpp> +#include <boost/archive/archive_exception.hpp> +#include <boost/archive/basic_binary_iprimitive.hpp> +#include <boost/archive/detail/common_iarchive.hpp> +#include <boost/archive/detail/register_archive.hpp> + +#include "portable_binary_archive.hpp" + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// exception to be thrown if integer read from archive doesn't fit +// variable being loaded +class portable_binary_iarchive_exception : + public boost::archive::archive_exception +{ +public: + enum exception_code { + incompatible_integer_size + } m_exception_code ; + portable_binary_iarchive_exception(exception_code c = incompatible_integer_size ) : + boost::archive::archive_exception(boost::archive::archive_exception::other_exception), + m_exception_code(c) + {} + virtual const char *what( ) const throw( ) + { + const char *msg = "programmer error"; + switch(m_exception_code){ + case incompatible_integer_size: + msg = "integer cannot be represented"; + break; + default: + msg = boost::archive::archive_exception::what(); + assert(false); + break; + } + return msg; + } +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// "Portable" input binary archive. It addresses integer size and endienness so +// that binary archives can be passed across systems. Note:floating point types +// not addressed here +class portable_binary_iarchive : + public boost::archive::basic_binary_iprimitive< + portable_binary_iarchive, + std::istream::char_type, + std::istream::traits_type + >, + public boost::archive::detail::common_iarchive< + portable_binary_iarchive + > + { + typedef boost::archive::basic_binary_iprimitive< + portable_binary_iarchive, + std::istream::char_type, + std::istream::traits_type + > primitive_base_t; + typedef boost::archive::detail::common_iarchive< + portable_binary_iarchive + > archive_base_t; +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend archive_base_t; + friend primitive_base_t; // since with override load below + friend class boost::archive::detail::interface_iarchive< + portable_binary_iarchive + >; + friend class boost::archive::load_access; +protected: +#endif + unsigned int m_flags; + void load_impl(boost::intmax_t & l, char maxsize); + + // default fall through for any types not specified here + template<class T> + void load(T & t){ + boost::intmax_t l; + load_impl(l, sizeof(T)); + // use cast to avoid compile time warning + //t = static_cast< T >(l); + t = T(l); + } + void load(boost::serialization::item_version_type & t){ + boost::intmax_t l; + load_impl(l, sizeof(boost::serialization::item_version_type)); + // use cast to avoid compile time warning + t = boost::serialization::item_version_type(l); + } + void load(boost::archive::version_type & t){ + boost::intmax_t l; + load_impl(l, sizeof(boost::archive::version_type)); + // use cast to avoid compile time warning + t = boost::archive::version_type(l); + } + void load(boost::archive::class_id_type & t){ + boost::intmax_t l; + load_impl(l, sizeof(boost::archive::class_id_type)); + // use cast to avoid compile time warning + t = boost::archive::class_id_type(static_cast<int>(l)); + } + void load(std::string & t){ + this->primitive_base_t::load(t); + } + #ifndef BOOST_NO_STD_WSTRING + void load(std::wstring & t){ + this->primitive_base_t::load(t); + } + #endif + void load(float & t){ + this->primitive_base_t::load(t); + // floats not supported + //BOOST_STATIC_ASSERT(false); + } + void load(double & t){ + this->primitive_base_t::load(t); + // doubles not supported + //BOOST_STATIC_ASSERT(false); + } + void load(char & t){ + this->primitive_base_t::load(t); + } + void load(unsigned char & t){ + this->primitive_base_t::load(t); + } + typedef boost::archive::detail::common_iarchive<portable_binary_iarchive> + detail_common_iarchive; + template<class T> + void load_override(T & t){ + this->detail_common_iarchive::load_override(t); + } + void load_override(boost::archive::class_name_type & t); + // binary files don't include the optional information + void load_override(boost::archive::class_id_optional_type &){} + + void init(unsigned int flags); +public: + portable_binary_iarchive(std::istream & is, unsigned flags = 0) : + primitive_base_t( + * is.rdbuf(), + 0 != (flags & boost::archive::no_codecvt) + ), + archive_base_t(flags), + m_flags(0) + { + init(flags); + } + + portable_binary_iarchive( + std::basic_streambuf< + std::istream::char_type, + std::istream::traits_type + > & bsb, + unsigned int flags + ) : + primitive_base_t( + bsb, + 0 != (flags & boost::archive::no_codecvt) + ), + archive_base_t(flags), + m_flags(0) + { + init(flags); + } +}; + +// required by export in boost version > 1.34 +#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE + BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive) +#endif + +// required by export in boost <= 1.34 +#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +#endif // PORTABLE_BINARY_IARCHIVE_HPP diff --git a/src/boost/libs/serialization/example/portable_binary_oarchive.cpp b/src/boost/libs/serialization/example/portable_binary_oarchive.cpp new file mode 100644 index 000000000..a5d404965 --- /dev/null +++ b/src/boost/libs/serialization/example/portable_binary_oarchive.cpp @@ -0,0 +1,98 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// portable_binary_oarchive.cpp + +// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <ostream> +#include <boost/predef/other/endian.h> +#include "portable_binary_oarchive.hpp" + +void +portable_binary_oarchive::save_impl( + const boost::intmax_t l, + const char maxsize +){ + char size = 0; + + if(l == 0){ + this->primitive_base_t::save(size); + return; + } + + boost::intmax_t ll; + bool negative = (l < 0); + if(negative) + ll = -l; + else + ll = l; + + do{ + ll >>= CHAR_BIT; + ++size; + }while(ll != 0); + + this->primitive_base_t::save( + static_cast<char>(negative ? -size : size) + ); + + if(negative) + ll = -l; + else + ll = l; + char * cptr = reinterpret_cast<char *>(& ll); + #if BOOST_ENDIAN_BIG_BYTE + cptr += (sizeof(boost::intmax_t) - size); + if(m_flags & endian_little) + reverse_bytes(size, cptr); + #else + if(m_flags & endian_big) + reverse_bytes(size, cptr); + #endif + this->primitive_base_t::save_binary(cptr, size); +} + +void +portable_binary_oarchive::init(unsigned int flags) { + if(m_flags == (endian_big | endian_little)){ + boost::serialization::throw_exception( + portable_binary_oarchive_exception() + ); + } + if(0 == (flags & boost::archive::no_header)){ + // write signature in an archive version independent manner + const std::string file_signature( + boost::archive::BOOST_ARCHIVE_SIGNATURE() + ); + * this << file_signature; + // write library version + const boost::archive::library_version_type v( + boost::archive::BOOST_ARCHIVE_VERSION() + ); + * this << v; + } + save(static_cast<unsigned char>(m_flags >> CHAR_BIT)); +} + +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_binary_oprimitive.ipp> + +namespace boost { +namespace archive { + +namespace detail { + template class archive_serializer_map<portable_binary_oarchive>; +} + +template class basic_binary_oprimitive< + portable_binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type +> ; + +} // namespace archive +} // namespace boost diff --git a/src/boost/libs/serialization/example/portable_binary_oarchive.hpp b/src/boost/libs/serialization/example/portable_binary_oarchive.hpp new file mode 100644 index 000000000..5085fc3db --- /dev/null +++ b/src/boost/libs/serialization/example/portable_binary_oarchive.hpp @@ -0,0 +1,191 @@ +#ifndef PORTABLE_BINARY_OARCHIVE_HPP +#define PORTABLE_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 ) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// portable_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <ostream> +#include <boost/serialization/string.hpp> +#include <boost/archive/archive_exception.hpp> +#include <boost/archive/basic_binary_oprimitive.hpp> +#include <boost/archive/detail/common_oarchive.hpp> +#include <boost/archive/detail/register_archive.hpp> + +#include "portable_binary_archive.hpp" + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// exception to be thrown if integer read from archive doesn't fit +// variable being loaded +class portable_binary_oarchive_exception : + public boost::archive::archive_exception +{ +public: + typedef enum { + invalid_flags + } exception_code; + portable_binary_oarchive_exception(exception_code c = invalid_flags ) + {} + virtual const char *what( ) const throw( ) + { + const char *msg = "programmer error"; + switch(code){ + case invalid_flags: + msg = "cannot be both big and little endian"; + default: + boost::archive::archive_exception::what(); + } + return msg; + } +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// "Portable" output binary archive. This is a variation of the native binary +// archive. it addresses integer size and endienness so that binary archives can +// be passed across systems. Note:floating point types not addressed here + +class portable_binary_oarchive : + public boost::archive::basic_binary_oprimitive< + portable_binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type + >, + public boost::archive::detail::common_oarchive< + portable_binary_oarchive + > +{ + typedef boost::archive::basic_binary_oprimitive< + portable_binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type + > primitive_base_t; + typedef boost::archive::detail::common_oarchive< + portable_binary_oarchive + > archive_base_t; +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend archive_base_t; + friend primitive_base_t; // since with override save below + friend class boost::archive::detail::interface_oarchive< + portable_binary_oarchive + >; + friend class boost::archive::save_access; +protected: +#endif + unsigned int m_flags; + void save_impl(const boost::intmax_t l, const char maxsize); + // add base class to the places considered when matching + // save function to a specific set of arguments. Note, this didn't + // work on my MSVC 7.0 system so we use the sure-fire method below + // using archive_base_t::save; + + // default fall through for any types not specified here + template<class T> + void save(const T & t){ + save_impl(t, sizeof(T)); + } + void save(const std::string & t){ + this->primitive_base_t::save(t); + } + #ifndef BOOST_NO_STD_WSTRING + void save(const std::wstring & t){ + this->primitive_base_t::save(t); + } + #endif + void save(const float & t){ + this->primitive_base_t::save(t); + // floats not supported + //BOOST_STATIC_ASSERT(false); + } + void save(const double & t){ + this->primitive_base_t::save(t); + // doubles not supported + //BOOST_STATIC_ASSERT(false); + } + void save(const char & t){ + this->primitive_base_t::save(t); + } + void save(const unsigned char & t){ + this->primitive_base_t::save(t); + } + + // default processing - kick back to base class. Note the + // extra stuff to get it passed borland compilers + typedef boost::archive::detail::common_oarchive<portable_binary_oarchive> + detail_common_oarchive; + template<class T> + void save_override(T & t){ + this->detail_common_oarchive::save_override(t); + } + // explicitly convert to char * to avoid compile ambiguities + void save_override(const boost::archive::class_name_type & t){ + const std::string s(t); + * this << s; + } + // binary files don't include the optional information + void save_override( + const boost::archive::class_id_optional_type & /* t */ + ){} + + void init(unsigned int flags); +public: + portable_binary_oarchive(std::ostream & os, unsigned flags = 0) : + primitive_base_t( + * os.rdbuf(), + 0 != (flags & boost::archive::no_codecvt) + ), + archive_base_t(flags), + m_flags(flags & (endian_big | endian_little)) + { + init(flags); + } + + portable_binary_oarchive( + std::basic_streambuf< + std::ostream::char_type, + std::ostream::traits_type + > & bsb, + unsigned int flags + ) : + primitive_base_t( + bsb, + 0 != (flags & boost::archive::no_codecvt) + ), + archive_base_t(flags), + m_flags(0) + { + init(flags); + } +}; + + +// required by export in boost version > 1.34 +#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE + BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive) +#endif + +// required by export in boost <= 1.34 +#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +#endif // PORTABLE_BINARY_OARCHIVE_HPP diff --git a/src/boost/libs/serialization/example/simple_log_archive.hpp b/src/boost/libs/serialization/example/simple_log_archive.hpp new file mode 100644 index 000000000..44f6d73dd --- /dev/null +++ b/src/boost/libs/serialization/example/simple_log_archive.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_SIMPLE_LOG_ARCHIVE_HPP +#define BOOST_SIMPLE_LOG_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// simple_log_archive.hpp + +// (C) Copyright 2010 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to 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. + +#include <ostream> +#include <cstddef> // std::size_t + +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include <boost/type_traits/is_enum.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/serialization/nvp.hpp> +#include <boost/serialization/array.hpp> +#include <boost/serialization/string.hpp> +#include <boost/serialization/access.hpp> + +///////////////////////////////////////////////////////////////////////// +// log data to an output stream. This illustrates a simpler implemenation +// of text output which is useful for getting a formatted display of +// any serializable class. Intended to be useful as a debugging aid. +class simple_log_archive { + std::ostream & m_os; + unsigned int m_depth; + + template<class Archive> + struct save_enum_type { + template<class T> + static void invoke(Archive &ar, const T &t){ + ar.m_os << static_cast<int>(t); + } + }; + template<class Archive> + struct save_primitive { + template<class T> + static void invoke(Archive & ar, const T & t){ + ar.m_os << t; + } + }; + template<class Archive> + struct save_only { + template<class T> + static void invoke(Archive & ar, const T & t){ + // make sure call is routed through the highest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, + const_cast<T &>(t), + ::boost::serialization::version< T >::value + ); + } + }; + template<class T> + void save(const T &t){ + typedef + BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<boost::is_enum< T >, + boost::mpl::identity<save_enum_type<simple_log_archive> >, + //else + BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< + // if its primitive + boost::mpl::equal_to< + boost::serialization::implementation_level< T >, + boost::mpl::int_<boost::serialization::primitive_type> + >, + boost::mpl::identity<save_primitive<simple_log_archive> >, + // else + boost::mpl::identity<save_only<simple_log_archive> > + > >::type typex; + typex::invoke(*this, t); + } + #ifndef BOOST_NO_STD_WSTRING + void save(const std::wstring &ws){ + m_os << "wide string types not suported in log archive"; + } + #endif + +public: + /////////////////////////////////////////////////// + // Implement requirements for archive concept + + typedef boost::mpl::bool_<false> is_loading; + typedef boost::mpl::bool_<true> is_saving; + + // this can be a no-op since we ignore pointer polymorphism + template<class T> + void register_type(const T * = NULL){} + + unsigned int get_library_version(){ + return 0; + } + + void + save_binary(const void *address, std::size_t count){ + m_os << "save_binary not implemented"; + } + + // the << operators + template<class T> + simple_log_archive & operator<<(T const & t){ + m_os << ' '; + save(t); + return * this; + } + template<class T> + simple_log_archive & operator<<(T * const t){ + m_os << " ->"; + if(NULL == t) + m_os << " null"; + else + *this << * t; + return * this; + } + template<class T, int N> + simple_log_archive & operator<<(const T (&t)[N]){ + return *this << boost::serialization::make_array( + static_cast<const T *>(&t[0]), + N + ); + } + template<class T> + simple_log_archive & operator<<(const boost::serialization::nvp< T > & t){ + m_os << '\n'; // start line with each named object + // indent according to object depth + for(unsigned int i = 0; i < m_depth; ++i) + m_os << ' '; + ++m_depth; + m_os << t.name(); // output the name of the object + * this << t.const_value(); + --m_depth; + return * this; + } + + // the & operator + template<class T> + simple_log_archive & operator&(const T & t){ + return * this << t; + } + /////////////////////////////////////////////// + + simple_log_archive(std::ostream & os) : + m_os(os), + m_depth(0) + {} +}; + +#endif // BOOST_SIMPLE_LOG_ARCHIVE_HPP |