PolyConf is a small C++20 configuration library that loads different configuration syntaxes into one normalized tree and exposes typed path lookups.
Current format support:
- ACF load and save
- XML load and save
- JSON load and save
- AUTO detection from file extension or input shape
- Preserved comments for ACF and XML
- Normalized save output
The project is still in an MVP state. The core API is usable, but the parsers are intentionally small and focused on the supported test cases.
- Typed accessors:
get_string,get_int,get_float,get_bool - Path lookup with repeated nodes:
account.name,account[1].name hasandcounthelpers for checking configuration shape- Repeated ACF sections and repeated XML elements map to arrays
- ACF writer preserves insertion order and comments
- XML writer preserves insertion order, comments, and escapes text values
save_stringandsave_filefor ACF, XML, and JSON- JSON parser and writer preserve JSON scalar types, arrays, and object order
Boolean values accept true, false, 1, 0, yes, no, on, and off,
case-insensitively.
ACF uses dotted section headers and key = value scalar entries.
.account
name = colin
developer = true
.account.info
active = true
Comments beginning with # are preserved when loading and saving. Inline
comments are preserved too:
.account # user account
name = "colin stewart" # display name
XML support handles nested elements, repeated elements, self-closing elements, text values, declarations, and comments.
<!-- Generated by PolyConf -->
<account>
<name>colin</name>
<developer>true</developer>
</account>XML attributes are currently skipped by the parser and are not represented in the normalized tree.
JSON support handles objects, arrays, strings, numbers, booleans, null values, standard string escapes, and Unicode surrogate pairs.
{
"account": {
"name": "colin",
"developer": true,
"aliases": ["colin", "cj"]
}
}Arrays map to repeated named nodes, so indexed paths such as
account.aliases[1] work with the existing lookup API. JSON syntax errors
throw std::invalid_argument with the byte offset of the parse failure.
Include the public umbrella header:
#include "polyconf.hpp"Load configuration from a string:
const char* input =
".account\n"
"name = colin\n"
"developer = true\n";
POLYCONF::CONFIG config = POLYCONF::load_string(input, POLYCONF::FORMAT::ACF);
std::string name = config.get_string("account.name", "");
bool dev = config.get_int("account.developer", false);Load from a file with automatic format detection:
POLYCONF::CONFIG config = POLYCONF::load_file("settings.xml", POLYCONF::FORMAT::AUTO);Save to a string:
std::string json = POLYCONF::save_string(config, POLYCONF::FORMAT::JSON);Save to a file:
bool ok = POLYCONF::save_file(config, "settings.acf", POLYCONF::FORMAT::ACF);The FORMAT enum currently supports:
POLYCONF::FORMAT::AUTOPOLYCONF::FORMAT::ACFPOLYCONF::FORMAT::XMLPOLYCONF::FORMAT::JSON
Paths are dot-separated. Repeated nodes can be indexed with square brackets.
When an index is omitted, index 0 is used.
config.get_string("account.name", "");
config.get_string("account[1].name", "");
config.count("account");
config.has("account.info.active");Invalid paths or failed conversions return the caller-provided default value.
PolyConf uses makeshift makefile support.
makeThe default project configuration builds static and shared libraries for the 64-bit debug profile.
Useful targets:
make static
make shared
make cleanBuild outputs are written under bld/.
Unit tests are built and run with:
make utClean test build output with:
make clean-testsThe current test tree lives in tst/ut. The build still keeps compatibility
with the older src/tst/ut layout through makeshift.
src/inc/ Public headers
src/inc/parser/ Parser and writer headers
src/lib/ Core implementation
src/lib/parser/ ACF/XML parsers and writers
tst/ut/ Unit tests and reference files
dep/ Local build/test dependencies
- INI and YAML are not implemented.
- XML attributes are ignored.
- XML save output is normalized and does not preserve original whitespace.
- ACF save output is normalized and organized from the in-memory tree.
- Comment text is preserved as metadata and re-emitted in the target format, but exact original placement may change when converting between formats.
PolyConf is licensed under the Apache License, Version 2.0. See LICENSE.
Copyright 2026 Colin J.D. Stewart.