[macruby-changes] [723] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Nov 10 07:04:25 PST 2008


Revision: 723
          http://trac.macosforge.org/projects/ruby/changeset/723
Author:   ben at tanjero.com
Date:     2008-11-10 07:04:25 -0800 (Mon, 10 Nov 2008)
Log Message:
-----------
Added more support for Set on the native side. Tests still don't pass, but it's an improvement.

Modified Paths:
--------------
    MacRuby/trunk/lib/set.rb
    MacRuby/trunk/set.c

Modified: MacRuby/trunk/lib/set.rb
===================================================================
--- MacRuby/trunk/lib/set.rb	2008-11-10 15:04:22 UTC (rev 722)
+++ MacRuby/trunk/lib/set.rb	2008-11-10 15:04:25 UTC (rev 723)
@@ -55,15 +55,15 @@
   include Enumerable
 
   # Creates a new set containing the given objects.
-  def self.[](*ary)
-    new(ary)
-  end
-
-  # Creates a new set containing the elements of the given enumerable
-  # object.
-  #
-  # If a block is given, the elements of enum are preprocessed by the
-  # given block.
+#  def self.[](*ary)
+#    new(ary)
+#  end
+#
+#  # Creates a new set containing the elements of the given enumerable
+#  # object.
+#  #
+#  # If a block is given, the elements of enum are preprocessed by the
+#  # given block.
 #  def initialize(enum = nil, &block) # :yields: o
 #    @hash ||= Hash.new
 #
@@ -75,17 +75,12 @@
 #      merge(enum)
 #    end
 #  end
-
-  # Copy internal hash.
+#
+#  # Copy internal hash.
 #  def initialize_copy(orig)
-#    @hash = orig.instance_eval{@hash}.dup
+#    replace(orig)
 #  end
 
-  # Returns true if the set contains no elements.
-  def empty?
-    size == 0
-  end
-
   # Replaces the contents of the set with the contents of the given
   # enumerable object and returns self.
   def replace(enum)
@@ -159,21 +154,13 @@
   end
 
 #  # Do collect() destructively.
-#  def collect!
-#    set = self.class.new
-#    each { |o| set << yield(o) }
-#    replace(set)
-#  end
-#  alias map! collect!
+  def collect!
+    set = self.class.new
+    each { |o| set << yield(o) }
+    replace(set)
+  end
+  alias map! collect!
 
-#  # Equivalent to Set#delete_if, but returns nil if no changes were
-#  # made.
-#  def reject!
-#    n = size
-#    delete_if { |o| yield(o) }
-#    size == n ? nil : self
-#  end
-
   # Returns a new set containing elements exclusive between the set
   # and the given enumerable object.  (set ^ enum) is equivalent to
   # ((set | enum) - (set & enum)).
@@ -291,95 +278,17 @@
 end
 
 # SortedSet implements a set which elements are sorted in order.  See Set.
-#class SortedSet < Set
-#  @@setup = false
-#
-#  class << self
-#    def [](*ary)	# :nodoc:
-#      new(ary)
-#    end
-#
-#    def setup	# :nodoc:
-#      @@setup and return
-#
-#      module_eval {
-#        # a hack to shut up warning
-#        alias old_init initialize
-#        remove_method :old_init
-#      }
-#      begin
-#	require 'rbtree'
-#
-#	module_eval %{
-#	  def initialize(*args, &block)
-#	    @hash = RBTree.new
-#	    super
-#	  end
-#	}
-#      rescue LoadError
-#	module_eval %{
-#	  def initialize(*args, &block)
-#	    @keys = nil
-#	    super
-#	  end
-#
-#	  def clear
-#	    @keys = nil
-#	    super
-#	  end
-#
-#	  def replace(enum)
-#	    @keys = nil
-#	    super
-#	  end
-#
-#	  def add(o)
-#	    @keys = nil
-#	    @hash[o] = true
-#	    self
-#	  end
-#	  alias << add
-#
-#	  def delete(o)
-#	    @keys = nil
-#	    @hash.delete(o)
-#	    self
-#	  end
-#
-#	  def delete_if
-#	    n = @hash.size
-#	    @hash.delete_if { |o,| yield(o) }
-#	    @keys = nil if @hash.size != n
-#	    self
-#	  end
-#
-#	  def merge(enum)
-#	    @keys = nil
-#	    super
-#	  end
-#
-#	  def each
-#	    block_given? or return enum_for(__method__)
-#	    to_a.each { |o| yield(o) }
-#	  end
-#
-#	  def to_a
-#	    (@keys = @hash.keys).sort! unless @keys
-#	    @keys
-#	  end
-#	}
-#      end
-#
-#      @@setup = true
-#    end
-#  end
-#
-#  def initialize(*args, &block)	# :nodoc:
-#    SortedSet.setup
-#    initialize(*args, &block)
-#  end
-#end
+class SortedSet < Set
+  def each
+    block_given? or return enum_for(__method__)
+    to_a.each { |o| yield(o) }
+  end
 
