Are there c++ like iterators in dart - dart

In c++ we have iterators that act as reference to some element in list. Assigning to the iterator it is possible to change elements inside the list.
for example:
std::map<std::pair<int,int> ,Ship> playgroundMap;
playgroundMap.insert(std::make_pair(std::make_pair(2,2),Ship(100,Cannon(50))));
playgroundMap.insert(std::make_pair(std::make_pair(3,3),Ship(200,Cannon(60))));
std::cout<<"Iterators : "<<std::endl;
auto shipPtr = playgroundMap.find(std::make_pair(2,2));
std::cout<<" address of ship Before : "<<&shipPtr->second<<std::endl;
shipPtr->second.cannon.firepower = 1000;
auto tmp = Ship(200,Cannon(90));
shipPtr->second = tmp;
std::cout<<" address of ship After newly Assigned : "<<&shipPtr->second<<std::endl;
std::cout<<"finalList : "<<std::endl;
for(auto a : playgroundMap)
{
std::cout<<a.second.durability<<std::endl<<a.second.cannon.firepower<<std::endl;
}
Let alone the fact that reference in c++ are enough to achieve this. References in c++ do not rebound on assignment like they do in dart.
for example in c++:
std::map<std::pair<int,int> ,Ship> playgroundMap;
playgroundMap.insert(std::make_pair(std::make_pair(2,2),Ship(100,Cannon(50))));
playgroundMap.insert(std::make_pair(std::make_pair(3,3),Ship(200,Cannon(60))));
std::cout<<"Reference : "<<std::endl;
auto &shipRef = playgroundMap[std::make_pair(2,2)];
std::cout<<" address of ship Before : "<<&shipRef<<std::endl;
shipRef.cannon.firepower = 1000;
auto tmp = Ship(200,Cannon(90));
auto &tmpRef = tmp;
std::cout<<" address of tmpref (newly created ship) : "<<&tmpRef<<std::endl;
shipRef = tmpRef;
std::cout<<" address of ship After newly Assigned : "<<&shipRef<<std::endl;
std::cout<<" address of finalList : "<<std::endl;
for(auto a : playgroundMap)
{
std::cout<<a.second.durability<<std::endl<<a.second.cannon.firepower<<std::endl;
}
This would modify the list element in c++ while in dart the reference would rebind and element in list would not change.That is whole another thing i understand that both these concepts are different in both languages.
My question is, Is there some kind of c++ iterator like way in dart that allows me to do these kind of operations. I know i can just store the index but i don't want to do that.

There is nothing like that in the platform libraries.
In general, Dart iterators give access to the values of a collection, not to changing the collection itself.
One of the reasons for this restriction could be that Dart doesn't have reference variables to begin with, but nothing inherently prevents Dart from having an iterator that allows you to change the value of the current element. At least for a list, it could work. A hash set probably wouldn't work, because the changed value wouldn't be in the same place of the iteration.
All in all, it's not something the platform libraries support, or have wanted to support. The Dart platform libraries are, in most places, slightly more functional programming like than C++.

Related

vector<reference_wrapper> .. things going out of scope? how does it work?

Use case: I am converting data from a very old program of mine to a database friendly format. There are parts where I have to do multiple passes over the old data, because in particular the keys have to first exist before I can reference them in relationships. So I thought why not put the incomplete parts in a vector of references during the first pass and return it from the working function, so I can easily use that vector to make the second pass over whatever is still incomplete. I like to avoid pointers when possible so I looked into std::reference_wrapper<T> which seemes like exactly what I need .. except I don't understand it's behavior at all.
I have both vector<OldData> old_data and vector<NewData> new_data as member of my conversion class. The converting member function essentially does:
//...
vector<reference_wrapper<NewData>> incomplete;
for(const auto& old_elem : old_data) {
auto& new_ref = *new_data.insert(new_data.end(), convert(old_elem));
if(is_incomplete(new_ref)) incomplete.push_back(ref(new_ref));
}
return incomplete;
However, incomplete is already broken immediately after the for loop. The program compiles, but crashes and produces gibberish. Now I don't know if I placed ref correctly, but this is only one of many tries where I tried to put it somewhere else, use push_back or emplace_back instead, etc. ..
Something seems to be going out of scope, but what? both new_data and old_data are class members, incomplete also lives outside the loop, and according to the documentation, reference_wrapper is copyable.
Here's a simplified MWE that compiles, crashes, and produces gibberish:
// includes ..
using namespace std;
int main() {
int N = 2; // works correctly for N = 1 without any other changes ... ???
vector<string> strs;
vector<reference_wrapper<string>> refs;
for(int i = 0; i < N; ++i) {
string& sref = ref(strs.emplace_back("a"));
refs.push_back(sref);
}
for (const auto& r : refs) cout << r.get(); // crash & gibberish
}
This is g++ 10.2.0 with -std=c++17 if it means anything. Now I will probably just use pointers and be done, but I would like to understand what is going on here, documentation / search does not seem to help..
The problem here is that you are using vector data structure which might re-allocate memory for the entire vector any time that you add an element, so all previous references on that vector most probably get invalidated, you can resolve your problem by using list instead of vector.

