I'm always baffled on constraints like that. Boost is there, it works, it would take just a few hours to add to the project and then solve the problems in no time -- but instead weeks are spent on reimplementing a jagged wheel.
If you don't use boost you can still study it. The code itself will likely be ridden with macros as usual but the interface can provide insight.
MFC can be studied for both design and implementation if you have MSVC, whatever old version. The one is pretty straightforward and you can use the ideas to create your own variant. Guess you can find more existing frameworks.
The basic idea is simple, you have a CArchive-like class that manages the serialization, owning a data stream, and providing I/O for the primitive types. Normally using an overload set of a common function plus a few special variants.
Then you make all your classes implement their own load and save by calling that function for each data member. It can be intrusive or use overloaded free function or specializing a template or some combination of those. Also somewhere add support to serialize collections -- not really hard as it's just iteration and calling serialize on items. And for smart pointers.
The hard part is to deal with pointers, especially shared ones -- with some luck you can sidestep it.
The store format is arbitrary and you can even change it just in the archive manager without anyone noticing. Except is you want XML-like store that uses tags beside the content, you must plan for that in the interface.
For polymorphic pointers you will need some more support, some factory facility and identifiers.
Then drop in schema handling as in few weeks your classes will change and people will still want to load yesterday's file.
Are you sure you want to avoid using boost or another stock solution?