2 * Automatic object hierarchy externalization for XTL
4 * Copyright (C) 1998-2000 Jose' Orlando Pereira, Universidade do Minho
6 /* XTL - eXternalization Template Library - http://gsd.di.uminho.pt/~jop/xtl
7 * Copyright (C) 1998-2000 Jose' Orlando Pereira, Universidade do Minho
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24 * Id: autoio.h 1.4 Fri, 05 May 2000 18:57:58 +0100 jop
30 #include <xtl/objio.h>
31 #include <xtl/vobjio.h>
37 typedef std::map<int, reader*> externalizable_index;
39 class externalizable_base;
46 reader(int i, std::map<int, reader*>& repo):id(i) {
47 std::map<int, reader*>::const_iterator t=repo.find(id);
49 throw std::logic_error("registering duplicate class id");
50 repo.insert(std::make_pair(id, this));
53 virtual externalizable_base* read(obj_input<v_format>& stream)=0;
55 int classid() const {return id;}
59 class concrete_reader: public reader {
61 concrete_reader(int i, std::map<int, reader*>& repo):reader(i, repo) {}
63 virtual externalizable_base* read(obj_input<v_format>& stream) {
65 ptr->vcomposite(stream);
70 class externalizable_base {
72 int classid() const {return info().classid();}
73 virtual reader& info() const=0;
75 virtual void vcomposite(obj_output<v_format>& stream) const=0;
76 virtual void vcomposite(obj_input<v_format>& stream)=0;
79 class auto_obj_input: public obj_input<v_format> {
81 const std::map<int, reader*>& repo;
84 auto_obj_input(v_format& f, const std::map<int, reader*>& r):
85 obj_input<v_format>(f), repo(r) {}
88 auto_obj_input& auto_object(T*& data) {
91 std::map<int, reader*>::const_iterator t=repo.find(id);
93 throw std::logic_error("unknown class id");
94 externalizable_base* ptr=(*t).second->read(*this);
95 data=dynamic_cast<T*>(ptr);
100 class auto_obj_output: public obj_output<v_format> {
102 auto_obj_output(v_format& f):obj_output<v_format>(f) {}
105 auto_obj_output& auto_object(T*& data) {
106 const externalizable_base* ptr=data;
107 int id=ptr->classid();
109 ptr->vcomposite(*this);
114 #define decl_externalizable(name)\
116 virtual reader& info() const {return myinfo;}\
117 virtual void vcomposite(obj_output<v_format>& stream) const\
118 {const_cast<name*>(this)->composite(stream);}\
119 virtual void vcomposite(obj_input<v_format>& stream)\
120 {composite(stream);}\
122 static concrete_reader<name> myinfo
124 #define impl_externalizable(name, id, index)\
125 concrete_reader<name> name::myinfo(id, index)