toml11
toml11 copied to clipboard
Populating the toml table as required by the user
Hello
I currently use v3.6.0 version of the tomll11 header only library. The parsing part work as expected. But i see few issues w.r.t populating the toml table content in the order as required by the user.
This is a demo program
#include "toml.hpp" // that's all! now you can use it.
#include
It should have been Actual toml content hoge = "piyo" baz = "qux" bar = 3.14 foo = 42
Any reason for this behaviour? over-riding the type the std::map will just place the keys in alphabetical order(sorted manner). But in my case i want the key value pairs to be in the order as they are passed. How can we achieve this? Please give your inputs
Hi,
In toml11, the underlying map type is responsible for the order of key-value pairs. By default, it uses std::unordered_map
that is essentially does not preserve the order because it uses hash value, so it is the reason why the serialization result changes the order (note that the TOML spec says that it is designed to map to a hash table.)
To keep the order of the key-value pairs in a table, you need to use order-preserving map class, like https://github.com/Tessil/ordered-map. This map class keeps the insertion order. So,
#include "toml.hpp"
#include "tsl/ordered_map.h"
#include <iostream>
int main()
{
using value_type = toml::basic_value<toml::preserve_comments, tsl::ordered_map>;
value_type v;
v["hoge"] = "piyo";
v["baz"] = "qux";
v["bar"] = 3.14;
v["foo"] = 42;
std::cout << v << std::endl;
// hoge = "piyo"
// baz = "qux"
// bar = 3.14
// foo = 42
//
return 0;
}
You can also parse a file keeping the order of key-value pairs in the following way.
#include "toml.hpp"
#include "tsl/ordered_map.h"
#include <iostream>
int main()
{
auto data = toml::parse<toml::preserve_comments, tsl::ordered_map>("issue157.toml");
data["hoge"] = "piyo";
std::cout << data << std::endl;
return 0;
}
Note that, by doing this, the hoge
key is assigned to the table as the last element.
Thanks for the suggestion :) .
This works when a simple application using g++ (on ubuntu) is built and tested.
But when I try to incorporate the above logic in my application(QNX) using the alias
using tomlTableType = toml::basic_value<toml::preserve_comments, tsl::ordered_map>;
I get the below error
error: no type named 'value_type' in 'struct std::__1::allocator_traits<std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits
error: no type named 'value_type' in 'struct std::__1::allocator_traits<std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits
I am not sure if it is a general issue. Can you please suggest on how i can resolve this
The following code does not reproduce the error you reported. I compiled with g++-10 -std=c++11 issue157.cpp -Wall -Wextra -Wpedantic -O2
. And I don't know if I can do anything about a problem.
#include "toml.hpp"
#include "ordered-map/include/tsl/ordered_map.h"
#include <iostream>
int main(int argc, char** argv)
{
using tomlTableType = toml::basic_value<toml::preserve_comments, tsl::ordered_map>;
tomlTableType t;
t["foo"] = "bar";
return 0;
}
I think the error may be caused by the inclusion or definition order. You can try several patterns.
To chime in: I do think it is nice to have some sort of canonical output that is always the same for the same input (for many cases, versioning etc.). So e.g. making all tables have a defined alphabetical order would be a great define to have as behavior (or as output stream option like precision/inline tables)
#include "toml.hpp"
#include "tsl/ordered_map.h"
#include
int main() { using value_type = toml::basic_value<toml::preserve_comments, tsl::ordered_map>; value_type v; v["hoge"] = "piyo"; v["baz"] = "qux"; v["bar"] = 3.14; v["foo"] = 42;
//hello, with the similar question
//value_type& v = toml::find<toml::table>(data, testTable); this has error, so how to get the reference to the table?
//v[]="";
}