www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Gtk toArray List funkiness

reply Joseph <JE342 gmail.com> writes:
https://github.com/gtkd-developers/GtkD/blob/master/demos/gtkD/TestWindow/TestWindow.d

has the code

foreach ( int i, string selection ; fs.getSelections())
{
   writeln("File(s) selected [%d] %s",i,selection);
}

which is invalid for the demo, but

foreach ( int i, string selection ; 
fd.getFilenames().toArray!(string,?))
{
   writeln("File(s) selected [%d] %s",i,selection);
}

results in some funky code. Gives errors in ObjectG about uint 
when setting ? to string, string* or void* or even uint:

GtkD\generated\gtkd\gobject\ObjectG.d(172): Error: incompatible 
types for ((obj) is (null)): 'uint' and 'typeof(null)'
GtkD\generated\gtkd\glib\ListSG.d(98): Error: template instance 
gobject.ObjectG.ObjectG.getDObject!(string, string, uint) error 
instantiating
test.d(91):        instantiated from here: toArray!(string, uint)
test.d(93): Error: invalid foreach aggregate `fd.getFilenames()`, 
define opApply(), range primitives, or use .tupleof

without specifying ? it assumes it's a tuple, which seems wrong?



	public T[] toArray(T, TC = typeof(T.tupleof[0]))()
	{
		T[] arr = new T[length()];
		ListSG list = this;
		size_t count;

		while(list !is null && count < arr.length)
		{
			arr[count] = ObjectG.getDObject!(T)(cast(TC)list.data);
			list = list.next();
			count++;
		}

		return arr;
	}


										foreach ( int i, Value selection ; 
fd.getFilenames().toArray!(Value)())
{
   writeln("File(s) selected [%d] %s",i,selection.getString);
}

crashes ;/

I'm not sure what types are what and it changes depending on the 
input. I think Value is the wrong type to use but string doesn't 
work so...
Sep 16
parent reply Mike Wey <mike-wey example.com> writes:
On 16-09-17 20:58, Joseph wrote:
 
 https://github.com/gtkd-developers/GtkD/blob/master/demos/gtkD/Tes
Window/TestWindow.d 
 
 
 has the code
 
 foreach ( int i, string selection ; fs.getSelections())
 {
    writeln("File(s) selected [%d] %s",i,selection);
 }
 
 which is invalid for the demo, but
 
 foreach ( int i, string selection ; fd.getFilenames().toArray!(string,?))
 {
    writeln("File(s) selected [%d] %s",i,selection);
 }
 
 results in some funky code. Gives errors in ObjectG about uint when 
 setting ? to string, string* or void* or even uint:
 
 GtkD\generated\gtkd\gobject\ObjectG.d(172): Error: incompatible types 
 for ((obj) is (null)): 'uint' and 'typeof(null)'
 GtkD\generated\gtkd\glib\ListSG.d(98): Error: template instance 
 gobject.ObjectG.ObjectG.getDObject!(string, string, uint) error 
 instantiating
 test.d(91):        instantiated from here: toArray!(string, uint)
 test.d(93): Error: invalid foreach aggregate `fd.getFilenames()`, define 
 opApply(), range primitives, or use .tupleof
 
 without specifying ? it assumes it's a tuple, which seems wrong?
 
 
 
      public T[] toArray(T, TC = typeof(T.tupleof[0]))()
      {
          T[] arr = new T[length()];
          ListSG list = this;
          size_t count;
 
          while(list !is null && count < arr.length)
          {
              arr[count] = ObjectG.getDObject!(T)(cast(TC)list.data);
              list = list.next();
              count++;
          }
 
          return arr;
      }
 
 
                               
          foreach ( int i, Value 
 selection ; fd.getFilenames().toArray!(Value)())
 {
    writeln("File(s) selected [%d] %s",i,selection.getString);
 }
 
 crashes ;/
 
 I'm not sure what types are what and it changes depending on the input. 
 I think Value is the wrong type to use but string doesn't work so...
