SkillAgentSearch skills...

Boost.toml

header-only C++(98|11|14|17) TOML v0.5.0 parser/encoder depending on Boost

Install / Use

/learn @ToruNiina/Boost.toml
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Boost.toml

Build Status

日本語

Boost.toml is a header-only toml library depending on Boost.

compatible with TOML v0.5.0.

tested with C++(98|11|14|17) on Linux/macOS. Some functionalities (e.g. construction from std::initilalizer_list (after c++11), getting toml String as a std::string_view (after c++17)) would be disabled if older standard version is given.

Boost.toml depends on relatively later versions of the Boost C++ Library (tested with Boost 1.67.0 on Travis CI).

NOTE: This library is not a part of Boost C++ Library.

Are you looking for non-boost toml parser? Try toml11! It has almost the same (maybe a bit more powerful) functionality and better error messages. But the only weakness is, as the name suggests, it requires compiler which conforms C++11 standard.

Table of Contents

example code

Here is an example toml file (a bit modified from original file found in toml repository).

title = "TOML Example"

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

# modified to explain how to get an array of table
[[servers]]
name = "alpha"
ip = "10.0.0.1"
dc = "eqdc10"

[[servers]]
name = "beta"
ip = "10.0.0.2"
dc = "eqdc10"

[clients]
data = [ ["gamma", "delta"], [1, 2] ]

You can read this file with a code like the following.

#include <toml/toml.hpp>

int main()
{
    // reads toml file and return it as a map (toml::key -> toml::value).
    const toml::table file = toml::parse("example.toml");

    // you can get toml values by toml::get function.
    const std::string title = toml::get<std::string>(file.at("title"));

    // toml::get returns lvalue reference.
    const toml::table&  owner = toml::get<toml::table>(file.at("owner"));
    const std::string&  name  = toml::get<std::string>(owner.at("name"));
    const auto&         dob   = toml::get<toml::offset_datetime>(owner.at("dob"));

    const auto& database = toml::get<toml::table>(file.at("database"));
    // you can use a std::string_view if you have a c++17 compatible compiler.
    const auto  server = toml::get<std::string_view>(database.at("server"));
    // you can get a toml::array as your favorite container.
    const auto  ports = toml::get<std::vector<int>>(database.at("ports"));
    // you can cast types if they are convertible.
    const auto  connection_max = toml::get<std::size_t>(database.at("connection_max"));
    const auto  enabled = toml::get<bool>(database.at("enabled"));

    // an array of table is simply an `array<table>`.
    const auto servers = toml::get<std::vector<toml::table>>(file.at("servers"));

    // boost::string_(view|ref) are also supported.
    const auto name_alpha = toml::get<boost::string_view>(servers.at(0).at("name"));
    const auto ip_alpha   = toml::get<boost::string_view>(servers.at(0).at("ip"));
    const auto dc_alpha   = toml::get<boost::string_view>(servers.at(0).at("dc"));
    const auto name_beta  = toml::get<boost::string_ref >(servers.at(1).at("name"));
    const auto ip_beta    = toml::get<boost::string_ref >(servers.at(1).at("ip"));
    const auto dc_beta    = toml::get<boost::string_ref >(servers.at(1).at("dc"));

    const auto& clients = toml::get<toml::table>(file.at("clients"));

    // you can do this!
    // the first array is array of string, the second one is array of int.
    // data = [ ["gamma", "delta"], [1, 2] ]
    const auto  data = toml::get<
        std::pair<std::vector<std::string>, std::vector<int>>
        >(clients.at("data"));
    // it supports std::tuple also (after c++11).

    return 0;
}

parsing toml file

Since this library is header-only, including toml/toml.hpp is the only thing required.

toml::parse function parses toml file. You can pass std::string that represents file name or std::istream& to the function. std::runtime_error would be thrown if a file open error happens.

Both returns toml::table that includes all the data in a file. If an error appeared while parsing a file, it throws std::runtime_error.

