Commits

Leonard Ritter committed 25ce731

datenwerk++: object/array tests

  • Participants
  • Parent commits c366fa9

Comments (0)

Files changed (12)

File include/datenwerkpp/array.hpp

 public:
 	enum { class_type = item_type_array };
 
+	Array(const Item &item);
+
 	/** Create a new empty Array item.
 	 *
 	 * Returns a new item of type #dwk_item_type_array. The array will have a
 	 * 0..array count.
 	 * @return The item associated with the \p index.
 	 */
-	Item get(Item item, int index);
+	Item get(int index);
+	Item operator[](int index);
 
 	/** Erase an item from an array by index.
 	 *

File include/datenwerkpp/datenwerkpp.hpp

 #include "item_context.hpp"
 #include "item_link.hpp"
 #include "item_string.hpp"
-#include "ref.hpp"
 
 namespace dwk {
 

File include/datenwerkpp/item.hpp

 
 namespace dwk {
 
-template<typename T> class Ref;
+struct new_reference {
+	dwk_item_t *handle;
+	new_reference(dwk_item_t *handle) : handle(handle) {}
+};
 
 /** @addtogroup item Item
  * The item interface.
 	 * dereferenced after use.
 	 * @return The resulting copy.
 	 */
-	Ref<Item> copy();
+	Item copy();
 
 	/** Increase the reference count of an item.
 	 *
 
 	Item(const Item &item);
 	Item(dwk_item_t *item);
+	explicit Item(const new_reference &ref);
 	~Item();
 
 	dwk_item_t *c_ptr() const;

File include/datenwerkpp/item_int.hpp

 	 * @param value The value to initialize the new item with.
 	 * @return A new int item. Caller takes ownership.
 	 */
-	static Ref<Int> create(int value);
+	Int(int value);
 
 	/** Get the value of an int.
 	 *

File include/datenwerkpp/object.hpp

 
 	Object(const Item &item);
 
+	/** Create a new empty Object item.
+	 *
+	 * Returns a new item of type #dwk_item_type_object. The object will have a
+	 * reference count of 1 and must be dereferenced after use.
+	 * @return A new object item. Caller takes ownership.
+	 */
+	Object();
+
 	/** Add a child item to an object.
 	 *
 	 * The \p item will take ownership of \p element by not increasing the
 	 * @return The changed signal.
 	 */
 	Signal get_signal_changed();