ListG and ListSG are missing an toArray overload for string. And getFilenames returns a list of strings. I've added a string overload for toArray: https://github.com/gtkd-developers/GtkD/commit/ba20490b38e502a4d281226572c83c662a700858 -- Mike Wey
Sep 16
parent reply Joseph <JE342 gmail.com> writes:
On Saturday, 16 September 2017 at 20:54:21 UTC, Mike Wey wrote:
 On 16-09-17 20:58, Joseph wrote:
 
 https://github.com/gtkd-developers/GtkD/blob/master/demos/gtkD/TestWindow/TestWindow.d
 
 
 has the code
 
 foreach ( int i, string selection ; fs.getSelections())
 {
    writeln("File(s) selected [%d] %s",i,selection);
 }
 
 which is invalid for the demo, but
 
 foreach ( int i, string selection ; 
 fd.getFilenames().toArray!(string,?))
 {
    writeln("File(s) selected [%d] %s",i,selection);
 }
 
 results in some funky code. Gives errors in ObjectG about uint 
 when setting ? to string, string* or void* or even uint:
 
 GtkD\generated\gtkd\gobject\ObjectG.d(172): Error: 
 incompatible types for ((obj) is (null)): 'uint' and 
 'typeof(null)'
 GtkD\generated\gtkd\glib\ListSG.d(98): Error: template 
 instance gobject.ObjectG.ObjectG.getDObject!(string, string, 
 uint) error instantiating
 test.d(91):        instantiated from here: toArray!(string, 
 uint)
 test.d(93): Error: invalid foreach aggregate 
 `fd.getFilenames()`, define opApply(), range primitives, or 
 use .tupleof
 
 without specifying ? it assumes it's a tuple, which seems 
 wrong?
 
 
 
      public T[] toArray(T, TC = typeof(T.tupleof[0]))()
      {
          T[] arr = new T[length()];
          ListSG list = this;
          size_t count;
 
          while(list !is null && count < arr.length)
          {
              arr[count] = 
 ObjectG.getDObject!(T)(cast(TC)list.data);
              list = list.next();
              count++;
          }
 
          return arr;
      }
 
 
                               
          foreach ( int i, 
 Value selection ; fd.getFilenames().toArray!(Value)())
 {
    writeln("File(s) selected [%d] %s",i,selection.getString);
 }
 
 crashes ;/
 
 I'm not sure what types are what and it changes depending on 
 the input. I think Value is the wrong type to use but string 
 doesn't work so...
ListG and ListSG are missing an toArray overload for string. And getFilenames returns a list of strings. I've added a string overload for toArray: https://github.com/gtkd-developers/GtkD/commit/ba20490b38e502a4d281226572c83c662a700858
public ListSG getFilenames() { auto p = gtk_file_chooser_get_filenames(getFileChooserStruct()); if(p is null) { return null; } return new ListSG(cast(GSList*) p, true); } Doesn't return a list of strings? That was the first thing I tried and the foreach loop wouldn't work over it because it was a ListSG. Thanks.
Sep 16
parent Mike Wey <mike-wey example.com> writes:
On 16-09-17 23:08, Joseph wrote:
 On Saturday, 16 September 2017 at 20:54:21 UTC, Mike Wey wrote:
 On 16-09-17 20:58, Joseph wrote:
 https://github.com/gtkd-developers/GtkD/blob/master/demos/gtkD/Tes
Window/TestWindow.d 



 has the code

 foreach ( int i, string selection ; fs.getSelections())
 {
    writeln("File(s) selected [%d] %s",i,selection);
 }

 which is invalid for the demo, but

 foreach ( int i, string selection ; 
 fd.getFilenames().toArray!(string,?))
 {
    writeln("File(s) selected [%d] %s",i,selection);
 }

 results in some funky code. Gives errors in ObjectG about uint when 
 setting ? to string, string* or void* or even uint:

 GtkD\generated\gtkd\gobject\ObjectG.d(172): Error: incompatible types 
 for ((obj) is (null)): 'uint' and 'typeof(null)'
 GtkD\generated\gtkd\glib\ListSG.d(98): Error: template instance 
 gobject.ObjectG.ObjectG.getDObject!(string, string, uint) error 
 instantiating
 test.d(91):        instantiated from here: toArray!(string, uint)
 test.d(93): Error: invalid foreach aggregate `fd.getFilenames()`, 
 define opApply(), range primitives, or use .tupleof

 without specifying ? it assumes it's a tuple, which seems wrong?



      public T[] toArray(T, TC = typeof(T.tupleof[0]))()
      {
          T[] arr = new T[length()];
          ListSG list = this;
          size_t count;

          while(list !is null && count < arr.length)
          {
              arr[count] =
ObjectG.getDObject!(T)(cast(TC)list.data);
              list = list.next();
              count++;
          }

          return arr;
      }


                               
          foreach ( int i, Value 
 selection ; fd.getFilenames().toArray!(Value)())
 {
    writeln("File(s) selected [%d] %s",i,selection.getString);
 }

 crashes ;/

 I'm not sure what types are what and it changes depending on the 
 input. I think Value is the wrong type to use but string doesn't work 
 so...
ListG and ListSG are missing an toArray overload for string. And getFilenames returns a list of strings. I've added a string overload for toArray: https://github.com/gtkd-developers/GtkD/commit/ba20490b38e502a4d281 26572c83c662a700858
    public ListSG getFilenames()     {         auto p = gtk_file_chooser_get_filenames(getFileChooserStruct());         if(p is null)         {             return null;         }         return new ListSG(cast(GSList*) p, true);     } Doesn't return a list of strings? That was the first thing I tried and the foreach loop wouldn't work over it because it was a ListSG. Thanks.
getFilenames returns a singly linked list of C strings, ie the data member is a char*. With the changes in master you can use toArray!string() to get an array of strings out of it. Or you can loop over the list: ``` auto list = fd.getFilenames(); string[] files; while ( list.next !is null ) { files ~= to!string(cast(char*)list.data); list = list.next; } ``` -- Mike Wey
Sep 17