Thread overview
Gtk toArray List funkiness
Sep 16, 2017
Joseph
Sep 16, 2017
Mike Wey
Sep 16, 2017
Joseph
Sep 17, 2017
Mike Wey
September 16, 2017
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...



September 16, 2017
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

-- 
Mike Wey
September 16, 2017
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.

September 17, 2017
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/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.
> 

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