const toml::table data = parse("example.toml");
// or
std::ifstream ifs("example.toml");
if(!ifs.good){return 1;}
const toml::table data = parse(ifs);

getting toml values

Boost.toml provides a powerful function, toml::get, to get a value from TOML data.

basic usage of toml::get

You can extract value from toml::table by specifying a type of a value through toml::get<T>.

// you can get a reference when you specify a toml type
toml::value v1(42);
toml::integer& i_ref = toml::get<toml::integer>(v1);
i_ref = 6 * 9; // v1 will be 54.

// you can get a value as non-toml type(e.g. uint32_t) if they are convertible.
// in that case, a reference that points to the internal value cannot be gotten.
std::uint32_t i = toml::get<std::uint32_t>(v1); // 54

// to avoid deep-copy, it is useful to get const reference.
toml::value v2{{"int", 42}, {"float", 3.14}, {"str", "foo"}};
const toml::table& tab = toml::get<toml::table>(v2);

If you pass a convertible type (like int for toml::integer) to toml::get's template argument, it converts a value to the specified type. In that case, you can't get a lvalue reference that points to the contained value because it returns prvalue. You can find underlying types in this section. See this section for more information about type conversions.

If you pass a wrong type (like std::string for toml::integer) to toml::get, it will throw toml::bad_get. toml::bad_get::what might be helpful as an error message because it contains demangled typename powered by boost::typeindex::type_id().pretty_name().

toml::value v(42);
std::string s = toml::get<std::string>(v);

// exception thrown. the message would be something like this.
// terminate called after throwing an instance of 'toml::bad_get'
//   what():  toml::get: toml value has type `toml::integer`, but type `std::basic_string<char, std::char_traits<char>, std::allocator<char> >` is specified.

getting toml::array

You can get a toml::array as your favorite array type. The elements will also be converted to the specified type.

toml::value v{1, 2, 3, 4, 5};
std::vector<int>        vec = toml::get<std::vector<int>       >(v);
std::deque<unsigned>    deq = toml::get<std::deque<unsigned>   >(v);
std::list<std::int64_t> lst = toml::get<std::list<std::int64_t>>(v);
std::array<char, 5>     ary = toml::get<std::array<char, 5>    >(v);

Surprisingly, you can also get a std::pair or std::tuple from toml::array.

toml::value v{1, 2};
std::pair<int, unsigned>  p = toml::get<std::pair<int, unsigned>>(v);

toml::value v{1, 2, 3};
std::tuple<int, int, int> t = toml::get<std::tuple<int, int, int>>(v);

// unfortunately, boost::tuple is currently not supported.

This feature is convenient in the following case.

toml::array of toml::arrays having different types each other

Consider that you have this toml file.

array = [[1, 2, 3], ["foo", "bar", "baz"]]

What is the corresponding C++ type? Of course, its a std::pair of std::vector<int> and std::vector<std::string>.

Boost.toml supports this.

auto v = toml::get<std::pair<std::vector<int>, std::vector<std::string>>>(v);

Or it can be a tuple of two elements.

auto v = toml::get<std::tuple<std::vector<int>, std::vector<std::string>>>(v);

But generally, you might not be able to know the length or type of an array in a file before reading it. In that case, toml::array or std::vector<toml::value> can be used (actually, toml::array is just an alias of boost::container::vector<toml::value>, so in this case conversion may not be needed).

const toml::array& a = toml::get<toml::array>(v);

std::vector<int>    a1 = toml::get<std::vector<int>        >(a.at(0));
std::vector<string> a2 = toml::get<std::vector<std::string>>(a.at(1));

Or you can get this as std::vector<toml::array> because it is an array of arrays.

std::vector<toml::array> a = toml::get<std::vector<toml::array>>(v);

int        

Related Skills

View on GitHub
GitHub Stars31
CategoryDevelopment
Updated1y ago
Forks2

Languages

C++

Security Score

80/100

Audited on Dec 9, 2024

No findings