Simplifing C++ setups with configuration loader library
Every developer knows the drill: your application needs settings - API keys, server addresses, feature toggles, you name it. Storing these in a configuration file is standard practice. But in C++, actually reading these files can often lead to a surprising amount of boilerplate code or the need to pull in a hefty dependency. What if there was a simpler way?
That’s where libconfig_loader comes in. It’s a small, focused C++ library designed to do one thing well: parse straightforward key-value configuration files with minimal fuss.
The philosophy: keep it simple, keep it light
The core idea behind libconfig_loader is to provide essential configuration loading capabilities without overcomplicating things. If you’re working on a project where you just need to read some settings from a text file and don’t want to add a complex library for it, libconfig_loader might be a perfect fit.
It handles the common .ini-like format where:
- Each line is a
key = valuepair. - Lines starting with
#are comments. - Empty lines are ignored.
Key concepts in action
Let’s say you have a settings.conf file like this:
# My App Settings
AppName = Super Gizmo
MaxUsers = 200
EnableExperimentalFeatures = true
AdminEmails = [email protected],[email protected]
1. Loading the configuration
The first step is always to load the file. libconfig_loader makes this a one-liner:
#include "config_loader.h"
if (!Config::loadConfiguration("settings.conf")) {
// Uh oh, something went wrong (file not found, perhaps?)
// Handle the error appropriately.
}
Once loaded, the configuration values are held internally, ready for you to query.
2. Getting What you need with defaults
Retrieving values is type-safe and allows for easy default values. This will ensure your application can always run, even with a minimal or incomplete config file.
std::string appName = Config::getString("AppName", "Default App Name");
int maxUsers = Config::getInt("MaxUsers", 50); // Falls back to 50 if not in file or invalid
bool useExperimental = Config::getBool("EnableExperimentalFeatures", false);
If MaxUsers was, say, “many” in the config file (which isn’t a valid integer), maxUsers would gracefully become 50, and (by default) an error would be logged to std::cerr.
3. Handling vectors
Often, a configuration value is actually a list - like a set of server addresses or user IDs. libconfig_loader can parse delimited strings into std::vectors:
// For "AdminEmails = [email protected],[email protected]"
std::vector<std::string> admins = Config::getVectorString("AdminEmails");
// admins now contains {"[email protected]", "[email protected]"}
// You can even specify a different delimiter:
// If "AllowedPorts = 80;443;8080"
std::vector<int> ports = Config::getVectorInt("AllowedPorts", ';');
4. Controlling the Error Verbosity
Sometimes, especially during testing or if you have very robust default logic, you might not want parsing errors to spam your console. libconfig_loader lets you silence these:
Config::setVerboseErrors(false); // Shhh, no error messages to std::cerr
int items = Config::getInt("MalformedItemCount", 10); // Will use 10, no console output
Config::setVerboseErrors(true); // Back to normal
Conclusion
The main benefit of a small library like libconfig_loader is reduced cognitive load and boilerplate. Instead of writing string splitting, type conversion, and error checking logic yourself for every project, you get a tested, reusable component. It’s a tool for when you need something simple, reliable, and C++-native.
The code for this implementation is available on Github as part of ma-libs here.