JNA pointer to pointer mapping

I am working on a Java binding for the excellent libvips
Using this function all is fine:
VipsImage *in;
in = vips_image_new_from_file( test.jpg, NULL )
vips_image_write_to_file( in, "out.jpg", NULL )
So mapped in Java:
Pointer vips_image_new_from_file(String filename,String params);
But I have a problem when the parameter like this:
VipsImage *in;
VipsImage *out;
vips_invert( in, &out, NULL )
vips_image_write_to_file( out, "out.jpg", NULL )
I have tried:
int vips_resize(Pointer in, PointerByReference out, Double scale, String params);
Pointer in = vips_image_new_from_file("file.png",null);
PointerByReference ptr1 = new PointerByReference();
vips_invert(in, ptr1, null);
vips_image_write_to_file( ptr1.getValue(), "fileout.png", null);
But doesn't work. The ptr1.getValue() does not contains the expected result.
How can I do it?
Thanks
I'm the libvips maintainer, a Java binding would be great!
But I think you might be taking the wrong approach. I think you are trying a straight wrap of the C API, but that's going to be tricky to do well, since it makes use of a lot of C-isms that don't map well to Java. For example, in C you can write:
VipsImage *image;
if (!(image = vips_image_new_from_file("somefile.jpg",
"shrink", 2,
"autorotate", TRUE,
NULL)))
error ...;
ie. the final NULL marks the end of a varargs name / value list. Here I'm asking the jpeg loader to do a x2 shrink during load, and to apply any Orientation tags it finds in the EXIF.
libvips has a lower-level API based on GObject which is much easier to bind to. There's some discussion and example code in this issue, where someone is making a C# binding using p/invoke.
https://github.com/jcupitt/libvips/issues/558
The code for the C++ and PHP bindings might be a useful reference:
https://github.com/jcupitt/libvips/tree/master/cplusplus
https://github.com/jcupitt/php-vips-ext
That's a PHP binding for the entire library in 1800 lines of C.
I'd be very happy to help if I can. Open an issue on the libvips tracker:
https://github.com/jcupitt/libvips/issues

How to convert C# code that uses Shell COM to F#?

I have the following C# method:
private static bool IsLink(string shortcutFilename)
{
var pathOnly = Path.GetDirectoryName(shortcutFilename);
var filenameOnly = Path.GetFileName(shortcutFilename);
var shell = new Shell32.Shell();
var folder = shell.NameSpace(pathOnly);
var folderItem = folder.ParseName(filenameOnly);
return folderItem != null && folderItem.IsLink;
}
I have tried converting this to F# as:
let private isLink filename =
let pathOnly = Path.GetDirectoryName(filename)
let filenameOnly = Path.GetFileName(filename)
let shell = new Shell32.Shell()
let folder = shell.NameSpace(pathOnly)
let folderItem = folder.ParseName(filenameOnly)
folderItem <> null && folderItem.IsLink
It however reports an error for the let shell = new Shell32.Shell() line, saying that new cannot be used on interface types.
Have I just made a silly syntactic mistake, or is there extra work needed to access COM from F#?
I don't know enough about the F# compiler but your comments makes it obvious enough. The C# and VB.NET compilers have a fair amount of explicit support for COM built-in. Note that your statement uses the new operator on an interface type, Shell32.Shell in the interop library looks like this:
[ComImport]
[Guid("286E6F1B-7113-4355-9562-96B7E9D64C54")]
[CoClass(typeof(ShellClass))]
public interface Shell : IShellDispatch6 {}
IShellDispatch6 is the real interface type, you can also see the IShellDispatch through IShellDispatch5 interfaces. That's versioning across the past 20 years at work, COM interface definitions are immutable since changing them almost always causes an undiagnosable hard crash at runtime.
The [CoClass] attribute is the important one for this story, that's what the C# compiler goes looking for you use new on a [ComImport] interface type. Tells it to create the object by creating an instance of Shell32.ShellClass instance and obtain the Shell interface. What the F# compiler doesn't do.
ShellClass is a fake class, it is auto-generated by the type library importer. COM never exposes concrete classes, it uses a hyper-pure interface-based programming paradigm. Objects are always created by an object factory, CoCreateInstance() is the workhorse for that. Itself a convenience function, the real work is done by the universal IClassFactory interface, hyper-pure style. Every COM coclass implements its CreateInstance() method.
The type library importer makes ShellClass look like this:
[ComImport]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("13709620-C279-11CE-A49E-444553540000")]
public class ShellClass : IShellDispatch6, Shell {
// Methods
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60040000)]
public virtual extern void AddToRecent([In, MarshalAs(UnmanagedType.Struct)] object varFile, [In, Optional, MarshalAs(UnmanagedType.BStr)] string bstrCategory);
// Etc, many more methods...
}
Lots of fire and movement, none of it should ever be used. The only thing that really matters is the [Guid] attribute, that provides the CLSID that CoCreateInstance() needs. It also needs the IID, the [Guid] of the interface, provided by the interface declaration.
So the workaround in F# is to create the Shell32.ShellClass object, just like the C# compiler does implicitly. While technically you can keep the reference in a ShellClass variable, you should strongly favor the interface type instead. The COM way, the pure way, it avoids this kind of problem. Ultimately it is the CLR that gets the job done, it recognizes the [ClassInterface] attribute on the ShellClass class declaration in its new operator implementation. The more explicit way in .NET is to use Type.GetTypeFromCLSID() and Activator.CreateInstance(), handy when you only have the Guid of the coclass.

