Classdesc 3.44
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 CLASSDESC_OBJECT_H
10#define CLASSDESC_OBJECT_H
11#include "classdesc.h"
12#include "pack_base.h"
13
14#include <limits>
15
16namespace classdesc
17{
18 struct object;
19 typedef std::vector<shared_ptr<object> > ObjectFactory;
20 inline ObjectFactory& factory()
21 {
22 // ensure factory is initialised on first use
23 static ObjectFactory f;
24 return f;
25 }
26
28 struct object
29 {
30 typedef int TypeID;
31 virtual TypeID type() const=0;
32 static classdesc::object* create(TypeID);
33 virtual classdesc::object* clone() const=0;
34 classdesc::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: 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 classdesc::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
105template <class T> typename
107pack(classdesc::pack_t& b, const classdesc::string& d, const classdesc::shared_ptr<T>& a)
108{
109 if (a)
110 {
111 b<<(a->type()+1);
112 a->pack(b);
113 }
114 else
115 b<<classdesc::object::TypeID(0);
116}
117
118template <class T> typename
120unpack(classdesc::unpack_t& b, const classdesc::string& d, classdesc::shared_ptr<T>& a)
121{
122 classdesc::object::TypeID t;
123 b>>t;
124 if (t)
125 {
126 classdesc::shared_ptr<classdesc::object> tmp(classdesc::object::create(t-1));
127#if defined(__cplusplus) && __cplusplus>=201103L
128 a=classdesc::dynamic_pointer_cast<T>(std::move(tmp));
129#else
130 a=classdesc::dynamic_pointer_cast<T>(tmp);
131#endif
132 a->unpack(b);
133 }
134}
135
136template <class T> typename
138unpack(classdesc::unpack_t& b, const classdesc::string& d, const classdesc::shared_ptr<T>& a)
139{
140 classdesc::object::TypeID t;
141 b>>t;
142 if (t)
143 {
144#if defined(__cplusplus) && __cplusplus>=201103L
145 std::unique_ptr<classdesc::object> a(classdesc::object::create(t-1));
146#else
147 std::auto_ptr<classdesc::object> a(classdesc::object::create(t-1));
148#endif
149 a->unpack(b);
150 }
151}
152
153
154#ifdef _CLASSDESC
155#pragma omit pack classdesc::object
156#pragma omit unpack classdesc::object
157#pragma omit pack classdesc::Object
158#pragma omit unpack classdesc::Object
159#endif
160#endif
Definition pack_base.h:138
Contains definitions related to classdesc functionality.
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
serialisation descriptor
Definition object.h:77
virtual Base::TypeID type() const
Definition object.h:80
This * cloneT() const
same as clone(), but returning fully typed pointer
Definition object.h:92
controlled template specialisation: stolen from boost::enable_if.
Definition classdesc.h:282
Definition object.h:29
Definition pack_base.h:486