mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-11-03 21:25:56 +01:00 
			
		
		
		
	The move `String(Value&&)` constructor tries to partially move `String` values from a `Value` type. However, since there was no an appropriate `Value::Get<T>()` implementation that binds to the requested move operation, the compiler will actually not move the value but copy it instead as the only available implementation of `Value::Get<T>()` returns a const reference `const T&`. This commit adds a new overload that returns a non-const reference and allows to optionally move the string value of a Value type.
		
			
				
	
	
		
			262 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			262 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
 | 
						|
 | 
						|
#ifndef VALUE_H
 | 
						|
#define VALUE_H
 | 
						|
 | 
						|
#include "base/object.hpp"
 | 
						|
#include "base/string.hpp"
 | 
						|
#include <boost/variant/variant.hpp>
 | 
						|
#include <boost/variant/get.hpp>
 | 
						|
#include <boost/throw_exception.hpp>
 | 
						|
 | 
						|
namespace icinga
 | 
						|
{
 | 
						|
 | 
						|
typedef double Timestamp;
 | 
						|
 | 
						|
/**
 | 
						|
 * The type of a Value.
 | 
						|
 *
 | 
						|
 * @ingroup base
 | 
						|
 */
 | 
						|
enum ValueType
 | 
						|
{
 | 
						|
	ValueEmpty = 0,
 | 
						|
	ValueNumber = 1,
 | 
						|
	ValueBoolean = 2,
 | 
						|
	ValueString = 3,
 | 
						|
	ValueObject = 4
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * A type that can hold an arbitrary value.
 | 
						|
 *
 | 
						|
 * @ingroup base
 | 
						|
 */
 | 
						|
class Value
 | 
						|
{
 | 
						|
public:
 | 
						|
	Value() = default;
 | 
						|
	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))
 | 
						|
	{
 | 
						|
		static_assert(!std::is_same<T, Object>::value, "T must not be Object");
 | 
						|
	}
 | 
						|
 | 
						|
	bool ToBool() const;
 | 
						|
 | 
						|
	operator double() const;
 | 
						|
	operator String() const;
 | 
						|
 | 
						|
	Value& operator=(const Value& other);
 | 
						|
	Value& operator=(Value&& other);
 | 
						|
 | 
						|
	bool operator==(bool rhs) const;
 | 
						|
	bool operator!=(bool rhs) const;
 | 
						|
 | 
						|
	bool operator==(int rhs) const;
 | 
						|
	bool operator!=(int rhs) const;
 | 
						|
 | 
						|
	bool operator==(double rhs) const;
 | 
						|
	bool operator!=(double rhs) const;
 | 
						|
 | 
						|
	bool operator==(const char *rhs) const;
 | 
						|
	bool operator!=(const char *rhs) const;
 | 
						|
 | 
						|
	bool operator==(const String& rhs) const;
 | 
						|
	bool operator!=(const String& rhs) const;
 | 
						|
 | 
						|
	bool operator==(const Value& rhs) const;
 | 
						|
	bool operator!=(const Value& rhs) const;
 | 
						|
 | 
						|
	template<typename T>
 | 
						|
	operator intrusive_ptr<T>() const
 | 
						|
	{
 | 
						|
		if (IsEmpty() && !IsString())
 | 
						|
			return intrusive_ptr<T>();
 | 
						|
 | 
						|
		if (!IsObject())
 | 
						|
			BOOST_THROW_EXCEPTION(std::runtime_error("Cannot convert value of type '" + GetTypeName() + "' to an object."));
 | 
						|
 | 
						|
		const auto& object = Get<Object::Ptr>();
 | 
						|
 | 
						|
		ASSERT(object);
 | 
						|
 | 
						|
		intrusive_ptr<T> tobject = dynamic_pointer_cast<T>(object);
 | 
						|
 | 
						|
		if (!tobject)
 | 
						|
			BOOST_THROW_EXCEPTION(std::bad_cast());
 | 
						|
 | 
						|
		return tobject;
 | 
						|
	}
 | 
						|
 | 
						|
	bool IsEmpty() const;
 | 
						|
	bool IsScalar() const;
 | 
						|
	bool IsNumber() const;
 | 
						|
	bool IsBoolean() const;
 | 
						|
	bool IsString() const;
 | 
						|
	bool IsObject() const;
 | 
						|
 | 
						|
	template<typename T>
 | 
						|
	bool IsObjectType() const
 | 
						|
	{
 | 
						|
		if (!IsObject())
 | 
						|
			return false;
 | 
						|
 | 
						|
		return dynamic_cast<T *>(Get<Object::Ptr>().get());
 | 
						|
	}
 | 
						|
 | 
						|
	ValueType GetType() const;
 | 
						|
 | 
						|
	void Swap(Value& other);
 | 
						|
 | 
						|
	String GetTypeName() const;
 | 
						|
 | 
						|
	Type::Ptr GetReflectionType() const;
 | 
						|
 | 
						|
	Value Clone() const;
 | 
						|
 | 
						|
	template<typename T>
 | 
						|
	const T& Get() const
 | 
						|
	{
 | 
						|
		return boost::get<T>(m_Value);
 | 
						|
	}
 | 
						|
 | 
						|
	template<typename T>
 | 
						|
	T& Get()
 | 
						|
	{
 | 
						|
		return boost::get<T>(m_Value);
 | 
						|
	}
 | 
						|
 | 
						|
private:
 | 
						|
	boost::variant<boost::blank, double, bool, String, Object::Ptr> m_Value;
 | 
						|
};
 | 
						|
 | 
						|