How to create a dynamic variable in dart

I am moving java script to dart, in java script I create dynamic variable like
window["text" + pageNumber] = 123;
alert(window["text" + pageNumber]);
How can I do it with dart?
In Dart Window (the type of window) is a class. You can't dynamically add properties to a Dart class.
window["text" + pageNumber] = 123; would work with a Map. Object representation in JS is quite similar to a map and therefore this works there.
If another class implements the [] operator you could call it on instances of that class as well but it would still not add properties. What it actually does just depends on the implementation of the [] operator.
There are probably different ways in Dart to achieve what you want, but you didn't add details about what actual problem you try to solve.
You can use normal global variables in Dart like explained in
Global Variables in Dart.
For your use case you can create a global Map variable this way
final Map<String,int> myGlobals = <String,int>{};
to create a map that stores integer values with string names.
Set values with myGlobals['someName'] = 123; and read them with print(myGlobals['someName']);.
If you need to set a global value that is also available for JS libraries you might use, you can use dart-js-interop
import 'dart:js';
import 'dart:html';
main() {
int pagenumber = 5;
context['Window']['text$pagenumber'] = 123;
window.alert('${context['Window']['text$pagenumber']}');
}
Try it on DartPad.
Hint:
"text" + pageNumber doesn't work when pageNumber is not a string.
In Dart you can't add string and numbers.
"text" + pageNumber.toString() would work but 'text$pagenumber' is a more darty way to do this. In string interpolation toString() is called automatically for you.
See also Dart js-interop not working if .dart file isn't included.

Can record constructors make record constants more concise?

I have some tabular data:
Foo Bar
-------------
fooes 42
bars 666
...
So, I declare the entity structure:
type TFoo = record
Foo: string;
Bar: Integer
end;
and the table of entities:
const FOOES = array [M..N] of TFoo = (
// Have to specify the field names for each record...
(Foo: 'fooes'; Bar: 42),
(Foo: 'bars'; Bar: 666)
{ so on }
);
As you see, this looks quite verbose and redundant, and it is because I initialize all of the fields for all of the records. And there is a lot of editing if I copy tabular data prepared elsewhere. I'd prefer to not enumerate all of the fields and stick to the more laconic C style, that is, constants only. And here comes the record constructor...
Can record constructors help me in this case?
Here's an example in C. You'll notice that we don't have to specify the field names in each declaration:
#include <stdio.h>
typedef struct {
char foo[10];
int bar;
} foo;
int main(void) {
/* Look here */
foo FOOES[2] = {{"foo", 42}, {"bar", 666}};
int i = 0;
for (; i < 2; i++) {
printf("%s\t%d\n", FOOES[i].foo, FOOES[i].bar);
}
return 0;
}
A const is just a read-only var which is loaded/mapped within the code, when the executable is launched.
You can create a var record (or a const but overriding the writable const option), then initialize it in the initialization section of the unit.
var FOOES = array [M..N] of TFoo;
....
initialization
SetFooArray(FOOES,['fooes',42,'bar',230]);
...
end.
The custom SetFooArray() function will put all array of const parameters into FOOES.
I use this technique sometimes to initialize computable arrays (e.g. conversion or lookup tables). Sometimes, it does make sense to compute once at startup a huge array, saving some KB of const in the source code, with a few lines of code.
But I'm not sure it will be worth it in your case. The default const declaration is a bit verbose, but not a problem if you use Ctrl+C/Ctrl+V or a find and replace. It is the most standard, is secure if you change later the record layout (whereas the C construction may compile without error), and will create a true constant.
Record constructors are runtime only and so for constants your current solution is the only option.
If you want it done in source then what you have already typed is your answer. You could, of course, put the data in separate arrays and initialize them that way, but that can make your code look messy.
You could also store them in an text file (Foo=Bar format) and read them into a TStringList at run-time (SL.LoadFromFile()). But even with a sorted TStringList it will be far less efficient (MyVariable := SL.Values['Foo1']; for example).
There are a million ways to solve this problem outside of source code. Taking it from the other direction, put the data into Excel and create an Excel macro to build the source and put it into the clipboard to paste into your PAS file. This wouldn't be too difficult and probably easier than formatting the Delphi code within the IDE.

Resources