summaryrefslogtreecommitdiff
path: root/src/core/script
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-10-24 22:22:26 +0000
committerandreas <andreas@daaaf23c-2e50-4459-9457-1e69db5a47bf>2014-10-24 22:22:26 +0000
commit7e51bf3804e50ea063fcc97b2682a32a8505902f (patch)
tree6a6097216708049b5dd7a4c43020c85aafb046a1 /src/core/script
parent4a9912f516bf096c6f8c6259b3fc6ba4b95b8d69 (diff)
added Function, Property and Object classes; added CMakeLists entries for the mozjs-24 library (the Firefox JavaScript engine which is available as Package on Fedora); added Doxygen target to makefile
git-svn-id: file:///var/local/svn/basicwriter@75 daaaf23c-2e50-4459-9457-1e69db5a47bf
Diffstat (limited to 'src/core/script')
-rw-r--r--src/core/script/Function.hpp243
-rw-r--r--src/core/script/Object.cpp83
-rw-r--r--src/core/script/Object.hpp132
-rw-r--r--src/core/script/Variant.cpp254
-rw-r--r--src/core/script/Variant.hpp229
5 files changed, 669 insertions, 272 deletions
diff --git a/src/core/script/Function.hpp b/src/core/script/Function.hpp
index 4c13dbc..2e92f08 100644
--- a/src/core/script/Function.hpp
+++ b/src/core/script/Function.hpp
@@ -29,12 +29,23 @@ namespace ousia {
namespace script {
/**
- * The abstract Function class is most basic version of a function handle --
- * just a virtual "call" function which calls the underlying code.
+ * The abstract Function class is most basic version of a function handle,
+ * maintaining a "call" function and basic virtual functions for lifecyle
+ * management.
*/
class Function {
-
public:
+ /**
+ * Virtual clone function (e.g. used in the variant class).
+ */
+ virtual Function *clone() const = 0;
+
+ /**
+ * Virtual destructor.
+ */
+ virtual ~Function()
+ {
+ }
/**
* Abstract function which is meant to call the underlying function (be it
@@ -51,26 +62,27 @@ public:
*
* @return a Variant containing the return value.
*/
- Variant call() const { return call({}); }
+ Variant call() const
+ {
+ return call({});
+ }
+ // TODO: Use () operator instead of the call function
};
/**
- * The ArgumentDescriptor class is used to describe the type of a function
+ * The Argument class is used to describe the type of a function
* argument.
*/
-struct ArgumentDescriptor {
-
+struct Argument {
const VariantType type;
const bool hasDefault;
const Variant defaultValue;
- ArgumentDescriptor(VariantType type) :
- type(type), hasDefault(false) {};
-
- ArgumentDescriptor(VariantType type, const Variant &defaultValue) :
- type(type), hasDefault(true), defaultValue(defaultValue) {};
+ Argument(VariantType type) : type(type), hasDefault(false){};
+ Argument(VariantType type, const Variant &defaultValue)
+ : type(type), hasDefault(true), defaultValue(defaultValue){};
};
/**
@@ -78,21 +90,18 @@ struct ArgumentDescriptor {
* validator errors.
*/
class ArgumentValidatorError : public std::exception {
-
public:
-
const int index;
const std::string msg;
- ArgumentValidatorError(int index, const std::string &msg) :
- index(index), msg(msg) {};
+ ArgumentValidatorError(int index, const std::string &msg)
+ : index(index), msg(msg){};
- virtual const char* what() const noexcept override
+ virtual const char *what() const noexcept override
{
return msg.c_str();
}
-
};
/**
@@ -100,12 +109,11 @@ public:
* arguments passed to a function match the description.
*/
class ArgumentValidator {
-
private:
/**
* List containing the argument descriptors.
*/
- const std::vector<ArgumentDescriptor> descriptors;
+ const std::vector<Argument> descriptors;
/**
* Argument index in the input array, at which the last error occured.
@@ -118,20 +126,22 @@ private:
std::string errorMessage;
std::pair<bool, std::vector<Variant>> setError(int idx,
- const std::string &msg, std::vector<Variant> &res);
+ const std::string &msg,
+ std::vector<Variant> &res);
void resetError();
public:
-
/**
* Constructor of the argument validator class.
*
- * @param descriptors is a list of ArgumentDescriptors which should be used
+ * @param descriptors is a list of Arguments which should be used
* for the validation.
*/
- ArgumentValidator(const std::vector<ArgumentDescriptor> &descriptors) :
- descriptors(descriptors) {}
+ ArgumentValidator(const std::vector<Argument> &descriptors)
+ : descriptors(descriptors)
+ {
+ }
/**
* Validates and augments the given argument list (e.g. adds the default
@@ -143,7 +153,8 @@ public:
* list of arguments. If false is returned, use the error function to get
* more information about the error.
*/
- std::pair<bool, std::vector<Variant>> validate(const std::vector<Variant> &args);
+ std::pair<bool, std::vector<Variant>> validate(
+ const std::vector<Variant> &args);
/**
* Returns an ArgumentValidatorError instance containing the argument index
@@ -157,68 +168,174 @@ public:
*/
ArgumentValidatorError error()
{
- return ArgumentValidatorError(errorIndex, errorMessage);
+ return ArgumentValidatorError{errorIndex, errorMessage};
}
-
};
/**
- * The HostFunction class represents a function that resides in the script host.
+ * A validating function
*/
-template<class T>
-class HostFunction : public Function {
-
+class ValidatingFunction : public Function {
private:
- T callback;
ArgumentValidator *validator;
- void *data;
-
-public:
-
- HostFunction(T callback, std::vector<ArgumentDescriptor> signature,
- void *data = nullptr) :
- callback(callback), validator(new ArgumentValidator(signature)),
- data(data) {}
- HostFunction(T callback, void *data = nullptr) :
- callback(callback), validator(nullptr), data(data) {}
-
- ~HostFunction()
- {
- delete validator;
- }
+protected:
+ virtual Variant validatedCall(const std::vector<Variant> &args) const = 0;
virtual Variant call(const std::vector<Variant> &args) const override
{
if (validator) {
- std::pair<bool, std::vector<Variant>> res = validator->validate(args);
+ std::pair<bool, std::vector<Variant>> res =
+ validator->validate(args);
if (!res.first) {
throw validator->error();
}
- return callback(res.second, data);
- } else {
- return callback(args, data);
+ return validatedCall(res.second);
}
+ return validatedCall(args);
}
using Function::call;
+public:
+ ValidatingFunction() : validator(nullptr)
+ {
+ }
+
+ ValidatingFunction(std::vector<Argument> signature)
+ : validator(new ArgumentValidator(signature))
+ {
+ }
+
+ ~ValidatingFunction() override
+ {
+ delete validator;
+ }
};
-template<class T>
-static HostFunction<T> createHostFunction(T callback,
- std::vector<ArgumentDescriptor> signature, void *data = nullptr)
-{
- return HostFunction<T>(callback, signature, data);
-}
+using HostFunctionCallback = Variant (*)(const std::vector<Variant> &args,
+ void *data);
+using GetterCallback = Variant (*)(void *data);
+using SetterCallback = void (*)(Variant arg, void *data);
-template<class T>
-static HostFunction<T> createHostFunction(T callback, void *data = nullptr)
-{
- return HostFunction<T>(callback, data);
-}
+class HostFunction : public ValidatingFunction {
+private:
+ HostFunctionCallback callback;
+ void *data;
+
+protected:
+ virtual Variant validatedCall(
+ const std::vector<Variant> &args) const override
+ {
+ return callback(args, data);
+ }
+
+public:
+ HostFunction(HostFunctionCallback callback, std::vector<Argument> signature,
+ void *data = nullptr)
+ : ValidatingFunction(signature), callback(callback), data(data)
+ {
+ }
+ HostFunction(HostFunctionCallback callback, void *data = nullptr)
+ : ValidatingFunction(), callback(callback), data(data)
+ {
+ }
+
+ Function *clone() const override
+ {
+ return new HostFunction(*this);
+ }
+
+ using ValidatingFunction::call;
+};
+
+class Getter : public ValidatingFunction {
+private:
+ GetterCallback callback;
+ void *data;
+
+protected:
+ virtual Variant validatedCall(
+ const std::vector<Variant> &args) const override
+ {
+ if (!callback) {
+ // TODO: Use another exception class here
+ throw "Getter not defined";
+ }
+ return callback(data);
+ }
+
+public:
+ Getter(GetterCallback callback, void *data = nullptr)
+ : ValidatingFunction(std::vector<Argument>{}),
+ callback(callback),
+ data(data){};
+
+ Function *clone() const override
+ {
+ return new Getter(*this);
+ }
+
+ Variant call() const
+ {
+ return ValidatingFunction::call();
+ }
+
+ Variant operator()() const
+ {
+ return call();
+ }
+ bool exists()
+ {
+ return callback != nullptr;
+ }
+};
+
+class Setter : public ValidatingFunction {
+private:
+ SetterCallback callback;
+ void *data;
+
+protected:
+ virtual Variant validatedCall(
+ const std::vector<Variant> &args) const override
+ {
+ if (!callback) {
+ // TODO: Use another exception class here
+ throw "Setter not defined";
+ }
+ callback(args[0], data);
+ return VarNull;
+ }
+
+public:
+ Setter(VariantType type, SetterCallback callback, void *data = nullptr)
+ : ValidatingFunction({Argument{type}}),
+ callback(callback),
+ data(data){};
+
+ Function *clone() const override
+ {
+ return new Setter(*this);
+ }
+
+ void call(Variant arg) const
+ {
+ ValidatingFunction::call({arg});
+ }
+
+ void operator()(Variant arg) const
+ {
+ return call(arg);
+ }
+
+ bool exists()
+ {
+ return callback != nullptr;
+ }
+};
}
}
diff --git a/src/core/script/Object.cpp b/src/core/script/Object.cpp
new file mode 100644
index 0000000..8d858bc
--- /dev/null
+++ b/src/core/script/Object.cpp
@@ -0,0 +1,83 @@
+/*
+ Ousía
+ Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Object.hpp"
+
+namespace ousia {
+namespace script {
+
+bool Object::hasElement(std::string name) const
+{
+ return (properties.find(name) != properties.end()) ||
+ (methods.find(name) != methods.end());
+}
+
+void Object::addProperty(std::string name, const Property &property)
+{
+ if (hasElement(name)) {
+ // TODO Throw another exception class here
+ throw "Element already exists";
+ }
+ properties.emplace(name, property);
+}
+
+void Object::addProperty(std::string name, const Getter &get, const Setter &set)
+{
+ addProperty(name, Property{get, set});
+}
+
+void Object::addProperty(std::string name, VariantType type,
+ const GetterCallback get, const SetterCallback set)
+{
+ addProperty(name, Property{type, get, set, data});
+}
+
+void Object::addReadonlyProperty(std::string name, const Getter &get)
+{
+ addProperty(name, Property{get, Setter{VariantType::null, nullptr}});
+}
+
+void Object::addReadonlyProperty(std::string name, const GetterCallback get)
+{
+ addProperty(
+ name, Property{Getter{get, data}, Setter{VariantType::null, nullptr}});
+}
+
+void Object::addMethod(std::string name, const HostFunction &fun)
+{
+ if (hasElement(name)) {
+ // TODO Throw another exception class here
+ throw "Element already exists";
+ }
+ methods.emplace(name, fun);
+}
+
+void Object::addMethod(std::string name, const HostFunctionCallback fun)
+{
+ addMethod(name, HostFunction{fun, data});
+}
+
+void Object::addMethod(std::string name, const HostFunctionCallback fun,
+ const std::vector<Argument> &signature)
+{
+ addMethod(name, HostFunction{fun, signature, data});
+}
+
+}
+}
+
diff --git a/src/core/script/Object.hpp b/src/core/script/Object.hpp
new file mode 100644
index 0000000..20e0f0f
--- /dev/null
+++ b/src/core/script/Object.hpp
@@ -0,0 +1,132 @@
+/*
+ Ousía
+ Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _OBJECT_HPP_
+#define _OBJECT_HPP_
+
+#include <string>
+#include <map>
+
+#include "Function.hpp"
+
+namespace ousia {
+namespace script {
+
+/**
+ * The Property struct represents an object property with corresponding getter
+ * and setter function.
+ */
+struct Property {
+ /**
+ * Constructor of the Property struct. Copies the given getter and setter.
+ *
+ * @param get is the getter that should be used for the property.
+ * @param set is the setter that should be used for the property.
+ */
+ Property(const Getter &get, const Setter &set) : get(get), set(set){};
+
+ /**
+ * Constructor of the Property struct. Creates new Getter and Setter
+ * instances from the given parameters.
+ *
+ * @param type is the VariantType used within the getter function.
+ * @param get is the pointer to the getter function.
+ * @param set is the pointer to the setter function.
+ * @param data is the used-defined data that should be used.
+ */
+ Property(VariantType type, const GetterCallback get,
+ const SetterCallback set, void *data = nullptr)
+ : get(get, data), set(type, set, data){};
+
+ /**
+ * Getter function.
+ */
+ const Getter get;
+
+ /**
+ * Setter function.
+ */
+ const Setter set;
+};
+
+/**
+ * The Object type represents an object on the script host. An object consits of
+ * properties with corresponding getter and setter functions and a number of
+ * methods which can be called on the object.
+ */
+class Object {
+private:
+ /**
+ * Pointer to user defined data that is automatically passed to the
+ * underlying functions.
+ */
+ void *data;
+
+ /**
+ * Map used internally for storing all properties along with their
+ * corresponding
+ * name.
+ */
+ std::map<std::string, Property> properties;
+
+ /**
+ * Map used internally for storing all methods along with their
+ * corresponding name.
+ */
+ std::map<std::string, HostFunction> methods;
+
+public:
+ Object() : data(nullptr){};
+
+ Object(void *data) : data(data){};
+
+ bool hasElement(std::string name) const;
+
+ void addProperty(std::string name, const Property &property);
+
+ void addProperty(std::string name, const Getter &get, const Setter &set);
+
+ void addProperty(std::string name, VariantType type,
+ const GetterCallback get, const SetterCallback set);
+
+ void addReadonlyProperty(std::string name, const Getter &get);
+
+ void addReadonlyProperty(std::string name, const GetterCallback get);
+
+ void addMethod(std::string name, const HostFunction &fun);
+
+ void addMethod(std::string name, const HostFunctionCallback fun);
+
+ void addMethod(std::string name, const HostFunctionCallback fun,
+ const std::vector<Argument> &signature);
+
+ const std::map<std::string, Property> &getProperties()
+ {
+ return properties;
+ }
+
+ const std::map<std::string, HostFunction> &getMethods()
+ {
+ return methods;
+ }
+};
+}
+}
+
+#endif /* _OBJECT_HPP_ */
+
diff --git a/src/core/script/Variant.cpp b/src/core/script/Variant.cpp
index 3858b68..75f46ba 100644
--- a/src/core/script/Variant.cpp
+++ b/src/core/script/Variant.cpp
@@ -17,13 +17,242 @@
*/
#include "Variant.hpp"
+#include "Function.hpp"
+#include "Object.hpp"
namespace ousia {
namespace script {
-/* Class VariantTypeException */
+/* Class Variant */
+
+Variant::Variant(const Variant &v) : type(v.type)
+{
+ switch (v.type) {
+ case VariantType::null:
+ break;
+ case VariantType::boolean:
+ booleanValue = v.booleanValue;
+ break;
+ case VariantType::integer:
+ integerValue = v.integerValue;
+ break;
+ case VariantType::number:
+ numberValue = v.numberValue;
+ break;
+ case VariantType::string:
+ objectValue =
+ new std::string(*static_cast<std::string *>(v.objectValue));
+ break;
+ case VariantType::array:
+ objectValue = new std::vector<Variant>(
+ *static_cast<std::vector<Variant> *>(v.objectValue));
+ break;
+ case VariantType::map:
+ objectValue = new std::map<std::string, Variant>(
+ *static_cast<std::map<std::string, Variant> *>(v.objectValue));
+ break;
+ case VariantType::function:
+ objectValue = static_cast<Function *>(v.objectValue)->clone();
+ break;
+ case VariantType::object:
+ objectValue = new Object(*static_cast<Object *>(v.objectValue));
+ break;
+ case VariantType::buffer:
+ // TODO
+ break;
+ }
+}
+
+Variant::Variant(Variant &&v) : type(v.type)
+{
+ switch (type) {
+ case VariantType::null:
+ break;
+ case VariantType::boolean:
+ booleanValue = v.booleanValue;
+ break;
+ case VariantType::integer:
+ integerValue = v.integerValue;
+ break;
+ case VariantType::number:
+ numberValue = v.numberValue;
+ break;
+ case VariantType::string:
+ case VariantType::array:
+ case VariantType::map:
+ case VariantType::function:
+ case VariantType::object:
+ case VariantType::buffer:
+ objectValue = v.objectValue;
+ v.objectValue = nullptr;
+ break;
+ }
+}
+
+Variant::Variant() : type(VariantType::null)
+{
+}
+
+Variant::Variant(bool b) : type(VariantType::boolean), booleanValue(b)
+{
+}
+
+Variant::Variant(int64_t i) : type(VariantType::integer), integerValue(i)
+{
+}
+
+Variant::Variant(double d) : type(VariantType::number), numberValue(d)
+{
+}
+
+Variant::Variant(const char *s)
+ : type(VariantType::string), objectValue(new std::string(s))
+{
+}
+
+Variant::Variant(const std::vector<Variant> &a)
+ : type(VariantType::array), objectValue(new std::vector<Variant>(a))
+{
+}
+
+Variant::Variant(const std::map<std::string, Variant> &m)
+ : type(VariantType::map), objectValue(new std::map<std::string, Variant>(m))
+{
+}
+
+Variant::Variant(const Function *f)
+ : type(VariantType::function), objectValue(f->clone())
+{
+}
+
+Variant::Variant(const Object &o)
+ : type(VariantType::object), objectValue(new Object(o))
+{
+}
+
+Variant::~Variant()
+{
+ switch (type) {
+ case VariantType::string:
+ delete static_cast<std::string *>(objectValue);
+ break;
+ case VariantType::array:
+ delete static_cast<std::vector<Variant> *>(objectValue);
+ break;
+ case VariantType::map:
+ delete static_cast<std::map<std::string, Variant> *>(objectValue);
+ break;
+ case VariantType::function:
+ delete static_cast<Function*>(objectValue);
+ break;
+ case VariantType::object:
+ delete static_cast<Object*>(objectValue);
+ break;
+ default:
+ break;
+ }
+}
-const char* Variant::getTypeName(VariantType type)
+bool Variant::getBooleanValue() const
+{
+ switch (type) {
+ case VariantType::null:
+ return false;
+ case VariantType::boolean:
+ return booleanValue;
+ case VariantType::integer:
+ return integerValue != 0;
+ case VariantType::number:
+ return numberValue != 0.0;
+ case VariantType::string:
+ return !getStringValue().empty();
+ case VariantType::array:
+ return !getArrayValue().empty();
+ case VariantType::map:
+ return !getMapValue().empty();
+ default:
+ throw VariantTypeException{type, VariantType::boolean};
+ }
+}
+
+int64_t Variant::getIntegerValue() const
+{
+ switch (type) {
+ case VariantType::boolean:
+ return booleanValue ? 1 : 0;
+ case VariantType::integer:
+ return integerValue;
+ case VariantType::number:
+ return static_cast<int64_t>(numberValue);
+ default:
+ throw VariantTypeException{type, VariantType::integer};
+ }
+}
+
+double Variant::getNumberValue() const
+{
+ switch (type) {
+ case VariantType::boolean:
+ return booleanValue ? 1.0 : 0.0;
+ case VariantType::integer:
+ return static_cast<double>(integerValue);
+ case VariantType::number:
+ return numberValue;
+ default:
+ throw VariantTypeException{type, VariantType::number};
+ }
+}
+
+const std::string &Variant::getStringValue() const
+{
+ switch (type) {
+ case VariantType::string:
+ return *(static_cast<std::string *>(objectValue));
+ default:
+ throw VariantTypeException{type, VariantType::string};
+ }
+}
+
+const std::vector<Variant> &Variant::getArrayValue() const
+{
+ switch (type) {
+ case VariantType::array:
+ return *(static_cast<std::vector<Variant> *>(objectValue));
+ default:
+ throw VariantTypeException{type, VariantType::array};
+ }
+}
+
+const std::map<std::string, Variant> &Variant::getMapValue() const
+{
+ switch (type) {
+ case VariantType::map:
+ return *(static_cast<std::map<std::string, Variant> *>(
+ objectValue));
+ default:
+ throw VariantTypeException{type, VariantType::map};
+ }
+}
+
+const Function *Variant::getFunctionValue() const
+{
+ switch (type) {
+ case VariantType::function: return static_cast<Function *>(objectValue);
+ default:
+ throw VariantTypeException{type, VariantType::function};
+ }
+}
+
+const Object &Variant::getObjectValue() const
+{
+ switch (type) {
+ case VariantType::object: return *(static_cast<Object *>(objectValue));
+ default:
+ throw VariantTypeException{type, VariantType::function};
+ }
+}
+
+const char *Variant::getTypeName(VariantType type)
{
switch (type) {
case VariantType::null:
@@ -50,22 +279,26 @@ const char* Variant::getTypeName(VariantType type)
return "unknown";
}
+/* Class VariantTypeException */
+
VariantTypeException::VariantTypeException(VariantType actualType,
- VariantType requestedType) :
- msg(std::string("Cannot get value of variant of type \"")
- + Variant::getTypeName(actualType)
- + std::string("\" as \"") + Variant::getTypeName(requestedType)
- + std::string("\"")),
- actualType(actualType), requestedType(requestedType) {}
+ VariantType requestedType)
+ : msg(std::string("Cannot get value of variant of type \"") +
+ Variant::getTypeName(actualType) + std::string("\" as \"") +
+ Variant::getTypeName(requestedType) + std::string("\"")),
+ actualType(actualType),
+ requestedType(requestedType)
+{
+}
-const char* VariantTypeException::what() const noexcept
+const char *VariantTypeException::what() const noexcept
{
return msg.c_str();
}
/* Global scope operator */
-std::ostream& operator<< (std::ostream& os, const Variant &v)
+std::ostream &operator<<(std::ostream &os, const Variant &v)
{
switch (v.type) {
case VariantType::null:
@@ -121,7 +354,6 @@ std::ostream& operator<< (std::ostream& os, const Variant &v)
}
return os;
}
-
}
}
diff --git a/src/core/script/Variant.hpp b/src/core/script/Variant.hpp
index 923c8ca..295c044 100644
--- a/src/core/script/Variant.hpp
+++ b/src/core/script/Variant.hpp
@@ -29,6 +29,10 @@
namespace ousia {
namespace script {
+/* Class forward declarations */
+class Object;
+class Function;
+
/**
* Enum containing the possible types a variant may have.
*/
@@ -50,7 +54,6 @@ enum class VariantType : int16_t {
* is not supported for the current variant type.
*/
class VariantTypeException : public std::exception {
-
private:
/**
* Internally used string holding the exception message.
@@ -82,8 +85,7 @@ public:
*
* @return the error message as C string.
*/
- virtual const char* what() const noexcept override;
-
+ virtual const char *what() const noexcept override;
};
/**
@@ -91,9 +93,7 @@ public:
* between the host application and the script engine. Variants are immutable.
*/
class Variant {
-
private:
-
const VariantType type;
union {
@@ -104,213 +104,46 @@ private:
};
public:
-
- Variant(const Variant &v) :
- type(v.type)
- {
- switch (v.type) {
- case VariantType::null:
- break;
- case VariantType::boolean:
- booleanValue = v.booleanValue;
- break;
- case VariantType::integer:
- integerValue = v.integerValue;
- break;
- case VariantType::number:
- numberValue = v.numberValue;
- break;
- case VariantType::string:
- objectValue = new std::string(
- *static_cast<std::string*>(v.objectValue));
- break;
- case VariantType::array:
- objectValue = new std::vector<Variant>(
- *static_cast<std::vector<Variant>*>(v.objectValue));
- break;
- case VariantType::map:
- objectValue = new std::map<std::string, Variant>(
- *static_cast<std::map<std::string, Variant>*>(v.objectValue));
- break;
- case VariantType::function:
- case VariantType::object:
- case VariantType::buffer:
- // TODO
- break;
- }
- }
-
- Variant(Variant &&v) :
- type(v.type)
- {
- switch (type) {
- case VariantType::null:
- break;
- case VariantType::boolean:
- booleanValue = v.booleanValue;
- break;
- case VariantType::integer:
- integerValue = v.integerValue;
- break;
- case VariantType::number:
- numberValue = v.numberValue;
- break;
- case VariantType::string:
- case VariantType::array:
- case VariantType::map:
- case VariantType::function:
- case VariantType::object:
- case VariantType::buffer:
- objectValue = v.objectValue;
- v.objectValue = nullptr;
- break;
- }
- }
-
- ~Variant()
- {
- switch (type) {
- case VariantType::string:
- delete static_cast<std::string*>(objectValue);
- break;
- case VariantType::array:
- delete static_cast<std::vector<Variant>*>(objectValue);
- break;
- case VariantType::map:
- delete static_cast<std::map<std::string, Variant>*>(objectValue);
- break;
- default:
- break;
- }
- }
-
- Variant& operator=(const Variant &v) = delete;
- Variant& operator=(Variant &&v) = delete;
-
- Variant() :
- type(VariantType::null) {}
-
- Variant(bool b) :
- type(VariantType::boolean),
- booleanValue(b) {}
-
- Variant(int64_t i) :
- type(VariantType::integer),
- integerValue(i) {}
-
- Variant(double d) :
- type(VariantType::number),
- numberValue(d) {}
-
- Variant(const char *s) :
- type(VariantType::string),
- objectValue(new std::string(s)) {}
-
- Variant(const std::vector<Variant> &a) :
- type(VariantType::array),
- objectValue(new std::vector<Variant>(a)) {}
-
- Variant(const std::map<std::string, Variant> &m) :
- type(VariantType::map),
- objectValue(new std::map<std::string, Variant>(m)) {}
+ Variant(const Variant &v);
+ Variant(Variant &&v);
+
+ Variant();
+ Variant(bool b);
+ Variant(int64_t i);
+ Variant(double d);
+ Variant(const char *s);
+ Variant(const std::vector<Variant> &a);
+ Variant(const std::map<std::string, Variant> &m);
+ Variant(const Function *f);
+ Variant(const Object &o);
+ ~Variant();
+
+ Variant &operator=(const Variant &v) = delete;
+ Variant &operator=(Variant &&v) = delete;
VariantType getType() const
{
return type;
}
- bool getBooleanValue() const
- {
- switch (type) {
- case VariantType::null:
- return false;
- case VariantType::boolean:
- return booleanValue;
- case VariantType::integer:
- return integerValue != 0;
- case VariantType::number:
- return numberValue != 0.0;
- case VariantType::string:
- return !getStringValue().empty();
- case VariantType::array:
- return !getArrayValue().empty();
- case VariantType::map:
- return !getMapValue().empty();
- default:
- throw VariantTypeException{type, VariantType::boolean};
- }
- }
-
- int64_t getIntegerValue() const
- {
- switch (type) {
- case VariantType::boolean:
- return booleanValue ? 1 : 0;
- case VariantType::integer:
- return integerValue;
- case VariantType::number:
- return static_cast<int64_t>(numberValue);
- default:
- throw VariantTypeException{type, VariantType::integer};
- }
- }
+ bool getBooleanValue() const;
+ int64_t getIntegerValue() const;
+ double getNumberValue() const;
+ const std::string &getStringValue() const;
+ const std::vector<Variant> &getArrayValue() const;
+ const std::map<std::string, Variant> &getMapValue() const;
+ const Function *getFunctionValue() const;
+ const Object &getObjectValue() const;
- double getNumberValue() const
- {
- switch (type) {
- case VariantType::boolean:
- return booleanValue ? 1.0 : 0.0;
- case VariantType::integer:
- return static_cast<double>(integerValue);
- case VariantType::number:
- return numberValue;
- default:
- throw VariantTypeException{type, VariantType::number};
- }
- }
-
- const std::string& getStringValue() const
- {
- switch (type) {
- case VariantType::string:
- return *(static_cast<std::string*>(objectValue));
- default:
- throw VariantTypeException{type, VariantType::string};
- }
- }
-
- const std::vector<Variant>& getArrayValue() const
- {
- switch (type) {
- case VariantType::array:
- return *(static_cast<std::vector<Variant>*>(objectValue));
- default:
- throw VariantTypeException{type, VariantType::array};
- }
- }
-
- const std::map<std::string, Variant>& getMapValue() const
- {
- switch (type) {
- case VariantType::map:
- return *(static_cast<std::map<std::string, Variant>*>(objectValue));
- default:
- throw VariantTypeException{type, VariantType::map};
- }
- }
-
- static const char* getTypeName(VariantType type);
-
- friend std::ostream& operator<< (std::ostream& os, const Variant &v);
+ static const char *getTypeName(VariantType type);
+ friend std::ostream &operator<<(std::ostream &os, const Variant &v);
};
-
/**
* Shorthand for a constant representing a "null" as a variant.
*/
static const Variant VarNull;
-
}
}