Skip to content

odeviceblack/Config-Library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Config Library (C++)

Lightweight, header-based configuration library for C++17, providing INI-style file parsing with type-safe value access and section/key management.


πŸ“Œ Overview

This library provides:

  • Type-safe configuration values (bool, int32_t, double, std::string)
  • INI file format with section support
  • Automatic type parsing and serialization
  • Comment preservation (full round-trip support)
  • Quoted string values β€” "..." and '...' protect # and ; from being parsed as comments
  • Section and key iteration via GetSectionList / GetEntryList
  • Simple bind system for easy variable management

🧱 Structure

config.hpp      β†’ Main library header (ConfigEntry, Config)
config.cpp      β†’ Implementation
config_c.h      β†’ C-compatible API header
config_c.cpp    β†’ C-compatible API implementation

βš™οΈ Requirements

  • C++17 compiler
  • Standard Library (string, variant, unordered_map, vector, fstream, cstdint)

No external dependencies.


πŸš€ Usage

Basic example

#include "config.hpp"

Config cfg("settings"); // opens settings.ini
cfg.Load();

// Bind or create entries
ConfigEntry& volume = cfg.Bind("volume", 0.75, "Audio");
ConfigEntry& fullscreen = cfg.Bind("fullscreen", true);

// Read values
double vol = volume.Get<double>();      // 0.75
bool fs = fullscreen.Get<bool>();       // true

// Modify values
volume.Set(0.8);
fullscreen.Set(false);

// Save back to file
cfg.Save();

Working with sections

Config cfg("game");
cfg.Load();

ConfigEntry& username = cfg.Bind("name", std::string("player"), "Account");
ConfigEntry& score = cfg.Bind("highscore", int32_t{0}, "Stats");

if (cfg.HasSection("Account")) {
    // section exists
}

if (cfg.HasKey("name", "Account")) {
    std::string name = cfg.Bind("name", std::string{}, "Account").Get<std::string>();
}

Iterating sections and entries

Config cfg("settings");
cfg.Load();

for (const std::string& section : cfg.GetSectionList()) {
    std::cout << "[" << section << "]\n";

    for (const ConfigEntry* entry : cfg.GetEntryList(section)) {
        std::cout << "  " << entry->GetKey() << " = ";

        if (entry->IsInt())    std::cout << entry->Get<int32_t>();
        if (entry->IsDouble()) std::cout << entry->Get<double>();
        if (entry->IsBool())   std::cout << entry->Get<bool>();
        if (entry->IsString()) std::cout << entry->Get<std::string>();

        std::cout << "\n";
    }
}

INI file format

# Global section (no brackets)
fullscreen = true
language = english

[Audio]
volume = 0.8         ; inline comment with semicolon
muted = false

[Graphics]
width = 1920         # inline comment with hash
vsync = true

[Paths]
save_dir = "C:\Users\save ; folder"  ; semicolon inside quotes is preserved
label    = "hello #world"            ; hash inside quotes is preserved

Type safety

ConfigEntry& entry = cfg.Bind("answer", int32_t{42});

int32_t value = entry.Get<int32_t>();   // OK: 42
double  f     = entry.Get<double>();    // Returns fallback 0.0
bool    b     = entry.Get<bool>();      // Returns fallback false

if (entry.IsInt()) {
    int32_t x = entry.Get<int32_t>();
}

Comment preservation (full round-trip)

// Original file:
// # This is a comment
// fullscreen = true
//
// [Audio]  # section comment
// volume = 0.8  # inline comment

cfg.Load();
cfg.Bind("volume", 0.0, "Audio").Set(0.9);
cfg.Save();

// Saved file preserves all comments:
// # This is a comment
// fullscreen = true
//
// [Audio]  # section comment
// volume = 0.9  # inline comment

πŸ”§ API Reference

ConfigEntry

Method Description
Set<T>(const T& value) Sets the entry value. T must be bool, int32_t, double, or std::string
Get<T>(const T& fallback = {}) Returns value if type matches, otherwise returns fallback
GetKey() Returns the entry's key name
GetSection() Returns the entry's section name (empty string = global)
GetInlineComment() Returns the inline comment string, if any
GetPreComments() Returns comment lines that appear before this entry
IsBool() Returns true if the stored type is bool
IsInt() Returns true if the stored type is int32_t
IsDouble() Returns true if the stored type is double
IsString() Returns true if the stored type is std::string

Config

Method Description
Config(const std::string& configName) Constructor. Appends .ini to the provided name
Load() Loads and parses the INI file
Save() Saves current values preserving all comments
Bind(key, defaultValue, section = "") Returns existing entry or creates a new one with defaultValue
HasSection(section) Returns true if the section exists
HasKey(key, section = "") Returns true if the key exists in the given section
CanInteract() Returns true if the file is accessible for read/write
GetSectionList() Returns sorted list of all section names (empty string = global)
GetEntryList(section = "") Returns sorted list of pointers to all entries in the given section

🧠 Technical Notes

  • Values are stored as std::variant<bool, int32_t, double, std::string>
  • int literals bind as int32_t; floating-point literals bind as double
  • Inline comments are supported with both # and ;
  • String values containing # or ; must be wrapped in quotes ("..." or '...') in the INI file; Save() adds quotes automatically when needed
  • double values are always serialized with a decimal point (e.g. 90.0) to survive reload as double instead of int32_t
  • Boolean values: true / false (case-sensitive)
  • Empty lines and all comment styles are preserved on round-trip

⚠️ Migration from v1.x

v1.x v2.0
int int32_t
float double
IsFloat() IsDouble()
Config_BindFloat Config_BindDouble
ConfigEntry_GetFloat ConfigEntry_GetDouble
ConfigEntry_SetFloat ConfigEntry_SetDouble
Only # as comment marker # and ; both supported
No iteration API GetSectionList / GetEntryList

πŸ“„ License

MIT License


πŸ‘€ Credits

  • DeviceBlack β€” full implementation, design, and documentation

About

Lightweight, header-based configuration library for C++17, providing INI-style file parsing with type-safe value access and section/key management.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors