]> granicus.if.org Git - icinga2/commitdiff
Remove inline methods and use explicit template instantiation to minimize the number... 5937/head
authorGunnar Beutner <gunnar.beutner@icinga.com>
Wed, 3 Jan 2018 05:01:02 +0000 (06:01 +0100)
committerGunnar Beutner <gunnar.beutner@icinga.com>
Wed, 3 Jan 2018 10:04:58 +0000 (11:04 +0100)
18 files changed:
lib/base/CMakeLists.txt
lib/base/array.cpp
lib/base/array.hpp
lib/base/dictionary.cpp
lib/base/dictionary.hpp
lib/base/logger.cpp
lib/base/logger.hpp
lib/base/object.cpp
lib/base/object.hpp
lib/base/objectlock.cpp [new file with mode: 0644]
lib/base/objectlock.hpp
lib/base/string.cpp
lib/base/string.hpp
lib/base/type.cpp
lib/base/type.hpp
lib/base/value.cpp
lib/base/value.hpp
tools/mkclass/classcompiler.cpp

index ba9ee5d0eab8a946e46070ca228876ea26251c27..fd61c89227eb8561fed64a1e493bdc5765f39553 100644 (file)
@@ -33,7 +33,7 @@ set(base_SOURCES
   exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp
   json-script.cpp library.cpp loader.cpp logger.cpp logger.thpp math-script.cpp
   netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp
-  object-script.cpp objecttype.cpp primitivetype.cpp process.cpp ringbuffer.cpp scriptframe.cpp
+  object-script.cpp objectlock.cpp objecttype.cpp primitivetype.cpp process.cpp ringbuffer.cpp scriptframe.cpp
   function.cpp function.thpp function-script.cpp
   perfdatavalue.cpp perfdatavalue.thpp scriptglobal.cpp
   scriptutils.cpp serializer.cpp socket.cpp socketevents.cpp socketevents-epoll.cpp socketevents-poll.cpp stacktrace.cpp
index 54439ad932a87288d865779d291630ba4ff90b77..8a5f884e25e9b5102829c2a18ae742ec73e8a058 100644 (file)
 
 using namespace icinga;
 
+template class std::vector<Value>;
+
 REGISTER_PRIMITIVE_TYPE(Array, Object, Array::GetPrototype());
 
+Array::Array(void)
+{ }
+
+Array::Array(std::initializer_list<Value> init)
+       : m_Data(init)
+{ }
+
+Array::~Array(void)
+{ }
+
 /**
  * Restrieves a value from an array.
  *
@@ -93,6 +105,34 @@ void Array::Add(Value&& value)
        m_Data.emplace_back(std::move(value));
 }
 
+/**
+ * Returns an iterator to the beginning of the array.
+ *
+ * Note: Caller must hold the object lock while using the iterator.
+ *
+ * @returns An iterator.
+ */
+Array::Iterator Array::Begin(void)
+{
+       ASSERT(OwnsLock());
+
+       return m_Data.begin();
+}
+
+/**
+ * Returns an iterator to the end of the array.
+ *
+ * Note: Caller must hold the object lock while using the iterator.
+ *
+ * @returns An iterator.
+ */
+Array::Iterator Array::End(void)
+{
+       ASSERT(OwnsLock());
+
+       return m_Data.end();
+}
+
 /**
  * Returns the number of elements in the array.
  *
@@ -273,3 +313,14 @@ void Array::SetFieldByName(const String& field, const Value& value, const DebugI
 
        Set(index, value);
 }
+
+Array::Iterator icinga::begin(Array::Ptr x)
+{
+       return x->Begin();
+}
+
+Array::Iterator icinga::end(Array::Ptr x)
+{
+       return x->End();
+}
+
index 1df29f506384a1660f3142eadd8419c7b0f5db09..a601b34d6d5eda28f41795ed2c3de099285edee2 100644 (file)
@@ -47,15 +47,10 @@ public:
 
        typedef std::vector<Value>::size_type SizeType;
 
-       Array(void)
-       { }
+       Array(void);
+       Array(std::initializer_list<Value> init);
 
-       Array(std::initializer_list<Value> init)
-               : m_Data(init)
-       { }
-
-       ~Array(void)
-       { }
+       ~Array(void);
 
        Value Get(SizeType index) const;
        void Set(SizeType index, const Value& value);
@@ -63,33 +58,8 @@ public:
        void Add(const Value& value);
        void Add(Value&& value);
 
-       /**
-        * Returns an iterator to the beginning of the array.
-        *
-        * Note: Caller must hold the object lock while using the iterator.
-        *
-        * @returns An iterator.
-        */
-       Iterator Begin(void)
-       {
-               ASSERT(OwnsLock());
-
-               return m_Data.begin();
-       }
-
-       /**
-        * Returns an iterator to the end of the array.
-        *
-        * Note: Caller must hold the object lock while using the iterator.
-        *
-        * @returns An iterator.
-        */
-       Iterator End(void)
-       {
-               ASSERT(OwnsLock());
-
-               return m_Data.end();
-       }
+       Iterator Begin(void);
+       Iterator End(void);
 
        size_t GetLength(void) const;
        bool Contains(const Value& value) const;
@@ -148,16 +118,11 @@ private:
        std::vector<Value> m_Data; /**< The data for the array. */
 };
 
-inline Array::Iterator begin(Array::Ptr x)
-{
-       return x->Begin();
-}
+Array::Iterator begin(Array::Ptr x);
+Array::Iterator end(Array::Ptr x);
 
-inline Array::Iterator end(Array::Ptr x)
-{
-       return x->End();
 }
 
-}
+extern template class std::vector<icinga::Value>;
 
 #endif /* ARRAY_H */
index 68f78f4cdef1b4d3c0827a6f2066672d38b5ebe7..bc16071743556c20ac506ba85d2d63d8ba3c5371 100644 (file)
 
 using namespace icinga;
 
+template class std::map<String, Value>;
+
 REGISTER_PRIMITIVE_TYPE(Dictionary, Object, Dictionary::GetPrototype());
 
+Dictionary::Dictionary(void)
+{ }
+
+Dictionary::~Dictionary(void)
+{ }
+
 /**
  * Retrieves a value from a dictionary.
  *
@@ -116,6 +124,46 @@ bool Dictionary::Contains(const String& key) const
        return (m_Data.find(key) != m_Data.end());
 }
 
+/**
+ * Returns an iterator to the beginning of the dictionary.
+ *
+ * Note: Caller must hold the object lock while using the iterator.
+ *
+ * @returns An iterator.
+ */
+Dictionary::Iterator Dictionary::Begin(void)
+{
+       ASSERT(OwnsLock());
+
+       return m_Data.begin();
+}
+
+/**
+ * Returns an iterator to the end of the dictionary.
+ *
+ * Note: Caller must hold the object lock while using the iterator.
+ *
+ * @returns An iterator.
+ */
+Dictionary::Iterator Dictionary::End(void)
+{
+       ASSERT(OwnsLock());
+
+       return m_Data.end();
+}
+
+/**
+ * Removes the item specified by the iterator from the dictionary.
+ *
+ * @param it The iterator.
+ */
+void Dictionary::Remove(Dictionary::Iterator it)
+{
+       ASSERT(OwnsLock());
+
+       m_Data.erase(it);
+}
+
 /**
  * Removes the specified key from the dictionary.
  *
@@ -233,3 +281,14 @@ bool Dictionary::GetOwnField(const String& field, Value *result) const
 {
        return Get(field, result);
 }
+
+Dictionary::Iterator icinga::begin(Dictionary::Ptr x)
+{
+       return x->Begin();
+}
+
+Dictionary::Iterator icinga::end(Dictionary::Ptr x)
+{
+       return x->End();
+}
+
index fadc1f41ab84c310e8bbc1ad7d485d396f8e2d12..cfca95a6d53a323f9c858fd1f5ce02fee9f8914f 100644 (file)
@@ -49,11 +49,9 @@ public:
 
        typedef std::map<String, Value>::value_type Pair;
 
-       Dictionary(void)
-       { }
+       Dictionary(void);
 
-       ~Dictionary(void)
-       { }
+       ~Dictionary(void);
 
        Value Get(const String& key) const;
        bool Get(const String& key, Value *result) const;
@@ -61,49 +59,14 @@ public:
        void Set(const String& key, Value&& value);
        bool Contains(const String& key) const;
 
-       /**
-        * Returns an iterator to the beginning of the dictionary.
-        *
-        * Note: Caller must hold the object lock while using the iterator.
-        *
-        * @returns An iterator.
-        */
-       Iterator Begin(void)
-       {
-               ASSERT(OwnsLock());
-
-               return m_Data.begin();
-       }
-
-       /**
-        * Returns an iterator to the end of the dictionary.
-        *
-        * Note: Caller must hold the object lock while using the iterator.
-        *
-        * @returns An iterator.
-        */
-       Iterator End(void)
-       {
-               ASSERT(OwnsLock());
-
-               return m_Data.end();
-       }
+       Iterator Begin(void);
+       Iterator End(void);
 
        size_t GetLength(void) const;
 
        void Remove(const String& key);
 
-       /**
-        * Removes the item specified by the iterator from the dictionary.
-        *
-        * @param it The iterator.
-        */
-       void Remove(Iterator it)
-       {
-               ASSERT(OwnsLock());
-
-               m_Data.erase(it);
-       }
+       void Remove(Iterator it);
 
        void Clear(void);
 
@@ -127,16 +90,11 @@ private:
        std::map<String, Value> m_Data; /**< The data for the dictionary. */
 };
 
-inline Dictionary::Iterator begin(Dictionary::Ptr x)
-{
-       return x->Begin();
-}
+Dictionary::Iterator begin(Dictionary::Ptr x);
+Dictionary::Iterator end(Dictionary::Ptr x);
 
-inline Dictionary::Iterator end(Dictionary::Ptr x)
-{
-       return x->End();
 }
 
-}
+extern template class std::map<icinga::String, icinga::Value>;
 
 #endif /* DICTIONARY_H */
index 5897527ccc24e56d533630e7e34af371bd3de736..e134f065547d168510a59a61d2819b995a328fbb 100644 (file)
 
 using namespace icinga;
 
+template Log& Log::operator<<(const Value&);
+template Log& Log::operator<<(const String&);
+template Log& Log::operator<<(const std::string&);
+template Log& Log::operator<<(const bool&);
+template Log& Log::operator<<(const unsigned int&);
+template Log& Log::operator<<(const int&);
+template Log& Log::operator<<(const unsigned long&);
+template Log& Log::operator<<(const long&);
+template Log& Log::operator<<(const double&);
+
 REGISTER_TYPE(Logger);
 
 std::set<Logger::Ptr> Logger::m_Loggers;
@@ -73,46 +83,6 @@ std::set<Logger::Ptr> Logger::GetLoggers(void)
        return m_Loggers;
 }
 
-/**
- * Writes a message to the application's log.
- *
- * @param severity The message severity.
- * @param facility The log facility.
- * @param message The message.
- */
-void icinga::IcingaLog(LogSeverity severity, const String& facility,
-       const String& message)
-{
-       LogEntry entry;
-       entry.Timestamp = Utility::GetTime();
-       entry.Severity = severity;
-       entry.Facility = facility;
-       entry.Message = message;
-
-       if (severity >= LogWarning) {
-               ContextTrace context;
-
-               if (context.GetLength() > 0) {
-                       std::ostringstream trace;
-                       trace << context;
-                       entry.Message += "\nContext:" + trace.str();
-               }
-       }
-
-       for (const Logger::Ptr& logger : Logger::GetLoggers()) {
-               ObjectLock llock(logger);
-
-               if (!logger->IsActive())
-                       continue;
-
-               if (entry.Severity >= logger->GetMinSeverity())
-                       logger->ProcessLogEntry(entry);
-       }
-
-       if (Logger::IsConsoleLogEnabled() && entry.Severity >= Logger::GetConsoleLogSeverity())
-               StreamLogger::ProcessLogEntry(std::cout, entry);
-}
-
 /**
  * Retrieves the minimum severity for this logger.
  *
@@ -223,3 +193,54 @@ void Logger::ValidateSeverity(const String& value, const ValidationUtils& utils)
                BOOST_THROW_EXCEPTION(ValidationError(this, { "severity" }, "Invalid severity specified: " + value));
        }
 }
+
+Log::Log(LogSeverity severity, const String& facility, const String& message)
+       : m_Severity(severity), m_Facility(facility)
+{
+       m_Buffer << message;
+}
+
+Log::Log(LogSeverity severity, const String& facility)
+       : m_Severity(severity), m_Facility(facility)
+{ }
+
+/**
+ * Writes the message to the application's log.
+ */
+Log::~Log(void)
+{
+       LogEntry entry;
+       entry.Timestamp = Utility::GetTime();
+       entry.Severity = m_Severity;
+       entry.Facility = m_Facility;
+       entry.Message = m_Buffer.str();
+
+       if (m_Severity >= LogWarning) {
+               ContextTrace context;
+
+               if (context.GetLength() > 0) {
+                       std::ostringstream trace;
+                       trace << context;
+                       entry.Message += "\nContext:" + trace.str();
+               }
+       }
+
+       for (const Logger::Ptr& logger : Logger::GetLoggers()) {
+               ObjectLock llock(logger);
+
+               if (!logger->IsActive())
+                       continue;
+
+               if (entry.Severity >= logger->GetMinSeverity())
+                       logger->ProcessLogEntry(entry);
+       }
+
+       if (Logger::IsConsoleLogEnabled() && entry.Severity >= Logger::GetConsoleLogSeverity())
+               StreamLogger::ProcessLogEntry(std::cout, entry);
+}
+
+Log& Log::operator<<(const char *val)
+{
+       m_Buffer << val;
+       return *this;
+}
index 406341d5783b415aee896d2c57bf2d01991a26b3..69606158c6aa3be5eb51efa44e13a85943fbd8e1 100644 (file)
@@ -104,25 +104,17 @@ private:
        static LogSeverity m_ConsoleLogSeverity;
 };
 
-void IcingaLog(LogSeverity severity, const String& facility, const String& message);
-
 class Log
 {
 public:
-       Log(LogSeverity severity, const String& facility, const String& message)
-               : m_Severity(severity), m_Facility(facility)
-       {
-               m_Buffer << message;
-       }
+       Log(void) = delete;
+       Log(const Log& other) = delete;
+       Log& operator=(const Log& rhs) = delete;
 
-       Log(LogSeverity severity, const String& facility)
-               : m_Severity(severity), m_Facility(facility)
-       { }
+       Log(LogSeverity severity, const String& facility, const String& message);
+       Log(LogSeverity severity, const String& facility);
 
-       ~Log(void)
-       {
-               IcingaLog(m_Severity, m_Facility, m_Buffer.str());
-       }
+       ~Log(void);
 
        template<typename T>
        Log& operator<<(const T& val)
@@ -131,16 +123,24 @@ public:
                return *this;
        }
 
+       Log& operator<<(const char *val);
+
 private:
        LogSeverity m_Severity;
        String m_Facility;
        std::ostringstream m_Buffer;
-
-       Log(void);
-       Log(const Log& other);
-       Log& operator=(const Log& rhs);
 };
 
+extern template Log& Log::operator<<(const Value&);
+extern template Log& Log::operator<<(const String&);
+extern template Log& Log::operator<<(const std::string&);
+extern template Log& Log::operator<<(const bool&);
+extern template Log& Log::operator<<(const unsigned int&);
+extern template Log& Log::operator<<(const int&);
+extern template Log& Log::operator<<(const unsigned long&);
+extern template Log& Log::operator<<(const long&);
+extern template Log& Log::operator<<(const double&);
+
 }
 
 #endif /* LOGGER_H */
index 73104c0b97d04e0d9eb374badc82fe7896126ad2..f435ca9be692811e0387f44cc1e6331adc8bf759 100644 (file)
@@ -26,6 +26,7 @@
 #include "base/logger.hpp"
 #include "base/exception.hpp"
 #include <boost/lexical_cast.hpp>
+#include <boost/thread/recursive_mutex.hpp>
 
 using namespace icinga;
 
index 8740f337ce05920502c1c1cca866e7c00625f83c..a5cfaf502ace076c15925d0fb89b05b6970bbba2 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "base/i2-base.hpp"
 #include "base/debug.hpp"
-#include <boost/thread/recursive_mutex.hpp>
 #include <boost/thread/condition_variable.hpp>
 #include <boost/smart_ptr/intrusive_ptr.hpp>
 #include <vector>
diff --git a/lib/base/objectlock.cpp b/lib/base/objectlock.cpp
new file mode 100644 (file)
index 0000000..5d44de3
--- /dev/null
@@ -0,0 +1,140 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
+ *                                                                            *
+ * This program is free software; you can redistribute it and/or              *
+ * modify it under the terms of the GNU General Public License                *
+ * as published by the Free Software Foundation; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * This program is distributed in the hope that it will be useful,            *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
+ * GNU General Public License for more details.                               *
+ *                                                                            *
+ * You should have received a copy of the GNU General Public License          *
+ * along with this program; if not, write to the Free Software Foundation     *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
+ ******************************************************************************/
+
+#include "base/objectlock.hpp"
+#include <boost/thread/recursive_mutex.hpp>
+
+using namespace icinga;
+
+#define I2MUTEX_UNLOCKED 0
+#define I2MUTEX_LOCKED 1
+
+ObjectLock::ObjectLock(void)
+       : m_Object(nullptr), m_Locked(false)
+{ }
+
+ObjectLock::~ObjectLock(void)
+{
+       Unlock();
+}
+
+ObjectLock::ObjectLock(const Object::Ptr& object)
+       : m_Object(object.get()), m_Locked(false)
+{
+       if (m_Object)
+               Lock();
+}
+
+ObjectLock::ObjectLock(const Object *object)
+       : m_Object(object), m_Locked(false)
+{
+       if (m_Object)
+               Lock();
+}
+
+void ObjectLock::LockMutex(const Object *object)
+{
+       unsigned int it = 0;
+
+#ifdef _WIN32
+#      ifdef _WIN64
+       while (likely(InterlockedCompareExchange64((LONGLONG *)&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED)) {
+#      else /* _WIN64 */
+       while (likely(InterlockedCompareExchange(&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED)) {
+#      endif /* _WIN64 */
+#else /* _WIN32 */
+       while (likely(!__sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_UNLOCKED, I2MUTEX_LOCKED))) {
+#endif /* _WIN32 */
+               if (likely(object->m_Mutex > I2MUTEX_LOCKED)) {
+                       boost::recursive_mutex *mtx = reinterpret_cast<boost::recursive_mutex *>(object->m_Mutex);
+                       mtx->lock();
+
+                       return;
+               }
+
+               Spin(it);
+               it++;
+       }
+
+       boost::recursive_mutex *mtx = new boost::recursive_mutex();
+       mtx->lock();
+#ifdef _WIN32
+#      ifdef _WIN64
+       InterlockedCompareExchange64((LONGLONG *)&object->m_Mutex, reinterpret_cast<LONGLONG>(mtx), I2MUTEX_LOCKED);
+#      else /* _WIN64 */
+       InterlockedCompareExchange(&object->m_Mutex, reinterpret_cast<LONG>(mtx), I2MUTEX_LOCKED);
+#      endif /* _WIN64 */
+#else /* _WIN32 */
+       __sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_LOCKED, reinterpret_cast<uintptr_t>(mtx));
+#endif /* _WIN32 */
+}
+
+void ObjectLock::Lock(void)
+{
+       ASSERT(!m_Locked && m_Object);
+
+       LockMutex(m_Object);
+
+       m_Locked = true;
+
+#ifdef I2_DEBUG
+#      ifdef _WIN32
+       InterlockedExchange(&m_Object->m_LockOwner, GetCurrentThreadId());
+#      else /* _WIN32 */
+       __sync_lock_test_and_set(&m_Object->m_LockOwner, pthread_self());
+#      endif /* _WIN32 */
+#endif /* I2_DEBUG */
+}
+
+void ObjectLock::Spin(unsigned int it)
+{
+       if (it < 8) {
+               /* Do nothing. */
+       }
+#ifdef SPIN_PAUSE
+       else if (it < 16) {
+               SPIN_PAUSE();
+       }
+#endif /* SPIN_PAUSE */
+       else {
+#ifdef _WIN32
+               Sleep(0);
+#else /* _WIN32 */
+               sched_yield();
+#endif /* _WIN32 */
+       }
+}
+
+void ObjectLock::Unlock(void)
+{
+#ifdef I2_DEBUG
+       if (m_Locked) {
+#      ifdef _WIN32
+               InterlockedExchange(&m_Object->m_LockOwner, 0);
+#      else /* _WIN32 */
+               __sync_lock_release(&m_Object->m_LockOwner);
+#      endif /* _WIN32 */
+       }
+#endif /* I2_DEBUG */
+
+       if (m_Locked) {
+               reinterpret_cast<boost::recursive_mutex *>(m_Object->m_Mutex)->unlock();
+               m_Locked = false;
+       }
+}
index 427e90a265b4f027c1a6e7499bafb0615f31d254..cf7c6d12b1def34e6160c0a6171d28cf610247c0 100644 (file)
@@ -22,9 +22,6 @@
 
 #include "base/object.hpp"
 
-#define I2MUTEX_UNLOCKED 0
-#define I2MUTEX_LOCKED 1
-
 namespace icinga
 {
 
@@ -34,119 +31,19 @@ namespace icinga
 struct ObjectLock
 {
 public:
-       ObjectLock(void)
-               : m_Object(nullptr), m_Locked(false)
-       { }
-
-       ~ObjectLock(void)
-       {
-               Unlock();
-       }
-
-       ObjectLock(const Object::Ptr& object)
-               : m_Object(object.get()), m_Locked(false)
-       {
-               if (m_Object)
-                       Lock();
-       }
-
-       ObjectLock(const Object *object)
-               : m_Object(object), m_Locked(false)
-       {
-               if (m_Object)
-                       Lock();
-       }
-
-       static void LockMutex(const Object *object)
-       {
-               unsigned int it = 0;
-
-#ifdef _WIN32
-#      ifdef _WIN64
-               while (likely(InterlockedCompareExchange64((LONGLONG *)&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED)) {
-#      else /* _WIN64 */
-               while (likely(InterlockedCompareExchange(&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED)) {
-#      endif /* _WIN64 */
-#else /* _WIN32 */
-               while (likely(!__sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_UNLOCKED, I2MUTEX_LOCKED))) {
-#endif /* _WIN32 */
-                       if (likely(object->m_Mutex > I2MUTEX_LOCKED)) {
-                               boost::recursive_mutex *mtx = reinterpret_cast<boost::recursive_mutex *>(object->m_Mutex);
-                               mtx->lock();
-
-                               return;
-                       }
-
-                       Spin(it);
-                       it++;
-               }
-
-               boost::recursive_mutex *mtx = new boost::recursive_mutex();
-               mtx->lock();
-#ifdef _WIN32
-#      ifdef _WIN64
-               InterlockedCompareExchange64((LONGLONG *)&object->m_Mutex, reinterpret_cast<LONGLONG>(mtx), I2MUTEX_LOCKED);
-#      else /* _WIN64 */
-               InterlockedCompareExchange(&object->m_Mutex, reinterpret_cast<LONG>(mtx), I2MUTEX_LOCKED);
-#      endif /* _WIN64 */
-#else /* _WIN32 */
-               __sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_LOCKED, reinterpret_cast<uintptr_t>(mtx));
-#endif /* _WIN32 */
-       }
-
-       void Lock(void)
-       {
-               ASSERT(!m_Locked && m_Object);
-
-               LockMutex(m_Object);
+       ObjectLock(void);
+       ObjectLock(const Object::Ptr& object);
+       ObjectLock(const Object *object);
 
-               m_Locked = true;
+       ~ObjectLock(void);
 
-#ifdef I2_DEBUG
-#      ifdef _WIN32
-               InterlockedExchange(&m_Object->m_LockOwner, GetCurrentThreadId());
-#      else /* _WIN32 */
-               __sync_lock_test_and_set(&m_Object->m_LockOwner, pthread_self());
-#      endif /* _WIN32 */
-#endif /* I2_DEBUG */
-       }
+       static void LockMutex(const Object *object);
 
-       static void Spin(unsigned int it)
-       {
-               if (it < 8) {
-                       /* Do nothing. */
-               }
-#ifdef SPIN_PAUSE
-               else if (it < 16) {
-                       SPIN_PAUSE();
-               }
-#endif /* SPIN_PAUSE */
-               else {
-#ifdef _WIN32
-                       Sleep(0);
-#else /* _WIN32 */
-                       sched_yield();
-#endif /* _WIN32 */
-               }
-       }
+       void Lock(void);
 
-       void Unlock(void)
-       {
-#ifdef I2_DEBUG
-               if (m_Locked) {
-#      ifdef _WIN32
-                       InterlockedExchange(&m_Object->m_LockOwner, 0);
-#      else /* _WIN32 */
-                       __sync_lock_release(&m_Object->m_LockOwner);
-#      endif /* _WIN32 */
-               }
-#endif /* I2_DEBUG */
+       static void Spin(unsigned int it);
 
-               if (m_Locked) {
-                       reinterpret_cast<boost::recursive_mutex *>(m_Object->m_Mutex)->unlock();
-                       m_Locked = false;
-               }
-       }
+       void Unlock(void);
 
 private:
        const Object *m_Object;
index 75300c2340edec47e4cd91211918d03d746d9dc5..4e8c1c1f6bc17f9f59f8cbef0cefdf972f55a85d 100644 (file)
 
 using namespace icinga;
 
+template class std::vector<String>;
+
 REGISTER_BUILTIN_TYPE(String, String::GetPrototype());
 
 const String::SizeType String::NPos = std::string::npos;
 
+String::String(void)
+       : m_Data()
+{ }
+
+String::String(const char *data)
+       : m_Data(data)
+{ }
+
+String::String(const std::string& data)
+       : m_Data(data)
+{ }
+
+String::String(std::string&& data)
+       : m_Data(std::move(data))
+{ }
+
+String::String(String::SizeType n, char c)
+       : m_Data(n, c)
+{ }
+
+String::String(const String& other)
+       : m_Data(other)
+{ }
+
+String::String(String&& other)
+       : m_Data(std::move(other.m_Data))
+{ }
+
 #ifndef _MSC_VER
 String::String(Value&& other)
 {
@@ -36,6 +66,9 @@ String::String(Value&& other)
 }
 #endif /* _MSC_VER */
 
+String::~String(void)
+{ }
+
 String& String::operator=(Value&& other)
 {
        if (other.IsString())
@@ -52,3 +85,392 @@ String& String::operator+=(const Value& rhs)
        return *this;
 }
 
+String& String::operator=(const String& rhs)
+{
+       m_Data = rhs.m_Data;
+       return *this;
+}
+
+String& String::operator=(String&& rhs)
+{
+       m_Data = std::move(rhs.m_Data);
+       return *this;
+}
+
+String& String::operator=(const std::string& rhs)
+{
+       m_Data = rhs;
+       return *this;
+}
+
+String& String::operator=(const char *rhs)
+{
+       m_Data = rhs;
+       return *this;
+}
+
+const char& String::operator[](String::SizeType pos) const
+{
+       return m_Data[pos];
+}
+
+char& String::operator[](String::SizeType pos)
+{
+       return m_Data[pos];
+}
+
+String& String::operator+=(const String& rhs)
+{
+       m_Data += rhs.m_Data;
+       return *this;
+}
+
+String& String::operator+=(const char *rhs)
+{
+       m_Data += rhs;
+       return *this;
+}
+
+String& String::operator+=(char rhs)
+{
+       m_Data += rhs;
+       return *this;
+}
+
+bool String::IsEmpty(void) const
+{
+       return m_Data.empty();
+}
+
+bool String::operator<(const String& rhs) const
+{
+       return m_Data < rhs.m_Data;
+}
+
+String::operator const std::string&(void) const
+{
+       return m_Data;
+}
+
+const char *String::CStr(void) const
+{
+       return m_Data.c_str();
+}
+
+void String::Clear(void)
+{
+       m_Data.clear();
+}
+
+String::SizeType String::GetLength(void) const
+{
+       return m_Data.size();
+}
+
+std::string& String::GetData(void)
+{
+       return m_Data;
+}
+
+const std::string& String::GetData(void) const
+{
+       return m_Data;
+}
+
+String::SizeType String::Find(const String& str, String::SizeType pos) const
+{
+       return m_Data.find(str, pos);
+}
+
+String::SizeType String::RFind(const String& str, String::SizeType pos) const
+{
+       return m_Data.rfind(str, pos);
+}
+
+String::SizeType String::FindFirstOf(const char *s, String::SizeType pos) const
+{
+       return m_Data.find_first_of(s, pos);
+}
+
+String::SizeType String::FindFirstOf(char ch, String::SizeType pos) const
+{
+       return m_Data.find_first_of(ch, pos);
+}
+
+String::SizeType String::FindFirstNotOf(const char *s, String::SizeType pos) const
+{
+       return m_Data.find_first_not_of(s, pos);
+}
+
+String::SizeType String::FindFirstNotOf(char ch, String::SizeType pos) const
+{
+       return m_Data.find_first_not_of(ch, pos);
+}
+
+String::SizeType String::FindLastOf(const char *s, String::SizeType pos) const
+{
+       return m_Data.find_last_of(s, pos);
+}
+
+String::SizeType String::FindLastOf(char ch, String::SizeType pos) const
+{
+       return m_Data.find_last_of(ch, pos);
+}
+
+String String::SubStr(String::SizeType first, String::SizeType len) const
+{
+       return m_Data.substr(first, len);
+}
+
+std::vector<String> String::Split(const char *separators) const
+{
+       std::vector<String> result;
+       boost::algorithm::split(result, m_Data, boost::is_any_of(separators));
+       return result;
+}
+
+void String::Replace(String::SizeType first, String::SizeType second, const String& str)
+{
+       m_Data.replace(first, second, str);
+}
+
+String String::Trim(void) const
+{
+       String t = m_Data;
+       boost::algorithm::trim(t);
+       return t;
+}
+
+String String::ToLower(void) const
+{
+       String t = m_Data;
+       boost::algorithm::to_lower(t);
+       return t;
+}
+
+String String::ToUpper(void) const
+{
+       String t = m_Data;
+       boost::algorithm::to_upper(t);
+       return t;
+}
+
+String String::Reverse(void) const
+{
+       String t = m_Data;
+       std::reverse(t.m_Data.begin(), t.m_Data.end());
+       return t;
+}
+
+void String::Append(int count, char ch)
+{
+       m_Data.append(count, ch);
+}
+
+bool String::Contains(const String& str) const
+{
+       return (m_Data.find(str) != std::string::npos);
+}
+
+void String::swap(String& str)
+{
+       m_Data.swap(str.m_Data);
+}
+
+String::Iterator String::erase(String::Iterator first, String::Iterator last)
+{
+       return m_Data.erase(first, last);
+}
+
+String::Iterator String::Begin(void)
+{
+       return m_Data.begin();
+}
+
+String::ConstIterator String::Begin(void) const
+{
+       return m_Data.begin();
+}
+
+String::Iterator String::End(void)
+{
+       return m_Data.end();
+}
+
+String::ConstIterator String::End(void) const
+{
+       return m_Data.end();
+}
+
+String::ReverseIterator String::RBegin(void)
+{
+       return m_Data.rbegin();
+}
+
+String::ConstReverseIterator String::RBegin(void) const
+{
+       return m_Data.rbegin();
+}
+
+String::ReverseIterator String::REnd(void)
+{
+       return m_Data.rend();
+}
+
+String::ConstReverseIterator String::REnd(void) const
+{
+       return m_Data.rend();
+}
+
+std::ostream& icinga::operator<<(std::ostream& stream, const String& str)
+{
+       stream << str.GetData();
+       return stream;
+}
+
+std::istream& icinga::operator>>(std::istream& stream, String& str)
+{
+       std::string tstr;
+       stream >> tstr;
+       str = tstr;
+       return stream;
+}
+
+String icinga::operator+(const String& lhs, const String& rhs)
+{
+       return lhs.GetData() + rhs.GetData();
+}
+
+String icinga::operator+(const String& lhs, const char *rhs)
+{
+       return lhs.GetData() + rhs;
+}
+
+String icinga::operator+(const char *lhs, const String& rhs)
+{
+       return lhs + rhs.GetData();
+}
+
+bool icinga::operator==(const String& lhs, const String& rhs)
+{
+       return lhs.GetData() == rhs.GetData();
+}
+
+bool icinga::operator==(const String& lhs, const char *rhs)
+{
+       return lhs.GetData() == rhs;
+}
+
+bool icinga::operator==(const char *lhs, const String& rhs)
+{
+       return lhs == rhs.GetData();
+}
+
+bool icinga::operator<(const String& lhs, const char *rhs)
+{
+       return lhs.GetData() < rhs;
+}
+
+bool icinga::operator<(const char *lhs, const String& rhs)
+{
+       return lhs < rhs.GetData();
+}
+
+bool icinga::operator>(const String& lhs, const String& rhs)
+{
+       return lhs.GetData() > rhs.GetData();
+}
+
+bool icinga::operator>(const String& lhs, const char *rhs)
+{
+       return lhs.GetData() > rhs;
+}
+
+bool icinga::operator>(const char *lhs, const String& rhs)
+{
+       return lhs > rhs.GetData();
+}
+
+bool icinga::operator<=(const String& lhs, const String& rhs)
+{
+       return lhs.GetData() <= rhs.GetData();
+}
+
+bool icinga::operator<=(const String& lhs, const char *rhs)
+{
+       return lhs.GetData() <= rhs;
+}
+
+bool icinga::operator<=(const char *lhs, const String& rhs)
+{
+       return lhs <= rhs.GetData();
+}
+
+bool icinga::operator>=(const String& lhs, const String& rhs)
+{
+       return lhs.GetData() >= rhs.GetData();
+}
+
+bool icinga::operator>=(const String& lhs, const char *rhs)
+{
+       return lhs.GetData() >= rhs;
+}
+
+bool icinga::operator>=(const char *lhs, const String& rhs)
+{
+       return lhs >= rhs.GetData();
+}
+
+bool icinga::operator!=(const String& lhs, const String& rhs)
+{
+       return lhs.GetData() != rhs.GetData();
+}
+
+bool icinga::operator!=(const String& lhs, const char *rhs)
+{
+       return lhs.GetData() != rhs;
+}
+
+bool icinga::operator!=(const char *lhs, const String& rhs)
+{
+       return lhs != rhs.GetData();
+}
+
+String::Iterator icinga::begin(String& x)
+{
+       return x.Begin();
+}
+
+String::ConstIterator icinga::begin(const String& x)
+{
+       return x.Begin();
+}
+
+String::Iterator icinga::end(String& x)
+{
+       return x.End();
+}
+
+String::ConstIterator icinga::end(const String& x)
+{
+       return x.End();
+}
+String::Iterator icinga::range_begin(String& x)
+{
+       return x.Begin();
+}
+
+String::ConstIterator icinga::range_begin(const String& x)
+{
+       return x.Begin();
+}
+
+String::Iterator icinga::range_end(String& x)
+{
+       return x.End();
+}
+
+String::ConstIterator icinga::range_end(const String& x)
+{
+       return x.End();
+}
index 9a844d447314263202c1e03418b8cf822bab59a2..ca2cb96af7dea6a99594da369cda074b2cba3e14 100644 (file)
@@ -58,246 +58,84 @@ public:
 
        typedef std::string::size_type SizeType;
 
-       String(void)
-               : m_Data()
-       { }
-
-       String(const char *data)
-               : m_Data(data)
-       { }
-
-       String(const std::string& data)
-               : m_Data(data)
-       { }
-
-       String(std::string&& data)
-               : m_Data(data)
-       { }
-
-       String(String::SizeType n, char c)
-               : m_Data(n, c)
-       { }
-
-       String(const String& other)
-               : m_Data(other)
-       { }
-
-       String(String&& other)
-               : m_Data(std::move(other.m_Data))
-       { }
+       String(void);
+       String(const char *data);
+       String(const std::string& data);
+       String(std::string&& data);
+       String(String::SizeType n, char c);
+       String(const String& other);
+       String(String&& other);
 
 #ifndef _MSC_VER
        String(Value&& other);
 #endif /* _MSC_VER */
 
-       ~String(void)
-       { }
+       ~String(void);
 
        template<typename InputIterator>
        String(InputIterator begin, InputIterator end)
                : m_Data(begin, end)
        { }
 
-       String& operator=(const String& rhs)
-       {
-               m_Data = rhs.m_Data;
-               return *this;
-       }
-
-       String& operator=(String&& rhs)
-       {
-               m_Data = std::move(rhs.m_Data);
-               return *this;
-       }
-
+       String& operator=(const String& rhs);
+       String& operator=(String&& rhs);
        String& operator=(Value&& rhs);
+       String& operator=(const std::string& rhs);
+       String& operator=(const char *rhs);
 
-       String& operator=(const std::string& rhs)
-       {
-               m_Data = rhs;
-               return *this;
-       }
-
-       String& operator=(const char *rhs)
-       {
-               m_Data = rhs;
-               return *this;
-       }
-
-       const char& operator[](SizeType pos) const
-       {
-               return m_Data[pos];
-       }
-
-       char& operator[](SizeType pos)
-       {
-               return m_Data[pos];
-       }
-
-       String& operator+=(const String& rhs)
-       {
-               m_Data += rhs.m_Data;
-               return *this;
-       }
-
-       String& operator+=(const char *rhs)
-       {
-               m_Data += rhs;
-               return *this;
-       }
+       const char& operator[](SizeType pos) const;
+       char& operator[](SizeType pos);
 
+       String& operator+=(const String& rhs);
+       String& operator+=(const char *rhs);
        String& operator+=(const Value& rhs);
+       String& operator+=(char rhs);
 
-       String& operator+=(char rhs)
-       {
-               m_Data += rhs;
-               return *this;
-       }
-
-       bool IsEmpty(void) const
-       {
-               return m_Data.empty();
-       }
-
-       bool operator<(const String& rhs) const
-       {
-               return m_Data < rhs.m_Data;
-       }
-
-       operator const std::string&(void) const
-       {
-               return m_Data;
-       }
-
-       const char *CStr(void) const
-       {
-               return m_Data.c_str();
-       }
-
-       void Clear(void)
-       {
-               m_Data.clear();
-       }
+       bool IsEmpty(void) const;
 
-       SizeType GetLength(void) const
-       {
-               return m_Data.size();
-       }
+       bool operator<(const String& rhs) const;
 
-       std::string& GetData(void)
-       {
-               return m_Data;
-       }
+       operator const std::string&(void) const;
 
-       const std::string& GetData(void) const
-       {
-               return m_Data;
-       }
+       const char *CStr(void) const;
 
-       SizeType Find(const String& str, SizeType pos = 0) const
-       {
-               return m_Data.find(str, pos);
-       }
+       void Clear(void);
 
-       SizeType RFind(const String& str, SizeType pos = NPos) const
-       {
-               return m_Data.rfind(str, pos);
-       }
+       SizeType GetLength(void) const;
 
-       SizeType FindFirstOf(const char *s, SizeType pos = 0) const
-       {
-               return m_Data.find_first_of(s, pos);
-       }
+       std::string& GetData(void);
+       const std::string& GetData(void) const;
 
-       SizeType FindFirstOf(char ch, SizeType pos = 0) const
-       {
-               return m_Data.find_first_of(ch, pos);
-       }
+       SizeType Find(const String& str, SizeType pos = 0) const;
+       SizeType RFind(const String& str, SizeType pos = NPos) const;
+       SizeType FindFirstOf(const char *s, SizeType pos = 0) const;
+       SizeType FindFirstOf(char ch, SizeType pos = 0) const;
+       SizeType FindFirstNotOf(const char *s, SizeType pos = 0) const;
+       SizeType FindFirstNotOf(char ch, SizeType pos = 0) const;
+       SizeType FindLastOf(const char *s, SizeType pos = NPos) const;
+       SizeType FindLastOf(char ch, SizeType pos = NPos) const;
 
-       SizeType FindFirstNotOf(const char *s, SizeType pos = 0) const
-       {
-               return m_Data.find_first_not_of(s, pos);
-       }
+       String SubStr(SizeType first, SizeType len = NPos) const;
 
-       SizeType FindFirstNotOf(char ch, SizeType pos = 0) const
-       {
-               return m_Data.find_first_not_of(ch, pos);
-       }
+       std::vector<String> Split(const char *separators) const;
 
-       SizeType FindLastOf(const char *s, SizeType pos = NPos) const
-       {
-               return m_Data.find_last_of(s, pos);
-       }
+       void Replace(SizeType first, SizeType second, const String& str);
 
-       SizeType FindLastOf(char ch, SizeType pos = NPos) const
-       {
-               return m_Data.find_last_of(ch, pos);
-       }
+       String Trim(void) const;
 
-       String SubStr(SizeType first, SizeType len = NPos) const
-       {
-               return m_Data.substr(first, len);
-       }
+       String ToLower(void) const;
 
-       std::vector<String> Split(const char *separators) const
-       {
-               std::vector<String> result;
-               boost::algorithm::split(result, m_Data, boost::is_any_of(separators));
-               return result;
-       }
+       String ToUpper(void) const;
 
-       void Replace(SizeType first, SizeType second, const String& str)
-       {
-               m_Data.replace(first, second, str);
-       }
+       String Reverse(void) const;
 
-       String Trim(void) const
-       {
-               String t = m_Data;
-               boost::algorithm::trim(t);
-               return t;
-       }
+       void Append(int count, char ch);
 
-       String ToLower(void) const
-       {
-               String t = m_Data;
-               boost::algorithm::to_lower(t);
-               return t;
-       }
+       bool Contains(const String& str) const;
 
-       String ToUpper(void) const
-       {
-               String t = m_Data;
-               boost::algorithm::to_upper(t);
-               return t;
-       }
+       void swap(String& str);
 
-       String Reverse(void) const
-       {
-               String t = m_Data;
-               std::reverse(t.m_Data.begin(), t.m_Data.end());
-               return t;
-       }
-
-       void Append(int count, char ch)
-       {
-               m_Data.append(count, ch);
-       }
-
-       bool Contains(const String& str) const
-       {
-               return (m_Data.find(str) != std::string::npos);
-       }
-
-       void swap(String& str)
-       {
-               m_Data.swap(str.m_Data);
-       }
-
-       Iterator erase(Iterator first, Iterator last)
-       {
-               return m_Data.erase(first, last);
-       }
+       Iterator erase(Iterator first, Iterator last);
 
        template<typename InputIterator>
        void insert(Iterator p, InputIterator first, InputIterator last)
@@ -305,45 +143,14 @@ public:
                m_Data.insert(p, first, last);
        }
 
-       Iterator Begin(void)
-       {
-               return m_Data.begin();
-       }
-
-       ConstIterator Begin(void) const
-       {
-               return m_Data.begin();
-       }
-
-       Iterator End(void)
-       {
-               return m_Data.end();
-       }
-
-       ConstIterator End(void) const
-       {
-               return m_Data.end();
-       }
-
-       ReverseIterator RBegin(void)
-       {
-               return m_Data.rbegin();
-       }
-
-       ConstReverseIterator RBegin(void) const
-       {
-               return m_Data.rbegin();
-       }
-
-       ReverseIterator REnd(void)
-       {
-               return m_Data.rend();
-       }
-
-       ConstReverseIterator REnd(void) const
-       {
-               return m_Data.rend();
-       }
+       Iterator Begin(void);
+       ConstIterator Begin(void) const;
+       Iterator End(void);
+       ConstIterator End(void) const;
+       ReverseIterator RBegin(void);
+       ConstReverseIterator RBegin(void) const;
+       ReverseIterator REnd(void);
+       ConstReverseIterator REnd(void) const;
 
        static const SizeType NPos;
 
@@ -353,160 +160,48 @@ private:
        std::string m_Data;
 };
 
-inline std::ostream& operator<<(std::ostream& stream, const String& str)
-{
-       stream << str.GetData();
-       return stream;
-}
-
-inline std::istream& operator>>(std::istream& stream, String& str)
-{
-       std::string tstr;
-       stream >> tstr;
-       str = tstr;
-       return stream;
-}
-
-inline String operator+(const String& lhs, const String& rhs)
-{
-       return lhs.GetData() + rhs.GetData();
-}
-
-inline String operator+(const String& lhs, const char *rhs)
-{
-       return lhs.GetData() + rhs;
-}
-
-inline String operator+(const char *lhs, const String& rhs)
-{
-       return lhs + rhs.GetData();
-}
-
-inline bool operator==(const String& lhs, const String& rhs)
-{
-       return lhs.GetData() == rhs.GetData();
-}
-
-inline bool operator==(const String& lhs, const char *rhs)
-{
-       return lhs.GetData() == rhs;
-}
-
-inline bool operator==(const char *lhs, const String& rhs)
-{
-       return lhs == rhs.GetData();
-}
-
-inline bool operator<(const String& lhs, const char *rhs)
-{
-       return lhs.GetData() < rhs;
-}
-
-inline bool operator<(const char *lhs, const String& rhs)
-{
-       return lhs < rhs.GetData();
-}
-
-inline bool operator>(const String& lhs, const String& rhs)
-{
-       return lhs.GetData() > rhs.GetData();
-}
+std::ostream& operator<<(std::ostream& stream, const String& str);
+std::istream& operator>>(std::istream& stream, String& str);
 
-inline bool operator>(const String& lhs, const char *rhs)
-{
-       return lhs.GetData() > rhs;
-}
+String operator+(const String& lhs, const String& rhs);
+String operator+(const String& lhs, const char *rhs);
+String operator+(const char *lhs, const String& rhs);
 
-inline bool operator>(const char *lhs, const String& rhs)
-{
-       return lhs > rhs.GetData();
-}
-
-inline bool operator<=(const String& lhs, const String& rhs)
-{
-       return lhs.GetData() <= rhs.GetData();
-}
+bool operator==(const String& lhs, const String& rhs);
+bool operator==(const String& lhs, const char *rhs);
+bool operator==(const char *lhs, const String& rhs);
 
-inline bool operator<=(const String& lhs, const char *rhs)
-{
-       return lhs.GetData() <= rhs;
-}
+bool operator<(const String& lhs, const char *rhs);
+bool operator<(const char *lhs, const String& rhs);
 
-inline bool operator<=(const char *lhs, const String& rhs)
-{
-       return lhs <= rhs.GetData();
-}
+bool operator>(const String& lhs, const String& rhs);
+bool operator>(const String& lhs, const char *rhs);
+bool operator>(const char *lhs, const String& rhs);
 
-inline bool operator>=(const String& lhs, const String& rhs)
-{
-       return lhs.GetData() >= rhs.GetData();
-}
+bool operator<=(const String& lhs, const String& rhs);
+bool operator<=(const String& lhs, const char *rhs);
+bool operator<=(const char *lhs, const String& rhs);
 
-inline bool operator>=(const String& lhs, const char *rhs)
-{
-       return lhs.GetData() >= rhs;
-}
+bool operator>=(const String& lhs, const String& rhs);
+bool operator>=(const String& lhs, const char *rhs);
+bool operator>=(const char *lhs, const String& rhs);
 
-inline bool operator>=(const char *lhs, const String& rhs)
-{
-       return lhs >= rhs.GetData();
-}
+bool operator!=(const String& lhs, const String& rhs);
+bool operator!=(const String& lhs, const char *rhs);
+bool operator!=(const char *lhs, const String& rhs);
 
-inline bool operator!=(const String& lhs, const String& rhs)
-{
-       return lhs.GetData() != rhs.GetData();
-}
+String::Iterator begin(String& x);
+String::ConstIterator begin(const String& x);
+String::Iterator end(String& x);
+String::ConstIterator end(const String& x);
+String::Iterator range_begin(String& x);
+String::ConstIterator range_begin(const String& x);
+String::Iterator range_end(String& x);
+String::ConstIterator range_end(const String& x);
 
-inline bool operator!=(const String& lhs, const char *rhs)
-{
-       return lhs.GetData() != rhs;
 }
 
-inline bool operator!=(const char *lhs, const String& rhs)
-{
-       return lhs != rhs.GetData();
-}
-
-inline String::Iterator begin(String& x)
-{
-       return x.Begin();
-}
-
-inline String::ConstIterator begin(const String& x)
-{
-       return x.Begin();
-}
-
-inline String::Iterator end(String& x)
-{
-       return x.End();
-}
-
-inline String::ConstIterator end(const String& x)
-{
-       return x.End();
-}
-inline String::Iterator range_begin(String& x)
-{
-       return x.Begin();
-}
-
-inline String::ConstIterator range_begin(const String& x)
-{
-       return x.Begin();
-}
-
-inline String::Iterator range_end(String& x)
-{
-       return x.End();
-}
-
-inline String::ConstIterator range_end(const String& x)
-{
-       return x.End();
-}
-
-}
+extern template class std::vector<icinga::String>;
 
 namespace boost
 {
index bd08445729d8833e63e80f62161b5ef5249e8b6a..c18ae9f9a87605e9038693489228c62521e135b2 100644 (file)
@@ -32,6 +32,12 @@ INITIALIZE_ONCE_WITH_PRIORITY([]() {
        Type::Register(type);
 }, 20);
 
+Type::Type(void)
+{ }
+
+Type::~Type(void)
+{ }
+
 String Type::ToString(void) const
 {
        return "type '" + GetName() + "'";
index 3b860bc79fd4c10699f05079a31926a7f74099b5..09d550bd4baef8baaa25e48c1149c8ac72e99ea9 100644 (file)
@@ -75,6 +75,9 @@ class Type : public Object
 public:
        DECLARE_OBJECT(Type);
 
+       Type(void);
+       ~Type(void);
+
        virtual String ToString(void) const override;
 
        virtual String GetName(void) const = 0;
index cb94720493e79b7bb7987666b8e195d334132588..ee2f1816c5b94f2fbfc50af619bfb5e01230c246 100644 (file)
 
 using namespace icinga;
 
+template class boost::variant<boost::blank, double, bool, String, Object::Ptr>;
+template const double& Value::Get<double>(void) const;
+template const bool& Value::Get<bool>(void) const;
+template const String& Value::Get<String>(void) const;
+template const Object::Ptr& Value::Get<Object::Ptr>(void) const;
+
 Value icinga::Empty;
 
+Value::Value(void)
+{ }
+
+Value::Value(std::nullptr_t)
+{ }
+
+Value::Value(int value)
+       : m_Value(double(value))
+{ }
+
+Value::Value(unsigned int value)
+       : m_Value(double(value))
+{ }
+
+Value::Value(long value)
+       : m_Value(double(value))
+{ }
+
+Value::Value(unsigned long value)
+       : m_Value(double(value))
+{ }
+
+Value::Value(long long value)
+       : m_Value(double(value))
+{ }
+
+Value::Value(unsigned long long value)
+       : m_Value(double(value))
+{ }
+
+Value::Value(double value)
+       : m_Value(value)
+{ }
+
+Value::Value(bool value)
+       : m_Value(value)
+{ }
+
+Value::Value(const String& value)
+       : m_Value(value)
+{ }
+
+Value::Value(String&& value)
+       : m_Value(value)
+{ }
+
+Value::Value(const char *value)
+       : m_Value(String(value))
+{ }
+
+Value::Value(const Value& other)
+       : m_Value(other.m_Value)
+{ }
+
+Value::Value(Value&& other)
+{
+#if BOOST_VERSION >= 105400
+       m_Value = std::move(other.m_Value);
+#else /* BOOST_VERSION */
+       m_Value.swap(other.m_Value);
+#endif /* BOOST_VERSION */
+}
+
+Value::Value(Object *value)
+       : Value(Object::Ptr(value))
+{ }
+
+Value::Value(const intrusive_ptr<Object>& value)
+{
+       if (value)
+               m_Value = value;
+}
+
+Value::~Value(void)
+{ }
+
+Value& Value::operator=(const Value& other)
+{
+       m_Value = other.m_Value;
+       return *this;
+}
+
+Value& Value::operator=(Value&& other)
+{
+#if BOOST_VERSION >= 105400
+       m_Value = std::move(other.m_Value);
+#else /* BOOST_VERSION */
+       m_Value.swap(other.m_Value);
+#endif /* BOOST_VERSION */
+
+       return *this;
+}
+
+/**
+ * Checks whether the variant is empty.
+ *
+ * @returns true if the variant is empty, false otherwise.
+ */
+bool Value::IsEmpty(void) const
+{
+       return (GetType() == ValueEmpty || (IsString() && boost::get<String>(m_Value).IsEmpty()));
+}
+
+/**
+ * Checks whether the variant is scalar (i.e. not an object and not empty).
+ *
+ * @returns true if the variant is scalar, false otherwise.
+ */
+bool Value::IsScalar(void) const
+{
+       return !IsEmpty() && !IsObject();
+}
+
+/**
+* Checks whether the variant is a number.
+*
+* @returns true if the variant is a number.
+*/
+bool Value::IsNumber(void) const
+{
+       return (GetType() == ValueNumber);
+}
+
+/**
+ * Checks whether the variant is a boolean.
+ *
+ * @returns true if the variant is a boolean.
+ */
+bool Value::IsBoolean(void) const
+{
+       return (GetType() == ValueBoolean);
+}
+
+/**
+ * Checks whether the variant is a string.
+ *
+ * @returns true if the variant is a string.
+ */
+bool Value::IsString(void) const
+{
+       return (GetType() == ValueString);
+}
+
+/**
+ * Checks whether the variant is a non-null object.
+ *
+ * @returns true if the variant is a non-null object, false otherwise.
+ */
+bool Value::IsObject(void) const
+{
+       return  (GetType() == ValueObject);
+}
+
+/**
+ * Returns the type of the value.
+ *
+ * @returns The type.
+ */
+ValueType Value::GetType(void) const
+{
+       return static_cast<ValueType>(m_Value.which());
+}
+
+void Value::Swap(Value& other)
+{
+       m_Value.swap(other.m_Value);
+}
+
 bool Value::ToBool(void) const
 {
        switch (GetType()) {
@@ -111,4 +285,3 @@ Value Value::Clone(void) const
        else
                return *this;
 }
-
index 688f6cc1060121c2d508be0983e728ed0b0a6eef..07c62c1748e3934194f29b6da1857a64c80098ac 100644 (file)
@@ -52,107 +52,40 @@ enum ValueType
 class Value
 {
 public:
-       Value(void)
-       { }
-
-       Value(std::nullptr_t)
-       { }
-
-       Value(int value)
-               : m_Value(double(value))
-       { }
-
-       Value(unsigned int value)
-               : m_Value(double(value))
-       { }
-
-       Value(long value)
-               : m_Value(double(value))
-       { }
-
-       Value(unsigned long value)
-               : m_Value(double(value))
-       { }
-
-       Value(long long value)
-               : m_Value(double(value))
-       { }
-
-       Value(unsigned long long value)
-               : m_Value(double(value))
-       { }
-
-       Value(double value)
-               : m_Value(value)
-       { }
-
-       Value(bool value)
-               : m_Value(value)
-       { }
-
-       Value(const String& value)
-               : m_Value(value)
-       { }
-
-       Value(String&& value)
-               : m_Value(value)
-       { }
-
-       Value(const char *value)
-               : m_Value(String(value))
-       { }
-
-       Value(const Value& other)
-               : m_Value(other.m_Value)
-       { }
-
-       Value(Value&& other)
-       {
-#if BOOST_VERSION >= 105400
-               m_Value = std::move(other.m_Value);
-#else /* BOOST_VERSION */
-               m_Value.swap(other.m_Value);
-#endif /* BOOST_VERSION */
-       }
-
-       Value(Object *value)
-       {
-               if (!value)
-                       return;
-
-               m_Value = Object::Ptr(value);
-       }
+       Value(void);
+       Value(std::nullptr_t);
+       Value(int value);
+       Value(unsigned int value);
+       Value(long value);
+       Value(unsigned long value);
+       Value(long long value);
+       Value(unsigned long long value);
+       Value(double value);
+       Value(bool value);
+       Value(const String& value);
+       Value(String&& value);
+       Value(const char *value);
+       Value(const Value& other);
+       Value(Value&& other);
+       Value(Object *value);
+       Value(const intrusive_ptr<Object>& value);
 
        template<typename T>
        Value(const intrusive_ptr<T>& value)
+               : Value(static_pointer_cast<Object>(value))
        {
-               if (!value)
-                       return;
-
-               m_Value = static_pointer_cast<Object>(value);
+               static_assert(!std::is_same<T, Object>::value, "T must not be Object");
        }
 
+       ~Value(void);
+
        bool ToBool(void) const;
 
        operator double(void) const;
        operator String(void) const;
 
-       Value& operator=(const Value& other)
-       {
-               m_Value = other.m_Value;
-               return *this;
-       }
-
-       Value& operator=(Value&& other)
-       {
-#if BOOST_VERSION >= 105400
-               m_Value = std::move(other.m_Value);
-#else /* BOOST_VERSION */
-               m_Value.swap(other.m_Value);
-#endif /* BOOST_VERSION */
-
-               return *this;
-       }
+       Value& operator=(const Value& other);
+       Value& operator=(Value&& other);
 
        bool operator==(bool rhs) const;
        bool operator!=(bool rhs) const;
@@ -181,7 +114,7 @@ public:
                if (!IsObject())
                        BOOST_THROW_EXCEPTION(std::runtime_error("Cannot convert value of type '" + GetTypeName() + "' to an object."));
 
-               const Object::Ptr& object = boost::get<Object::Ptr>(m_Value);
+               const Object::Ptr& object = Get<Object::Ptr>();
 
                ASSERT(object);
 
@@ -193,65 +126,12 @@ public:
                return tobject;
        }
 
-       /**
-       * Checks whether the variant is empty.
-       *
-       * @returns true if the variant is empty, false otherwise.
-       */
-       bool IsEmpty(void) const
-       {
-               return (GetType() == ValueEmpty || (IsString() && boost::get<String>(m_Value).IsEmpty()));
-       }
-
-       /**
-       * Checks whether the variant is scalar (i.e. not an object and not empty).
-       *
-       * @returns true if the variant is scalar, false otherwise.
-       */
-       bool IsScalar(void) const
-       {
-               return !IsEmpty() && !IsObject();
-       }
-
-       /**
-       * Checks whether the variant is a number.
-       *
-       * @returns true if the variant is a number.
-       */
-       bool IsNumber(void) const
-       {
-               return (GetType() == ValueNumber);
-       }
-
-       /**
-        * Checks whether the variant is a boolean.
-        *
-        * @returns true if the variant is a boolean.
-        */
-       bool IsBoolean(void) const
-       {
-               return (GetType() == ValueBoolean);
-       }
-
-       /**
-       * Checks whether the variant is a string.
-       *
-       * @returns true if the variant is a string.
-       */
-       bool IsString(void) const
-       {
-               return (GetType() == ValueString);
-       }
-
-       /**
-       * Checks whether the variant is a non-null object.
-       *
-       * @returns true if the variant is a non-null object, false otherwise.
-       */
-       bool IsObject(void) const
-       {
-               return  (GetType() == ValueObject);
-       }
+       bool IsEmpty(void) const;
+       bool IsScalar(void) const;
+       bool IsNumber(void) const;
+       bool IsBoolean(void) const;
+       bool IsString(void) const;
+       bool IsObject(void) const;
 
        template<typename T>
        bool IsObjectType(void) const
@@ -259,23 +139,12 @@ public:
                if (!IsObject())
                        return false;
 
-               return dynamic_cast<T *>(boost::get<Object::Ptr>(m_Value).get());
+               return dynamic_cast<T *>(Get<Object::Ptr>().get());
        }
 
-       /**
-       * Returns the type of the value.
-       *
-       * @returns The type.
-       */
-       ValueType GetType(void) const
-       {
-               return static_cast<ValueType>(m_Value.which());
-       }
+       ValueType GetType(void) const;
 
-       void Swap(Value& other)
-       {
-               m_Value.swap(other.m_Value);
-       }
+       void Swap(Value& other);
 
        String GetTypeName(void) const;
 
@@ -293,6 +162,11 @@ private:
        boost::variant<boost::blank, double, bool, String, Object::Ptr> m_Value;
 };
 
+extern template const double& Value::Get<double>(void) const;
+extern template const bool& Value::Get<bool>(void) const;
+extern template const String& Value::Get<String>(void) const;
+extern template const Object::Ptr& Value::Get<Object::Ptr>(void) const;
+
 extern Value Empty;
 
 Value operator+(const Value& lhs, const char *rhs);
@@ -390,4 +264,6 @@ std::istream& operator>>(std::istream& stream, Value& value);
 
 }
 
+extern template class boost::variant<boost::blank, double, bool, icinga::String, icinga::Object::Ptr>;
+
 #endif /* VALUE_H */
index 525358d75847505661d1b730558153f697473884..63f0f8ad0e2d3eda71552068a1047fd506d28c1b 100644 (file)
@@ -219,7 +219,14 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
        m_Header << std::endl
                        << "{" << std::endl
                        << "public:" << std::endl
-                       << "\t" << "DECLARE_PTR_TYPEDEFS(TypeImpl<" << klass.Name << ">);" << std::endl << std::endl;
+                       << "\t" << "DECLARE_PTR_TYPEDEFS(TypeImpl<" << klass.Name << ">);" << std::endl << std::endl
+                       << "\t" << "TypeImpl(void);" << std::endl
+                       << "\t" << "~TypeImpl(void);" << std::endl << std::endl;
+
+       m_Impl << "TypeImpl<" << klass.Name << ">::TypeImpl(void)" << std::endl
+               << "{ }" << std::endl << std::endl
+               << "TypeImpl<" << klass.Name << ">::~TypeImpl(void)" << std::endl
+               << "{ }" << std::endl << std::endl;
 
        /* GetName */
        m_Header << "\t" << "virtual String GetName(void) const;" << std::endl;
@@ -445,11 +452,11 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
 
        /* ObjectImpl */
        m_Header << "template<>" << std::endl
-                       << "class ObjectImpl<" << klass.Name << ">"
-                       << " : public " << (klass.Parent.empty() ? "Object" : klass.Parent) << std::endl
-                       << "{" << std::endl
-                       << "public:" << std::endl
-                       << "\t" << "DECLARE_PTR_TYPEDEFS(ObjectImpl<" << klass.Name << ">);" << std::endl << std::endl;
+               << "class ObjectImpl<" << klass.Name << ">"
+               << " : public " << (klass.Parent.empty() ? "Object" : klass.Parent) << std::endl
+               << "{" << std::endl
+               << "public:" << std::endl
+               << "\t" << "DECLARE_PTR_TYPEDEFS(ObjectImpl<" << klass.Name << ">);" << std::endl << std::endl;
 
        /* Validate */
        m_Header << "\t" << "virtual void Validate(int types, const ValidationUtils& utils) override;" << std::endl;
@@ -541,27 +548,27 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
                m_Impl << "}" << std::endl << std::endl;
        }
 
-       if (!klass.Fields.empty()) {
-               /* constructor */
-               m_Header << "public:" << std::endl
-                               << "\t" << "ObjectImpl<" << klass.Name << ">(void);" << std::endl;
+       /* constructor */
+       m_Header << "public:" << std::endl
+                       << "\t" << "ObjectImpl<" << klass.Name << ">(void);" << std::endl;
 
-               m_Impl << "ObjectImpl<" << klass.Name << ">::ObjectImpl(void)" << std::endl
-                       << "{" << std::endl;
+       m_Impl << "ObjectImpl<" << klass.Name << ">::ObjectImpl(void)" << std::endl
+               << "{" << std::endl;
 
-               for (const Field& field : klass.Fields) {
-                       m_Impl << "\t" << "Set" << field.GetFriendlyName() << "(" << "GetDefault" << field.GetFriendlyName() << "(), true);" << std::endl;
-               }
+       for (const Field& field : klass.Fields) {
+               m_Impl << "\t" << "Set" << field.GetFriendlyName() << "(" << "GetDefault" << field.GetFriendlyName() << "(), true);" << std::endl;
+       }
 
-               m_Impl << "}" << std::endl << std::endl;
+       m_Impl << "}" << std::endl << std::endl;
 
-               /* destructor */
-               m_Header << "public:" << std::endl
-                               << "\t" << "~ObjectImpl<" << klass.Name << ">(void);" << std::endl;
+       /* destructor */
+       m_Header << "public:" << std::endl
+                       << "\t" << "~ObjectImpl<" << klass.Name << ">(void);" << std::endl;
 
-               m_Impl << "ObjectImpl<" << klass.Name << ">::~ObjectImpl(void)" << std::endl
-                       << "{ }" << std::endl << std::endl;
+       m_Impl << "ObjectImpl<" << klass.Name << ">::~ObjectImpl(void)" << std::endl
+               << "{ }" << std::endl << std::endl;
 
+       if (!klass.Fields.empty()) {
                /* SetField */
                m_Header << "public:" << std::endl
                                << "\t" << "virtual void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty) override;" << std::endl;