Classdesc 3.44
poly.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_POLY_H
10#define CLASSDESC_POLY_H
12// the Poly class in polyBase.h
13#include "object.h"
14#include "ref.h"
15
16namespace classdesc
17{
18
20 class Eobject: public Object<Eobject> {};
21
25 template <class T=Eobject>
27 {
28 static std::vector<T*> data;
29 public:
30 T& operator[](std::size_t i) {return *data[i];}
31 void register_type(const T* t) {
32 if (t->type()+1>int(data.size()))
33 data.resize(t->type()+1);
34 if (!data[t->type()])
35 data[t->type()]=dynamic_cast<T*>(t->clone());
36 }
37 };
38
39 template <class T> std::vector<T*> SimpleTypeTable<T>::data;
40
42 template <class T=Eobject, class TT=SimpleTypeTable<T> >
43 class poly
44 {
45 T* item;
46 // force a compile error if these are used
47 template <class U, class UU> bool operator==(const poly<U,UU>&) const;
48 template <class U, class UU> bool operator!=(const poly<U,UU>&) const;
49 void asg(const poly& x) {
50 if (x) item=dynamic_cast<T*>(x->clone()); else item=NULL;
51 }
52 public:
53 TT TypeTable;
54 poly(): item(NULL) {}
55 poly(const poly& x) {asg(x);}
56 poly(const T& x) {item=dynamic_cast<T*>(x.clone()); }
57 poly& operator=(const poly& x) {delete item; asg(x); return *this;}
58 poly& operator=(const T& x) {
59 delete item; item=dynamic_cast<T*>(x.clone()); return *this;}
60 ~poly() {delete item;}
61
63
68 template <class U> poly addObject() {
69 delete item; item=new U; TypeTable.register_type(item);
70 return *this;}
71 template <class U, class A> poly addObject(A x) {
72 delete item; item=new U(x); TypeTable.register_type(item);
73 return *this;}
74 template <class U, class A1, class A2> poly addObject(A1 x1, A2 x2) {
75 delete item; item=new U(x1,x2); TypeTable.register_type(item);
76 return *this;}
78 T* operator->() {assert(item); return item;}
79 T& operator*() {assert(item); return *item;}
80 const T* operator->() const {assert(item); return item;}
81 const T& operator*() const {assert(item); return *item;}
82
84
85 template <class U> U& cast() {return dynamic_cast<U&>(*item);}
86 template <class U> const U& cast() const {return dynamic_cast<U&>(*item);}
88
89 void swap(poly& x) {std::swap(item,x.item);}
90
91 bool operator==(const poly& x) const {return x.item==item;}
92 bool operator!=(const poly& x) const {return x.item!=item;};
93 operator bool() const {return item!=NULL;}
94 };
95
97 template <class T=Eobject, class TT=SimpleTypeTable<T> >
98 class polyref: public classdesc::ref<classdesc::poly<T,TT> >
99 {
100 typedef ref<poly<T,TT> > super;
101 poly<T,TT>& polyObj() {return super::operator*();}
102 const poly<T,TT>& polyObj() const {return super::operator*();}
103 // prevent problems with accidental bool conversions
104 template <class U> bool operator==(const U&) const;
105 public:
106 // delegate poly specific methods
108
109 template <class U> polyref addObject() {
110 polyObj().template addObject<U>();
111 return *this;
112 }
113 template <class U, class A> polyref addObject(A x) {
114 polyObj().template addObject<U,A>(x);
115 return *this;}
116 template <class U, class A1, class A2> polyref addObject(A1 x1, A2 x2) {
117 polyObj().template addObject<U,A1,A2>(x1,x2);
118 return *this;}
120
121 T* operator->() {return &*polyObj();}
122 T& operator*() {return *polyObj();}
123 const T* operator->() const {return &*polyObj();}
124 const T& operator*() const {return *polyObj();}
125
126 bool operator==(const polyref& x) {
127 return super::operator==(static_cast<super&>(x));
128 }
129 template <class U>
130 bool operator!=(const U& x) const {return !operator==(x);}
131
133
134 template <class U> U& cast() {return polyObj().template cast<U>();}
135 template <class U> const U& cast() const {return polyObj().template cast<U>();}
137 operator bool () const {return !super::nullref() && bool(polyObj());}
138 };
139
140#ifdef _CLASSDESC
141#pragma omit pack classdesc::poly
142#pragma omit unpack classdesc::poly
143#pragma omit isa classdesc::poly
144#pragma omit pack classdesc::object
145#pragma omit unpack classdesc::object
146#pragma omit javaClass classdesc::object
147#pragma omit pack classdesc::Object
148#pragma omit unpack classdesc::Object
149#pragma omit javaClass classdesc::Object
150#pragma omit dump classdesc::SimpleTypeTable
151#pragma omit dump classdesc::poly
152#pragma omit javaClass classdesc::poly
153#endif
154}
155
156namespace classdesc_access
157{
158 template <class T, class TT>
159 struct access_pack<classdesc::poly<T,TT> >
160 {
161 template <class U>
162 void operator()(classdesc::pack_t& t, const classdesc::string& d, U& a)
163 {
164 t<<bool(a);
165 if (a)
166 {
167 t<<a->type();
168 a->pack(t);
169 }
170 }
171 };
172
173 template <class T, class TT>
174 struct access_unpack<classdesc::poly<T,TT> >
175 {
176 template <class U>
177 void operator()(classdesc::pack_t& t, const classdesc::string& d, U& a)
178 {
179 bool valid; t>>valid;
180 if (valid)
181 {
182 typename T::TypeID type;
183 t>>type;
184 if (!a || type!=a->type())
185 a=a.TypeTable[type];
186 a->unpack(t);
187 }
188 }
189 };
190
191}
192
193namespace classdesc
194{
195//TODO is this really what we want to do with dump of polys?
196 class dump_t;
197 template <class T> void dump(dump_t&, const string&, const T&);
198
199 template <class T, class TT>
200 void dump(dump_t& t, const string& d, const poly<T,TT>& a) {}
201}
202using classdesc::dump;
203
207namespace std
208{
209 template <class T, class TT> void swap(classdesc::poly<T,TT>& x,classdesc::poly<T,TT>& y) {x.swap(y);}
210}
211
212#endif
Definition poly.h:20
Definition pack_base.h:138
Definition poly.h:44
poly addObject()
Target object initialisation.
Definition poly.h:68
U & cast()
cast target to type U. Thows std::bad_cast if impossible.
Definition poly.h:85
Definition poly.h:99
U & cast()
cast target to type U. Throws if not possible
Definition poly.h:134
polyref addObject()
add object of type U
Definition poly.h:109
Definition ref.h:28
T & operator*()
Definition ref.h:65
bool nullref() const
Definition ref.h:73
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition classdesc_access.h:20
Contains definitions related to classdesc functionality.
void dump(dump_t &o, const string &d, const T &a)
forward declare generic dump operation
Definition dump_epilogue.h:55
STL namespace.
Reference counted smart pointer classes.
Definition object.h:77
Definition poly.h:27
class to allow access to private members
Definition classdesc_access.h:21
class to allow access to private members
Definition classdesc_access.h:22