using transform algorithm with boost range - stl-algorithm

Hi i'm trying to add two std vectors with boost.range but i get a bunch of errors.
this works:
std::transform(a.begin(),a.end(),b.begin(),a.begin(),std::plus<double>());
this doesn't:
boost::transform(a,b,a,std::plus<double>());
with an error:
In file included from /usr/local/include/boost/range/algorithm.hpp:80:0,
from /home/kirill/Dropbox/work/projects/doing/quasiclass/dev/source/simple_pcet.h:15,
from /home/kirill/Dropbox/work/projects/doing/quasiclass/dev/source/simple_pcet.cc:1:
/usr/local/include/boost/range/algorithm/transform.hpp: In function ‘OutputIterator boost::range_detail::transform_impl(SinglePassTraversalReadableIterator1, SinglePassTraversalReadableIterator1, SinglePassTraversalReadableIterator2, SinglePassTraversalReadableIterator2, OutputIterator, BinaryFunction) [with SinglePassTraversalReadableIterator1 = __gnu_cxx::__normal_iterator<const double*, std::vector<double> >, SinglePassTraversalReadableIterator2 = __gnu_cxx::__normal_iterator<const double*, std::vector<double> >, OutputIterator = std::vector<double>, BinaryFunction = std::plus<double>]’:
/usr/local/include/boost/range/algorithm/transform.hpp:90:33: instantiated from ‘OutputIterator boost::range::transform(const SinglePassRange1&, const SinglePassRange2&, OutputIterator, BinaryOperation) [with SinglePassRange1 = std::vector<double>, SinglePassRange2 = std::vector<double>, OutputIterator = std::vector<double>, BinaryOperation = std::plus<double>]’
/home/kirill/Dropbox/work/projects/doing/quasiclass/dev/source/simple_pcet.cc:9:45: instantiated from here
/usr/local/include/boost/range/algorithm/transform.hpp:64:17: error: no match for ‘operator*’ in ‘*out’
/usr/local/include/boost/range/algorithm/transform.hpp:64:17: note: candidates are:
/usr/include/c++/4.6/complex:399:5: note: template<class _Tp> std::complex<_Tp> std::operator*(const _Tp&, const std::complex<_Tp>&)
/usr/include/c++/4.6/complex:390:5: note: template<class _Tp> std::complex<_Tp> std::operator*(const std::complex<_Tp>&, const _Tp&)
/usr/include/c++/4.6/complex:381:5: note: template<class _Tp> std::complex<_Tp> std::operator*(const std::complex<_Tp>&, const std::complex<_Tp>&)
/usr/local/include/boost/range/algorithm/transform.hpp:65:17: error: no match for ‘operator++’ in ‘++out’
/usr/local/include/boost/range/algorithm/transform.hpp:65:17: note: candidate is:
/usr/local/include/boost/iterator/iterator_facade.hpp:722:3: note: template<class I, class V, class TC, class R, class D> typename boost::detail::postfix_increment_result<I, V, R, TC>::type boost::operator++(boost::iterator_facade<Derived, V, TC, R, D>&, int)
and neither this:
std::vector<double> c;
boost::transform(a,b,c,std::plus<double>());
with an error:
In file included from /usr/local/include/boost/range/algorithm.hpp:80:0,
from /home/kirill/Dropbox/work/projects/doing/quasiclass/dev/source/simple_pcet.h:15,
from /home/kirill/Dropbox/work/projects/doing/quasiclass/dev/source/simple_pcet.cc:1:
/usr/local/include/boost/range/algorithm/transform.hpp: In function ‘OutputIterator boost::range_detail::transform_impl(SinglePassTraversalReadableIterator1, SinglePassTraversalReadableIterator1, SinglePassTraversalReadableIterator2, SinglePassTraversalReadableIterator2, OutputIterator, BinaryFunction) [with SinglePassTraversalReadableIterator1 = __gnu_cxx::__normal_iterator<const double*, std::vector<double> >, SinglePassTraversalReadableIterator2 = __gnu_cxx::__normal_iterator<const double*, std::vector<double> >, OutputIterator = std::vector<double>, BinaryFunction = std::plus<double>]’:
/usr/local/include/boost/range/algorithm/transform.hpp:90:33: instantiated from ‘OutputIterator boost::range::transform(const SinglePassRange1&, const SinglePassRange2&, OutputIterator, BinaryOperation) [with SinglePassRange1 = std::vector<double>, SinglePassRange2 = std::vector<double>, OutputIterator = std::vector<double>, BinaryOperation = std::plus<double>]’
/home/kirill/Dropbox/work/projects/doing/quasiclass/dev/source/simple_pcet.cc:8:45: instantiated from here
/usr/local/include/boost/range/algorithm/transform.hpp:64:17: error: no match for ‘operator*’ in ‘*out’
/usr/local/include/boost/range/algorithm/transform.hpp:64:17: note: candidates are:
/usr/include/c++/4.6/complex:399:5: note: template<class _Tp> std::complex<_Tp> std::operator*(const _Tp&, const std::complex<_Tp>&)
/usr/include/c++/4.6/complex:390:5: note: template<class _Tp> std::complex<_Tp> std::operator*(const std::complex<_Tp>&, const _Tp&)
/usr/include/c++/4.6/complex:381:5: note: template<class _Tp> std::complex<_Tp> std::operator*(const std::complex<_Tp>&, const std::complex<_Tp>&)
/usr/local/include/boost/range/algorithm/transform.hpp:65:17: error: no match for ‘operator++’ in ‘++out’
/usr/local/include/boost/range/algorithm/transform.hpp:65:17: note: candidate is:
/usr/local/include/boost/iterator/iterator_facade.hpp:722:3: note: template<class I, class V, class TC, class R, class D> typename boost::detail::postfix_increment_result<I, V, R, TC>::type boost::operator++(boost::iterator_facade<Derived, V, TC, R, D>&, int)