extern template const double& Value::Get<double>() const;
 | 
						|
extern template double& Value::Get<double>();
 | 
						|
extern template const bool& Value::Get<bool>() const;
 | 
						|
extern template bool& Value::Get<bool>();
 | 
						|
extern template const String& Value::Get<String>() const;
 | 
						|
extern template String& Value::Get<String>();
 | 
						|
extern template const Object::Ptr& Value::Get<Object::Ptr>() const;
 | 
						|
extern template Object::Ptr& Value::Get<Object::Ptr>();
 | 
						|
 | 
						|
extern const Value Empty;
 | 
						|
 | 
						|
Value operator+(const Value& lhs, const char *rhs);
 | 
						|
Value operator+(const char *lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator+(const Value& lhs, const String& rhs);
 | 
						|
Value operator+(const String& lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator+(const Value& lhs, const Value& rhs);
 | 
						|
Value operator+(const Value& lhs, double rhs);
 | 
						|
Value operator+(double lhs, const Value& rhs);
 | 
						|
Value operator+(const Value& lhs, int rhs);
 | 
						|
Value operator+(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator-(const Value& lhs, const Value& rhs);
 | 
						|
Value operator-(const Value& lhs, double rhs);
 | 
						|
Value operator-(double lhs, const Value& rhs);
 | 
						|
Value operator-(const Value& lhs, int rhs);
 | 
						|
Value operator-(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator*(const Value& lhs, const Value& rhs);
 | 
						|
Value operator*(const Value& lhs, double rhs);
 | 
						|
Value operator*(double lhs, const Value& rhs);
 | 
						|
Value operator*(const Value& lhs, int rhs);
 | 
						|
Value operator*(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator/(const Value& lhs, const Value& rhs);
 | 
						|
Value operator/(const Value& lhs, double rhs);
 | 
						|
Value operator/(double lhs, const Value& rhs);
 | 
						|
Value operator/(const Value& lhs, int rhs);
 | 
						|
Value operator/(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator%(const Value& lhs, const Value& rhs);
 | 
						|
Value operator%(const Value& lhs, double rhs);
 | 
						|
Value operator%(double lhs, const Value& rhs);
 | 
						|
Value operator%(const Value& lhs, int rhs);
 | 
						|
Value operator%(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator^(const Value& lhs, const Value& rhs);
 | 
						|
Value operator^(const Value& lhs, double rhs);
 | 
						|
Value operator^(double lhs, const Value& rhs);
 | 
						|
Value operator^(const Value& lhs, int rhs);
 | 
						|
Value operator^(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator&(const Value& lhs, const Value& rhs);
 | 
						|
Value operator&(const Value& lhs, double rhs);
 | 
						|
Value operator&(double lhs, const Value& rhs);
 | 
						|
Value operator&(const Value& lhs, int rhs);
 | 
						|
Value operator&(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator|(const Value& lhs, const Value& rhs);
 | 
						|
Value operator|(const Value& lhs, double rhs);
 | 
						|
Value operator|(double lhs, const Value& rhs);
 | 
						|
Value operator|(const Value& lhs, int rhs);
 | 
						|
Value operator|(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator<<(const Value& lhs, const Value& rhs);
 | 
						|
Value operator<<(const Value& lhs, double rhs);
 | 
						|
Value operator<<(double lhs, const Value& rhs);
 | 
						|
Value operator<<(const Value& lhs, int rhs);
 | 
						|
Value operator<<(int lhs, const Value& rhs);
 | 
						|
 | 
						|
Value operator>>(const Value& lhs, const Value& rhs);
 | 
						|
Value operator>>(const Value& lhs, double rhs);
 | 
						|
Value operator>>(double lhs, const Value& rhs);
 | 
						|
Value operator>>(const Value& lhs, int rhs);
 | 
						|
Value operator>>(int lhs, const Value& rhs);
 | 
						|
 | 
						|
bool operator<(const Value& lhs, const Value& rhs);
 | 
						|
bool operator<(const Value& lhs, double rhs);
 | 
						|
bool operator<(double lhs, const Value& rhs);
 | 
						|
bool operator<(const Value& lhs, int rhs);
 | 
						|
bool operator<(int lhs, const Value& rhs);
 | 
						|
 | 
						|
bool operator>(const Value& lhs, const Value& rhs);
 | 
						|
bool operator>(const Value& lhs, double rhs);
 | 
						|
bool operator>(double lhs, const Value& rhs);
 | 
						|
bool operator>(const Value& lhs, int rhs);
 | 
						|
bool operator>(int lhs, const Value& rhs);
 | 
						|
 | 
						|
bool operator<=(const Value& lhs, const Value& rhs);
 | 
						|
bool operator<=(const Value& lhs, double rhs);
 | 
						|
bool operator<=(double lhs, const Value& rhs);
 | 
						|
bool operator<=(const Value& lhs, int rhs);
 | 
						|
bool operator<=(int lhs, const Value& rhs);
 | 
						|
 | 
						|
bool operator>=(const Value& lhs, const Value& rhs);
 | 
						|
bool operator>=(const Value& lhs, double rhs);
 | 
						|
bool operator>=(double lhs, const Value& rhs);
 | 
						|
bool operator>=(const Value& lhs, int rhs);
 | 
						|
bool operator>=(int lhs, const Value& rhs);
 | 
						|
 | 
						|
std::ostream& operator<<(std::ostream& stream, const Value& value);
 | 
						|
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 */
 |