How to convert __value enum from VS2003 to VS2010 - c++-cli

I have this code snippet from VS2003, Managed C++ and I want to rewrite it in the 2010 C++/CLI way but the newer compiler doesn't accept the 'feature_all' enumeration.. Can someone tell me how to convert it correctly?
This is the snippet in VS 2003:
[Flags]
__value enum Features: unsigned int
{
feature_1 = 1,
feature_2 = 2,
feature_3 = 4,
feature_all = feature_1 | feature_2 | feature_3 // accepted by compiler
};
I tried writing it like this in VS 2010:
[FlagsAttribute]
value class enum Features: unsigned int {
feature1 = 1,
feature2 = 2,
feature3 = 4,
feature_all = feature_1 | feature_2 | feature_3 // not accepted by compiler
};
But the second is definitely not working...
The compiler returns 7 Errors: (C2332, C2236, 3x C2065, C2056 and C3115)

The proper keyword is enum class, also adopted in C++11:
[FlagsAttribute]
public enum class Features: int {
feature1 = 1,
feature2 = 2,
feature3 = 4,
feature_all = feature1 | feature2 | feature3
};
Note how I also removed the mysterious underscores, assumed that you want to make this enum type visible to other .NET projects and wanted it to be CLS compliant so it can be consumed by languages that don't support unsigned types. int is the default and can be omitted. Tweak as needed.

Related

enums in nim for wrapper of c library

I am trying to create a simple nim wrapper around the Clever Audio Plugin c library.
In c there is an enum of format flags that can be activated using bitwise operations.
summary of the c code
# definitions
enum clap_note_dialect {
CLAP_NOTE_DIALECT_CLAP = 1 << 0,
CLAP_NOTE_DIALECT_MIDI = 1 << 1,
CLAP_NOTE_DIALECT_MIDI_MPE = 1 << 2,
CLAP_NOTE_DIALECT_MIDI2 = 1 << 3,
};
typedef struct clap_note_port_info {
...
uint32_t supported_dialects; // bitfield, see clap_note_dialect
...
} clap_note_port_info_t;
# implementation
info->supported_dialects =
CLAP_NOTE_DIALECT_CLAP | CLAP_NOTE_DIALECT_MIDI_MPE | CLAP_NOTE_DIALECT_MIDI2;
using c2nim I get the following nim code:
type
clap_note_dialect* = enum
CLAP_NOTE_DIALECT_CLAP = 1 shl 0,
CLAP_NOTE_DIALECT_MIDI = 1 shl 1,
CLAP_NOTE_DIALECT_MIDI_MPE = 1 shl 2,
CLAP_NOTE_DIALECT_MIDI2 = 1 shl 3
clap_note_port_info* {.bycopy.} = object
...
supported_dialects*: uint32 ## bitfield, see clap_note_dialect
# implementation:
info.supported_dialects = CLAP_NOTE_DIALECT_CLAP or CLAP_NOTE_DIALECT_MIDI_MPE or
CLAP_NOTE_DIALECT_MIDI2
When compiling I get an mismatch error and message that "expression 'CLAP_NOTE_DIALECT_CLAP' is of type: clap_note_dialect"
How can I let nim know that my enum should be uint32 values?
Note that you may also use an enum set in Nim when you have to wrap C enums that are used as ored bits. I did that in the GTK wrapper. You can find an example at the end of the the "Sets" section here: https://ssalewski.de/nimprogramming.html#_sets
But some care is necessary, so for plain and ugly wrappers, or unexperienced people, using distinct ints may be another solution.
This fix came from user Vindaar on the Nim #main discord channel:
"in order to or the enum values you'll want to wrap them in an ord, so:"
info.supported_dialects = ord(CLAP_NOTE_DIALECT_CLAP) or ord(CLAP_NOTE_DIALECT_MIDI_MPE) or ord(CLAP_NOTE_DIALECT_MIDI2)

Anyway to type convert all elements in solidity array?

I have been trying Solidity lately.
While trying to create a public int array.
Test.sol
pragma solidity >=0.8.12 <0.9.0;
contract Test {
int[5] public array = [1, 2, 3, 4, 5];
}
The following error is thrown:
TypeError: Type uint8[5] memory is not implicitly convertible to
expected type int256[5] storage ref.
--> first.sol:4:27:
|
4 | int[5] public array = [1, 2, 3, 4, 5];
| ^^^^^^^^^^^^^^^
So I tried with type conversion, like below:
pragma solidity >=0.8.12 <0.9.0;
contract Test {
int[5] public array = [int(1), int(2), int(3), int(4), int(5)];
}
Which works, but type converting every element doesn't seem conventional to me.
Is there any other way?
--------------------- Edit ------------------------------
In solidity, just type casting first element works.
So following solved the problem:
int[5] staticArray = [int(1), 2, 3, 4, 5];
This seems to be a bug in the compiler.
A small enough number literal (such as 1 or 2 in your example) fits into the type for uint8 (max value 255), so the compiler treats the literal as uint8 type by default.
You need to workaround this by using the typecast function, just as shown in your question.
int[5] public array = [int(1), int(2), int(3), int(4), int(5)];
Hopefully it's fixed in a later Solidity version.