Your problem is that the third parameter to boost::transform is not a range, but rather an (output) iterator that is used to write the results into.
The following code compiles for me:
boost::transform ( a, b, a.begin(), std::plus<double>());

Related

A value of type 'num' can't be assigned to a variable of type 'T'

hello when i use this generic method i get this error
A value of type 'num' can't be assigned to a variable of type 'T'. Try changing the type of the variable, or casting the right-hand type to 'T'.
what the error here
sums<T extends num>(List<T> list) {
T res =list[0];
for (var i = 1; i < list.length; i++) {
res = res + list[i];
}
print(res);
}
The issue here is that Dart's new Null Safety feature, introduced in Dart 2.12.0, removed implicit downcasts from the language.
If res has type T where T extends num, then the operation res + something has static type num. The only thing we know about T is that it implements num, and num.operator+ returns num.
However, num is not assignable to T extends num because the latter is a subtype of the former (T could be int, not all num values are assignable to int).
So, you need an explicit cast to make the assignment valid:
res = (res + list[i]) as T;
is such a cast. If you just write res = res + list[i] as T;, the precedence of as means that it's the same as the cast above.
In Dart 2.10.x, it worked without the explicit cast because the language inserted an implicit cast for you.
If you write res += list[i] as T; it instead means res = res + (list[i] as T); which is an unnecessary cast since list[i] already has type T, and doesn't cast the result of the addition.
The reason this doesn't fail all the time for int res = ...; res = res + otherInt; is that the language specification treats int.operator+ specially (along with some similar integer operators) and recognizes when the result is an integer, even if the + operator's return type is num. That special-casing does not apply to T extends num.
This appears to either be a bug or a misunderstood feature of Dart 2.12+. In either case, it might be worth opening an issue on the Dart Github page.
If I run the following code in 2.12.0:
void main() {
final nums = [1, 2.0, 3.5];
final ints = [1, 2, 3];
final doubles = [1.1, 2.2, 3.3];
sums(nums);
sums(ints);
sums(doubles);
}
void sums<T extends num>(List<T> list) {
T res = list[0];
for (var i = 1; i < list.length; i++) {
res = res + list[i];
}
print(res);
}
I get the error you mentioned:
main.dart:14:9: Error: A value of type 'num' can't be assigned to a variable of type 'T'.
res = res + list[i];
^
If, however, I run the same code in Dart 2.10.5, the program compiles and runs without a problem and I get the following printout:
6.5
6
6.6
My best guess is that there is an issue with type inference where the type parameter of the List is concerned. Instead of taking the actual type parameter passed to sums, it seems instead to be taking the type restraint num as its inferred type. As a result, the type system sees that you are adding a num to a T extends num and then assigning it to the latter. (To explain, imagine T is int. A num plus an int would result in a num. Trying to then assign that to an int results in a type error since, for all the type system knows, the num might actually be a double.)
At any rate, the error goes away once you do what the error suggests and cast the elements of list to T:
void sums<T extends num>(List<T> list) {
T res = list[0] as T;
for (var i = 1; i < list.length; i++) {
res = res + list[i] as T;
}
print(res);
}
// Prints:
//
// 6.5
// 6
// 6.6
Interestingly, though, using an addition-assignment instead will cause the same error regardless of the cast:
void sums<T extends num>(List<T> list) {
T res = list[0];
for (var i = 1; i < list.length; i++) {
res += list[i] as T;
}
print(res);
}
// Prints:
//
// main.dart:14:9: Error: A value of type 'num' can't be assigned to a variable of type 'T'.
// res += list[i];
// ^
EDIT: I've filed an issue for this topic on the Dart SDK Github page.
EDIT 2: Turns out this is not a bug but the result of an intended change to Dart as part of 2.12. See Irn's answer for details.

