I have this c++11 code:
auto gen = []() -> double { /* do stuff */ };
std::generate(myArray.begin(), myArray.end(), gen);
How would I do the same with D's array? std.algorithm.fill doesn't take a function object, and I don't know how to pass a function to recurrence.
Here's a version that seems to work:
import std.algorithm, std.array, std.range, std.stdio;
void main() {
writefln("%s", __VERSION__);
int i;
auto dg = delegate float(int) { return i++; };
float[] res = array(map!dg(iota(0, 10)));
float[] res2 = new float[10];
fill(res2, map!dg(iota(0, res2.length)));
writefln("meep");
writefln("%s", res);
writefln("%s", res2);
}
[edit] Added fill-based version (res2).
I tested it in Ideone (http://www.ideone.com/DFK5A) but it crashes .. a friend with a current version of DMD says it works though, so I assume Ideone's DMD is just outdated by about ten to twenty versions.
You could do something like
auto arr = {/* generate an array and return that array */}();
If it's assigned to a global it should be evaluated at compile-time.
You can also use string mixins to generate code for an array literal.
Related
I am trying to learn Kotlin/Native C interop
I exported some Kotlin classes as C dynamic Lib and succeeded in access methods with primitive return types
But When trying to access class members in a instance object which returned by a method, the object contains something named as pinned
Code sample:
#Serializable
data class Persons (
val results: Array<Result>,
val info: Info
)
class RandomUserApiJS {
fun getPersonsDirect() : Persons {
return runBlocking {
RandomUserApi().getPersons()
}
}
}
Now when using them in C codeblocks,
In this image, note that the persons obj only showing a field named pinned and no other member functions found.
Since I don't know that much in C/C++ and can't investigate further.
Please help me to understand to access instance members of Kotlin Class in exported C lib?
Header file for ref:
https://gist.github.com/RageshAntony/a0b9007376084fa8b213b022b58f9886
for your gist
https://gist.github.com/RageshAntony/a0b9007376084fa8b213b022b58f9886
I modified the following:
// I comment this annotation
// #Serializable
data class Persons(
val results: List<Result>,
val info: Info,
/**
* the Result's properties too many
* I will use a simple data class for this example
* how to get c array from Persons (also suitable any iterable)
*/
val testList: List<Simple>,
) {
public fun toJson() = Json.encodeToString(this)
companion object {
public fun fromJson(json: String) = Json.decodeFromString<Persons>(json)
}
val arena = Arena()
fun getTestListForC(size: CPointer<IntVar>): CPointer<COpaquePointerVar> {
size.pointed.value = testList.size
return arena.allocArray<COpaquePointerVar>(testList.size) {
this.value = StableRef.create(testList[it]).asCPointer()
}
}
fun free() {
arena.clear()
}
}
/**
* kotlin <-> c bridge is primitive type
* like int <-> Int
* like char* <-> String
* so the Simple class has two primitive properties
*/
data class Simple(
val name: String,
val age: Int,
)
#include <stdio.h>
#include "libnative_api.h"
int main(int argc, char **argv) {
libnative_ExportedSymbols* lib = libnative_symbols();
libnative_kref_MathNative mn = lib->kotlin.root.MathNative.MathNative();
const char *a = lib->kotlin.root.MathNative.mul(mn,5,6); // working
printf ("Math Resullt %s\n",a);
libnative_kref_RandomUserApiJS pr = lib->kotlin.root.RandomUserApiJS.RandomUserApiJS();
libnative_kref_Persons persons = lib->kotlin.root.RandomUserApiJS.getPersonsDirect(pr);
// when accessing above persons obj, only a field 'pinned' availabe, nothing else
int size;
libnative_kref_Simple* list = (libnative_kref_Simple *)lib->kotlin.root.Persons.getTestListForC(persons, &size);
printf("size = %d\n", size);
for (int i = 0; i < size; ++i) {
const char *name = lib->kotlin.root.Simple.get_name(list[i]);
int age = lib->kotlin.root.Simple.get_age(list[i]);
printf("%s\t%d\n", name, age);
}
lib->kotlin.root.Persons.free(persons);
return 0;
}
// for output
Math Resullt The answer is 30
size = 3
name1 1
name2 2
name3 3
But I don't think calling kotlin lib through C is a good behavior, because kotlin native is not focused on improving performance for now, in my opinion, all functions that can be implemented with kotlin native can find solutions implemented in pure c, So I'm more focused on how to access the c lib from kotlin. Of course, it's a good solution if you absolutely need to access klib from c, but I'm still not very satisfied with it, then I may create a github template to better solve kotlin-interop from c.But that's not the point of this answer.
In the constructor of an Array is there a guarantee that the init function will be called for the indexes in an increasing order?
It would make sense but I did not find any such information in the docs:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/-init-.html#kotlin.Array%24%28kotlin.Int%2C+kotlin.Function1%28%28kotlin.Int%2C+kotlin.Array.T%29%29%29%2Finit
There is no guarantee for this in the API.
TLDR: If you need the sequential execution, because you have some state that changes see bottom.
First lets have a look at the implementations of the initializer:
Native: It is implemented in increasing order for Kotlin Native.
#InlineConstructor
public constructor(size: Int, init: (Int) -> Char): this(size) {
for (i in 0..size - 1) {
this[i] = init(i)
}
}
JVM: Decompiling the Kotlin byte code for
class test {
val intArray = IntArray(100) { it * 2 }
}
to Java in Android Studio yields:
public final class test {
#NotNull
private final int[] intArray;
#NotNull
public final int[] getIntArray() {
return this.intArray;
}
public test() {
int size$iv = 100;
int[] result$iv = new int[size$iv];
int i$iv = 0;
for(int var4 = result$iv.length; i$iv < var4; ++i$iv) {
int var6 = false;
int var11 = i$iv * 2;
result$iv[i$iv] = var11;
}
this.intArray = result$iv;
}
}
which supports the claim that it is initialized in ascending order.
Conclusion: It commonly is implemented to be executed in ascending order.
BUT: You can not rely on the execution order, as the implementation is not guaranteed by the API. It can change and it can be different for different platforms (although both is unlikely).
Solution: You can initialize the array manually in a loop, then you have control about the execution order.
The following example outlines a possible implementation that has a stable initialisation with random values, e.g. for tests.
val intArray = IntArray(100).also {
val random = Random(0)
for (index in it.indices) {
it[index] = index * random.nextInt()
}
}
Starting from the version 1.3.50 Kotlin has guaranteed sequential array initialization order in its API documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/-init-.html
The function init is called for each array element sequentially starting from the first one. It should return the value for an array element given its index.
I want to be able to modify my array of objects using map in Swift of the fly, without looping through each element.
Before here were able to do something like this (Described in more details here:
gnomes = gnomes.map { (var gnome: Gnome) -> Gnome in
gnome.age = 140
return gnome
}
Thanks for Erica Sadun and others, new proposals have gone through and we're now getting rid of C-style loops and using var inside the loop.
In my case I'm first getting a warning to remove the var in then an error my gnome is a constant (naturally)
My question is : How do we alter arrays inside a map or the new styled loops for that matter to be fully prepared for Swift 3.0?
If you want to keep that syntax, just use a (mutable) temporary variable
gnomes = gnomes.map { (gnome: Gnome) -> Gnome in
var mutableGnome = gnome
mutableGnome.age = 140
return mutableGnome
}
(Below follows the case where Gnome is a reference type; a class -- since you haven't showed us how you've defined Gnome. For the case where Gnome as value type (a struct), see #vadian:s answer)
The removal of var will not effect using .map to mutate mutable members of an array of reference type objects. I.e., you could simply use your old approach (omitting however, the var in the .map closure signature).
class Gnome {
var age = 42
}
var gnomes = [Gnome(), Gnome(), Gnome()]
gnomes = gnomes.map {
$0.age = 150
return $0
}
/* result */
gnomes.forEach { print($0.age) } // 3x 150
However, in case you just want to modify your original array rather than assigning the result of .map to a new array, .forEach might be a more appropriate choice than .map.
gnomes.forEach { $0.age = 140 }
/* result */
gnomes.forEach { print($0.age) } // 3x 140
Given:
struct Gnome {
var age: Int = 0
}
var gnomes = Array(count: 5, repeatedValue: Gnome())
... there are two decent options. The first is as #vadian put it:
gnomes = gnomes.map{
var gnome = $0
gnome.age = 70
return gnome
}
Whilst the second keeps control over "ageing" private and simplifies mapping at the point of call:
struct Gnome {
private(set) var age: Int = 0
func aged(age: Int) -> Gnome {
var gnome = self
gnome.age = age
// any other ageing related changes
return gnome
}
}
gnomes = gnomes.map{ $0.aged(140) }
Of course, reference types still have their place in programming, which may well be a better fit in this case. The friction we are experiencing here suggests that we are trying to treat these structures as if they were objects. If that is the behaviour you need, then you should consider implementing Gnome as a class.
Using Object or * as a type for a Vector doesn't provide generic functionality (like List in Java). Witness:
public static function someGenericVectorUtil (value:Vector.<*>) :void {
// do stuff to/with the Vector
}
var someVector:Vector.<Number>;
someGenericVectorUtil(someVector); // compile-time implicit coercion error
So, perhaps we redefine the utility method to accept an Array. But there's no easy way to convert Vectors going into the utility to Arrays, nor an easy way to pack them back in afterwards, resulting in code like this:
public static function someGenericArrayUtil (value:Array) :void {
// do stuff to/with the formerly-known-as-Vector
}
var someVector:Vector.<Number>;
var tempArray:Array = new Array(someVector.length);
for (var i:uint=0; i<someVector.length; i++) {
tempArray[i] = someVector[i];
}
someGenericVectorUtil(tempArray);
someVector = Vector.<Number>([tempArray]);
Needless to say, that's pretty hideous. Okay, so let's move the Vector-Array-Vector nonsense into a utility:
public static function vectorToArray (Vector.<*>) :Array {
// oh wait....that Vector.<*> param is useless,
// as demonstrated earlier.
}
Any way to straighten out this mess? Or should I just stop using Vectors when I think I might need to run them through generic utilities? (Obviously, also not really much of an option...)
public static function someGenericVectorUtil (value:Vector.<*>) :void {
// do stuff to/with the Vector
}
var someVector:Vector.<Number>;
someGenericVectorUtil(Vector.<*>(someVector));
^ it works. Also try with Array.
This is not an answer but more a long comment to #Lukasz's answer.
The problem with his answer is that you're actually creating a new Vector, so you need to return the Vector from someGenericVectorUtil and re-cast it. E.g. try:
var v:Vector.<int> = Vector.<int>([1,2,3]);
trace( v == Vector.<int>( Vector.<*>( v ) ) ); // traces false
That code just creates a simple Vector of ints, then compares it with a version of itself casted (first to *, then back to int). If you trace the Vectors out, they'll trace identical, but the actual Vectors references themselves aren't the same object. Thus if you have a utility function that modifies the Vector (e.g. a shuffle or randomise function), nothing will change.
E.g:
var v:Vector.<int> = Vector.<int>([1,2,3]);
trace( v ); // traces "1,2,3"
// shuffle() randomises the elements in a vector - this first call won't work
// as the cast creates a new vector
VectorUtil.shuffle( Vector.<*>( v ) );
trace( v ); // traces "1,2,3"
// we need to recast it back, and change shuffle() to return the vector
v = Vector.<int>( VectorUtil.shuffle( Vector.<*>( v ) ) );
trace( v ); // traces "3,1,2"
As you can see, it starts to get a bit ugly towards the end, and if you're keeping track of the Vector anywhere else, you'll need to update the references, but it's the only solution that I've found so far :S
I am writing a C extension for Ruby that really needs to merge two hashes, however the rb_hash_merge() function is STATIC in Ruby 1.8.6. I have tried instead to use:
rb_funcall(hash1, rb_intern("merge"), 1, hash2);
but this is much too slow, and performance is very critical in this application.
Does anyone know how to go about performing this merge with efficiency and speed in mind?
(Note I have tried simply looking at the source for rb_hash_merge() and replicating it but it is RIDDLED with other static functions, which are themselves riddled with yet more static functions so it seems almost impossible to disentangle...i need another way)
Ok, looks like might be not possible to optimize within the published API.
Test code:
#extconf.rb
require 'mkmf'
dir_config("hello")
create_makefile("hello")
// hello.c
#include "ruby.h"
static VALUE rb_mHello;
static VALUE rb_cMyCalc;
static void calc_mark(void *f) { }
static void calc_free(void *f) { }
static VALUE calc_alloc(VALUE klass) { return Data_Wrap_Struct(klass, calc_mark, calc_free, NULL); }
static VALUE calc_init(VALUE obj) { return Qnil; }
static VALUE calc_merge(VALUE obj, VALUE h1, VALUE h2) {
return rb_funcall(h1, rb_intern("merge"), 1, h2);
}
static VALUE
calc_merge2(VALUE obj, VALUE h1, VALUE h2)
{
VALUE h3 = rb_hash_new();
VALUE keys;
VALUE akey;
keys = rb_funcall(h1, rb_intern("keys"), 0);
while (akey = rb_each(keys)) {
rb_hash_aset(h3, akey, rb_hash_aref(h1, akey));
}
keys = rb_funcall(h2, rb_intern("keys"), 0);
while (akey = rb_each(keys)) {
rb_hash_aset(h3, akey, rb_hash_aref(h2, akey));
}
return h3;
}
static VALUE
calc_merge3(VALUE obj, VALUE h1, VALUE h2)
{
VALUE keys;
VALUE akey;
keys = rb_funcall(h1, rb_intern("keys"), 0);
while (akey = rb_each(keys)) {
rb_hash_aset(h2, akey, rb_hash_aref(h1, akey));
}
return h2;
}
void
Init_hello()
{
rb_mHello = rb_define_module("Hello");
rb_cMyCalc = rb_define_class_under(rb_mHello, "Calculator", rb_cObject);
rb_define_alloc_func(rb_cMyCalc, calc_alloc);
rb_define_method(rb_cMyCalc, "initialize", calc_init, 0);
rb_define_method(rb_cMyCalc, "merge", calc_merge, 2);
rb_define_method(rb_cMyCalc, "merge2", calc_merge, 2);
rb_define_method(rb_cMyCalc, "merge3", calc_merge, 2);
}
# test.rb
require "hello"
h1 = Hash.new()
h2 = Hash.new()
1.upto(100000) { |x| h1[x] = x+1; }
1.upto(100000) { |x| h2["#{x}-12"] = x+1; }
c = Hello::Calculator.new()
puts c.merge(h1, h2).keys.length if ARGV[0] == "1"
puts c.merge2(h1, h2).keys.length if ARGV[0] == "2"
puts c.merge3(h1, h2).keys.length if ARGV[0] == "3"
Now the test results:
$ time ruby test.rb
real 0m1.021s
user 0m0.940s
sys 0m0.080s
$ time ruby test.rb 1
200000
real 0m1.224s
user 0m1.148s
sys 0m0.076s
$ time ruby test.rb 2
200000
real 0m1.219s
user 0m1.132s
sys 0m0.084s
$ time ruby test.rb 3
200000
real 0m1.220s
user 0m1.128s
sys 0m0.092s
So it looks like we might shave off at maximum ~0.004s on a 0.2s operation.
Given that there's probably not that much besides setting the values, there might not be that much space for further optimizations. Maybe try to hack the ruby source itself - but at that point you no longer really develop "extension" but rather change the language, so it probably won't work.
If the join of hashes is something that you need to do many times in the C part - then probably using the internal data structures and only exporting them into Ruby hash in the final pass would be the only way of optimizing things.
p.s. The initial skeleton for the code borrowed from this excellent tutorial