+  def to_a
+    super.sort!
+  end
+end
+
 module Enumerable
   # Makes a set from the enumerable object with given arguments.
   # Needs to +require "set"+ to use this method.

Modified: MacRuby/trunk/set.c
===================================================================
--- MacRuby/trunk/set.c	2008-11-10 15:04:22 UTC (rev 722)
+++ MacRuby/trunk/set.c	2008-11-10 15:04:25 UTC (rev 723)
@@ -88,6 +88,12 @@
     return INT2FIX(CFSetGetCount((CFSetRef)set));
 }
 
+static VALUE
+rb_set_empty_q(VALUE set)
+{
+    return CFSetGetCount((CFSetRef)set) == 0 ? Qtrue : Qnil;
+}
+
 static void
 rb_set_intersect_callback(const void *value, void *context)
 {
@@ -211,8 +217,12 @@
 static void
 rb_set_delete_if_callback(const void *value, void *context)
 {
-    if (rb_yield(OC2RB(value)) == Qtrue)
-	rb_set_delete((VALUE)context, (VALUE)value);
+    VALUE set = ((VALUE *)context)[0];
+    VALUE *acted = ((VALUE **)context)[1];
+    if (rb_yield(OC2RB(value)) == Qtrue) {
+	*acted = Qtrue;
+	rb_set_delete(set, (VALUE)value);
+    }
 }
 
 static VALUE
@@ -221,11 +231,26 @@
     rb_set_modify_check(set);
 
     VALUE new_set = rb_set_dup(set);
-    CFSetApplyFunction((CFMutableSetRef)new_set, rb_set_delete_if_callback, (void *)set);
+    VALUE acted = Qfalse;
+    VALUE context[2] = { set, (VALUE)&acted };
+    CFSetApplyFunction((CFMutableSetRef)new_set, rb_set_delete_if_callback, (void *)context);
 
     return set;
 }
 
+static VALUE
+rb_set_reject_bang(VALUE set)
+{
+    rb_set_modify_check(set);
+
+    VALUE new_set = rb_set_dup(set);
+    VALUE acted = Qfalse;
+    VALUE context[2] = { set, (VALUE)&acted };
+    CFSetApplyFunction((CFMutableSetRef)new_set, rb_set_delete_if_callback, (void *)context);
+
+    return acted == Qtrue ? set : Qnil ;
+}
+
 static void
 rb_set_each_callback(const void *value, void *context)
 {
@@ -285,6 +310,7 @@
     rb_define_method(rb_cSet, "to_a", rb_set_to_a, 0);
     rb_define_method(rb_cSet, "==", rb_set_equal, 1);
     rb_define_method(rb_cSet, "size", rb_set_size, 0);
+    rb_define_method(rb_cSet, "empty?", rb_set_empty_q, 0);
     rb_define_alias(rb_cSet, "length", "size");
     rb_define_method(rb_cSet, "&", rb_set_intersect, 1);
     rb_define_alias(rb_cSet, "intersect", "&");
@@ -300,6 +326,7 @@
     rb_define_method(rb_cSet, "delete", rb_set_delete, 1);
     rb_define_method(rb_cSet, "delete?", rb_set_delete2, 1);
     rb_define_method(rb_cSet, "delete_if", rb_set_delete_if, 0);
+    rb_define_method(rb_cSet, "reject!", rb_set_reject_bang, 0);
     rb_define_method(rb_cSet, "each", rb_set_each, 0);
     rb_define_method(rb_cSet, "include?", rb_set_include, 1);
     rb_define_alias(rb_cSet, "member?", "include?");
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20081110/614335f7/attachment.html>


More information about the macruby-changes mailing list