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:
Michael Friedrich 2018-01-03 11:24:34 +01:00 committed by GitHub
commit b8839fe238
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1119 additions and 846 deletions

View 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

View File

@ -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();
}

View 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();
}
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 */

View File

@ -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();
}

View 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();
}
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 */

View File

@ -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;
}

View 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 */

View 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;

View 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>

140
lib/base/objectlock.cpp Normal file
View File

@ -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;
}
}

View 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);
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;

View File

@ -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();
}

View 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;
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
{

View 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() + "'";

View 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;

View File

@ -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;
}

View 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 */

View 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;
}
/* 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;