Genie Vala Generics and Nullable Types

Simple question: In the following generic class, how should the generic type and contained types be defined so that they are nullable? The following will not compile.
class Pair? of G1, G2: Object
_first:G1?
_second:G2?
construct()
_first = null
_second = null
def insert( first:G1, second:G2 )
_first = first
_second = second
def insert_first( value:G1 )
_first = value
def insert_second( value:G2 )
_second = value
def second():G2
return _second
Usage:
var pair = new Pair() of string, string
pair = null
Due to the way Vala Generics work, generic parameters are always nullable.
As long as you don't switch on --enable-experimental-non-null class variables are nullable as well, so your code simplifies to:
[indent=4]
class Pair of G1, G2: Object
_first:G1
_second:G2
construct()
_first = null
_second = null
def insert( first:G1, second:G2 )
_first = first
_second = second
def insert_first( value:G1 )
_first = value
def insert_second( value:G2 )
_second = value
def second():G2
return _second
init
var pair = new Pair of string, string
pair = null
When --enable-experimental-non-null is on, you have to be explicit in the type of the variable. I don't know how to write this in Genie, I tried this, but the compiler does not like it:
init
pair: Pair? of string, string = new Pair of string, string
pair = null
In Vala it's no problem:
class Pair<G1,G2>: Object {
private G1 first;
private G2 second;
public Pair () {
first = null;
second = null;
}
// ...
}
int main () {
Pair<string, string>? pair = new Pair<string, string> ();
pair = null;
return 0;
}
I can't wrap my head around the concept of a type parameter that has null as the type. I don't think that is a useful concept. So the definition of your class would be:
[indent = 4]
class Pair of G1, G2: Object
_first:G1?
_second:G2?
def insert( first:G1, second:G2 )
_first = first
_second = second
def insert_first( value:G1 )
_first = value
def insert_second( value:G2 )
_second = value
def second():G2
return _second
If you must re-assign the variable that has the object instance to null then it would be:
[indent = 4]
init
var pair = new Pair of string,string()
pair = null
The Vala compiler will, however, dereference pair when it goes out of scope. So I'm not sure why you would need to assign null.
The use of nulls would ideally only be used when interfacing with a C library in my view. Accessing a null can lead to a crash (segmentation fault) if it is not checked for properly. For example:
init
a:int? = 1
a = null
var b = a + 1
The Vala compiler does have an experimental non-null mode that does some checking for unsafe code. If you compile the following with the Vala switch --enable-experimental-non-null:
[indent = 4]
init
var pair = new Pair of string,string()
pair = null
you will get the error:
error: Assignment: Cannot convert fromnull' to Pair<string,string>'
If you understand the consequences then you can tell the compiler this is OK with:
[indent = 4]
init
pair:Pair? = new Pair of string,string()
pair = null

