]> git.lyx.org Git - lyx.git/blob - src/xtl/autoio.h
fix typo that put too many include paths for most people
[lyx.git] / src / xtl / autoio.h
1 /*
2  * Automatic object hierarchy externalization for XTL
3  *
4  * Copyright (C) 1998-2000 Jose' Orlando Pereira, Universidade do Minho
5  */
6 /* XTL - eXternalization Template Library - http://gsd.di.uminho.pt/~jop/xtl
7  * Copyright (C) 1998-2000 Jose' Orlando Pereira, Universidade do Minho
8  *
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.
13  * 
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.
18  * 
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,
22  * MA 02111-1307, USA
23  *
24  * Id: autoio.h 1.4 Fri, 05 May 2000 18:57:58 +0100 jop 
25  */
26
27 #ifndef __XTL_AUTOIO
28 #define __XTL_AUTOIO
29
30 #include <xtl/objio.h>
31 #include <xtl/vobjio.h>
32 #include <map>
33 #include <stdexcept>
34
35 class reader;
36
37 typedef std::map<int, reader*> externalizable_index;
38
39 class externalizable_base;
40
41 class reader {
42  private:
43         int id;
44
45  public:
46         reader(int i, std::map<int, reader*>& repo):id(i) {
47                 std::map<int, reader*>::const_iterator t=repo.find(id);
48                 if (t!=repo.end())
49                         throw std::logic_error("registering duplicate class id");
50                 repo.insert(std::make_pair(id, this));
51         }
52
53         virtual externalizable_base* read(obj_input<v_format>& stream)=0;
54
55         int classid() const {return id;}
56 };
57
58 template <class T>
59 class concrete_reader: public reader {
60  public:
61         concrete_reader(int i, std::map<int, reader*>& repo):reader(i, repo) {}
62
63         virtual externalizable_base* read(obj_input<v_format>& stream) {
64                 T* ptr=new T;
65                 ptr->vcomposite(stream);
66                 return ptr;
67         }
68 };
69
70 class externalizable_base {
71  public:
72         int classid() const {return info().classid();}
73         virtual reader& info() const=0;
74         
75         virtual void vcomposite(obj_output<v_format>& stream) const=0;
76         virtual void vcomposite(obj_input<v_format>& stream)=0;
77 };
78
79 class auto_obj_input: public obj_input<v_format> {
80  private:
81         const std::map<int, reader*>& repo;
82
83  public:
84         auto_obj_input(v_format& f, const std::map<int, reader*>& r):
85                 obj_input<v_format>(f), repo(r) {}
86
87         template <class T>
88         auto_obj_input& auto_object(T*& data) {
89                 int id=0;
90                 simple(id);
91                 std::map<int, reader*>::const_iterator t=repo.find(id);
92                 if (t==repo.end())
93                         throw std::logic_error("unknown class id");
94                 externalizable_base* ptr=(*t).second->read(*this);
95                 data=dynamic_cast<T*>(ptr);
96                 return *this;
97         }
98 };
99
100 class auto_obj_output: public obj_output<v_format> {
101  public:
102         auto_obj_output(v_format& f):obj_output<v_format>(f) {}
103
104         template <class T>
105         auto_obj_output& auto_object(T*& data) {
106                 const externalizable_base* ptr=data;
107                 int id=ptr->classid();
108                 simple(id);
109                 ptr->vcomposite(*this);
110                 return *this;
111         }
112 };
113
114 #define decl_externalizable(name)\
115 public:\
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);}\
121 private:\
122         static concrete_reader<name> myinfo
123
124 #define impl_externalizable(name, id, index)\
125 concrete_reader<name> name::myinfo(id, index)
126
127 #endif