I have a struct that looks something like this:
struct MultipartMessage {
ubyte[] mime, data;
Header header;
void setSender(string sender) {
header.sender = sender;
}
void setId(int id) {
header.id = id;
}
}
and I would like to iterate over it, in another class with something like this:
struct Socket {
...
void send(MultipartMessage msg) {
foreach (part; msg) {
sendPart(part);
}
}
...
}
Is this possible? I'd like to use something analogous to Python's __iter__ in the MultipartMessage that can return the fields in a specific order, and ideally even run some additional code, like header.serialize().
Ideally I would add a function to MultipartMessage that would look something like this (pseudocode):
ubyte[] __iter__() {
yield mime;
yield data;
yield header.serialize(); //header.serialize returns a ubyte[]
}
Use tupleof:
foreach (ref part; msg.tupleof)
sendPart(part);
This will call sendPart with mime, data and header (the struct's fields, in the order they were declared). You can filter fields by checking their type with e.g. static if (!is(typeof(part) == Header)).
To get the field's name, you can use __traits(identifier):
foreach (i, ref part; msg.tupleof)
writeln(__traits(identifier, msg.tupleof[i]));
(__traits(identifier, part) would return part.)
There's also __traits(allMembers), which also returns methods.
The closest thing to what you want is probably opApply.
See http://dlang.org/spec/statement.html , Section Foreach over Structs and Classes wit opApply
This will work:
int opApply(int delegate(ref ubyte[]) dg) {
int result = 0;
result = dg(mime);
result = dg(data);
ubyte[] header_bytes = header.serialize();
result = dg(header_bytes);
return result;
}
There are several ways to do iterate over objects in D.
One is to implement the InputRange API. Input ranges are similar to iterators, but have a different API. Implementing a range interface means that you can use all of the std.range/std.algorithm functions on your object, such as map, array, joiner and so on.
D doesn't have an __iter__ function to get an iterator from arbitrary collections, so you will need to implement a function that returns an input range.
import std.range;
auto bytes() {
return chain(mime, data, header.serialize);
}
This will return a ubyte input range, consisting of the bytes in mime, followed by the bytes in data, then in header.serialize.
You can also implement the opApply method on your struct. opApply will only work with foreach, so you can't use range methods with it, but it allows you to do things like execute the loop body in separate threads.
The gist of opApply is that D passes the loop body to opApply as a function; that is, foreach(x; myObj) { body } is transformed into myObj.opApply((x) { body }).
void opApply(void delegate(ubyte[] part) loopbody) {
loopbody(mime);
loopbody(data);
loopbody(header.serialize());
}
However, instead of either of those options, I recommend that you implement a function on your object that takes an output range and writes the data to it.
An output range is an object that accepts other objects, and does something to them. In this case, the output range should accept ubytes, making it similar to an output stream.
void serialize(Range)(ref Range outRange) if(isOutputRange!(Range, ubyte)) {
put(outRange, mime); -- `put` simply feeds data into the output range
put(outRange, data);
header.serialize(outRange); // No longer have to allocate/return a ubyte array
}
Example usage, that stores the output into an Appender, which can be converted into an array:
import std.array;
auto serializedDataAppender = appender!ubyte();
myMsg.serialize(serializedDataAppender);
auto serializedData = serializedDataAppender.data;
If you implement an output range on top of your socket, then that means that the output range solution does not have to allocate any memory from the heap.
Check out the Programming in D book (specifically, the Ranges and More Ranges sections) for info on how to implement your own ranges.
Related
Let me elaborate:
I need to be able to iterate over a list of objects. Each of the objects has a property which is a list, and I have to check if that list contains any elements that are not in another list.
When I tried to do it by using nested for loops, it kept giving me concurrent modification exceptions, so I tried to use an iterator, but now I'm stuck, since if I make an iterator based on the list of objects, I can't access the individual object's properties to then iterate over.
Here's some example code of what I was trying to accomplish:
for (preference in preferencesWithRestaurant) {
for (restaurantID in preference.restaurantIDs) {
// One method I tried using
preferencesWithRestaurant.removeIf{ !listOfIds.contains(restaurantID) }
/* alternate method I tried using
if (!listOfIds.contains(restaurantID)) {
preferencesWithRestaurant.remove(preference)
}
*/
}
}
If you can replace the value of preferencesWithRestaurant or store the result in another variable then you can filter it:
preferencesWithRestaurant = preferencesWithRestaurant.filter { preference ->
preference.restaurantIDs.all { it in listOfIds }
}
Depending on the exact type of preferencesWithRestaurant you may need to convert it to the proper type, e.g. invoke toMutableList() at the end.
If you prefer to modify preferencesWithRestaurant in-place, then you can use retainAll() (thanks #Tenfour04):
preferencesWithRestaurant.retainAll { preference ->
preference.restaurantIDs.all { it in listOfIds }
}
Alternatively, you can keep your original approach, but use a mutable iterator to remove an item while iterating:
val iter = preferencesWithRestaurant.listIterator()
for (preference in iter) {
for (restaurantID in preference.restaurantIDs) {
if (!listOfIds.contains(restaurantID)) {
iter.remove()
break
}
}
}
I am trying to define a mapping to use inside a function as a means of quickly determining whether a key exists. I realize I could also use an array and loop thorugh it but that seems like it might get expensive. But that you can't create mappings dynamically, and if I create a state variable for the purpose, then I have the problem of clearing state between calls to this function which makes it pricey.
Here is what I was tyring to do, any suggestions for the most efficient method to dedupe a set of strings inside a pure function?
function dedupe(string[] memory keys) public pure returns(string[] memory) {
string[] memory deduped;
mapping(string=>bool) map;
string memory ikey;
for(uint i=0; i<keys.length; i++) {
ikey = keys[i];
if (!map[ikey]) {
map[ikey]=true;
deduped.push(ikey);
}
}
return deduped;
}
As an exercise I'm trying to micro-optimize code in Rust 1.3.0. I have a loop of a loop over an array. Something like this:
loop {
for i in 0..arr.len() {
// something happens here
}
}
Since arrays are fixed size in Rust, will the compiler optimize the code by evaluating arr.len() just once and reusing the value, or will the expression be evaluated with each pass of the top-level loop? The question can be expanded to more calculation-heavy functions without side-effects, other than arr.len().
In other words, would the above code be equivalent to this:
let arr_len = arr.len();
loop {
for i in 0..arr_len {
// something happens here
}
}
The .. is a range operator, which forms a Range<Idx> object (or a derivative: RangeFrom, RangeFull or RangeTo). Those objects only contain indexes (the Idx type), so you can rest assured that .len() is only evaluated once.
In general, it is a good idea to inspect the LLVM IR. If you have a synthetic example, you can use the playground easily enough. For example:
// A black-box prevents optimization, and its calls are easy to spot.
extern {
fn doit(i: i32) -> ();
}
fn main() {
let arr = [1, 2, 3, 4, 5];
for i in 0..arr.len() {
unsafe { doit(arr[i]); }
}
}
Yields the following function:
; Function Attrs: uwtable
define internal void #_ZN4main20hd87dea49c835fe43laaE() unnamed_addr #1 {
entry-block:
tail call void #doit(i32 1)
tail call void #doit(i32 2)
tail call void #doit(i32 3)
tail call void #doit(i32 4)
tail call void #doit(i32 5)
ret void
}
In this case, with a fixed length, there is no loop at all: it has been unrolled.
At least in a quick check with using arr.len() nested inside another loop, no code seems to be generated for the "call" to arr.len() at all. In the generated code, the size of the array is simply hard-coded into the output.
In other words, I would not expect your second snippet to execute any faster than the first one.
I have two queries against a particular table in Go - one to retrieve a single item and the other to return a list. The first one uses sql.DB.QueryRow because it only needs to retrieve a single row, and the second one uses sql.DB.Query to return a few different results.
The problem is that serialization takes some work and I'd like to DRY it up by having a single method that scans from a database row and reads it into a Go type. My code right now looks like:
// Some type which varies considerably from its DB representation, and takes some effort to serialize.
type Foo struct {
Baz *Baz
Board [8][8]int
}
// Get one foo by its id
func GetFoo(id int) {
row := db.QueryRow("select * from foo where id = ?", id)
// Work that's duplicated from below...
var foo Foo
row.Scan(&foo.blah, &foo.etc)
// Do more work to serialize the type...
}
// Get all of the fooes
func GetFooes() {
rows, err := db.Query("select * from foo")
for rows.Next() {
// Work that's duplicated from above...
var foo Foo
rows.Scan(&foo.blah, &foo.etc)
// Do more work to serialize the type...
}
}
However combining row.Scan and rows.Scan is proving to be a little tricky. I thought I could use something like:
func serializeFoo(scanner sql.Scanner) (*Foo, error) {
}
though sql.Scanner takes a single (value interface{}) and not a list of (...value interface{}).
Any advice here? Another solution would be to convert the single QueryRow call into a db.Query.
db.QueryRow is a convenience function. There is no reason to use it unless it will save on typing/code-complexity. In this case, it doesn't so I recommend you just use db.Query.
See http://golang.org/src/pkg/database/sql/sql.go?s=25740:25802#L966 for more details
As you mentioned, neither Row nor Rows implement the Scanner interface. Scanner is used for arguments of the variatic scan functions.
If you want to have a parameter that allows either Row or Rows, you need to make your own interface For example:
func serializeFoo(scanner interface{Scan(dest ...interface{}) error}) (*Foo, error) {
}
I am a developer in C-like languages (Java/JavaScript/C#) and I am attempting to convert some Objective-C code into Java.
For the most part, it is relatively straightforward but I have hit a stumbling block with the following bit of code:
typedef struct {
char *PAGE_AREA_ONE;
char *PAGE_AREA_TWO;
char *PAGE_AREA_THREE;
} CODES;
- (CODES*) getOpCode {
CODES *result = NULL;
result = malloc(sizeof(CODES));
result->PAGE_AREA_ONE = "\x1b\x1b\x1b";
result->PAGE_AREA_TWO = "\x2d\x2d\x2d";
result->PAGE_AREA_THREE = "\x40\x40";
return result;
}
What would the Java equivalent of this be? From what I can tell in other areas of the code, it is being used to store constants. But I am not 100% certain.
Thanks.
The typedef is just creating a structure that contains three string properties. The getOpCode method is apparently trying to create a new structure and assign values to those three properties. C# code would be:
public class Codes
{
public string PageAreaOne;
public string PageAreaTwo;
public string PageAreaThree;
}
public Codes GetCodes()
{
Codes result = new Codes();
result.PageAreaOne = "\x1b\x1b\x1b"; // three ESC characters
result.PageAreaTwo = "---";
result.PageAreaThree = "##";
return result;
}
The code in question is allocating a block of memory that the size of the CODES structure, filling it with some data, and returning a pointer to the new block. The data is apparently some operation codes (that is, instructions) for something, so perhaps the data is being sent to some other device where the instructions will be executed.