source: liblaziness/r.h

Last change on this file was 4, checked in by artyom, 13 years ago

liblaziness

File size: 6.0 KB
Line 
1#ifndef __R_H__
2#define __R_H__
3#include <exception>
4#include "primitive.h"
5#include "assert.h"
6#include <type_traits>
7#include <unordered_map>
8
9class NullReference : public std::exception
10{
11        public:
12                virtual const char* what() const throw() override { return "Trying to use null reference"; }
13};
14
15/*
16 * Ahhoz hogy önhívatkozás működjön egyelőre egy hash_map-et
17 * használjuk, későbbiékben majd vmi jobb megoldás, mert nagyon nem
18 * teccik ez :)
19 */
20/*class RBase
21{
22        public:
23                typedef std::unordered_map<const void*, long> map;
24                inline RBase()
25                {
26                }
27                inline void init()
28                {
29                        instances.insert(map::value_type(ptr(), 0));
30                }
31                virtual ~RBase()
32                {
33                        instances.erase(ptr());
34                }
35                inline bool isInitialized() const
36                {
37                        return instances.end() != instances.find(ptr());
38                };
39        private:
40                inline map::key_type ptr() const
41                {
42                        return static_cast<map::key_type>(this);
43                };
44                static map instances;
45};
46
47RBase::map RBase::instances;*/
48
49template <typename T, bool overridden = true>
50class R //: public RBase
51{
52        public: // TODO: make protected
53                struct VS // Value Structure
54                {
55                        Int c;
56                        T* pVal;
57                        VS(Int c) : c(c) { }
58                };
59
60        protected:
61                /*R<T>* stub;
62                inline bool isStub()
63                {
64
65                }*/
66                // ctor
67                explicit R(int i) : vs(new VS(1))
68                {
69                        // init();
70                }
71                // ctor (lvalue)
72                template<typename U, bool od>
73                R(R<U, od>& o, int i)
74                {
75                        vs = reinterpret_cast<R<T, overridden>::VS*>(o.vs);
76                        cinc();
77                }
78                // ctor (rvalue)
79                template<typename U, bool od>
80                R(R<U, od>&& o, int i)
81                {
82                        vs = reinterpret_cast<R<T, overridden>::VS*>(o.vs);
83                        cinc();
84                }
85
86        public:
87                // element type
88                typedef T etype;
89                // def ctor
90                R() : vs(nullptr)
91                {
92                        // init();
93                }
94                // ctor
95                template<typename U, bool od> R(R<U, od>& o)
96                {
97                        _assert_subclass<U, T> ERROR;
98                        vs = reinterpret_cast<R<T, overridden>::VS*>(o.vs);
99                        cinc();
100                }
101                template<typename U, bool od> R(R<U, od>&& o)
102                {
103                        _assert_subclass<U, T> ERROR;
104                        vs = reinterpret_cast<R<T, overridden>::VS*>(o.vs);
105                        cinc();
106                }
107                // dtor
108                virtual ~R()
109                {
110                        free();
111                }
112                template<typename U, bool od>
113                R<T, od>& operator=(R<U, od>&& o)
114                {
115                        _assert_subclass<U, T> ERROR;
116                        return copy(o);
117                }
118                template<typename U, bool od>
119                R<T, od>& operator=(R<U, od>& o)
120                {
121                        _assert_subclass<U, T> ERROR;
122                        return copy(o);
123                }
124        protected:
125                template<typename U, bool od>
126                inline R<T, od>& copy(R<U, od>& o)
127                {
128                        // forceInit();
129                        if ((void*)&o != (void*)this)
130                        {
131                                free();
132                                vs = reinterpret_cast<R<T, overridden>::VS*>(o.vs);
133                                cinc();
134                        }
135                        return *reinterpret_cast< R<T, od>* >(this);
136                }
137                template<typename U, bool od>
138                inline R<T, od>& copy(R<U, od>&& o)
139                {
140                        // forceInit();
141                        if ((void*)&o != (void*)this)
142                        {
143                                free();
144                                vs = reinterpret_cast<R<T, overridden>::VS*>(o.vs);
145                                cinc();
146                        }
147                        return *reinterpret_cast< R<T, od>* >(this);
148                }
149        public:
150                // freeing
151                void free()
152                {
153                        if (/*isInitialized() && */cdec() == 0) // TODO: Implement structural cycle freeing
154                        {
155                                delete vs->pVal;
156                                delete vs;
157                        }
158                        vs = nullptr;
159                }
160                // dereferencing
161                inline T& deref()
162                {
163                        ensure();
164                        return *vs->pVal;
165                }
166                inline Int refCount() const
167                {
168                        ensure();
169                        return vs->c;
170                }
171                bool isNull() const
172                {
173                        return vs == nullptr;
174                }
175
176                /*friend R<Int> mkR(Int i);
177                template<typename U> friend R<U> mkR();
178                template<typename U, typename UFirst> friend R<U> mkR(UFirst first);
179                template<typename U, typename UFirst, typename USecond> friend R<U> mkR(UFirst first, USecond second);
180                template<typename U, typename UFirst, typename USecond, typename UThird> friend R<U> mkR(UFirst first, USecond second, UThird third);
181                template<typename U, typename UFirst, typename USecond, typename UThird, typename UFourth>
182                friend R<U> mkR(UFirst first, USecond second, UThird third, UFourth fourth);*/
183                friend class Ref;
184
185                // operators
186                inline T* operator->()
187                {
188                        return &this->deref();
189                }
190                inline T& operator *()
191                {
192                        return this->deref();
193                }
194
195        private:
196                /*inline void forceInit()
197                {
198                        if (!isInitialized())
199                        {
200                                RBase::init();
201                                vs = nullptr;
202                        }
203                }*/
204                inline void ensure() const
205                {
206                        if (vs == nullptr)
207                        {
208                                throw NullReference();
209                        }
210                }
211                inline Int cinc()
212                {
213                        if (vs != nullptr)
214                        {
215                                return ++vs->c;
216                        }
217                        else
218                        {
219                                return -1;
220                        }
221                }
222                inline Int cdec()
223                {
224                        if (vs != nullptr)
225                        {
226                                return --vs->c;
227                        }
228                        else
229                        {
230                                return -1;
231                        }
232                }
233                // private data
234        public: // TODO: make private
235                VS* vs;
236
237};
238
239class Ref
240{
241        public:
242                template <typename T>
243                static R<T> mk()
244                {
245                        R<T> ref(0);
246                        ref.vs->pVal = new T();
247                        return ref;
248                }
249
250                template <typename T, typename TFirst>
251                static R<T> mk(TFirst first)
252                {
253                        R<T> ref(0);
254                        ref.vs->pVal = new T(first);
255                        return ref;
256                }
257
258                template <typename T, typename TFirst, typename TSecond>
259                static R<T> mk(TFirst first, TSecond second)
260                {
261                        R<T> ref(0);
262                        ref.vs->pVal = new T(first, second);
263                        return ref;
264                }
265
266                template <typename T, typename TFirst, typename TSecond, typename TThird>
267                static R<T> mk(TFirst first, TSecond second, TThird third)
268                {
269                        R<T> ref(0);
270                        ref.vs->pVal = new T(first, second, third);
271                        return ref;
272                }
273
274                template <typename T, typename TFirst, typename TSecond, typename TThird, typename TFourth>
275                static R<T> mk(TFirst first, TSecond second, TThird third, TFourth fourth)
276                {
277                        R<T> ref(0);
278                        ref.vs->pVal = new T(first, second, third, fourth);
279                        return ref;
280                }
281
282                static R<Int> mk(Int i)
283                {
284                        R<Int> ref(0);
285                        ref.vs->pVal = new Int(i);
286                        return ref;
287                }
288};
289
290/**** specialize for base types ****/
291template<>
292class R<bool, true> : public R<bool, false>
293{
294        protected:
295                inline R(int i) : R<bool, false>(i) { }
296        public:
297                inline R() : R<bool, false>() { }
298                inline R(R<bool, true>&  o) : R<bool, false>(o, 0) { }
299                inline R(R<bool, true>&& o) : R<bool, false>(o, 0) { }
300                // additional ctor
301                inline R(bool val) : R<bool, false>(0) { vs->pVal = new bool(val); }
302                R<bool, true>& operator=(R<bool, true>&  o) { R<bool, false>::copy(o); return *this; }
303                R<bool, true>& operator=(R<bool, true>&& o) { R<bool, false>::copy(o); return *this; }
304                friend class Ref;
305};
306
307#endif
Note: See TracBrowser for help on using the repository browser.