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.
// 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;
// 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 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.
// Add an item.
registry["foo"] = myItem;
// Remove an item.
// 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
// Or the keys
// 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.
auto item = registry[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.