Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding a stringset

  • Loading branch information...
commit 3d99c47076498c60dbb265727dc81af85cca7975 1 parent bafa76d
@tenderlove authored
View
4 Manifest.txt
@@ -8,6 +8,10 @@ ext/stree/stree.c
ext/stree/stree.h
ext/stree/stree_string.c
ext/stree/stree_string.h
+ext/stree/stree_stringset.c
+ext/stree/stree_stringset.h
lib/stree.rb
+lib/stree/string_set.rb
test/test_stree.rb
test/test_string.rb
+test/test_string_set.rb
View
1  ext/stree/stree.c
@@ -6,4 +6,5 @@ void Init_stree()
{
cStree = rb_define_class("Stree", rb_cObject);
Init_stree_string();
+ Init_stree_stringset();
}
View
1  ext/stree/stree.h
@@ -3,6 +3,7 @@
#include <ruby.h>
#include <stree_string.h>
+#include <stree_stringset.h>
#include <stree/lst_string.h>
View
2  ext/stree/stree_string.h
@@ -5,4 +5,6 @@
void Init_stree_string();
+extern VALUE cStreeString;
+
#endif
View
74 ext/stree/stree_stringset.c
@@ -0,0 +1,74 @@
+#include <stree_stringset.h>
+
+VALUE cStreeStringSet;
+
+static void dealloc(void *ptr)
+{
+ LST_StringSet *set = (LST_StringSet *)ptr;
+
+ free(set);
+}
+
+static VALUE allocate(VALUE klass)
+{
+ LST_StringSet * ss = lst_stringset_new();
+ return Data_Wrap_Struct(klass, NULL, dealloc, ss);
+}
+
+static VALUE push(VALUE self, VALUE sstring)
+{
+ if(cStreeString != rb_obj_class(sstring))
+ rb_raise(rb_eArgError, "must be of type Stree::String");
+
+ VALUE weakrefs = rb_iv_get(self, "@weak_refs");
+
+ LST_String * sstring_p;
+ LST_StringSet * ss;
+
+ Data_Get_Struct(sstring, LST_String, sstring_p);
+ Data_Get_Struct(self, LST_StringSet, ss);
+
+ VALUE key = INT2NUM((int)sstring_p);
+ rb_hash_aset(weakrefs, key, sstring);
+
+ lst_stringset_add(ss, sstring_p);
+
+ return self;
+}
+
+static VALUE length(VALUE self)
+{
+ LST_StringSet * ss;
+
+ Data_Get_Struct(self, LST_StringSet, ss);
+ return INT2NUM(ss->size);
+}
+
+static VALUE delete(VALUE self, VALUE obj)
+{
+ if(cStreeString != rb_obj_class(obj))
+ rb_raise(rb_eArgError, "must be of type Stree::String");
+
+ LST_String * sstring_p;
+ LST_StringSet * ss;
+
+ Data_Get_Struct(obj, LST_String, sstring_p);
+ Data_Get_Struct(self, LST_StringSet, ss);
+
+ int before = ss->size;
+ lst_stringset_remove(ss, sstring_p);
+
+ if(ss->size != before) return obj;
+ return Qnil;
+}
+
+void Init_stree_stringset()
+{
+ cStreeStringSet = rb_define_class_under(cStree, "StringSet", rb_cObject);
+ rb_define_alloc_func(cStreeStringSet, allocate);
+
+ rb_define_method(cStreeStringSet, "push", push, 1);
+ rb_define_method(cStreeStringSet, "length", length, 0);
+ rb_define_method(cStreeStringSet, "push", push, 1);
+ rb_define_method(cStreeStringSet, "delete", delete, 1);
+}
View
8 ext/stree/stree_stringset.h
@@ -0,0 +1,8 @@
+#ifndef RUBY_STREE_STRINGSET
+#define RUBY_STREE_STRINGSET
+
+#include <stree.h>
+
+void Init_stree_stringset();
+
+#endif
View
1  lib/stree.rb
@@ -1,4 +1,5 @@
require 'stree/stree'
+require 'stree/string_set'
class Stree
VERSION = '1.0.0'
View
9 lib/stree/string_set.rb
@@ -0,0 +1,9 @@
+class Stree
+ class StringSet
+ def initialize
+ @weak_refs = {}
+ end
+
+ alias :<< :push
+ end
+end
View
40 test/test_string_set.rb
@@ -0,0 +1,40 @@
+require "test/unit"
+require "stree"
+
+class Stree
+ class TestStringSet < Test::Unit::TestCase
+ def setup
+ @ss = Stree::StringSet.new
+ end
+
+ def test_push_arg_error
+ assert_raises(ArgumentError) do
+ @ss << Object.new
+ end
+ end
+
+ def test_push
+ @ss << Stree::String.new('foo')
+ assert_equal 1, @ss.length
+ end
+
+ def test_delete
+ foo = Stree::String.new('foo')
+ @ss << foo
+
+ assert_equal 1, @ss.length
+ assert_equal foo, @ss.delete(foo)
+ end
+
+ def test_delete_not_there
+ foo = Stree::String.new('foo')
+ assert_nil @ss.delete(foo)
+ end
+
+ def test_delete_arg_error
+ assert_raises(ArgumentError) do
+ @ss.delete Object.new
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.