rust-numpy asks for a different version of ndarray

I can reproduce the problem I am currently having with Cargo.toml and lib.rs as shown below.
use ndarray::{ArrayD, ArrayViewD, ArrayViewMutD};
use numpy::{IntoPyArray, PyArrayDyn, PyReadonlyArrayDyn};
use pyo3::prelude::{pymodule, PyModule, PyResult, Python};
#[pymodule]
fn rust_ext(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
// immutable example
fn axpy(a: f64, x: ArrayViewD<'_, f64>, y: ArrayViewD<'_, f64>) -> ArrayD<f64> {
a * &x + &y
}
// mutable example (no return)
fn mult(a: f64, mut x: ArrayViewMutD<'_, f64>) {
x *= a;
}
// wrapper of `axpy`
#[pyfn(m, "axpy")]
fn axpy_py<'py>(
py: Python<'py>,
a: f64,
x: PyReadonlyArrayDyn<f64>,
y: PyReadonlyArrayDyn<f64>,
) -> &'py PyArrayDyn<f64> {
let x = x.as_array();
let y = y.as_array();
axpy(a, x, y).into_pyarray(py)
}
// wrapper of `mult`
#[pyfn(m, "mult")]
fn mult_py(_py: Python<'_>, a: f64, x: &PyArrayDyn<f64>) -> PyResult<()> {
let x = unsafe { x.as_array_mut() };
mult(a, x);
Ok(())
}
Ok(())
}
This code is from the README.md of rust-numpy.
We also created a Cargo.toml as shown below.
[package]
name = "pyotest"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
pyo3 = { version = "0.13",features=["extension-module"] }
numpy = "0.13"
ndarray = "0.14"
[lib]
name="preprocess"
crate-type = ["cdylib"]
If you do this, two versions of ndarray will be installed, resulting in version conflicts, so it will not compile.
The error message is as follows
Compiling pyotest v0.1.0 (/home/bokutotu/pyotest)
error[E0308]: mismatched types
--> src/lib.rs:50:17
|
50 | axpy(a, x, y).into_pyarray(py)
| ^ expected struct `ArrayBase`, found struct `ndarray::ArrayBase`
|
= note: expected struct `ArrayBase<ViewRepr<&f64>, Dim<IxDynImpl>>`
found struct `ndarray::ArrayBase<ndarray::ViewRepr<&f64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>>`
= note: perhaps two different versions of crate `ndarray` are being used?
error[E0308]: mismatched types
--> src/lib.rs:50:20
|
50 | axpy(a, x, y).into_pyarray(py)
| ^ expected struct `ArrayBase`, found struct `ndarray::ArrayBase`
|
= note: expected struct `ArrayBase<ViewRepr<&f64>, Dim<IxDynImpl>>`
found struct `ndarray::ArrayBase<ndarray::ViewRepr<&f64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>>`
= note: perhaps two different versions of crate `ndarray` are being used?
error[E0599]: no method named `into_pyarray` found for struct `ArrayBase<OwnedRepr<f64>, Dim<IxDynImpl>>` in the current scope
--> src/lib.rs:50:23
|
50 | axpy(a, x, y).into_pyarray(py)
| ^^^^^^^^^^^^ method not found in `ArrayBase<OwnedRepr<f64>, Dim<IxDynImpl>>`
error[E0308]: mismatched types
--> src/lib.rs:57:17
|
57 | mult(a, x);
| ^ expected struct `ArrayBase`, found struct `ndarray::ArrayBase`
|
= note: expected struct `ArrayBase<ViewRepr<&mut f64>, Dim<IxDynImpl>>`
found struct `ndarray::ArrayBase<ndarray::ViewRepr<&mut f64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>>`
= note: perhaps two different versions of crate `ndarray` are being used?
warning: unused import: `IntoPyArray`
--> src/lib.rs:25:13
|
25 | use numpy::{IntoPyArray, PyArrayDyn, PyReadonlyArrayDyn};
| ^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error: aborting due to 4 previous errors; 1 warning emitted
Some errors have detailed explanations: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `pyotest`
To learn more, run the command again with --verbose.
You can also check Cargo.lock to see that it is trying to install two versions of ndarray.
....
[[package]]
name = "ndarray"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c0d5c9540a691d153064dc47a4db2504587a75eae07bf1d73f7a596ebc73c04"
dependencies = [
"matrixmultiply 0.2.4",
"num-complex 0.3.1",
"num-integer",
"num-traits",
"rawpointer",
]
...
[[package]]
name = "ndarray"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08e854964160a323e65baa19a0b1a027f76d590faba01f05c0cbc3187221a8c9"
dependencies = [
"matrixmultiply 0.3.1",
"num-complex 0.4.0",
"num-integer",
"num-traits",
"rawpointer",
]
...
[[package]]
name = "numpy"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996bcd58fb29bef9debf717330cd8876c3b4adbeea4939020a5326a3afad4d9"
dependencies = [
"cfg-if 0.1.10",
"libc",
"ndarray 0.15.3",
"num-complex 0.4.0",
"num-traits",
"pyo3",
]
As you can see, I have installed a strange version due to rust-numpy. What should I do in this case?
I want to use 0.14 for ndarray-linalg because of the version of ndarray.

