diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2014-12-21 23:46:14 +0100 |
---|---|---|
committer | Andreas Stöckel <andreas@somweyr.de> | 2014-12-21 23:46:14 +0100 |
commit | 9c02d6698f852d94736ce3a88e593bf45d22361d (patch) | |
tree | a6c8fbe7e65278fc958d05ded8a6d2c9edf63426 | |
parent | 1a7c77c9175c4e9ed5c554b1986d4f2bf8b18197 (diff) |
allowing to store Function objects in Variants, added simple unit test for the Method class
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/core/common/Function.hpp | 24 | ||||
-rw-r--r-- | src/core/common/Variant.cpp | 14 | ||||
-rw-r--r-- | src/core/common/Variant.hpp | 46 | ||||
-rw-r--r-- | test/core/common/FunctionTest.cpp | 44 | ||||
-rw-r--r-- | test/core/managed/VariantObjectTest.cpp | 6 |
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); |