|
Boost : |
From: Wesley W. Terpstra (terpstra_at_[hidden])
Date: 2002-11-19 14:30:45
On Tue, Nov 19, 2002 at 06:07:23PM +0100, Wesley W. Terpstra wrote:
> The trick is to use the FUNCTION boundary of the serializor.
<snip code>
I have attached a working proto-type.
This is merely proof of concept; I am not sure whether one should bracket
fundamental types for instance.
The output is presently:
[ 1 [ 2 ] 3 4 [ 5 ] ]
but maybe should be:
[ [1] [ [2] ] [3] [4] [ [5] ] ]
What do people think?
I am certain someone smarter than I could make this even more clever.
--- Wes //-------------------------------------------------------- Example begins // Compiles and works with g++-2.95.4 #include <iostream> using namespace std; //-------------------------------------------------------- Common Framework class object_stream; class streamer { protected: object_stream* m_impl; streamer(object_stream* stream) : m_impl(stream) { } public: template <class T> object_stream& operator << (const T& x); friend class object_stream; }; class object_stream { protected: streamer m_helper; virtual void object_begin() = 0; virtual void object_end () = 0; public: object_stream() : m_helper(this) { } virtual ~object_stream() { } operator streamer& () { // Casted on return from method object_end(); return m_helper; } // All fundamental types go here virtual object_stream& operator << (int x) = 0; // This catches all non-fundamental types and safely preserves // our type information while calling template <class T> object_stream& operator << (const T& x) { // Don't use conversion routine to cast us (not end of object) return *(m_helper << x).m_impl; } friend class streamer; }; template <class T> object_stream& streamer::operator << (const T& x) { m_impl->object_begin(); return *m_impl << x; } //-------------------------------------------------------- Concrete streamer class paran_object_stream : public object_stream { protected: void object_begin() { cout << "[ "; } void object_end () { cout << "] "; } public: paran_object_stream& operator << (int x) { cout << x << " "; return *this; } }; class paran_streamer : public streamer { protected: paran_object_stream m_obj; public: paran_streamer() : streamer(&m_obj) // a bit bad since it is not init'd, but since { } // we won't do anything in the base-class, ok }; //-------------------------------------------------------- Generic user struct Foo { int x; }; streamer& operator << (streamer& o, const Foo& f) { return o << f.x; } struct Bar { int a; Foo b; int c; int d; Foo e; }; streamer& operator << (streamer& o, const Bar& b) { return o << b.a << b.b << b.c << b.d << b.e; } //-------------------------------------------------------- test int main() { Bar b; b.a = 1; b.b.x = 2; b.c = 3; b.d = 4; b.e.x = 5; paran_streamer s; s << b; cout << endl; }
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk