mirror of https://github.com/Icinga/icinga2.git
Merge pull request #5937 from Icinga/feature/remove-inline-methods
Remove inline methods and use explicit template instantiation to minimize the number of weak symbols
This commit is contained in:
commit
b8839fe238
|
@ -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
|
||||
|
|
|
@ -28,8 +28,20 @@
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
inline Array::Iterator end(Array::Ptr x)
|
||||
{
|
||||
return x->End();
|
||||
}
|
||||
Array::Iterator begin(Array::Ptr x);
|
||||
Array::Iterator end(Array::Ptr x);
|
||||
|
||||
}
|
||||
|
||||
extern template class std::vector<icinga::Value>;
|
||||
|
||||
#endif /* ARRAY_H */
|
||||
|
|
|
@ -25,8 +25,16 @@
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
inline Dictionary::Iterator end(Dictionary::Ptr x)
|
||||
{
|
||||
return x->End();
|
||||
}
|
||||
Dictionary::Iterator begin(Dictionary::Ptr x);
|
||||
Dictionary::Iterator end(Dictionary::Ptr x);
|
||||
|
||||
}
|
||||
|
||||
extern template class std::map<icinga::String, icinga::Value>;
|
||||
|
||||
#endif /* DICTIONARY_H */
|
||||
|
|
|
@ -30,6 +30,16 @@
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
ObjectLock(const Object::Ptr& object);
|
||||
ObjectLock(const Object *object);
|
||||
|
||||
~ObjectLock(void)
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
~ObjectLock(void);
|
||||
|
||||
ObjectLock(const Object::Ptr& object)
|
||||
: m_Object(object.get()), m_Locked(false)
|
||||
{
|
||||
if (m_Object)
|
||||
Lock();
|
||||
}
|
||||
static void LockMutex(const Object *object);
|
||||
|
||||
ObjectLock(const Object *object)
|
||||
: m_Object(object), m_Locked(false)
|
||||
{
|
||||
if (m_Object)
|
||||
Lock();
|
||||
}
|
||||
void Lock(void);
|
||||
|
||||
static void LockMutex(const Object *object)
|
||||
{
|
||||
unsigned int it = 0;
|
||||
static void Spin(unsigned int it);
|
||||
|
||||
#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);
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
void Unlock(void);
|
||||
|
||||
private:
|
||||
const Object *m_Object;
|
||||
|
|
|
@ -25,10 +25,40 @@
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
bool IsEmpty(void) const
|
||||
{
|
||||
return m_Data.empty();
|
||||
}
|
||||
bool operator<(const String& rhs) const;
|
||||
|
||||
bool operator<(const String& rhs) const
|
||||
{
|
||||
return m_Data < rhs.m_Data;
|
||||
}
|
||||
operator const std::string&(void) const;
|
||||
|
||||
operator const std::string&(void) const
|
||||
{
|
||||
return m_Data;
|
||||
}
|
||||
const char *CStr(void) const;
|
||||
|
||||
const char *CStr(void) const
|
||||
{
|
||||
return m_Data.c_str();
|
||||
}
|
||||
void Clear(void);
|
||||
|
||||
void Clear(void)
|
||||
{
|
||||
m_Data.clear();
|
||||
}
|
||||
SizeType GetLength(void) const;
|
||||
|
||||
SizeType GetLength(void) const
|
||||
{
|
||||
return m_Data.size();
|
||||
}
|
||||
std::string& GetData(void);
|
||||
const std::string& GetData(void) const;
|
||||
|
||||
std::string& GetData(void)
|
||||
{
|
||||
return m_Data;
|
||||
}
|
||||
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;
|
||||
|
||||
const std::string& GetData(void) const
|
||||
{
|
||||
return m_Data;
|
||||
}
|
||||
String SubStr(SizeType first, SizeType len = NPos) const;
|
||||
|
||||
SizeType Find(const String& str, SizeType pos = 0) const
|
||||
{
|
||||
return m_Data.find(str, pos);
|
||||
}
|
||||
std::vector<String> Split(const char *separators) const;
|
||||
|
||||
SizeType RFind(const String& str, SizeType pos = NPos) const
|
||||
{
|
||||
return m_Data.rfind(str, pos);
|
||||
}
|
||||
void Replace(SizeType first, SizeType second, const String& str);
|
||||
|
||||
SizeType FindFirstOf(const char *s, SizeType pos = 0) const
|
||||
{
|
||||
return m_Data.find_first_of(s, pos);
|
||||
}
|
||||
String Trim(void) const;
|
||||
|
||||
SizeType FindFirstOf(char ch, SizeType pos = 0) const
|
||||
{
|
||||
return m_Data.find_first_of(ch, pos);
|
||||
}
|
||||
String ToLower(void) const;
|
||||
|
||||
SizeType FindFirstNotOf(const char *s, SizeType pos = 0) const
|
||||
{
|
||||
return m_Data.find_first_not_of(s, pos);
|
||||
}
|
||||
String ToUpper(void) const;
|
||||
|
||||
SizeType FindFirstNotOf(char ch, SizeType pos = 0) const
|
||||
{
|
||||
return m_Data.find_first_not_of(ch, pos);
|
||||
}
|
||||
String Reverse(void) const;
|
||||
|
||||
SizeType FindLastOf(const char *s, SizeType pos = NPos) const
|
||||
{
|
||||
return m_Data.find_last_of(s, pos);
|
||||
}
|
||||
void Append(int count, char ch);
|
||||
|
||||
SizeType FindLastOf(char ch, SizeType pos = NPos) const
|
||||
{
|
||||
return m_Data.find_last_of(ch, pos);
|
||||
}
|
||||
bool Contains(const String& str) const;
|
||||
|
||||
String SubStr(SizeType first, SizeType len = NPos) const
|
||||
{
|
||||
return m_Data.substr(first, len);
|
||||
}
|
||||
void swap(String& str);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Replace(SizeType first, SizeType second, const String& str)
|
||||
{
|
||||
m_Data.replace(first, second, str);
|
||||
}
|
||||
|
||||
String Trim(void) const
|
||||
{
|
||||
String t = m_Data;
|
||||
boost::algorithm::trim(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
String ToLower(void) const
|
||||
{
|
||||
String t = m_Data;
|
||||
boost::algorithm::to_lower(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
String ToUpper(void) const
|
||||
{
|
||||
String t = m_Data;
|
||||
boost::algorithm::to_upper(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
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,161 +160,49 @@ private:
|
|||
std::string m_Data;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream, const String& str)
|
||||
{
|
||||
stream << str.GetData();
|
||||
return stream;
|
||||
}
|
||||
std::ostream& operator<<(std::ostream& stream, const String& str);
|
||||
std::istream& operator>>(std::istream& stream, String& str);
|
||||
|
||||
inline std::istream& operator>>(std::istream& stream, String& str)
|
||||
{
|
||||
std::string tstr;
|
||||
stream >> tstr;
|
||||
str = tstr;
|
||||
return stream;
|
||||
}
|
||||
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 String 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 String 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 String 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 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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
extern template class std::vector<icinga::String>;
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
|
|
|
@ -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() + "'";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -24,8 +24,182 @@
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* constructor */
|
||||
m_Header << "public:" << std::endl
|
||||
<< "\t" << "ObjectImpl<" << klass.Name << ">(void);" << 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;
|
||||
}
|
||||
|
||||
m_Impl << "}" << std::endl << 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;
|
||||
|
||||
if (!klass.Fields.empty()) {
|
||||
/* constructor */
|
||||
m_Header << "public:" << std::endl
|
||||
<< "\t" << "ObjectImpl<" << klass.Name << ">(void);" << 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;
|
||||
}
|
||||
|
||||
m_Impl << "}" << std::endl << 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;
|
||||
|
||||
/* 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;
|
||||
|
|
Loading…
Reference in New Issue