1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
6 #include "base/i2-base.hpp"
7 #include "base/debug.hpp"
8 #include <boost/smart_ptr/intrusive_ptr.hpp>
16 using boost::intrusive_ptr;
17 using boost::dynamic_pointer_cast;
18 using boost::static_pointer_cast;
28 class ValidationUtils;
32 #define DECLARE_PTR_TYPEDEFS(klass) \
33 typedef intrusive_ptr<klass> Ptr
35 #define IMPL_TYPE_LOOKUP_SUPER() \
37 #define IMPL_TYPE_LOOKUP() \
38 static intrusive_ptr<Type> TypeInstance; \
39 virtual intrusive_ptr<Type> GetReflectionType() const override \
41 return TypeInstance; \
44 #define DECLARE_OBJECT(klass) \
45 DECLARE_PTR_TYPEDEFS(klass); \
48 #define REQUIRE_NOT_NULL(ptr) RequireNotNullInternal(ptr, #ptr)
50 void RequireNotNullInternal(const intrusive_ptr<Object>& object, const char *description);
52 void DefaultObjectFactoryCheckArgs(const std::vector<Value>& args);
55 intrusive_ptr<Object> DefaultObjectFactory(const std::vector<Value>& args)
57 DefaultObjectFactoryCheckArgs(args);
63 intrusive_ptr<Object> DefaultObjectFactoryVA(const std::vector<Value>& args)
68 typedef intrusive_ptr<Object> (*ObjectFactory)(const std::vector<Value>&);
70 template<typename T, bool VA>
76 struct TypeHelper<T, false>
78 static ObjectFactory GetFactory()
80 return DefaultObjectFactory<T>;
85 struct TypeHelper<T, true>
87 static ObjectFactory GetFactory()
89 return DefaultObjectFactoryVA<T>;
96 using Accessor = std::function<T ()>;
98 explicit Lazy(T value)
99 : m_Cached(true), m_Value(value)
102 explicit Lazy(Accessor accessor)
103 : m_Accessor(accessor)
107 explicit Lazy(const Lazy<U>& other)
109 if (other.m_Cached) {
110 m_Accessor = Accessor();
111 m_Value = static_cast<T>(other.m_Value);
114 auto accessor = other.m_Accessor;
115 m_Accessor = [accessor]() { return static_cast<T>(accessor()); };
121 operator Lazy<U>() const
124 return Lazy<U>(static_cast<U>(m_Value));
126 Accessor accessor = m_Accessor;
127 return Lazy<U>(static_cast<typename Lazy<U>::Accessor>([accessor]() { return static_cast<U>(accessor()); }));
131 const T& operator()() const
134 m_Value = m_Accessor();
143 mutable bool m_Cached{false};
151 * Base class for all heap-allocated objects. At least one of its methods
152 * has to be virtual for RTTI to work.
159 DECLARE_PTR_TYPEDEFS(Object);
164 virtual String ToString() const;
166 virtual intrusive_ptr<Type> GetReflectionType() const;
168 virtual void Validate(int types, const ValidationUtils& utils);
170 virtual void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty);
171 virtual Value GetField(int id) const;
172 virtual Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const;
173 virtual void SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo);
174 virtual bool HasOwnField(const String& field) const;
175 virtual bool GetOwnField(const String& field, Value *result) const;
176 virtual void ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils);
177 virtual void NotifyField(int id, const Value& cookie = Empty);
178 virtual Object::Ptr NavigateField(int id) const;
181 bool OwnsLock() const;
182 #endif /* I2_DEBUG */
184 static Object::Ptr GetPrototype();
186 virtual Object::Ptr Clone() const;
188 static intrusive_ptr<Type> TypeInstance;
191 Object(const Object& other) = delete;
192 Object& operator=(const Object& rhs) = delete;
194 std::atomic<uint_fast64_t> m_References;
195 mutable std::recursive_mutex m_Mutex;
198 mutable std::atomic<std::thread::id> m_LockOwner;
199 mutable size_t m_LockCount = 0;
200 #endif /* I2_DEBUG */
202 friend struct ObjectLock;
204 friend void intrusive_ptr_add_ref(Object *object);
205 friend void intrusive_ptr_release(Object *object);
208 Value GetPrototypeField(const Value& context, const String& field, bool not_found_error, const DebugInfo& debugInfo);
210 void TypeAddObject(Object *object);
211 void TypeRemoveObject(Object *object);
213 void intrusive_ptr_add_ref(Object *object);
214 void intrusive_ptr_release(Object *object);
223 #endif /* OBJECT_H */
225 #include "base/type.hpp"