[libgee] Fix converting enumerations and flags to arrays



commit 72671f62aaf0c73d3ea4578270f894674f2045e1
Author: Colomban Wendling <ban herbesfolles org>
Date:   Fri Nov 18 12:12:04 2016 +0100

    Fix converting enumerations and flags to arrays
    
    Enumerations and flags are classed types for Vala, not integers, so
    they don't fall in the `typeof(G) == typeof(int)` kind of tests. This
    leads to using the generic code in which Vala assumes pointer-sized
    elements, which is often not true for enumerations and flags.
    
    Add special case for those to use the `int` converters for enumerations
    and flags.
    
    This is most generally correct, but not always: the compiler will
    likely chose a larger type for a specific enumeration if one of its
    value is larger than `int`.  It would be tempting to use the
    enumeration's class minimum and maximum values to determine the
    appropriate type, but unfortunately the API for this uses int itself,
    so doesn't help.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=774669

 gee/arraylist.vala       |    2 ++
 gee/collection.vala      |    8 ++++++++
 tests/testarraylist.vala |   16 ++++++++++++++++
 3 files changed, 26 insertions(+), 0 deletions(-)
---
diff --git a/gee/arraylist.vala b/gee/arraylist.vala
index c672639..6270c38 100644
--- a/gee/arraylist.vala
+++ b/gee/arraylist.vala
@@ -525,6 +525,8 @@ public class Gee.ArrayList<G> : AbstractBidirList<G> {
                        return wrap_float<G> ((float?[])data);
                } else if (t == typeof (double)) {
                        return wrap_double<G> ((double?[])data);
+               } else if (t.is_enum () || t.is_flags ()) {
+                       return wrap_int<G> ((int[])data);
                } else {
                        return (owned)data;
                }
diff --git a/gee/collection.vala b/gee/collection.vala
index a67f944..35c3286 100644
--- a/gee/collection.vala
+++ b/gee/collection.vala
@@ -179,6 +179,8 @@ public interface Gee.Collection<G> : Iterable<G> {
                        return (G[]) to_float_array ((Collection<float>) this);
                } else if (t == typeof (double)) {
                        return (G[]) to_double_array ((Collection<double>) this);
+               } else if (t.is_enum () || t.is_flags ()) {
+                       return (G[]) to_int_array ((Collection<int>) this);
                } else {
                        G[] array = new G[size];
                        int index = 0;
@@ -222,6 +224,8 @@ public interface Gee.Collection<G> : Iterable<G> {
                        return add_all_float_array ((Collection<float>) this, (float? [])array);
                } else if (t == typeof (double)) {
                        return add_all_double_array ((Collection<double>) this, (double? [])array);
+               } else if (t.is_enum () || t.is_flags ()) {
+                       return add_all_int_array ((Collection<int>) this, (int [])array);
                } else {
                        bool changed = false;
                        foreach (unowned G item in array) {
@@ -265,6 +269,8 @@ public interface Gee.Collection<G> : Iterable<G> {
                        return contains_all_float_array ((Collection<float>) this, (float? [])array);
                } else if (t == typeof (double)) {
                        return contains_all_double_array ((Collection<double>) this, (double? [])array);
+               } else if (t.is_enum () || t.is_flags ()) {
+                       return contains_all_int_array ((Collection<int>) this, (int [])array);
                } else {
                        foreach (unowned G item in array) {
                                if (!contains (item)) {
@@ -311,6 +317,8 @@ public interface Gee.Collection<G> : Iterable<G> {
                        return remove_all_float_array ((Collection<float>) this, (float? [])array);
                } else if (t == typeof (double)) {
                        return remove_all_double_array ((Collection<double>) this, (double? [])array);
+               } else if (t.is_enum () || t.is_flags ()) {
+                       return remove_all_int_array ((Collection<int>) this, (int [])array);
                } else {
                        bool changed = false;
                        foreach (unowned G item in array) {
diff --git a/tests/testarraylist.vala b/tests/testarraylist.vala
index 40809aa..4de1475 100644
--- a/tests/testarraylist.vala
+++ b/tests/testarraylist.vala
@@ -100,6 +100,10 @@ public class ArrayListTests : BidirListTests {
                }
        }
 
+       private enum TestEnum {
+               ONE, TWO, THREE
+       }
+
        private void test_typed_to_array () {
                // Test with a bool collection
                Gee.List<bool> bool_list = new ArrayList<bool> ();
@@ -140,5 +144,17 @@ public class ArrayListTests : BidirListTests {
                foreach (double element in double_list) {
                        assert (element == double_array[index++]);
                }
+
+               // Test with an enum collection
+               Gee.List<TestEnum> enum_list = new ArrayList<TestEnum> ();
+               assert (enum_list.add (TestEnum.ONE));
+               assert (enum_list.add (TestEnum.TWO));
+               assert (enum_list.add (TestEnum.THREE));
+
+               TestEnum[] enum_array = enum_list.to_array ();
+               index = 0;
+               foreach (TestEnum element in enum_list) {
+                       assert (element == enum_array[index++]);
+               }
        }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]