Type parameter issue in Scala with generic function

I'm trying to come up with a generic function (toBitSet) using type parameter T.
def toBitSet[T:Integral](x:T, valueBitwidth:Int, filterBitwidth:Int, bigEndian:Boolean = true, shift:Int = 0) = {
BitSet((for (i <- 0 to (valueBitwidth - 1) if (((x & 0xFF) >> i) & 1) == 1) yield (i + shift)): _*)
}
byteToBitSet and shortToBitSet functions are specializaton of the generic function.
def byteToBitSet(x:Byte, filterBitwidth:Int, bigEndian:Boolean = true, shift:Int = 0) = {
toBitSet[Byte](x = x, valueBitwidth = 8, filterBitwidth = filterBitwidth, bigEndian = bigEndian, shift = shift)
}
def shortToBitSet(x:Short, filterBitwidth:Int, bigEndian:Boolean = true, shift:Int = 0) = {
toBitSet[Short](x = x, valueBitwidth = 16, filterBitwidth = filterBitwidth, bigEndian = bigEndian, shift = shift)
}
However, Scala doesn't understand the operators (>>, &, ==, +) on type T to show an error message. I specified that T is Integral type, but it doesn't work.
How to solve this issue?
The type signature
def func[T: Integral](arg: T) = {}
is actually a syntactic shorthand for:
def func[T](arg: T)(implicit ev: Integral[T]) = {} ("ev" is often chosen as the name for this "evidence" argument.)
The Integral trait outlines what operations you then use on elements of type T. Example: addition is ev.plus(t1, t2)
If you import Integral.Implicits._ then you can use the more natural infix notation: t1 + t2
Unfortunately, the Integral trait doesn't include bit-wise operations like & and >>.
If you can modify your algorithm to use only those available ops you'll get the function you're after.

Scala native methods in inner classes

I have:
class XCClass
{
#native protected def createWin(displayPtr: Long, width: Int, height: Int, backGroundColour: Int = white.value,
borderColour: Int = darkblue.value, borderWidth: Int = 0, xPosn: Int = 0, yPosn: Int = 0): Long
#native protected def xOpen(): Long
System.load("/sdat/projects/prXCpp/Release/libprXCpp.so")
//Code edited out
class Window(width: Int, height: Int, backGroundColour: ColourInt = white, borderColour: ColourInt = darkblue,
borderWidth: Int = 0, xPosn: Int = 0, yPosn: Int = 0)
{
val xWinPtr = createWin(xServPtr, width, height, backGroundColour.value, borderColour.value, borderWidth, xPosn, yPosn)
#native def drawLine(x1: Int, y1: Int, x2: Int, y2: Int): Unit
}
}
The first two methods work fine, but the native method on the inner class gives
object XApp extends App
{
val xc:XCClass = XCClass()
val win: xc.Window = xc.Window(800, 600)
win.drawLine(20, 20, 40, 40)
readLine()
}
Exception in thread "main" java.lang.UnsatisfiedLinkError: pXClient.XCClass$Window.drawLine(IIII)V
Here's the C++ signature
extern "C" JNIEXPORT void JNICALL Java_pXClient_XCClass$Window_drawLine(JNIEnv * env, jobject c1, Display *dpy,
Window win, jint x1, jint y1, jint x2, jint y2)
I tried using an underscore instead of the $ sign, and having no inner name at all but that failed as well.
Edit2: I managed to get javah to work just before seeing Robin's answer and it gave
JNIEXPORT void JNICALL Java_pXClient_XCClass_00024Window_drawLine
(JNIEnv *, jobject, jint, jint, jint, jint);
Edit4: It worked fine once I'd corrected errors in my code. It seems that the JVM will import a native function with the wrong parameter signature as long as the name is correct.
I just did a quick test with a .java file and javah, and a $ is represented as _00024.

