/home/docs/checkouts/readthedocs.org/user_builds/ratpac/checkouts/latest/src/external/stlplus/include/stlplus/persistent.hpp Source File

Ratpac-two: /home/docs/checkouts/readthedocs.org/user_builds/ratpac/checkouts/latest/src/external/stlplus/include/stlplus/persistent.hpp Source File
Ratpac-two
persistent.hpp
1 #ifndef PERSISTENT_HPP
2 #define PERSISTENT_HPP
3 /*------------------------------------------------------------------------------
4 
5  Author: Andy Rushton
6  Copyright: (c) Andy Rushton, 2004
7  License: BSD License, see ../docs/license.html
8 
9  ------------------------------------------------------------------------------*/
10 #include <stdlib.h>
11 
12 #include <bitset>
13 #include <complex>
14 #include <deque>
15 #include <list>
16 #include <map>
17 #include <set>
18 #include <stdexcept>
19 #include <string>
20 #include <typeinfo>
21 #include <vector>
22 
23 #include "clonable.hpp"
24 #include "os_fixes.hpp"
25 #include "textio.hpp"
26 
28 // The format version number currently supported
30 
31 extern unsigned char PersistentVersion;
32 
34 // Exceptions thrown by the persistence functions
35 
36 // exception thrown if you try to dump or restore an illegal polymorphic type
37 class persistent_illegal_type : public std::logic_error {
38  public:
39  persistent_illegal_type(const std::string& type) throw();
40  persistent_illegal_type(unsigned short key) throw();
41  ~persistent_illegal_type(void) throw();
42 };
43 
44 // exception thrown if a dump fails for any reason - but typically because the output stream couldn't take the data
45 class persistent_dump_failed : public std::runtime_error {
46  public:
47  persistent_dump_failed(const std::string& message) throw();
48  ~persistent_dump_failed(void) throw();
49 };
50 
51 // exception thrown if you try to restore from an out of date or unrecognised byte stream
52 class persistent_restore_failed : public std::runtime_error {
53  public:
54  persistent_restore_failed(const std::string& message) throw();
55  ~persistent_restore_failed(void) throw();
56 };
57 
59 // dump_context controls the formatting of a persistent dump
61 
62 class dump_context_body;
63 
64 class dump_context {
65  public:
66  // types used in making polymorphous classes persistent using the callback approach
67 
68  // callback function for dumping the class
69  typedef void (*dump_callback)(dump_context&, const void*);
70  // data stored per class registered
71  typedef std::pair<unsigned short, dump_callback> callback_data;
72 
73  // type of callback function used to install all polymorphic classes for either approach
74  typedef void (*installer)(dump_context&);
75 
77 
78  dump_context(const otext& device, unsigned char version = PersistentVersion) throw();
79  ~dump_context(void);
80 
81  // low level output used to dump a byte
82  void put(unsigned char data) throw();
83 
84  // access the device, for example to check the error status
85  const otext& device(void) const;
86 
87  // recover the version number of the dumped output
88  unsigned char version(void) const;
89 
90  // test whether the current platform uses little-endian or big-endian addressing of bytes
91  // this is used in dump/restore of integers
92  bool little_endian(void) const;
93 
94  // Assist functions for Pointers
95  // the return pair is a flag saying whether this is a new pointer and the magic key to dump to file
96  std::pair<bool, unsigned> pointer_map(const void* const pointer);
97 
98  // Assist functions for Polymorphous classes (i.e. subclasses) using callback approach
99  unsigned short register_type(const std::type_info& info, dump_callback);
100  bool is_callback(const std::type_info& info) const;
101  callback_data lookup_type(const std::type_info&) const throw();
102 
103  // Assist functions for Polymorphous classes (i.e. subclasses) using interface approach
104  unsigned short register_interface(const std::type_info& info);
105  bool is_interface(const std::type_info& info) const;
106  unsigned short lookup_interface(const std::type_info&) const throw();
107 
108  // Register all Polymorphous classes using either approach by calling an installer callback
109  void register_all(installer);
110 
111  private:
112  friend class dump_context_body;
113  dump_context_body* m_body;
114 
115  // disallow copying by making assignment and copy constructor private
116  dump_context(const dump_context&);
117  dump_context& operator=(const dump_context&);
118 };
119 
121 // restore_context controls the reading of the persistent data during a restore
122 
123 class persistent;
125 
127  public:
128  // types used in making polymorphous classes persistent using the callback approach
129 
130  // callback function for creating a new object of the class and returning the pointer
131  typedef void* (*create_callback)(void);
132  // callback for restoring the contents of a new object created by the create_callback
133  // and passed as the second argument
134  typedef void (*restore_callback)(restore_context&, void*);
135  // data stored per class registered
136  typedef std::pair<create_callback, restore_callback> callback_data;
137 
138  // types used in making polymorphous classes persistent using the interface approach
139 
140  friend class persistent;
141  typedef std::pair<unsigned short, persistent*> interface_data;
142 
143  // type of callback function used to install all polymorphic classes for either approach
144  typedef void (*installer)(restore_context&);
145 
147 
148  restore_context(const itext& device) throw();
149  ~restore_context(void);
150 
151  // low level input used to restore a byte
152  int get(void) throw();
153 
154  // access the device, for example to check the error status
155  const itext& device(void) const;
156 
157  // access the version number of the input being restored
158  unsigned char version(void) const;
159 
160  // test whether the current platform uses little-endian or big-endian addressing of bytes
161  // this is used in dump/restore of integers
162  bool little_endian(void) const;
163 
164  // Assist functions for Pointers
165  std::pair<bool, void*> pointer_map(unsigned magic);
166  void pointer_add(unsigned magic, void* new_pointer);
167 
168  // Assist functions for Polymorphous classes using the callback approach
169  unsigned short register_type(create_callback, restore_callback);
170  bool is_callback(unsigned short) const;
171  callback_data lookup_type(unsigned short) const throw();
172 
173  // Assist functions for Polymorphous classes using the interface approach
174  // the object class must be a derivative of class persistent - i.e. it must implement the persistent interface
175  unsigned short register_interface(const persistent&);
176  bool is_interface(unsigned short) const;
177  const persistent& lookup_interface(unsigned short) const throw();
178 
179  // Register all Polymorphous classes using either approach by calling an installer callback
180  void register_all(installer);
181 
182  private:
183  friend class restore_context_body;
184  restore_context_body* m_body;
185 
186  // disallow copying by making assignment and copy constructor private
188  restore_context& operator=(const restore_context&);
189 };
190 
192 // Class defines an interface for use in making polymorphous classes persistent
194 // Note that it is derived from the clonable interface - so you must provide
195 // that interface too
196 
197 class persistent : public clonable {
198  public:
199  virtual void dump(dump_context&) const throw() = 0;
200  virtual void restore(restore_context&) throw() = 0;
201  virtual ~persistent(){};
202 };
203 
205 // Integers
206 
207 void dump(dump_context&, const bool& data) throw();
208 void restore(restore_context&, bool& data) throw();
209 void dump(dump_context&, const char& data) throw();
210 void restore(restore_context&, char& data) throw();
211 void dump(dump_context&, const signed char& data) throw();
212 void restore(restore_context&, signed char& data) throw();
213 void dump(dump_context&, const unsigned char& data) throw();
214 void restore(restore_context&, unsigned char& data) throw();
215 void dump(dump_context&, const short& data) throw();
216 void restore(restore_context&, short& data) throw();
217 void dump(dump_context&, const unsigned short& data) throw();
218 void restore(restore_context&, unsigned short& data) throw();
219 void dump(dump_context&, const int& data) throw();
220 void restore(restore_context&, int& data) throw();
221 void dump(dump_context&, const unsigned& data) throw();
222 void restore(restore_context&, unsigned& data) throw();
223 void dump(dump_context&, const long& data) throw();
224 void restore(restore_context&, long& data) throw();
225 void dump(dump_context&, const unsigned long& data) throw();
226 void restore(restore_context&, unsigned long& data) throw();
227 
229 // Floating point types
230 //
231 // Note: despite years and years of IEEE standardisation, not all
232 // architectures use IEEE-standard representations of floating-point numbers.
233 // Therefore a binary dump is not necessarily portable between platforms.
234 // Solving this is (currently) beyond the scope of the STLplus project.
235 
236 void dump(dump_context&, const float& data) throw();
237 void restore(restore_context&, float& data) throw();
238 void dump(dump_context&, const double& data) throw();
239 void restore(restore_context&, double& data) throw();
240 
242 // enumeration types
243 
244 template <typename T>
245 void dump_enum(dump_context&, const T& data) throw();
246 template <typename T>
247 void restore_enum(restore_context&, T& data) throw();
248 
250 // C-style char arrays.
251 // These are handled differently to other pointer types as below
252 
253 // Warning! This means that pointers to char cannot be supported, since there
254 // is no type difference between a pointer to char and a C-style array of char
255 
256 // Warning! The restore deletes any old value of the data parameter and
257 // allocates a new char* which is (just) big enough and assigns it to the data
258 // field. This is because there is no way of knowing how long a char* is so
259 // the passed parameter is not safe to use. The allocation is done using
260 // standard new. If the data field is non-null on entry it will be deleted by
261 // standard delete. Best to make it null in the first place.
262 
263 void dump(dump_context&, char*& data) throw();
264 void restore(restore_context&, char*& data) throw();
265 
267 // STL strings
268 
269 template <typename charT, typename traits, typename allocator>
270 void dump_basic_string(dump_context&, const std::basic_string<charT, traits, allocator>& data) throw();
271 template <typename charT, typename traits, typename allocator>
272 void restore_basic_string(restore_context&, std::basic_string<charT, traits, allocator>& data) throw();
273 
274 void dump(dump_context&, const std::string& data) throw();
275 void restore(restore_context&, std::string& data) throw();
276 
278 // Pointers
279 
280 // Supports null pointers too!
281 
282 // Warning! The pointer must be a dynamically-allocated type, since the implementation uses new/delete
283 // If the data field to restore is null and the file format non-null, allocates a new T()
284 // If the data field is non-null and the file format is null, deletes it and sets it null
285 
286 // Multiple pointers to the same object *will* be restored as multiple
287 // pointers to the same object. The object is dumped only the first time it is
288 // encountered along with a "magic key". Subsequent pointers to the same
289 // object cause only the magic key to be dumped. On restore, the object is
290 // only restored once and the magic keys are matched up so that the other
291 // pointers now pojnt to the restored object.
292 
293 template <typename T>
294 void dump_pointer(dump_context&, const T* const data) throw();
295 
296 template <typename T>
297 void restore_pointer(restore_context&, T*& data) throw();
298 
300 // Cross-references
301 // A cross-reference is a pointer to an object that has definitely been dumped
302 // already by one of dump_pointer, dump_interface or dump_polymorph, i.e. by
303 // one of the dump routines for pointers to objects.
304 //
305 // These are typically used in data structures as back-pointers or pointers
306 // between nodes.
307 //
308 // For example, you may have a tree with cross links. Dump the tree as the
309 // primary data structure and then dump the cross links as cross-references.
310 // These functions will throw an exception if the cross-reference points to
311 // something not dumped before.
312 
313 template <typename T>
314 void dump_xref(dump_context&, const T* const data) throw();
315 
316 template <typename T>
317 void restore_xref(restore_context&, T*& data) throw();
318 
320 // Polymorphous types using the callback approach
321 // These are always dumped/restored as pointers to the superclass T.
322 
323 // Multiple pointers to the same object are handled in the same way as above
324 // for simple pointers
325 
326 // Only classes registered with the context can be dumped and restored as
327 // polymorphic types - see dump_context::register_type and restore_context::register_type.
328 
329 template <typename T>
330 void dump_polymorph(dump_context&, const T* const data) throw();
331 
332 template <typename T>
333 void restore_polymorph(restore_context&, T*& data) throw();
334 
336 // Polymorphous types using the interface approach
337 // These are always dumped/restored as pointers to the superclass T.
338 
339 // Multiple pointers to the same object are handled in the same way as above
340 // for simple pointers
341 
342 // Only classes registered with the context can be dumped and restored as
343 // polymorphic types - see dump_context::register_interface and restore_context::register_interface
344 
345 template <typename T>
346 void dump_interface(dump_context&, const T* const data) throw();
347 
348 template <typename T>
349 void restore_interface(restore_context&, T*& data) throw();
350 
352 // STL Containers
353 
354 template <size_t N>
355 void dump_bitset(dump_context&, const std::bitset<N>& data) throw();
356 template <size_t N>
357 void restore_bitset(restore_context&, std::bitset<N>& data) throw();
358 
359 template <typename T>
360 void dump_complex(dump_context&, const std::complex<T>& data) throw();
361 template <typename T>
362 void restore_complex(restore_context&, std::complex<T>& data) throw();
363 
364 template <typename T>
365 void dump_deque(dump_context&, const std::deque<T>& data) throw();
366 template <typename T>
367 void restore_deque(restore_context&, std::deque<T>& data) throw();
368 
369 template <typename T>
370 void dump_list(dump_context&, const std::list<T>& data) throw();
371 template <typename T>
372 void restore_list(restore_context&, std::list<T>& data) throw();
373 
374 template <typename K, typename T>
375 void dump_pair(dump_context&, const std::pair<K, T>& data) throw();
376 template <typename K, typename T>
377 void restore_pair(restore_context&, std::pair<K, T>& data) throw();
378 
379 template <typename K, typename T, typename P>
380 void dump_map(dump_context&, const std::map<K, T, P>& data) throw();
381 template <typename K, typename T, typename P>
382 void restore_map(restore_context&, std::map<K, T, P>& data) throw();
383 
384 template <typename K, typename T, typename P>
385 void dump_multimap(dump_context&, const std::multimap<K, T, P>& data) throw();
386 template <typename K, typename T, typename P>
387 void restore_multimap(restore_context&, std::multimap<K, T, P>& data) throw();
388 
389 template <typename K, typename P>
390 void dump_set(dump_context&, const std::set<K, P>& data) throw();
391 template <typename K, typename P>
392 void restore_set(restore_context&, std::set<K, P>& data) throw();
393 
394 template <typename K, typename P>
395 void dump_multiset(dump_context&, const std::multiset<K, P>& data) throw();
396 template <typename K, typename P>
397 void restore_multiset(restore_context&, std::multiset<K, P>& data) throw();
398 
399 template <typename T>
400 void dump_vector(dump_context&, const std::vector<T>& data) throw();
401 template <typename T>
402 void restore_vector(restore_context&, std::vector<T>& data) throw();
403 
405 // short-cut functions for dumping and restoring to common targets
406 //
407 // These functions use the installer callback function to install any
408 // polymorphic type handlers required. If there are no polymorphic types used
409 // in the data structure, then the callback can be set to null (i.e. 0).
410 
411 template <typename T>
412 void dump_to_device(const T& source, otext& result, dump_context::installer installer) throw();
413 template <typename T>
414 void restore_from_device(itext& source, T& result, restore_context::installer installer) throw();
415 
416 template <typename T>
417 void dump_to_string(const T& source, std::string& result, dump_context::installer installer) throw();
418 template <typename T>
419 void restore_from_string(const std::string& source, T& result, restore_context::installer installer) throw();
420 
421 template <typename T>
422 void dump_to_file(const T& source, const std::string& filename, dump_context::installer installer) throw();
423 template <typename T>
424 void restore_from_file(const std::string& filename, T& result, restore_context::installer installer) throw();
425 
427 #include "persistent.tpp"
428 #endif
Definition: clonable.hpp:24
Definition: persistent.cc:53
Definition: persistent.hpp:64
Definition: textio.hpp:242
Definition: textio.hpp:37
Definition: persistent.hpp:45
Definition: persistent.hpp:37
Definition: persistent.hpp:52
Definition: persistent.hpp:197
Definition: persistent.cc:209
Definition: persistent.hpp:126