Conditionally return empty iterator from flat_map

Given this definition for foo:
let foo = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
I'd like to be able to write code like this:
let result: Vec<_> = foo.iter()
.enumerate()
.flat_map(|(i, row)| if i % 2 == 0 {
row.iter().map(|x| x * 2)
} else {
std::iter::empty()
})
.collect();
but that raises an error about the if and else clauses having incompatible types. I tried removing the map temporarily and I tried defining an empty vector outside the closure and returning an iterator over that like so:
let empty = vec![];
let result: Vec<_> = foo.iter()
.enumerate()
.flat_map(|(i, row)| if i % 2 == 0 {
row.iter() //.map(|x| x * 2)
} else {
empty.iter()
})
.collect();
This seems kind of silly but it compiles. If I try to uncomment the map then it still complains about the if and else clauses having incompatible types. Here's part of the error message:
error[E0308]: if and else have incompatible types
--> src/main.rs:6:30
|
6 | .flat_map(|(i, row)| if i % 2 == 0 {
| ______________________________^
7 | | row.iter().map(|x| x * 2)
8 | | } else {
9 | | std::iter::empty()
10 | | })
| |_________^ expected struct `std::iter::Map`, found struct `std::iter::Empty`
|
= note: expected type `std::iter::Map<std::slice::Iter<'_, {integer}>, [closure#src/main.rs:7:28: 7:37]>`
found type `std::iter::Empty<_>`
Playground Link
I know I could write something that does what I want with some nested for loops but I'd like to know if there's a terse way to write it using iterators.
Since Rust is statically typed and each step in an iterator chain changes the result to a new type that entrains the previous types (unless you use boxed trait objects) you will have to write it in a way where both branches are covered by the same types.
One way to convey conditional emptiness with a single type is the TakeWhile iterator implementation.
.flat_map(|(i, row)| {
let iter = row.iter().map(|x| x * 2);
let take = i % 2 == 0;
iter.take_while(|_| take)
})
If you don't mind ignoring the edge-case where the input iterator foo could have more than usize elements you could also use Take instead with either 0 or usize::MAX. It has the advantage of providing a better size_hint() than TakeWhile.
In your specific example, you can use filter to remove unwanted elements prior to calling flat_map:
let result: Vec<_> = foo.iter()
.enumerate()
.filter(|&(i, _)| i % 2 == 0)
.flat_map(|(_, row)| row.iter().map(|x| x * 2))
.collect();
If you ever want to use it with map instead of flat_map, you can combine the calls to filter and map by using filter_map which takes a function returning an Option and only keeps elements that are Some(thing).

Setting bitmask enum declared in objective-c from swift

I'm trying to use Parse SDK for iOS in my new project. It has viewController with enum property;
typedef enum {
PFLogInFieldsNone = 0,
PFLogInFieldsUsernameAndPassword = 1 << 0,
PFLogInFieldsPasswordForgotten = 1 << 1,
PFLogInFieldsLogInButton = 1 << 2,
PFLogInFieldsFacebook = 1 << 3,
PFLogInFieldsTwitter = 1 << 4,
PFLogInFieldsSignUpButton = 1 << 5,
PFLogInFieldsDismissButton = 1 << 6,
PFLogInFieldsDefault = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton | PFLogInFieldsPasswordForgotten | PFLogInFieldsDismissButton
} PFLogInFields;
According to tutorial in Objective-C I should set it in this way:
[logInViewController setFields: PFLogInFieldsTwitter | PFLogInFieldsFacebook | PFLogInFieldsDismissButton];
I'm trying to do it in this way(using swift):
loginViewController.fields = PFLogInFieldsTwitter | PFLogInFieldsFacebook | PFLogInFieldsDismissButton
But I get error:"'PFLogInFields' is not convertible to 'Bool'"
So, what is the correct way to set such kind of properties?
Consecutive enums in Objective-C should be refactored to use NS_ENUM, and bit-field enums should be refactored to use NS_OPTIONS.
You should change
typedef enum {
//...
} PFLogInFields;
to
typedef NS_OPTIONS(NSInteger, PFLogInFields) {
//...
};
I had the same problem as you. See this answer for how to set PFLogInFields in Swift. It worked for me!!
In Swift you have to prefix the enums with the Type. I am not sure if this works automatically with Objective-C imports, but it might:
logInViewController.fields = PFLogInFields.PFLogInFieldsTwitter | ...
If the library were ported to Swift standard, the fields would already expect PFLoginFields and the enum items would be defined in a manner so that you can write
logInViewController.fields = .Twitter | .Facebook ...