//#include <iostream>
//#include <windows.h>
#include <string>
#include <fstream>

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

#include <boost/serialization/nvp.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/extended_type_info_no_rtti.hpp>


class Base
{
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & /* ar */, const unsigned int /* file_version */){
    }
public:
    virtual const char * get_key() const = 0;
    virtual ~Base(){};
};

BOOST_IS_ABSTRACT(Base)
BOOST_CLASS_TYPE_INFO(
    Base,
    extended_type_info_no_rtti<Base>
)
// note: types which use ...no_rtti MUST be exported
BOOST_CLASS_EXPORT(Base)


class Derived:public Base
{
private:
    friend class boost::serialization::access;
    // When the class Archive corresponds to an output archive, the
    // & operator is defined similar to <<.  Likewise, when the class Archive
    // is a type of input archive the & operator is defined similar to >>.

    template<class Archive>
    void serialize(Archive &ar, const unsigned int  /* file_version */){
        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
        ar & nValue;
    }

    int nValue;
public:
	Derived():nValue(0){};
    Derived(int d):nValue(d)
	{
	}
    virtual const char * get_key() const ;
};
 
BOOST_CLASS_TYPE_INFO(
    Derived,
    extended_type_info_no_rtti<Derived>
)
BOOST_CLASS_EXPORT(Derived)

void save(const std::string filename)
{
  //Base* pDerived = new Derived;
  //binarystream_out << pDerived;
	std::ofstream ofs(filename.c_str(),std::ios::binary);
	boost::archive::binary_oarchive oa(ofs);
	const Base* pos0 = new Derived(27);
	oa.register_type(static_cast<Derived*>(0));
	oa<<BOOST_SERIALIZATION_NVP(pos0);
};
 
void load(const std::string filename)
{
  //Base* pDerived = 0;
  //binarystream_in >> pDerived;
	Base *pos2=0;
	std::ifstream ifs(filename.c_str(),std::ios::binary);		
	boost::archive::binary_iarchive ia(ifs);
	ia.register_type(static_cast<Derived*>(0));
	ia>>BOOST_SERIALIZATION_NVP(pos2);
};





const char * Derived::get_key() const {
    const boost::serialization::extended_type_info *eti
        = boost::serialization::type_info_implementation<Derived>
            ::type::get_instance();
    return eti->get_key();
}


int main()
{
	save("file.bin");
	load("file.bin");
	return 0;
}

