Classdesc  3.D29
object.h
1 /*
2  @copyright Russell Standish 2000-2013
3  @author Russell Standish
4  This file is part of Classdesc
5 
6  Open source licensed under the MIT license. See LICENSE for details.
7 */
8 
9 #ifndef OBJECT_H
10 #define OBJECT_H
11 #include "classdesc.h"
12 #include "pack_base.h"
13 
14 #include <limits>
15 
16 namespace classdesc
17 {
18  struct object;
19  typedef std::vector<shared_ptr<object> > Factory;
20  inline Factory& factory()
21  {
22  // ensure factory is initialised on first use
23  static Factory f;
24  return f;
25  }
26 
28  struct object
29  {
30  typedef int TypeID;
31  virtual TypeID type() const=0;
32  static object* create(TypeID);
33  virtual object* clone() const=0;
34  object* cloneT() const {return clone();}
35  virtual void pack(pack_t& b) const=0;
36  virtual void unpack(pack_t& b)=0;
37  virtual ~object() {}
38  };
39 
40  inline void register_with_factory(shared_ptr<object> o)
41  {
42  if (o->type()>=int(factory().size()))
43  factory().resize(o->type()+1);
44  factory()[o->type()]=o;;
45  }
46 
47  // it would be nice for this to be a static method of object, but it
48  // appears static methods cannot be inlined
49  inline object* object::create(object::TypeID t) {// factory
50  assert(t<object::TypeID(factory().size()) && t>=0);
51  return factory()[t]->clone();
52  }
53 
54  template <class T>
55  struct Register
56  {
57  Register() {register_with_factory(shared_ptr<object>(new T));}
58  };
59 
75  template <class This, class Base=object>
76  struct Object: virtual public Base
77  {
80  virtual typename Base::TypeID type() const {
81  static typename Base::TypeID t=-1;
82  if (t==-1)
83  {
84  t=typename Base::TypeID(factory().size());
85  register_with_factory(shared_ptr<object>(clone()));
86  }
87  return t;
88  }
89  virtual object* clone() const {
90  return new This(*dynamic_cast<const This*>(this));}
92  This *cloneT() const {return dynamic_cast<This*>(clone());}
93  virtual void pack(pack_t& b) const {
94  ::pack(b,"",*dynamic_cast<const This*>(this));}
95  virtual void unpack(pack_t& b) {
96  ::unpack(b,"",*dynamic_cast<This*>(this));}
97  };
98 
99  template <class T>
100  struct pack_supported<classdesc::shared_ptr<T> >
101  {static const bool value=is_base_of<object,T>::value;};
102 
103 }
104 
106 template <class T> typename
108 pack(classdesc::pack_t& b, const classdesc::string& d, const classdesc::shared_ptr<T>& a)
109 {
110  if (a)
111  {
112  b<<(a->type()+1);
113  a->pack(b);
114  }
115  else
116  b<<classdesc::object::TypeID(0);
117 }
118 
119 template <class T> typename
121 unpack(classdesc::unpack_t& b, const classdesc::string& d, classdesc::shared_ptr<T>& a)
122 {
123  classdesc::object::TypeID t;
124  b>>t;
125  if (t)
126  {
127  a.reset(classdesc::object::create(t-1));
128  a->unpack(b);
129  }
130 }
131 
132 template <class T> typename
134 unpack(classdesc::unpack_t& b, const classdesc::string& d, const classdesc::shared_ptr<T>& a)
135 {
136  classdesc::object::TypeID t;
137  b>>t;
138  if (t)
139  {
140  std::auto_ptr<T> a(classdesc::object::create(t-1));
141  a->unpack(b);
142  }
143 }
144 
145 
146 namespace classdesc_access
147 {
148  namespace cd=classdesc;
149 
150  template <> struct access_pack<classdesc::object>: public cd::NullDescriptor<cd::pack_t>{};
151  template <> struct access_unpack<classdesc::object>: public cd::NullDescriptor<cd::pack_t>{};
152 
153  template <class T, class B>
154  struct access_pack<classdesc::Object<T, B> >
155  {
156  template <class U>
157  void operator()(cd::pack_t& b, const cd::string& d, U& a)
158  {pack(b,d,cd::base_cast<B>::cast(a));}
159  };
160 
161  template <class T, class B>
162  struct access_unpack<classdesc::Object<T, B> >
163  {
164  template <class U>
165  void operator()(cd::unpack_t& b, const cd::string& d, U& a)
166  {unpack(b,d,cd::base_cast<B>::cast(a));}
167  };
168 
169 }
170 
171 #ifdef _CLASSDESC
172 #pragma omit pack classdesc::object
173 #pragma omit unpack classdesc::object
174 #pragma omit pack classdesc::Object
175 #pragma omit unpack classdesc::Object
176 #endif
177 #endif
Definition: object.h:55
Definition: classdesc.h:778
serialisation descriptor
virtual Base::TypeID type() const
Definition: object.h:80
class to allow access to private members
Definition: classdesc_access.h:21
helper for constructing null descriptors
Definition: classdesc.h:768
This * cloneT() const
same as clone(), but returning fully typed pointer
Definition: object.h:92
class to allow access to private members
Definition: classdesc_access.h:22
Definition: object.h:28
Definition: object.h:76
Definition: pack_base.h:438
void unpack(unpack_t &targ, const string &desc, is_treenode dum, T *&arg)
unserialise a tree.
Definition: pack_graph.h:44
void pack(pack_t &targ, const string &desc, is_treenode dum, const T *const &arg)
serialise a tree (or DAG)
Definition: pack_graph.h:28
Definition: pack_base.h:124
controlled template specialisation: stolen from boost::enable_if.
Definition: classdesc.h:274