scala delimited continuations typing

I am still in a process of figuring out the exact typing rules/implications involved in here.
It seems easy/easier if the types in the examples are "simple enough" to "fit well" as in almost all simple examples is the case, but it becomes more interresting/difficult (at least for me) in comparing things to the typing given by tiark rompf:
|- e: A#cpsParam[B,C]; {[|r|]}: U
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )
so the result of [|e|].map( (x: A) => {[|r|]} ) will have the type Shift[U,B,C] according to the definition of map given in tiark's paper.
Here U is not necessarily the same as B.
So far I do not understand why U is allowed to be different from B without something like U <: B given in the definition of map in tiark's paper.
What am I missing respectively failing to understand here?
Any tips/ideas?
I had a second look at this as wanted to see what the result of the selective cps transform will yield in both cases.
U <: B
U is not a subtype of B
I used the following simple example:
package sample
import scala.util.continuations._
class Depp {
override def toString = "DEPP"
}
class Sepp extends Depp {
override def toString = "DEPP->SEPP"
}
object Sample extends Application {
val depp = new Depp
val sepp = new Sepp
val res = reset {
shift {
(k: Int => Depp) => k(7)
}
val z = sepp
z
}
println("Result = "+ res)
}
Compiling this using
scalac -P:continuations:enable -Xprint:selectivecps Sample.scala
proves successful and yields the following (interesting part only):
private[this] val res: sample.Depp = scala.util.continuations.package.reset[sample.Sepp, sample.Depp]({
package.this.shiftR[Int, sample.Depp, sample.Depp](((k: (Int) => sample.Depp) => k.apply(7))).map[sample.Sepp]
tmp1;
val z: sample.Sepp = Sample.this.sepp;
z
}))
ok so the type of the resulting (application of map) Shift object is [Sepp,Depp,Depp] as expected :)
which is fine because i understand how Shift objects like A#cpsParam[A,C] come into existence (the reset function given in Tiark's paper operates on such Shift objects)
Now changing the following in the simple example to yield a type unrelated to Depp: z.asInstanceOf[Float]
compiling this with
scalac -P:continuations:enable -Xprint:selectivecps -explaintypes Sample.scala
brings up the following error which tells what is actually checked:
Sample.scala:16: error: type mismatch;
found : Float #scala.util.continuations.cpsParam[sample.Depp,sample.Depp] #scala.util.continuations.cpsSynth
required: Float #scala.util.continuations.cpsParam[Float,sample.Depp]
val res = reset {
^
Float #scala.util.continuations.cpsParam[sample.Depp,sample.Depp] #scala.util.continuations.cpsSynth <: Float #scala.util.continuations.cpsParam[Float,sample.Depp]?
scala.util.continuations.cpsParam[sample.Depp,sample.Depp] <: scala.util.continuations.cpsParam[Float,sample.Depp]?
Float <: sample.Depp?
<notype> <: sample.Depp?
false
false
false
false
one error found
ahh and here is the test: Float <: sample.Depp?
so it fails because Float of course isn't a subtype of Depp
question: shouldn't the transformation rule then better be given as:
e: A#cpsParam[B,C] {[|r|]}: U U <: B
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )
to clearly express this?