D Arrays

posted in D Bits
Published May 26, 2011
Advertisement
Every D programmer loves D's arrays. All of them. I challenge you to find one who doesn't. Particularly, it's the ability to slice and manipulate arrays without worrying about memory that really pulls people in.

In my previous post, I talked about Dolce's game screens and the stack-based screen manager. Internally, the stack that the screen manager uses is not a custom-built stack class, nor any sort of container from an existing library. It's an array. You can implement a stack quite easily with a D array.


// Declare an empty dynamic array to use as your stack.
Item[] stack;

// To push an item onto the stack, use the array append/concat operator.
stack ~= something;

// To pop, simply decrease the length of the array.
stack.length -= 1;

// What if we have a queue instead of a stack and want to take the first item?
// First, save the item at the head of the queue.
auto item = queue[0];

// Then reassign the array to a slice of itself, starting from index #1 to the last index.
// The $ is a substitute for the length property of the array. The first number in a slice
// is inclusive, the second exclusive. So the resulting slice below will contain all elements
// from queue[1] to queue[queue.length - 1].
queue = queue[1 .. $];


D's arrays are quite powerful. In addition to being arrays, they are also ranges, which is something that would take more than a simple post to explain. I don't quite fully grok them myself yet. But, when used in conjunction with the std.algorithm module, there's a great deal of power behind them.

You can read more about D's arrays in this article on slicing in D by Steven Schveighoffer. Also, see the documentation for the std.range module to get an idea of what ranges are.

But wait, there's more! The registry the screen manager uses is a built-in associative array. While there are some more sophisticated hashmap implementations out there for when you really need them, the built-in AAs will cover a lot of your use cases.


// Declare an AA that uses strings as keys.
Item[string] registry;

// Add an item.
registry["foo"] = myItem;

// Remove an item.
registry.remove("foo");

// Test if an item exists in the AA .
// The in operator returns a pointer.
auto item = key in registry;
if(item !is null)
// Do something

// Efficiently iterate all the values via a delegate
foreach(val; registry.byValue())
writeln(val);

// Or the keys
foreach(key; registry.byKey())
writeln(key);

// But don't try to remove anything while iterating the delegates as above. Instead,
// iterate over an array of keys or values using the .keys or .values properties.
foreach(key; registry.keys)
{
auto item = registry[key];
if(item.removeMe)
registry.remove(key);
}



D's arrays and AAs will get you farther than those of C++ or Java. But, when you need more, there is also a range-based container module, std.container, which will eventually hold a number of container types. Also, as an alternative, Steven Schveighoffer's DCollections library is quite awesome.
Previous Entry Game Screens
0 likes 2 comments

Comments

Poita
Nice post.

One thing I really don't like about D's arrays is the fact that array literals are allocated by the GC, even when initialising a static array:

int[3] a = [1, 2, 3]; // performs GC alloc then copies the elements into the array

As far as I can tell, there is no simple (built in) way to initialise a static array without a heap allocation. You either have to do it manually:

// yuck!
int[3] a;
a[0] = 1;
a[1] = 2;
a[2] = 3;

Or I suppose you could write a funky variadic template function for it, but I can't figure out the syntax for that (or even determine if it's possible).
July 19, 2011 04:26 PM
Poita
According to some helpful peeps at stackoverflow, you can circumvent the heap alloc by declaring a static const array and then copying it.

static const int[3] data = [1, 2, 3];
int[3] a = data;

data goes in the data segment.
July 19, 2011 06:42 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement