1 /******************************************************************************
3 * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
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. *
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. *
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 ******************************************************************************/
23 #include "base/i2-base.hpp"
24 #include "base/debug.hpp"
25 #include <boost/smart_ptr/intrusive_ptr.hpp>
28 using boost::intrusive_ptr;
29 using boost::dynamic_pointer_cast;
30 using boost::static_pointer_cast;
40 class ValidationUtils;
44 #define DECLARE_PTR_TYPEDEFS(klass) \
45 typedef intrusive_ptr<klass> Ptr
47 #define IMPL_TYPE_LOOKUP_SUPER() \
49 #define IMPL_TYPE_LOOKUP() \
50 static intrusive_ptr<Type> TypeInstance; \
51 virtual intrusive_ptr<Type> GetReflectionType() const override \
53 return TypeInstance; \
56 #define DECLARE_OBJECT(klass) \
57 DECLARE_PTR_TYPEDEFS(klass); \
60 void DefaultObjectFactoryCheckArgs(const std::vector<Value>& args);
63 intrusive_ptr<Object> DefaultObjectFactory(const std::vector<Value>& args)
65 DefaultObjectFactoryCheckArgs(args);
71 intrusive_ptr<Object> DefaultObjectFactoryVA(const std::vector<Value>& args)
76 typedef intrusive_ptr<Object> (*ObjectFactory)(const std::vector<Value>&);
78 template<typename T, bool VA>
84 struct TypeHelper<T, false>
86 static ObjectFactory GetFactory()
88 return DefaultObjectFactory<T>;
93 struct TypeHelper<T, true>
95 static ObjectFactory GetFactory()
97 return DefaultObjectFactoryVA<T>;
104 using Accessor = std::function<T ()>;
106 explicit Lazy(T value)
107 : m_Cached(true), m_Value(value)
110 explicit Lazy(Accessor accessor)
111 : m_Accessor(accessor)
115 explicit Lazy(const Lazy<U>& other)
117 if (other.m_Cached) {
118 m_Accessor = Accessor();
119 m_Value = static_cast<T>(other.m_Value);
122 auto accessor = other.m_Accessor;
123 m_Accessor = [accessor]() { return static_cast<T>(accessor()); };
129 operator Lazy<U>() const
132 return Lazy<U>(static_cast<U>(m_Value));
134 Accessor accessor = m_Accessor;
135 return Lazy<U>(static_cast<typename Lazy<U>::Accessor>([accessor]() { return static_cast<U>(accessor()); }));
139 const T& operator()() const
142 m_Value = m_Accessor();
151 mutable bool m_Cached{false};
159 * Base class for all heap-allocated objects. At least one of its methods
160 * has to be virtual for RTTI to work.
167 DECLARE_PTR_TYPEDEFS(Object);
172 virtual String ToString() const;
174 virtual intrusive_ptr<Type> GetReflectionType() const;
176 virtual void Validate(int types, const ValidationUtils& utils);
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;
189 bool OwnsLock() const;
190 #endif /* I2_DEBUG */
192 static Object::Ptr GetPrototype();
194 virtual Object::Ptr Clone() const;
196 static intrusive_ptr<Type> TypeInstance;
199 Object(const Object& other) = delete;
200 Object& operator=(const Object& rhs) = delete;
202 uintptr_t m_References{0};
203 mutable uintptr_t m_Mutex{0};
207 mutable pthread_t m_LockOwner;
209 mutable DWORD m_LockOwner;
211 #endif /* I2_DEBUG */
213 friend struct ObjectLock;
215 friend void intrusive_ptr_add_ref(Object *object);
216 friend void intrusive_ptr_release(Object *object);
219 Value GetPrototypeField(const Value& context, const String& field, bool not_found_error, const DebugInfo& debugInfo);
221 void TypeAddObject(Object *object);
222 void TypeRemoveObject(Object *object);
224 void intrusive_ptr_add_ref(Object *object);
225 void intrusive_ptr_release(Object *object);
234 #endif /* OBJECT_H */
236 #include "base/type.hpp"