-
-	/** Create a new empty Object item.
-	 *
-	 * Returns a new item of type #dwk_item_type_object. The object will have a
-	 * reference count of 1 and must be dereferenced after use.
-	 * @return A new object item. Caller takes ownership.
-	 */
-	static Ref<Object> create();
 };
 
 /** Event structure passed to callbacks connected to the signals returned by

File include/datenwerkpp/ref.hpp

-/*
-Copyright (C) 2011 by Leonard Ritter <contact@leonard-ritter.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#ifndef __DATENWERKPP_REF_HPP__
-#define __DATENWERKPP_REF_HPP__
-
-namespace dwk {
-
-template<typename T>
-class Ref {
-public:
-	Ref() : _ref(None)
-	{
-	}
-
-	template<typename U>
-	Ref(const Ref<U> &other) : _ref(other._ref)
-	{
-		if (_ref.c_ptr()) {
-			_ref.incref();
-		}
-	}
-
-	Ref(const Item &item) : _ref(item)
-	{
-		if (_ref.c_ptr()) {
-			_ref.incref();
-		}
-	}
-
-	~Ref()
-	{
-		if (_ref.c_ptr()) {
-			_ref.decref();
-		}
-	}
-
-	template<typename U>
-	Ref<T> &operator =(const Ref<U> &other)
-	{
-		return operator =(other._ref);
-	}
-
-	Ref<T> &operator =(const Item &item)
-	{
-		if (_ref.c_ptr()) {
-			_ref.decref();
-		}
-		_ref = item;
-		if (_ref.c_ptr()) {
-			_ref.incref();
-		}
-		return *this;
-	}
-
-	operator T&()
-	{
-		return _ref;
-	}
-
-	T *operator ->()
-	{
-		return &_ref;
-	}
-
-	T _ref;
-};
-
-} // namespace dwk
-
-#endif // __DATENWERKPP_REF_HPP__

File src/datenwerkpp/array.cpp

+/*
+Copyright (C) 2011 by Leonard Ritter <contact@leonard-ritter.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "shared.hpp"
+
+namespace dwk {
+
+Array::Array(const Item &item)
+	: Item(item)
+{
+	assert(!c_ptr() || ((int)get_type() == Array::class_type));
+}
+
+Array::Array()
+	: Item(new_reference(dwk_array_new()))
+{
+}
+
+unsigned long Array::count()
+{
+	return dwk_array_count(handle);
+}
+
+void Array::insert(Item element, int index)
+{
+	dwk_array_insert(handle, dwk_item_incref(element.c_ptr()), index);
+}
+
+void Array::append(Item element)
+{
+	dwk_array_append(handle, dwk_item_incref(element.c_ptr()));
+}
+
+Item Array::get(int index)
+{
+	return dwk_array_get(handle, index);
+}
+
+Item Array::operator[](int index)
+{
+	return dwk_array_get(handle, index);
+}
+
+void Array::erase(int index)
+{
+	dwk_array_erase(handle, index);
+}
+
+void Array::remove(Item element)
+{
+	dwk_array_remove(handle, element.c_ptr());
+}
+
+void Array::clear()
+{
+	dwk_array_clear(handle);
+}
+
+int Array::index(Item element)
+{
+	return dwk_array_index(handle, element.c_ptr());
+}
+
+Signal Array::get_signal_insert()
+{
+	return dwk_array_get_signal_insert(handle);
+}
+
+Signal Array::get_signal_erase()
+{
+	return dwk_array_get_signal_erase(handle);
+}
+
+Signal Array::get_signal_changed()
+{
+	return dwk_array_get_signal_changed(handle);
+}
+
+} // namespace dwk

File src/datenwerkpp/item.cpp

 	return dwk_item_is_related(this->handle, item.c_ptr());
 }
 
-Ref<Item> Item::copy()
+Item Item::copy()
 {
-	return wrap_new(dwk_item_copy(handle));
+	return Item(new_reference(dwk_item_copy(handle)));
 }
 
 void Item::incref()
 Item::Item(const Item &item)
 	: handle(item.handle)
 {
-
+	if (handle)
+		incref();
 }
 
 Item::Item(dwk_item_t *handle)
 {
 	this->handle = handle;
+	if (this->handle)
+		incref();
+}
+
+Item::Item(const new_reference &ref)
+	: handle(ref.handle)
+{
 }
 
 Item::~Item()
 {
+	if (handle)
+		decref();
 }
 
 dwk_item_t *Item::c_ptr() const
 
 Item &Item::operator =(const Item &item)
 {
-	this->handle = item.c_ptr();
+	if (handle)
+		decref();
+	handle = item.handle;
+	if (handle)
+		incref();
 }
 
 Item::Item()

File src/datenwerkpp/item_int.cpp

 Int::Int(const Item &item)
 	: Item(item)
 {
-	assert(!item.c_ptr() || (item.get_type() == item_type_int));
+	assert(!c_ptr() || ((int)get_type() == Int::class_type));
 }
 
-Ref<Int> Int::create(int value)
+Int::Int(int value)
+	: Item(new_reference(dwk_int_new(value)))
 {
-	return wrap_new(dwk_int_new(value));
 }
 
 int Int::get()

File src/datenwerkpp/object.cpp

 Object::Object(const Item &item)
 	: Item(item)
 {
-	assert(!item.c_ptr() || (item.get_type() == item_type_object));
+	assert(!c_ptr() || ((int)get_type() == Object::class_type));
 }
 
-Ref<Object> Object::create()
+Object::Object()
+	: Item(new_reference(dwk_object_new()))
 {
-	return wrap_new(dwk_object_new());
 }
 
 void Object::set_key(const std::string &key, const Item &element)
 {
-	dwk_object_set_key(handle, key.c_str(), element.c_ptr());
+	dwk_object_set_key(handle, key.c_str(), dwk_item_incref(element.c_ptr()));
 }
 
 bool Object::has_key(const std::string &key)

File src/datenwerkpp/shared.hpp

 
 namespace dwk {
 
-inline Ref<Item> wrap_new(const Item &item)
-{
-	Ref<Item> ref = item;
-	//ref->decref();
-	return ref;
-}
-
 } // namespace dwk

File tests/testpp/test.cpp

 void test_object() {
 	using namespace dwk;
 
-	Ref<Object> object;
-	Ref<Object> object2;
-	Ref<Int> i;
+	Object object = None;
 
     printf("*** test_object\n");
 
-    object = Object::create();
-    print_item_ref(object);
-    object2 = Object::create();
-    print_item_ref(object2);
-    object->set_key("x", object2);
-    print_item_ref(object2);
-    assert(!object2->has_key("ten"));
-    object2->set_key("ten", Int::create(10));
-    assert(object2->has_key("ten"));
-    object2->set_key("ten2", Int::create(20));
-    assert(object2->has_key("ten"));
-    assert(object->has_key("x"));
-    assert(!object->has_key("ten"));
+    object = Object();
+    Object object2;
+    object.set_key("x", object2);
+    assert(!object2.has_key("ten"));
+    object2.set_key("ten", Int(10));
+    assert(object2.has_key("ten"));
+    object2.set_key("ten2", Int(20));
+    assert(object2.has_key("ten"));
+    assert(object.has_key("x"));
+    assert(!object.has_key("ten"));
 
-    object2 = object->get_key("x");
-    i = object2->get_key("ten");
-    assert(i->get() == 10);
-    assert(object2->key(i) == "ten");
+    object2 = object.get_key("x");
+    Int i = object2.get_key("ten");
+    assert(i.get() == 10);
+    assert(object2.key(i) == "ten");
 
-    object2->del_key("ten");
-    assert(!object2->has_key("ten"));
+    object2.del_key("ten");
+    assert(!object2.has_key("ten"));
 
-    assert(object2->has_key("ten2"));
-    object2->del_key("ten2");
-    assert(!object2->has_key("ten2"));
+    assert(object2.has_key("ten2"));
+    object2.del_key("ten2");
+    assert(!object2.has_key("ten2"));
 
     assert(get_item_count());
     object = None;
     assert(get_item_count() == 0);
 }
 
+void test_array() {
+	using namespace dwk;
+
+    int k;
+    int mass_count = 10000;
+
+    printf("*** test array\n");
+
+    Array array;
+    assert(array.count() == 0);
+    array.append(Int(1));
+    assert(array.count() == 1);
+    array.append(Int(2));
+    assert(array.count() == 2);
+    array.insert(Int(3), 0);
+
+    assert(Int(array.get(0)).get() == 3);
+    assert(Int(array.get(1)).get() == 1);
+    assert(Int(array.get(2)).get() == 2);
+
+    Int i = 3;
+
+    array.insert(i, 2);
+    assert(array.count() == 4);
+    assert(Int(array.get(0)).get() == 3);
+    assert(Int(array.get(1)).get() == 1);
+    assert(Int(array.get(2)).get() == 3);
+    assert(Int(array.get(3)).get() == 2);
+
+    assert(array.index(i) == 2);
+    array.remove(i);
+    assert(array.index(i) == -1);
+    assert(array.count() == 3);
+    assert(Int(array.get(0)).get() == 3);
+    assert(Int(array.get(1)).get() == 1);
+    assert(Int(array.get(2)).get() == 2);
+
+    Array array2 = array.copy();
+    array.clear();
+    assert(array.count() == 0);
+    assert(array2.count() == 3);
+    assert(Int(array2[0]).get() == 3);
+    assert(Int(array2[1]).get() == 1);
+    assert(Int(array2[2]).get() == 2);
+
+    // mass insert
+    for (k = 0; k < mass_count; ++k) {
+        array.append(Int(k));
+    }
+    // mass find
+    for (k = mass_count-1; k >=0; k--) {
+        int j = array.index(array.get(k));
+        assert(k == j);
+    }
+    // slow remove - always remove the last element, forcing
+    // an iteration of the entire structure per element
+    while (array.count()) {
+        array.remove(array.get(array.count()-1));
+    }
+
+    array.clear();
+
+    assert(get_item_count());
+    i = None;
+    array = None;
+    array2 = None;
+    assert(get_item_count() == 0);
+}
+
+
 int main(int argc, char **argv) {
     test_object();
+    test_array();
     printf("*** all tests done.\n");
 
     return 0;