]> granicus.if.org Git - icinga2/blob - lib/base/object.hpp
Remove unused includes
[icinga2] / lib / base / object.hpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #ifndef OBJECT_H
21 #define OBJECT_H
22
23 #include "base/i2-base.hpp"
24 #include "base/debug.hpp"
25 #include <boost/smart_ptr/intrusive_ptr.hpp>
26 #include <vector>
27
28 using boost::intrusive_ptr;
29 using boost::dynamic_pointer_cast;
30 using boost::static_pointer_cast;
31
32 namespace icinga
33 {
34
35 class Value;
36 class Object;
37 class Type;
38 class String;
39 struct DebugInfo;
40 class ValidationUtils;
41
42 extern Value Empty;
43
44 #define DECLARE_PTR_TYPEDEFS(klass) \
45         typedef intrusive_ptr<klass> Ptr
46
47 #define IMPL_TYPE_LOOKUP_SUPER()                                        \
48
49 #define IMPL_TYPE_LOOKUP()                                                      \
50         static intrusive_ptr<Type> TypeInstance;                                \
51         virtual intrusive_ptr<Type> GetReflectionType() const override          \
52         {                                                                       \
53                 return TypeInstance;                                            \
54         }
55
56 #define DECLARE_OBJECT(klass) \
57         DECLARE_PTR_TYPEDEFS(klass); \
58         IMPL_TYPE_LOOKUP();
59
60 void DefaultObjectFactoryCheckArgs(const std::vector<Value>& args);
61
62 template<typename T>
63 intrusive_ptr<Object> DefaultObjectFactory(const std::vector<Value>& args)
64 {
65         DefaultObjectFactoryCheckArgs(args);
66
67         return new T();
68 }
69
70 template<typename T>
71 intrusive_ptr<Object> DefaultObjectFactoryVA(const std::vector<Value>& args)
72 {
73         return new T(args);
74 }
75
76 typedef intrusive_ptr<Object> (*ObjectFactory)(const std::vector<Value>&);
77
78 template<typename T, bool VA>
79 struct TypeHelper
80 {
81 };
82
83 template<typename T>
84 struct TypeHelper<T, false>
85 {
86         static ObjectFactory GetFactory()
87         {
88                 return DefaultObjectFactory<T>;
89         }
90 };
91
92 template<typename T>
93 struct TypeHelper<T, true>
94 {
95         static ObjectFactory GetFactory()
96         {
97                 return DefaultObjectFactoryVA<T>;
98         }
99 };
100
101 template<typename T>
102 struct Lazy
103 {
104         using Accessor = std::function<T ()>;
105
106         explicit Lazy(T value)
107                 : m_Cached(true), m_Value(value)
108         { }
109
110         explicit Lazy(Accessor accessor)
111                 : m_Accessor(accessor)
112         { }
113
114         template<typename U>
115         explicit Lazy(const Lazy<U>& other)
116         {
117                 if (other.m_Cached) {
118                         m_Accessor = Accessor();
119                         m_Value = static_cast<T>(other.m_Value);
120                         m_Cached = true;
121                 } else {
122                         auto accessor = other.m_Accessor;
123                         m_Accessor = [accessor]() { return static_cast<T>(accessor()); };
124                         m_Cached = false;
125                 }
126         }
127
128         template<typename U>
129         operator Lazy<U>() const
130         {
131                 if (m_Cached)
132                         return Lazy<U>(static_cast<U>(m_Value));
133                 else {
134                         Accessor accessor = m_Accessor;
135                         return Lazy<U>(static_cast<typename Lazy<U>::Accessor>([accessor]() { return static_cast<U>(accessor()); }));
136                 }
137         }
138
139         const T& operator()() const
140         {
141                 if (!m_Cached) {
142                         m_Value = m_Accessor();
143                         m_Cached = true;
144                 }
145
146                 return m_Value;
147         }
148
149 private:
150         Accessor m_Accessor;
151         mutable bool m_Cached{false};
152         mutable T m_Value;
153
154         template<typename U>
155         friend struct Lazy;
156 };
157
158 /**
159  * Base class for all heap-allocated objects. At least one of its methods
160  * has to be virtual for RTTI to work.
161  *
162  * @ingroup base
163  */
164 class Object
165 {
166 public:
167         DECLARE_PTR_TYPEDEFS(Object);
168
169         Object() = default;
170         virtual ~Object();
171
172         virtual String ToString() const;
173
174         virtual intrusive_ptr<Type> GetReflectionType() const;
175
176         virtual void Validate(int types, const ValidationUtils& utils);
177
178         virtual void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty);
179         virtual Value GetField(int id) const;
180         virtual Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const;
181         virtual void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo);
182         virtual bool HasOwnField(const String& field) const;
183         virtual bool GetOwnField(const String& field, Value *result) const;
184         virtual void ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils);
185         virtual void NotifyField(int id, const Value& cookie = Empty);
186         virtual Object::Ptr NavigateField(int id) const;
187
188 #ifdef I2_DEBUG
189         bool OwnsLock() const;
190 #endif /* I2_DEBUG */
191
192         static Object::Ptr GetPrototype();
193
194         virtual Object::Ptr Clone() const;
195
196         static intrusive_ptr<Type> TypeInstance;
197
198 private:
199         Object(const Object& other) = delete;
200         Object& operator=(const Object& rhs) = delete;
201
202         uintptr_t m_References{0};
203         mutable uintptr_t m_Mutex{0};
204
205 #ifdef I2_DEBUG
206 #       ifndef _WIN32
207         mutable pthread_t m_LockOwner;
208 #       else /* _WIN32 */
209         mutable DWORD m_LockOwner;
210 #       endif /* _WIN32 */
211 #endif /* I2_DEBUG */
212
213         friend struct ObjectLock;
214
215         friend void intrusive_ptr_add_ref(Object *object);
216         friend void intrusive_ptr_release(Object *object);
217 };
218
219 Value GetPrototypeField(const Value& context, const String& field, bool not_found_error, const DebugInfo& debugInfo);
220
221 void TypeAddObject(Object *object);
222 void TypeRemoveObject(Object *object);
223
224 void intrusive_ptr_add_ref(Object *object);
225 void intrusive_ptr_release(Object *object);
226
227 template<typename T>
228 class ObjectImpl
229 {
230 };
231
232 }
233
234 #endif /* OBJECT_H */
235
236 #include "base/type.hpp"