D Bits

  • entries
    32
  • comments
    46
  • views
    122956

D Arrays

Sign in to follow this  
Aldacron

926 views

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.
Sign in to follow this  


2 Comments


Recommended Comments

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).

Share this comment


Link to comment
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.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now