mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-23 13:45:04 +02:00
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
|
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
|
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
|
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
|
function.cpp function.thpp function-script.cpp
|
||||||
perfdatavalue.cpp perfdatavalue.thpp scriptglobal.cpp
|
perfdatavalue.cpp perfdatavalue.thpp scriptglobal.cpp
|
||||||
scriptutils.cpp serializer.cpp socket.cpp socketevents.cpp socketevents-epoll.cpp socketevents-poll.cpp stacktrace.cpp
|
scriptutils.cpp serializer.cpp socket.cpp socketevents.cpp socketevents-epoll.cpp socketevents-poll.cpp stacktrace.cpp
|
||||||
|
@ -28,8 +28,20 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
template class std::vector<Value>;
|
||||||
|
|
||||||
REGISTER_PRIMITIVE_TYPE(Array, Object, Array::GetPrototype());
|
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.
|
* Restrieves a value from an array.
|
||||||
*
|
*
|
||||||
@ -93,6 +105,34 @@ void Array::Add(Value&& value)
|
|||||||
m_Data.emplace_back(std::move(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.
|
* 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);
|
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;
|
typedef std::vector<Value>::size_type SizeType;
|
||||||
|
|
||||||
Array(void)
|
Array(void);
|
||||||
{ }
|
Array(std::initializer_list<Value> init);
|
||||||
|
|
||||||
Array(std::initializer_list<Value> init)
|
~Array(void);
|
||||||
: m_Data(init)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~Array(void)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Value Get(SizeType index) const;
|
Value Get(SizeType index) const;
|
||||||
void Set(SizeType index, const Value& value);
|
void Set(SizeType index, const Value& value);
|
||||||
@ -63,33 +58,8 @@ public:
|
|||||||
void Add(const Value& value);
|
void Add(const Value& value);
|
||||||
void Add(Value&& value);
|
void Add(Value&& value);
|
||||||
|
|
||||||
/**
|
Iterator Begin(void);
|
||||||
* Returns an iterator to the beginning of the array.
|
Iterator End(void);
|
||||||
*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetLength(void) const;
|
size_t GetLength(void) const;
|
||||||
bool Contains(const Value& value) const;
|
bool Contains(const Value& value) const;
|
||||||
@ -148,16 +118,11 @@ private:
|
|||||||
std::vector<Value> m_Data; /**< The data for the array. */
|
std::vector<Value> m_Data; /**< The data for the array. */
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Array::Iterator begin(Array::Ptr x)
|
Array::Iterator begin(Array::Ptr x);
|
||||||
{
|
Array::Iterator end(Array::Ptr x);
|
||||||
return x->Begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Array::Iterator end(Array::Ptr x)
|
|
||||||
{
|
|
||||||
return x->End();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern template class std::vector<icinga::Value>;
|
||||||
|
|
||||||
#endif /* ARRAY_H */
|
#endif /* ARRAY_H */
|
||||||
|
@ -25,8 +25,16 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
template class std::map<String, Value>;
|
||||||
|
|
||||||
REGISTER_PRIMITIVE_TYPE(Dictionary, Object, Dictionary::GetPrototype());
|
REGISTER_PRIMITIVE_TYPE(Dictionary, Object, Dictionary::GetPrototype());
|
||||||
|
|
||||||
|
Dictionary::Dictionary(void)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Dictionary::~Dictionary(void)
|
||||||
|
{ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a value from a dictionary.
|
* 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());
|
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.
|
* Removes the specified key from the dictionary.
|
||||||
*
|
*
|
||||||
@ -233,3 +281,14 @@ bool Dictionary::GetOwnField(const String& field, Value *result) const
|
|||||||
{
|
{
|
||||||
return Get(field, result);
|
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;
|
typedef std::map<String, Value>::value_type Pair;
|
||||||
|
|
||||||
Dictionary(void)
|
Dictionary(void);
|
||||||
{ }
|
|
||||||
|
|
||||||
~Dictionary(void)
|
~Dictionary(void);
|
||||||
{ }
|
|
||||||
|
|
||||||
Value Get(const String& key) const;
|
Value Get(const String& key) const;
|
||||||
bool Get(const String& key, Value *result) const;
|
bool Get(const String& key, Value *result) const;
|
||||||
@ -61,49 +59,14 @@ public:
|
|||||||
void Set(const String& key, Value&& value);
|
void Set(const String& key, Value&& value);
|
||||||
bool Contains(const String& key) const;
|
bool Contains(const String& key) const;
|
||||||
|
|
||||||
/**
|
Iterator Begin(void);
|
||||||
* Returns an iterator to the beginning of the dictionary.
|
Iterator End(void);
|
||||||
*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetLength(void) const;
|
size_t GetLength(void) const;
|
||||||
|
|
||||||
void Remove(const String& key);
|
void Remove(const String& key);
|
||||||
|
|
||||||
/**
|
void Remove(Iterator it);
|
||||||
* 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 Clear(void);
|
void Clear(void);
|
||||||
|
|
||||||
@ -127,16 +90,11 @@ private:
|
|||||||
std::map<String, Value> m_Data; /**< The data for the dictionary. */
|
std::map<String, Value> m_Data; /**< The data for the dictionary. */
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Dictionary::Iterator begin(Dictionary::Ptr x)
|
Dictionary::Iterator begin(Dictionary::Ptr x);
|
||||||
{
|
Dictionary::Iterator end(Dictionary::Ptr x);
|
||||||
return x->Begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Dictionary::Iterator end(Dictionary::Ptr x)
|
|
||||||
{
|
|
||||||
return x->End();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern template class std::map<icinga::String, icinga::Value>;
|
||||||
|
|
||||||
#endif /* DICTIONARY_H */
|
#endif /* DICTIONARY_H */
|
||||||
|
@ -30,6 +30,16 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
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);
|
REGISTER_TYPE(Logger);
|
||||||
|
|
||||||
std::set<Logger::Ptr> Logger::m_Loggers;
|
std::set<Logger::Ptr> Logger::m_Loggers;
|
||||||
@ -73,46 +83,6 @@ std::set<Logger::Ptr> Logger::GetLoggers(void)
|
|||||||
return m_Loggers;
|
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.
|
* 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));
|
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;
|
static LogSeverity m_ConsoleLogSeverity;
|
||||||
};
|
};
|
||||||
|
|
||||||
void IcingaLog(LogSeverity severity, const String& facility, const String& message);
|
|
||||||
|
|
||||||
class Log
|
class Log
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Log(LogSeverity severity, const String& facility, const String& message)
|
Log(void) = delete;
|
||||||
: m_Severity(severity), m_Facility(facility)
|
Log(const Log& other) = delete;
|
||||||
{
|
Log& operator=(const Log& rhs) = delete;
|
||||||
m_Buffer << message;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(LogSeverity severity, const String& facility)
|
Log(LogSeverity severity, const String& facility, const String& message);
|
||||||
: m_Severity(severity), m_Facility(facility)
|
Log(LogSeverity severity, const String& facility);
|
||||||
{ }
|
|
||||||
|
|
||||||
~Log(void)
|
~Log(void);
|
||||||
{
|
|
||||||
IcingaLog(m_Severity, m_Facility, m_Buffer.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Log& operator<<(const T& val)
|
Log& operator<<(const T& val)
|
||||||
@ -131,16 +123,24 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log& operator<<(const char *val);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LogSeverity m_Severity;
|
LogSeverity m_Severity;
|
||||||
String m_Facility;
|
String m_Facility;
|
||||||
std::ostringstream m_Buffer;
|
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 */
|
#endif /* LOGGER_H */
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/thread/recursive_mutex.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "base/i2-base.hpp"
|
#include "base/i2-base.hpp"
|
||||||
#include "base/debug.hpp"
|
#include "base/debug.hpp"
|
||||||
#include <boost/thread/recursive_mutex.hpp>
|
|
||||||
#include <boost/thread/condition_variable.hpp>
|
#include <boost/thread/condition_variable.hpp>
|
||||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
140
lib/base/objectlock.cpp
Normal file
140
lib/base/objectlock.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -22,9 +22,6 @@
|
|||||||
|
|
||||||
#include "base/object.hpp"
|
#include "base/object.hpp"
|
||||||
|
|
||||||
#define I2MUTEX_UNLOCKED 0
|
|
||||||
#define I2MUTEX_LOCKED 1
|
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -34,119 +31,19 @@ namespace icinga
|
|||||||
struct ObjectLock
|
struct ObjectLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ObjectLock(void)
|
ObjectLock(void);
|
||||||
: m_Object(nullptr), m_Locked(false)
|
ObjectLock(const Object::Ptr& object);
|
||||||
{ }
|
ObjectLock(const Object *object);
|
||||||
|
|
||||||
~ObjectLock(void)
|
~ObjectLock(void);
|
||||||
{
|
|
||||||
Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectLock(const Object::Ptr& object)
|
static void LockMutex(const Object *object);
|
||||||
: m_Object(object.get()), m_Locked(false)
|
|
||||||
{
|
|
||||||
if (m_Object)
|
|
||||||
Lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectLock(const Object *object)
|
void Lock(void);
|
||||||
: m_Object(object), m_Locked(false)
|
|
||||||
{
|
|
||||||
if (m_Object)
|
|
||||||
Lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void LockMutex(const Object *object)
|
static void Spin(unsigned int it);
|
||||||
{
|
|
||||||
unsigned int it = 0;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
void Unlock(void);
|
||||||
# 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Object *m_Object;
|
const Object *m_Object;
|
||||||
|
@ -25,10 +25,40 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
template class std::vector<String>;
|
||||||
|
|
||||||
REGISTER_BUILTIN_TYPE(String, String::GetPrototype());
|
REGISTER_BUILTIN_TYPE(String, String::GetPrototype());
|
||||||
|
|
||||||
const String::SizeType String::NPos = std::string::npos;
|
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
|
#ifndef _MSC_VER
|
||||||
String::String(Value&& other)
|
String::String(Value&& other)
|
||||||
{
|
{
|
||||||
@ -36,6 +66,9 @@ String::String(Value&& other)
|
|||||||
}
|
}
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
String::~String(void)
|
||||||
|
{ }
|
||||||
|
|
||||||
String& String::operator=(Value&& other)
|
String& String::operator=(Value&& other)
|
||||||
{
|
{
|
||||||
if (other.IsString())
|
if (other.IsString())
|
||||||
@ -52,3 +85,392 @@ String& String::operator+=(const Value& rhs)
|
|||||||
return *this;
|
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;
|
typedef std::string::size_type SizeType;
|
||||||
|
|
||||||
String(void)
|
String(void);
|
||||||
: m_Data()
|
String(const char *data);
|
||||||
{ }
|
String(const std::string& data);
|
||||||
|
String(std::string&& data);
|
||||||
String(const char *data)
|
String(String::SizeType n, char c);
|
||||||
: m_Data(data)
|
String(const String& other);
|
||||||
{ }
|
String(String&& other);
|
||||||
|
|
||||||
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))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
String(Value&& other);
|
String(Value&& other);
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
~String(void)
|
~String(void);
|
||||||
{ }
|
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
String(InputIterator begin, InputIterator end)
|
String(InputIterator begin, InputIterator end)
|
||||||
: m_Data(begin, end)
|
: m_Data(begin, end)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
String& operator=(const String& rhs)
|
String& operator=(const String& rhs);
|
||||||
{
|
String& operator=(String&& rhs);
|
||||||
m_Data = rhs.m_Data;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
String& operator=(String&& rhs)
|
|
||||||
{
|
|
||||||
m_Data = std::move(rhs.m_Data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
String& operator=(Value&& rhs);
|
String& operator=(Value&& rhs);
|
||||||
|
String& operator=(const std::string& rhs);
|
||||||
|
String& operator=(const char *rhs);
|
||||||
|
|
||||||
String& operator=(const std::string& rhs)
|
const char& operator[](SizeType pos) const;
|
||||||
{
|
char& operator[](SizeType pos);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
String& operator+=(const String& rhs);
|
||||||
|
String& operator+=(const char *rhs);
|
||||||
String& operator+=(const Value& rhs);
|
String& operator+=(const Value& rhs);
|
||||||
|
String& operator+=(char rhs);
|
||||||
|
|
||||||
String& operator+=(char rhs)
|
bool IsEmpty(void) const;
|
||||||
{
|
|
||||||
m_Data += rhs;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEmpty(void) const
|
bool operator<(const String& rhs) const;
|
||||||
{
|
|
||||||
return m_Data.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<(const String& rhs) const
|
operator const std::string&(void) const;
|
||||||
{
|
|
||||||
return m_Data < rhs.m_Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator const std::string&(void) const
|
const char *CStr(void) const;
|
||||||
{
|
|
||||||
return m_Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *CStr(void) const
|
void Clear(void);
|
||||||
{
|
|
||||||
return m_Data.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear(void)
|
SizeType GetLength(void) const;
|
||||||
{
|
|
||||||
m_Data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType GetLength(void) const
|
std::string& GetData(void);
|
||||||
{
|
const std::string& GetData(void) const;
|
||||||
return m_Data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string& GetData(void)
|
SizeType Find(const String& str, SizeType pos = 0) const;
|
||||||
{
|
SizeType RFind(const String& str, SizeType pos = NPos) const;
|
||||||
return m_Data;
|
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
|
String SubStr(SizeType first, SizeType len = NPos) const;
|
||||||
{
|
|
||||||
return m_Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType Find(const String& str, SizeType pos = 0) const
|
std::vector<String> Split(const char *separators) const;
|
||||||
{
|
|
||||||
return m_Data.find(str, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType RFind(const String& str, SizeType pos = NPos) const
|
void Replace(SizeType first, SizeType second, const String& str);
|
||||||
{
|
|
||||||
return m_Data.rfind(str, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType FindFirstOf(const char *s, SizeType pos = 0) const
|
String Trim(void) const;
|
||||||
{
|
|
||||||
return m_Data.find_first_of(s, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType FindFirstOf(char ch, SizeType pos = 0) const
|
String ToLower(void) const;
|
||||||
{
|
|
||||||
return m_Data.find_first_of(ch, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType FindFirstNotOf(const char *s, SizeType pos = 0) const
|
String ToUpper(void) const;
|
||||||
{
|
|
||||||
return m_Data.find_first_not_of(s, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType FindFirstNotOf(char ch, SizeType pos = 0) const
|
String Reverse(void) const;
|
||||||
{
|
|
||||||
return m_Data.find_first_not_of(ch, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType FindLastOf(const char *s, SizeType pos = NPos) const
|
void Append(int count, char ch);
|
||||||
{
|
|
||||||
return m_Data.find_last_of(s, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType FindLastOf(char ch, SizeType pos = NPos) const
|
bool Contains(const String& str) const;
|
||||||
{
|
|
||||||
return m_Data.find_last_of(ch, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
String SubStr(SizeType first, SizeType len = NPos) const
|
void swap(String& str);
|
||||||
{
|
|
||||||
return m_Data.substr(first, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<String> Split(const char *separators) const
|
Iterator erase(Iterator first, Iterator last);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
void insert(Iterator p, InputIterator first, InputIterator last)
|
void insert(Iterator p, InputIterator first, InputIterator last)
|
||||||
@ -305,45 +143,14 @@ public:
|
|||||||
m_Data.insert(p, first, last);
|
m_Data.insert(p, first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator Begin(void)
|
Iterator Begin(void);
|
||||||
{
|
ConstIterator Begin(void) const;
|
||||||
return m_Data.begin();
|
Iterator End(void);
|
||||||
}
|
ConstIterator End(void) const;
|
||||||
|
ReverseIterator RBegin(void);
|
||||||
ConstIterator Begin(void) const
|
ConstReverseIterator RBegin(void) const;
|
||||||
{
|
ReverseIterator REnd(void);
|
||||||
return m_Data.begin();
|
ConstReverseIterator REnd(void) const;
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const SizeType NPos;
|
static const SizeType NPos;
|
||||||
|
|
||||||
@ -353,161 +160,49 @@ private:
|
|||||||
std::string m_Data;
|
std::string m_Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& stream, const String& str)
|
std::ostream& operator<<(std::ostream& stream, const String& str);
|
||||||
{
|
std::istream& operator>>(std::istream& stream, String& str);
|
||||||
stream << str.GetData();
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::istream& operator>>(std::istream& stream, String& str)
|
String operator+(const String& lhs, const String& rhs);
|
||||||
{
|
String operator+(const String& lhs, const char *rhs);
|
||||||
std::string tstr;
|
String operator+(const char *lhs, const String& rhs);
|
||||||
stream >> tstr;
|
|
||||||
str = tstr;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline String operator+(const String& lhs, const String& rhs)
|
bool operator==(const String& lhs, const String& rhs);
|
||||||
{
|
bool operator==(const String& lhs, const char *rhs);
|
||||||
return lhs.GetData() + rhs.GetData();
|
bool operator==(const char *lhs, const String& rhs);
|
||||||
}
|
|
||||||
|
|
||||||
inline String operator+(const String& lhs, const char *rhs)
|
bool operator<(const String& lhs, const char *rhs);
|
||||||
{
|
bool operator<(const char *lhs, const String& rhs);
|
||||||
return lhs.GetData() + rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline String operator+(const char *lhs, const String& rhs)
|
bool operator>(const String& lhs, const String& rhs);
|
||||||
{
|
bool operator>(const String& lhs, const char *rhs);
|
||||||
return lhs + rhs.GetData();
|
bool operator>(const char *lhs, const String& rhs);
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const String& lhs, const String& rhs)
|
bool operator<=(const String& lhs, const String& rhs);
|
||||||
{
|
bool operator<=(const String& lhs, const char *rhs);
|
||||||
return lhs.GetData() == rhs.GetData();
|
bool operator<=(const char *lhs, const String& rhs);
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const String& lhs, const char *rhs)
|
bool operator>=(const String& lhs, const String& rhs);
|
||||||
{
|
bool operator>=(const String& lhs, const char *rhs);
|
||||||
return lhs.GetData() == rhs;
|
bool operator>=(const char *lhs, const String& rhs);
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const char *lhs, const String& rhs)
|
bool operator!=(const String& lhs, const String& rhs);
|
||||||
{
|
bool operator!=(const String& lhs, const char *rhs);
|
||||||
return lhs == rhs.GetData();
|
bool operator!=(const char *lhs, const String& rhs);
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const String& lhs, const char *rhs)
|
String::Iterator begin(String& x);
|
||||||
{
|
String::ConstIterator begin(const String& x);
|
||||||
return lhs.GetData() < rhs;
|
String::Iterator end(String& x);
|
||||||
}
|
String::ConstIterator end(const String& x);
|
||||||
|
String::Iterator range_begin(String& x);
|
||||||
inline bool operator<(const char *lhs, const String& rhs)
|
String::ConstIterator range_begin(const String& x);
|
||||||
{
|
String::Iterator range_end(String& x);
|
||||||
return lhs < rhs.GetData();
|
String::ConstIterator range_end(const String& x);
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern template class std::vector<icinga::String>;
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -32,6 +32,12 @@ INITIALIZE_ONCE_WITH_PRIORITY([]() {
|
|||||||
Type::Register(type);
|
Type::Register(type);
|
||||||
}, 20);
|
}, 20);
|
||||||
|
|
||||||
|
Type::Type(void)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Type::~Type(void)
|
||||||
|
{ }
|
||||||
|
|
||||||
String Type::ToString(void) const
|
String Type::ToString(void) const
|
||||||
{
|
{
|
||||||
return "type '" + GetName() + "'";
|
return "type '" + GetName() + "'";
|
||||||
|
@ -75,6 +75,9 @@ class Type : public Object
|
|||||||
public:
|
public:
|
||||||
DECLARE_OBJECT(Type);
|
DECLARE_OBJECT(Type);
|
||||||
|
|
||||||
|
Type(void);
|
||||||
|
~Type(void);
|
||||||
|
|
||||||
virtual String ToString(void) const override;
|
virtual String ToString(void) const override;
|
||||||
|
|
||||||
virtual String GetName(void) const = 0;
|
virtual String GetName(void) const = 0;
|
||||||
|
@ -24,8 +24,182 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
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 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
|
bool Value::ToBool(void) const
|
||||||
{
|
{
|
||||||
switch (GetType()) {
|
switch (GetType()) {
|
||||||
@ -111,4 +285,3 @@ Value Value::Clone(void) const
|
|||||||
else
|
else
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,107 +52,40 @@ enum ValueType
|
|||||||
class Value
|
class Value
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Value(void)
|
Value(void);
|
||||||
{ }
|
Value(std::nullptr_t);
|
||||||
|
Value(int value);
|
||||||
Value(std::nullptr_t)
|
Value(unsigned int value);
|
||||||
{ }
|
Value(long value);
|
||||||
|
Value(unsigned long value);
|
||||||
Value(int value)
|
Value(long long value);
|
||||||
: m_Value(double(value))
|
Value(unsigned long long value);
|
||||||
{ }
|
Value(double value);
|
||||||
|
Value(bool value);
|
||||||
Value(unsigned int value)
|
Value(const String& value);
|
||||||
: m_Value(double(value))
|
Value(String&& value);
|
||||||
{ }
|
Value(const char *value);
|
||||||
|
Value(const Value& other);
|
||||||
Value(long value)
|
Value(Value&& other);
|
||||||
: m_Value(double(value))
|
Value(Object *value);
|
||||||
{ }
|
Value(const intrusive_ptr<Object>& 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Value(const intrusive_ptr<T>& value)
|
Value(const intrusive_ptr<T>& value)
|
||||||
|
: Value(static_pointer_cast<Object>(value))
|
||||||
{
|
{
|
||||||
if (!value)
|
static_assert(!std::is_same<T, Object>::value, "T must not be Object");
|
||||||
return;
|
|
||||||
|
|
||||||
m_Value = static_pointer_cast<Object>(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Value(void);
|
||||||
|
|
||||||
bool ToBool(void) const;
|
bool ToBool(void) const;
|
||||||
|
|
||||||
operator double(void) const;
|
operator double(void) const;
|
||||||
operator String(void) const;
|
operator String(void) const;
|
||||||
|
|
||||||
Value& operator=(const Value& other)
|
Value& operator=(const Value& other);
|
||||||
{
|
Value& operator=(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(bool rhs) const;
|
bool operator==(bool rhs) const;
|
||||||
bool operator!=(bool rhs) const;
|
bool operator!=(bool rhs) const;
|
||||||
@ -181,7 +114,7 @@ public:
|
|||||||
if (!IsObject())
|
if (!IsObject())
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error("Cannot convert value of type '" + GetTypeName() + "' to an object."));
|
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);
|
ASSERT(object);
|
||||||
|
|
||||||
@ -193,65 +126,12 @@ public:
|
|||||||
return tobject;
|
return tobject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bool IsEmpty(void) const;
|
||||||
* Checks whether the variant is empty.
|
bool IsScalar(void) const;
|
||||||
*
|
bool IsNumber(void) const;
|
||||||
* @returns true if the variant is empty, false otherwise.
|
bool IsBoolean(void) const;
|
||||||
*/
|
bool IsString(void) const;
|
||||||
bool IsEmpty(void) const
|
bool IsObject(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool IsObjectType(void) const
|
bool IsObjectType(void) const
|
||||||
@ -259,23 +139,12 @@ public:
|
|||||||
if (!IsObject())
|
if (!IsObject())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return dynamic_cast<T *>(boost::get<Object::Ptr>(m_Value).get());
|
return dynamic_cast<T *>(Get<Object::Ptr>().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
ValueType GetType(void) const;
|
||||||
* Returns the type of the value.
|
|
||||||
*
|
|
||||||
* @returns The type.
|
|
||||||
*/
|
|
||||||
ValueType GetType(void) const
|
|
||||||
{
|
|
||||||
return static_cast<ValueType>(m_Value.which());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Swap(Value& other)
|
void Swap(Value& other);
|
||||||
{
|
|
||||||
m_Value.swap(other.m_Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
String GetTypeName(void) const;
|
String GetTypeName(void) const;
|
||||||
|
|
||||||
@ -293,6 +162,11 @@ private:
|
|||||||
boost::variant<boost::blank, double, bool, String, Object::Ptr> m_Value;
|
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;
|
extern Value Empty;
|
||||||
|
|
||||||
Value operator+(const Value& lhs, const char *rhs);
|
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 */
|
#endif /* VALUE_H */
|
||||||
|
@ -219,7 +219,14 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
|||||||
m_Header << std::endl
|
m_Header << std::endl
|
||||||
<< "{" << std::endl
|
<< "{" << std::endl
|
||||||
<< "public:" << 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 */
|
/* GetName */
|
||||||
m_Header << "\t" << "virtual String GetName(void) const;" << std::endl;
|
m_Header << "\t" << "virtual String GetName(void) const;" << std::endl;
|
||||||
@ -541,7 +548,6 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
|||||||
m_Impl << "}" << std::endl << std::endl;
|
m_Impl << "}" << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!klass.Fields.empty()) {
|
|
||||||
/* constructor */
|
/* constructor */
|
||||||
m_Header << "public:" << std::endl
|
m_Header << "public:" << std::endl
|
||||||
<< "\t" << "ObjectImpl<" << klass.Name << ">(void);" << std::endl;
|
<< "\t" << "ObjectImpl<" << klass.Name << ">(void);" << std::endl;
|
||||||
@ -562,6 +568,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
|||||||
m_Impl << "ObjectImpl<" << klass.Name << ">::~ObjectImpl(void)" << std::endl
|
m_Impl << "ObjectImpl<" << klass.Name << ">::~ObjectImpl(void)" << std::endl
|
||||||
<< "{ }" << std::endl << std::endl;
|
<< "{ }" << std::endl << std::endl;
|
||||||
|
|
||||||
|
if (!klass.Fields.empty()) {
|
||||||
/* SetField */
|
/* SetField */
|
||||||
m_Header << "public:" << std::endl
|
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;
|
<< "\t" << "virtual void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty) override;" << std::endl;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user