...

/

Real-World Examples of Metaprogramming II

Real-World Examples of Metaprogramming II

Learn how to use the compile-time hash sum calculation in metaprogramming.

Example 2: hash strings at compile time

Let’s say we have a resource system consisting of an unordered map of strings that identifies bitmaps. If a bitmap is already loaded, the system returns the loaded bitmap; otherwise, it loads the bitmap and returns it:

Press + to interact
// External function which loads a bitmap from the filesystem
auto load_bitmap_from_filesystem(const char * /*path*/) -> Bitmap {
// ...
return Bitmap{};
}
// Bitmap cache
auto get_bitmap_resource(const PrehashedString& path) -> const Bitmap& {
// Static storage of all loaded bitmaps
static auto loaded_bitmaps = std::unordered_map<PrehashedString, Bitmap>{};
// If the bitmap is already in loaded_bitmaps, return it
if (loaded_bitmaps.count(path) > 0) {
return loaded_bitmaps.at(path);
}
// The bitmap isn’t already loaded, load and return it
auto bitmap = load_bitmap_from_filesystem(path.c_str());
loaded_bitmaps.emplace(path, std::move(bitmap));
return loaded_bitmaps.at(path);
}

The bitmap cache is then utilized wherever a bitmap resource is needed:

  • If it’s not loaded yet, the get_bitmap_resource() function will load and return it
  • If it’s already been loaded somewhere else, the get_bitmap_resource() will simply return the loaded function

So, independent of which of these draw functions is executed first, the second one will not have to load the bitmap from disk:

Press + to interact
auto draw_something() {
const auto& bm = get_bitmap_resource("my_bitmap.png");
draw_bitmap(bm);
}
auto draw_something_again() {
const auto& bm = get_bitmap_resource("my_bitmap.png");
draw_bitmap(bm);
}

Since we use an unordered map, we must compute a hash value whenever we check for a bitmap resource. You will now see how we can optimize the runtime code by moving computations to compile time.

The advantages of the compile-time hash sum calculation

The problem we will try to solve is that every time the line get_bitmap_ resource is executed, the application will compute the hash sum of the string "my_bitmap.png" at runtime. We want to perform this calculation at compile time so that when the application executes, the hash sum has already been calculated. In other words, just as we have learned to use metaprogramming to generate functions and classes at compile time, we will now have it generate the hash sum at compile time.

Note: You might have already come to the ...