Writing a Program
In this section, we will be going over a few example C++ programs using the cmemoir
collections API.
Example: Sequences
Let's start with a basic statistics program.
To get started, we need to include the cmemoir
headers.
#include <cmemoir/cmemoir.h>
using namespace memoir;
Now, let's make our main
function, where we will read the arguments into a MEMOIR sequence.
To start off with, we need to allocate a sequence.
Sequences can be allocated with the memoir_allocate_sequence
function.
The first argument to the function is the type of elements within the sequence and the second is the initial length of the sequence, for example:
#include <cmemoir/cmemoir.h>
using namespace memoir;
int main(int argc, char *argv[]) {
collection_ref input = memoir_allocate_sequence(memoir_i32_t, argc - 1);
}
Now let's populate the sequence!
To write to the sequence, we use the function memoir_index_write(T, v, s, i)
.
T
is the shorthand element type, v
is the value to write to s[i]
.
With this, we can update our main
function:
#include <cmemoir/cmemoir.h>
#include <stdlib.h>
using namespace memoir;
int main(int argc, char *argv[]) {
collection_ref input = memoir_allocate_sequence(memoir_i32_t, argc - 1);
for (int i = 0; i < argc - 1; ++i) {
memoir_index_write(i32, atoi(argv[i+1]), input, i);
}
}
Let's go ahead and use the sequence for something now! To do that, we can create a new function to compute the sum of the sequence:
int sum(collection_ref input) {
int32_t result = 0;
for (int i = 0; i < memoir_size(input); ++i) {
result += memoir_index_read(i32, input, i);
}
return result;
}
In sum
we use two new MEMOIR functions: memoir_index_read
and memoir_size
.
memoir_index_read(T, s, i)
reads s[i]
, which has element type T
.
memoir_size(s)
returns the size of the sequence as a size_t
.
Now we can call our sum
function in main
:
#include <stdio.h>
...
int main(int argc, char *argv[]) {
collection_ref input = memoir_allocate_sequence(memoir_i32_t, argc - 1);
for (int i = 0; i < argc - 1; ++i) {
memoir_index_write(i32, atoi(argv[i+1]), input, i);
}
int result = sum(input);
printf("sum = %d\n", result);
return 0;
}
Compiling your program
Compiling C/C++ programs using MEMOIR collections is straightforward.
The memoir-clang
and memoir-clang++
command-line tools provide similar functionality to clang
/clang++
.
NOTE: These should not be considered drop-in replacements.
To compile the program you just wrote, simply run:
memoir-clang++ my_program.cpp -o my_program
The result of this command is my_program
which can be executed, for example, if you run:
./my_program 123 123 321
The following will be printed on your command line:
sum = 567
Congratulations! You have now written and ran your first program in MEMOIR!
Example: Associative Array
Let's extend our statistics program to provide a histogram!
First off, we will need to create a new associative array, which can be done with memoir_allocate_assoc_array(K, V)
, where K
is the key rtype and V
is the value type:
collection_ref hist(collection_ref input) {
collection_ref histogram = memoir_allocate_assoc_array(memoir_i32_t, memoir_u32_t);
}
Following this, we need to populate it with values from the input sequence.
collection_ref hist(collection_ref input) {
collection_ref histogram = memoir_allocate_assoc_array(memoir_i32_t, memoir_u32_t);
for (int i = 0; i < memoir_size(input); ++i) {
int32_t value = memoir_index_read(i32, input, i);
if (memoir_assoc_has(histogram, value)) {
uint32_t current = memoir_assoc_read(u32, histogram, value);
memoir_assoc_write(u32, current + 1, histogram, value);
} else {
memoir_assoc_insert(histogram, value);
memoir_assoc_write(u32, 1, histogram, value);
}
}
return histogram;
}
Note that we must explicitly insert keys into the associative array before writing to it, it is undefined behavior to write a value to a key which doesn't exist in the associative array.
Now, let's use the new hist
function and see how to iterate over it:
int main(...) {
collection_ref input = ...;
{ ... }
collection_ref histogram = hist(input);
collection_ref keys = memoir_assoc_keys(histogram);
for (int i = 0; i < memoir_size(keys); ++i) {
int32_t key = memoir_index_read(i32, keys, i);
uint32_t count = memoir_assoc_read(u32, histogram, key);
printf("%d -> %ld\n", key, count);
}
return 0;
}
To iterate over the associative array, we need to collect its keys with the memoir_keys
function.
memoir_assoc_keys(a)
returns a sequence of the keys present in a
.
Note that their is no guarantee on the order of keys in the resultant.
If we recompile our program:
memoir-clang++ my_program.cpp -o my_program
And run it:
./my_program 123 123 321
You should get the following result:
sum = 567
123 -> 2
321 -> 1