summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-21 23:46:14 +0100
committerAndreas Stöckel <andreas@somweyr.de>2014-12-21 23:46:14 +0100
commit9c02d6698f852d94736ce3a88e593bf45d22361d (patch)
treea6c8fbe7e65278fc958d05ded8a6d2c9edf63426
parent1a7c77c9175c4e9ed5c554b1986d4f2bf8b18197 (diff)
allowing to store Function objects in Variants, added simple unit test for the Method class
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/core/common/Function.hpp24
-rw-r--r--src/core/common/Variant.cpp14
-rw-r--r--src/core/common/Variant.hpp46
-rw-r--r--test/core/common/FunctionTest.cpp44
-rw-r--r--test/core/managed/VariantObjectTest.cpp6
6 files changed, 71 insertions, 64 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3575d7a..628bcfc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -184,6 +184,7 @@ IF(TEST)
test/core/ResourceLocatorTest
test/core/TokenizerTest
test/core/common/CharReaderTest
+ test/core/common/FunctionTest
test/core/common/LoggerTest
test/core/common/RttiTest
test/core/common/VariantReaderTest
diff --git a/src/core/common/Function.hpp b/src/core/common/Function.hpp
index 8113c9d..04030c8 100644
--- a/src/core/common/Function.hpp
+++ b/src/core/common/Function.hpp
@@ -36,15 +36,18 @@ namespace ousia {
/**
* The Function interface defines all the methods needed to represent a
- * generic function. Function objects can be called using the "call" function in
+ * generic function. Function objects can be called using the "call" function in
* which an array of Variant is supplied to the function and a Variant is
* returned to the caller.
*/
class Function {
+protected:
+ Function() {};
+
public:
- Function(const Function&) = delete;
- Function(Function&&) = delete;
- virtual ~Function() {};
+ Function(const Function &) = delete;
+ Function(Function &&) = delete;
+ virtual ~Function(){};
/**
* Abstract function which is meant to call the underlying function (be it
@@ -90,29 +93,22 @@ public:
*
* @param method is a pointer at the C++ function that should be called.
*/
- Method(Callback method) : method(method){};
+ Method(Callback method) : method(method) {};
/**
* Calls the underlying method.
*
- * @param args is a vector containing all arguments that shouild be passed
+ * @param args is a vector containing all arguments that should be passed
* to the method.
* @return a Variant containing the return value.
*/
Variant call(const Variant::arrayType &args = Variant::arrayType{},
void *thisRef = nullptr) const override
{
- // Dynamically cast thisRef to the given type
- T *tRef = dynamic_cast<T>(thisRef);
-
- // Make sure the cast is successfull
- assert(tRef != nullptr);
-
// Call the method
- return method(args, tRef);
+ return method(args, static_cast<T*>(thisRef));
}
};
-
}
#endif /* _OUSIA_FUNCTION_HPP_ */
diff --git a/src/core/common/Variant.cpp b/src/core/common/Variant.cpp
index 8036bcd..0e69038 100644
--- a/src/core/common/Variant.cpp
+++ b/src/core/common/Variant.cpp
@@ -21,7 +21,6 @@
#include <core/managed/Managed.hpp>
#include "Utils.hpp"
-#include "Function.hpp"
#include "Variant.hpp"
namespace ousia {
@@ -40,19 +39,6 @@ Variant::TypeException::TypeException(Type actualType, Type requestedType)
/* Class Variant */
-void Variant::copyObject(objectType o)
-{
- Managed *managed = static_cast<objectType>(o);
- managed->getManager().addRef(o, nullptr);
- ptrVal = managed;
-}
-
-void Variant::destroyObject()
-{
- Managed *managed = static_cast<objectType>(ptrVal);
- managed->getManager().deleteRef(managed, nullptr);
-}
-
const char *Variant::getTypeName(Type type)
{
switch (type) {
diff --git a/src/core/common/Variant.hpp b/src/core/common/Variant.hpp
index 52db864..fe0bbb1 100644
--- a/src/core/common/Variant.hpp
+++ b/src/core/common/Variant.hpp
@@ -40,13 +40,12 @@
// http://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-representations.html
// later (will allow to use 8 bytes for a variant)
+#include <core/managed/Managed.hpp>
+
#include "Exceptions.hpp"
namespace ousia {
-/* Forward declaration of the Managed class */
-class Managed;
-
/* Forward declaration of the Function class */
class Function;
@@ -109,7 +108,7 @@ public:
using stringType = std::string;
using arrayType = std::vector<Variant>;
using mapType = std::map<std::string, Variant>;
- using objectType = Managed *;
+ using objectType = Rooted<Managed>;
using functionType = std::shared_ptr<Function>;
private:
@@ -157,21 +156,6 @@ private:
}
/**
- * Function used to copy a reference to a managed object (not defined in the
- * header to prevent an explicit reference to the Managed type).
- *
- * @param o is the pointer at the object that should be copied.
- */
- void copyObject(objectType o);
-
- /**
- * Function used internally to destroy a reference to a managed object (not
- * defined in the header to prevent an explicit reference to the Managed
- * type).
- */
- void destroyObject();
-
- /**
* Used internally to assign the value of another Variant instance to this
* instance.
*
@@ -203,7 +187,7 @@ private:
ptrVal = new mapType(v.asMap());
break;
case Type::OBJECT:
- copyObject(v.asObject());
+ ptrVal = new objectType(v.asObject());
break;
case Type::FUNCTION:
ptrVal = new functionType(v.asFunction());
@@ -262,7 +246,7 @@ private:
delete static_cast<mapType *>(ptrVal);
break;
case Type::OBJECT:
- destroyObject();
+ delete static_cast<objectType *>(ptrVal);
break;
case Type::FUNCTION:
delete static_cast<functionType *>(ptrVal);
@@ -358,7 +342,8 @@ public:
*
* @param o is a reference to the object.
*/
- Variant(objectType o) : ptrVal(nullptr) { setObject(o); }
+ template <class T>
+ Variant(Handle<T> o) : ptrVal(nullptr) { setObject(o); }
/**
* Copy assignment operator.
@@ -611,10 +596,7 @@ public:
*/
objectType asObject()
{
- if (isObject()) {
- return static_cast<objectType>(ptrVal);
- }
- throw TypeException(getType(), Type::OBJECT);
+ return asObj<objectType>(Type::OBJECT);
}
/**
@@ -626,10 +608,7 @@ public:
*/
const objectType asObject() const
{
- if (isObject()) {
- return static_cast<objectType>(ptrVal);
- }
- throw TypeException(getType(), Type::OBJECT);
+ return asObj<objectType>(Type::OBJECT);
}
/**
@@ -789,11 +768,12 @@ public:
* Sets the variant to the given managed object. The variant is equivalent
* to a Rooted handle.
*/
- void setObject(objectType o)
+ template<class T>
+ void setObject(Handle<T> o)
{
destroy();
type = Type::OBJECT;
- copyObject(o);
+ ptrVal = new objectType(o);
}
/**
@@ -866,7 +846,7 @@ public:
case Type::MAP:
return lhs.asMap() < rhs.asMap();
case Type::OBJECT:
- return lhs.asObject() < rhs.asObject();
+ return lhs.asObject().get() < rhs.asObject().get();
case Type::FUNCTION:
return lhs.asFunction() < rhs.asFunction();
}
diff --git a/test/core/common/FunctionTest.cpp b/test/core/common/FunctionTest.cpp
new file mode 100644
index 0000000..7225f9c
--- /dev/null
+++ b/test/core/common/FunctionTest.cpp
@@ -0,0 +1,44 @@
+/*
+ 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 <gtest/gtest.h>
+
+#include <core/common/Function.hpp>
+
+namespace ousia {
+
+class MethodTestClass {
+public:
+ bool visited = false;
+
+ void visit() { visited = true; }
+};
+
+TEST(Method, simpleTest)
+{
+ Method<MethodTestClass> m{
+ [](const Variant::arrayType &args, MethodTestClass *thisRef) {
+ thisRef->visit();
+ return Variant{};
+ }};
+
+ MethodTestClass inst;
+ m.call({}, &inst);
+}
+}
+
diff --git a/test/core/managed/VariantObjectTest.cpp b/test/core/managed/VariantObjectTest.cpp
index 6c8aebc..f590637 100644
--- a/test/core/managed/VariantObjectTest.cpp
+++ b/test/core/managed/VariantObjectTest.cpp
@@ -30,7 +30,7 @@ TEST(Variant, simpleManagedObject)
Manager mgr(1);
bool a = false;
{
- TestManaged *p = new TestManaged{mgr, a};
+ Handle<TestManaged> p{new TestManaged{mgr, a}};
Variant v(p);
ASSERT_TRUE(v.isObject());
ASSERT_EQ(p, v.asObject());
@@ -44,7 +44,7 @@ TEST(Variant, managedObjectCopy)
Manager mgr(1);
bool a = false;
{
- TestManaged *p = new TestManaged{mgr, a};
+ Handle<TestManaged> p{new TestManaged{mgr, a}};
Variant v1(p);
{
Variant v2 = v1;
@@ -62,7 +62,7 @@ TEST(Variant, managedObjectMove)
Manager mgr(1);
bool a = false;
{
- TestManaged *p = new TestManaged{mgr, a};
+ Handle<TestManaged> p{new TestManaged{mgr, a}};
Variant v1(p);
{
Variant v2 = std::move(v1);