ary

Full source code

C++

// -*- mode: c++ -*-
// $Id$
// http://www.bagley.org/~doug/shootout/

#include <cstdlib>
#include <iostream>
#include <vector>

int
main(int argc, char *argv[]) {
#ifdef SMALL_PROBLEM_SIZE
#define LENGTH 900000
#else
#define LENGTH 9000000
#endif
    int i, n = ((argc == 2) ? atoi(argv[1]) : LENGTH);
    typedef std::vector<int> ARY;
    ARY x(n);
    ARY y(n);

    for (i=0; i<n; i++) {
        x[i] = i;
    }
    for (int i = n - 1; i >= 0; --i) {
        y[i] = x[i];
    }

    std::cout << y.back() << std::endl;
}

Rust

// Adapted from https://github.com/llvm/llvm-test-suite and
// http://www.bagley.org/~doug/shootout/
use std::env;

#[cfg(feature = "small_problem_size")]
const LENGTH: i32 = 900000;

#[cfg(not(feature = "small_problem_size"))]
const LENGTH: i32 = 9000000;

fn main() {
    let mut args = env::args();
    let n = if args.len() == 2 {
        args.nth(1).unwrap().parse::<i32>().unwrap()
    } else {
        LENGTH
    };

    let mut x = Vec::<i32>::new();
    x.resize(n as usize, 0);
    let mut y = Vec::<i32>::new();
    y.resize(n as usize, 0);

    for i in 0..n {
        x[i as usize] = i;
    }
    for i in (0..n).rev() {
        y[i as usize] = x[i as usize];
    }

    println!("{}", y[(n - 1) as usize]);
}

Porting notes

Initializing vectors of type i32 and of size n as local, mutable variables

C++

    typedef std::vector<int> ARY;
    ARY x(n);
    ARY y(n);

Rust

#![allow(unused)]
fn main() {
    let mut x = Vec::<i32>::new();
    x.resize(n as usize, 0);
    let mut y = Vec::<i32>::new();
    y.resize(n as usize, 0);
}

We initialize the two vectors, x and y using let mut. let is the standard way to declare a local variable and mut is added because we will modify (mutate) the vector later.

When initializing a Vec of element type i32, we put the element type i32 in angly brackets as in Vec::<i32>, as opposed to the C++ style Vec<i32>.

As there isn't currently a way to initialize a Vec with a given size n in one shot in Rust, we initialize a vVec of size zero and then resize to n with default element value 0.

The vector indices in Rust are of type usize like size_t and there are no implicit integer conversions, we need to cast n (of type i32) to usize using the as keyword as in n as usize.

Writing for range loops

C++

    for (i=0; i<n; i++) {
        x[i] = i;
    }
    for (int i = n - 1; i >= 0; --i) {
        y[i] = x[i];
    }

Rust

#![allow(unused)]
fn main() {
    for i in 0..n {
        x[i as usize] = i;
    }
    for i in (0..n).rev() {
        y[i as usize] = x[i as usize];
    }
}

A for range loop is written as for i in 0..n { ... }. The loop iterates with the index range 0 up to n - 1 induction variable where n is exclusive. There are no parentheses around the for loop header like the if statement condition expression. It's equivalent to for (int i = 0; i < n; ++i) { ... } in C++.

There is no general for loop in Rust where the loop variable declaration, the loop termination condition and the loop increment statements are spelled out and can be customizable. We would use while loops instead.

To make n to be inclusive, we would write for i in 0..<=n { ... }.

A for range loop in the reverse order is written as for i in (0..n).rev() { ... }. This is equivalent to for (int i = n - 1; i >= 0; --i) { ... } in C++.

Since the variable i is of type i32, we convert it to usize, as in i as usize.