summaryrefslogtreecommitdiffstats
path: root/lib/base/value.hpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/base/value.hpp251
1 files changed, 251 insertions, 0 deletions
diff --git a/lib/base/value.hpp b/lib/base/value.hpp
new file mode 100644
index 0000000..86a3b11
--- /dev/null
+++ b/lib/base/value.hpp
@@ -0,0 +1,251 @@
+/* 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);
+ }
+
+private:
+ boost::variant<boost::blank, double, bool, String, Object::Ptr> m_Value;
+};
+
+extern template const double& Value::Get<double>() const;
+extern template const bool& Value::Get<bool>() const;
+extern template const String& Value::Get<String>() const;
+extern template const Object::Ptr& Value::Get<Object::Ptr>() const;
+
+extern 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 */