I have the following protocol buffer (proto3 syntax)
message Operation {
enum Operator {
UNKNOWN = 0;
ADD = 1;
...
}
float operand = 1;
Operator operator = 2;
}
The enum is generated as
type Operation_Operator int32
I'm creating the Operation message like so
//Assume package is pb
oper, found := pb.Operation_Operator_value(os.Args[1]) // one of the enums
if !found {
// do something
}
msg := &pb.Operation {
Operand: float32(aNum),
Operator: pb.Operation_Operator(oper),
}
My question is is there an idiomatic way of converting int32 to Operation_Operator apart from casting as I did above?
Related
I have a very simple question i guess but...
I have to sort a vector by it's own member, but I can not.
This is my function for filling the vector with objects from another vector.
I have to sort the vector SortDealers by specific product but I don't know how to send the name of the Stock to my overloading operator<
void CShop::sortVector(const CStock& s1)
{
vector<CDealer> SortDealers;
vector<CDealer* >::iterator it = Dealers.begin();
while (it != Dealers.end())
{
if ((*(*it)).ComapareNameProducts(s1))
{
SortDealers.push_back(*(*it));
}
it++;
}
sort(SortDealers.begin(), SortDealers.end());
copy(SortDealers.begin(), SortDealers.end(), ostream_iterator<CDealer>(cout, "\n"));
}
this is overloading operator<:
I have to sort by unsigned member of the map.
bool CDealer::operator<(const CDealer & o1)
{
unsigned res1 = 0;
unsigned res2= 0;
map<const CStock, pair<unsigned, double>>::const_iterator it = Stock.begin();
map<const CStock, pair<unsigned, double>>::const_iterator iter = o1.Stock.begin();
while (it != Stock.end())
{
res1 += it->second.first;
it++;
}
while (iter != o1.Stock.end())
{
res2 += iter->second.first;
iter++;
}
return (res1 < res2);
}
You can use functor:
class less_than
{
const string stockname;
public:
less_than(string s) : stockname(s) {}
inline bool operator() const (const CDealer& a, const CDealer& b)
{
// use stockname here
}
};
sort(SortDealers.begin(), SortDealers.end(), less_than("name"));
Also you can use lambda expression providing stock name in its capture.
Related answer.
I'm trying to call some ioctls from Go, and some of them take C strings as parameters. For example, in C:
/* When the user asks to bind a message name to an interface, they use: */
struct kbus_bind_request {
__u32 is_replier; /* are we a replier? */
__u32 name_len;
char *name;
};
extern int kbus_ksock_bind(kbus_ksock_t ksock,
const char *name,
uint32_t is_replier)
{
int rv;
kbus_bind_request_t bind_request;
bind_request.name = (char *) name;
bind_request.name_len = strlen(name);
bind_request.is_replier = is_replier;
rv = ioctl(ksock, KBUS_IOC_BIND, &bind_request);
if (rv < 0)
return -errno;
else
return rv;
}
I converted the struct to a Go struc like this:
type kbus_bind_request struct {
is_replier uint32 /* are we a replier? */
name_len uint32
name unsafe.Pointer // char*
}
Now, how do I convert a Go string to a C string stored in an unsafe.Pointer? I don't want to use CGo as I am cross-compiling and it makes things a pain.
Ah found the answer (well something that compiles anyway). First cast to []byte, then take the address of the first element:
func int_bind(ksock int, name string, is_replier uint32) int {
bind_request := &kbus_bind_request{}
s := []byte(name)
bind_request.name = unsafe.Pointer(&s[0])
bind_request.name_len = uint32(len(s))
bind_request.is_replier = is_replier
rv := ioctl(ksock, KBUS_IOC_BIND, unsafe.Pointer(bind_request))
if rv != 0 {
return -int(rv)
}
return 0
}
I have a custom method that pops an object from a queue of value objects as out parameter and returns an error code:
class Element
{
public:
Element() = delete;
Element(int32_t a, const std::string &s)
{
a_ = a;
s_ = s;
}
private:
int32_t a_;
std::string s_;
}
enum class ErrorCode : uint32_t
{
OK = 0,
QueueEmpty,
QueueFull
}
class QueueWrapper
{
public:
ErrorCode push(const Element &e)
{
// Implementation
}
ErrorCode pop(Element &outE)
{
// Simple example
if(queue_.empty())
{
return ErrorCode::QueueEmpty;
}
outE = queue_.front();
queue_.pop();
return ErrorCode::OK;
}
private
std::queue<Element> queue_;
}
void function()
{
QueueWrapper queueWrapper;
Element e1(1, "1");
ErrorCode errorCode = queueWrapper.push(e1);
// What should I do here?
// Element e2;
// errorCode = queueWrapper.pop(e2);
}
Can I get a non-default constructed object as output parameter using move semantics or other mechanisms?
Change the signature of pop() to return an Element and not an ErrorCode, then:
Element e( queueWrapper.pop() );
If you absolutely have to have the ErrorCode, pass it into pop() by reference. BUT error codes really aren't modern C++. Errors should mostly be handled with exceptions, leading to something more like this:
try {
...
Element e( queueWrapper.pop() );
...
}
catch ( QueueWrapper::Exception & e )
{
// exception handling/reporting
}
Error codes should really only be used for crossing module boundaries.
No. If you can form a reference to an Element, that means it has already be constructed (or it would be a segment of memory gibberish, not an Element).
If the behaviour you want is for the function to somehow get a designated space to construct the object into, let (N)RVO do the job.
I am converting some algorithm pseudo code to Swift and have the following function:
func max(a: [Int], b: Int) {
var result = a[0]
var i: Int
for (i = 1; i <= b; i++) {
if (a[i] > result) {
result = a[i]
}
}
return result
}
I get an error when returning the result: 'Int' is not convertible to '()'
I've had a search online and can't find an answer to this question and am hoping someone can point me in the right direction.
Thanks
The return type is missing in the function declaration:
func max(inout a: [Int], b: Int) -> Int {
^^^^^^
Without a return type, swift defaults to an empty tuple (), and that's what the error means: int is not convertible to an empty tuple.
Also note that your return statement is misplaced: it should go right before the last closing bracket
}
return result
}
and not
return result
}
}
You must Implement the return type like this
func max(inout a: [Int], b: Int)-> Int {
var result = a[0]
var i: Int
for (i = 1; i <= b; i++) {
if (a[i] > result) {
result = a[i]
}
}
return result
}
I am trying to implement a version of FNV hash in swift. Here it is in Objective-C:
+ (uint32_t)hash:(uint8_t *)a length:(uint32_t)length
{
uint8_t *p;
uint32_t x;
p = a;
x = *p << 7;
for (int i=0; i<length; i++) {
x = (1000003 * x) ^ *p++;
x ^= length;
}
if (x == -1) {
x = -2;
}
return x;
}
Here is my attempt at porting it to swift:
func hashFNV(data: UInt8[]) -> UInt32 {
var x = data[0] << 7
for byte in data {
x *= 1000003
x ^= byte
x ^= data.count
}
if x == -1 {
x = -2
}
return x
}
It compiles but results in an error at runtime:
EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode=0x0)
Same error when I try in the playground:
Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
* thread #1: tid = 0x619fa, 0x000000010d119aad, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
* frame #0: 0x000000010d119aad
frame #1: 0x0000000100204880 libswift_stdlib_core.dylib`value witness table for Swift.Int + 160
I thought that maybe it was related to the overflow, but the following code also fails with the same error:
func hashFNV(data: UInt8[]) -> UInt32 {
var x = UInt32(data[0]) << 7
for byte in data {
x = 1000003 &* x
x ^= byte
x ^= data.count
}
if x == -1 {
x = -2
}
return x
}
EDIT:
Actually, shouldn't the fact that I am trying to assign -2 to x result in a compile error? I thought swift won't implicitly cast from what looks like Int (-2) to UInt32 (x).
Same with the x ^= byte line. byte should be UInt8 and x is UInt32.
EDIT 2:
This was a compile error (see comments below).
Fixed the compile error, still fails at runtime:
func hashFNV(data: UInt8[]) -> UInt32 {
var x = Int(data[0]) << 7
for byte in data {
x = 1000003 &* x
x ^= Int(byte)
x ^= data.count
}
if x == -1 {
x = -2
}
return UInt32(x)
}
If you are still looking for an implementation, here is mine. It is built much like the regular default Hasher from the standard lib.
struct HasherFNV1a {
private var hash: UInt = 14_695_981_039_346_656_037
private let prime: UInt = 1_099_511_628_211
mutating func combine<S: Sequence>(_ sequence: S) where S.Element == UInt8 {
for byte in sequence {
hash ^= UInt(byte)
hash = hash &* prime
}
}
func finalize() -> Int {
Int(truncatingIfNeeded: hash)
}
}
extension HasherFNV1a {
mutating func combine(_ string: String) {
combine(string.utf8)
}
mutating func combine(_ bool: Bool) {
combine(CollectionOfOne(bool ? 1 : 0))
}
}
Keep in mind that this is FNV1a, if you truly need FNV1 you can just switch the 2 lines in the loop around.
I found this GPL Swift implementation:
//
// FNVHash.swift
//
// A Swift implementation of the Fowler–Noll–Vo (FNV) hash function
// See http://www.isthe.com/chongo/tech/comp/fnv/
//
// Created by Mauricio Santos on 3/9/15.
import Foundation
// MARK:- Constants
private struct Constants {
// FNV parameters
#if arch(arm64) || arch(x86_64) // 64-bit
static let OffsetBasis: UInt = 14695981039346656037
static let FNVPrime: UInt = 1099511628211
#else // 32-bit
static let OffsetBasis: UInt = 2166136261
static let FNVPrime: UInt = 16777619
#endif
}
// MARK:- Public API
/// Calculates FNV-1 hash from a raw byte array.
public func fnv1(bytes: [UInt8]) -> UInt {
var hash = Constants.OffsetBasis
for byte in bytes {
hash = hash &* Constants.FNVPrime // &* means multiply with overflow
hash ^= UInt(byte)
}
return hash
}
/// Calculates FNV-1a hash from a raw byte array.
public func fnv1a(bytes: [UInt8]) -> UInt {
var hash = Constants.OffsetBasis
for byte in bytes {
hash ^= UInt(byte)
hash = hash &* Constants.FNVPrime
}
return hash
}
/// Calculates FNV-1 hash from a String using it's UTF8 representation.
public func fnv1(str: String) -> UInt {
return fnv1(bytesFromString(str))
}
/// Calculates FNV-1a hash from a String using it's UTF8 representation.
public func fnv1a(str: String) -> UInt {
return fnv1a(bytesFromString(str))
}
/// Calculates FNV-1 hash from an integer type.
public func fnv1<T: IntegerType>(value: T) -> UInt {
return fnv1(bytesFromNumber(value))
}
/// Calculates FNV-1a hash from an integer type.
public func fnv1a<T: IntegerType>(value: T) -> UInt {
return fnv1a(bytesFromNumber(value))
}
/// Calculates FNV-1 hash from a floating point type.
public func fnv1<T: FloatingPointType>(value: T) -> UInt {
return fnv1(bytesFromNumber(value))
}
/// Calculates FNV-1a hash from a floating point type.
public func fnv1a<T: FloatingPointType>(value: T) -> UInt {
return fnv1a(bytesFromNumber(value))
}
// MARK:- Private helper functions
private func bytesFromString(str: String) -> [UInt8] {
var byteArray = [UInt8]()
for codeUnit in str.utf8 {
byteArray.append(codeUnit)
}
return byteArray
}
private func bytesFromNumber<T>(var value: T) -> [UInt8] {
return withUnsafePointer(&value) {
Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>($0), count: sizeof(T)))
}
}