mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-01-19 05:20:07 +00:00
feat: add examples
This commit is contained in:
parent
7789b4e8be
commit
da2a85b500
1
examples/boost_container/.gitignore
vendored
Normal file
1
examples/boost_container/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
container
|
8
examples/boost_container/CMakeLists.txt
Normal file
8
examples/boost_container/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
find_package(Boost 1.81.0)
|
||||
|
||||
if(Boost_FOUND)
|
||||
add_executable(container container.cpp)
|
||||
target_link_libraries(container PRIVATE toml11::toml11 Boost::boost)
|
||||
set_target_properties(container PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
13
examples/boost_container/README.md
Normal file
13
examples/boost_container/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# container
|
||||
|
||||
Use `boost::container::vector` and `boost::unordered_flat_map` as `array_type` and `table_type`.
|
||||
|
||||
## build
|
||||
|
||||
Install [boost](https://boost.org), especially after 1.81.0 that supports `unordered_flat_map`.
|
||||
|
||||
Then, build toml11 with `-DTOML11_BUILD_EXAMPLES=ON`
|
||||
|
||||
```cpp
|
||||
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
|
||||
```
|
47
examples/boost_container/container.cpp
Normal file
47
examples/boost_container/container.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
|
||||
#include <toml.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
struct boost_config
|
||||
{
|
||||
using comment_type = toml::preserve_comments;
|
||||
|
||||
using boolean_type = bool;
|
||||
using integer_type = std::int64_t;
|
||||
using floating_type = double;
|
||||
using string_type = std::string;
|
||||
|
||||
template<typename T>
|
||||
using array_type = boost::container::small_vector<T, 8>;
|
||||
template<typename K, typename T>
|
||||
using table_type = boost::unordered_flat_map<K, T>;
|
||||
|
||||
static toml::result<integer_type, toml::error_info>
|
||||
parse_int(const std::string& str, const toml::source_location src, const std::uint8_t base)
|
||||
{
|
||||
return toml::read_int<integer_type>(str, src, base);
|
||||
}
|
||||
static toml::result<floating_type, toml::error_info>
|
||||
parse_float(const std::string& str, const toml::source_location src, const bool is_hex)
|
||||
{
|
||||
return toml::read_float<floating_type>(str, src, is_hex);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if(argc != 2)
|
||||
{
|
||||
std::cerr << "usage: ./container <input.toml>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const auto input = toml::parse_str<boost_config>(argv[1]);
|
||||
|
||||
std::cout << toml::format(input) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
1
examples/boost_multiprecision/.gitignore
vendored
Normal file
1
examples/boost_multiprecision/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
multiprecision
|
8
examples/boost_multiprecision/CMakeLists.txt
Normal file
8
examples/boost_multiprecision/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
find_package(Boost 1.67.0)
|
||||
|
||||
if(Boost_FOUND)
|
||||
add_executable(multiprecision multiprecision.cpp)
|
||||
target_link_libraries(multiprecision PRIVATE toml11::toml11 Boost::boost)
|
||||
set_target_properties(multiprecision PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
13
examples/boost_multiprecision/README.md
Normal file
13
examples/boost_multiprecision/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# multiprecision
|
||||
|
||||
Use `boost::multiprecision` as `integer_type` and `floating_type`.
|
||||
|
||||
## build
|
||||
|
||||
Install [boost](https://boost.org).
|
||||
|
||||
Then, build toml11 with `-DTOML11_BUILD_EXAMPLES=ON`
|
||||
|
||||
```cpp
|
||||
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
|
||||
```
|
55
examples/boost_multiprecision/multiprecision.cpp
Normal file
55
examples/boost_multiprecision/multiprecision.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <boost/multiprecision/number.hpp>
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#include <boost/multiprecision/cpp_bin_float.hpp>
|
||||
|
||||
#include <toml.hpp>
|
||||
|
||||
struct large_num_config
|
||||
{
|
||||
using comment_type = toml::preserve_comments;
|
||||
|
||||
using boolean_type = bool;
|
||||
using integer_type = boost::multiprecision::cpp_int;
|
||||
using floating_type = boost::multiprecision::cpp_bin_float_oct;
|
||||
using string_type = std::string;
|
||||
|
||||
template<typename T>
|
||||
using array_type = std::vector<T>;
|
||||
template<typename K, typename T>
|
||||
using table_type = std::unordered_map<K, T>;
|
||||
|
||||
static toml::result<integer_type, toml::error_info>
|
||||
parse_int(const std::string& str, const toml::source_location src, const std::uint8_t base)
|
||||
{
|
||||
return toml::read_int<integer_type>(str, src, base);
|
||||
}
|
||||
static toml::result<floating_type, toml::error_info>
|
||||
parse_float(const std::string& str, const toml::source_location src, const bool is_hex)
|
||||
{
|
||||
return toml::read_float<floating_type>(str, src, is_hex);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
const std::string input_str(R"(
|
||||
large_int_dec = 10_000_000_000_000_000_000
|
||||
large_int_hex = 0x0001_0000_0000_0000_0000
|
||||
large_float_pi = 3.1415926535897932384626433832795028842
|
||||
)");
|
||||
|
||||
const auto input = toml::parse_str<large_num_config>(input_str);
|
||||
|
||||
std::cout << "int64_t max = " << (std::numeric_limits<std::int64_t>::max)() << std::endl;
|
||||
|
||||
std::cout << "large_int_dec = " << input.at("large_int_dec" ).as_integer() << std::endl;
|
||||
std::cout << "large_int_hex = " << input.at("large_int_hex" ).as_integer() << std::endl;
|
||||
std::cout << "large_float_pi = "
|
||||
<< std::setprecision(std::numeric_limits<boost::multiprecision::cpp_bin_float_oct>::max_digits10 - 1)
|
||||
<< input.at("large_float_pi").as_floating() << std::endl;
|
||||
|
||||
std::cout << "=================" << std::endl;
|
||||
std::cout << toml::format(input) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
4
examples/parse_file/.gitignore
vendored
Normal file
4
examples/parse_file/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
array_example
|
||||
array_of_tables_example
|
||||
key_example
|
||||
spec_example
|
19
examples/parse_file/CMakeLists.txt
Normal file
19
examples/parse_file/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
add_executable(spec_example spec_example.cpp)
|
||||
target_link_libraries(spec_example PRIVATE toml11::toml11)
|
||||
set_target_properties(spec_example PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
add_executable(key_example key_example.cpp)
|
||||
target_link_libraries(key_example PRIVATE toml11::toml11)
|
||||
set_target_properties(key_example PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
add_executable(array_example array_example.cpp)
|
||||
target_link_libraries(array_example PRIVATE toml11::toml11)
|
||||
set_target_properties(array_example PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
add_executable(array_of_tables_example array_of_tables_example.cpp)
|
||||
target_link_libraries(array_of_tables_example PRIVATE toml11::toml11)
|
||||
set_target_properties(array_of_tables_example PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
152
examples/parse_file/array_example.cpp
Normal file
152
examples/parse_file/array_example.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
#include <toml.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
const auto root = toml::parse("array_example.toml");
|
||||
|
||||
// using member functions
|
||||
{
|
||||
assert(root.at("integers").is_array());
|
||||
assert(root.at("integers").at(0).as_integer() == 1);
|
||||
assert(root.at("integers").at(1).as_integer() == 2);
|
||||
assert(root.at("integers").at(2).as_integer() == 3);
|
||||
|
||||
assert(root.at("colors").at(0).as_string() == "red");
|
||||
assert(root.at("colors").at(1).as_string() == "yellow");
|
||||
assert(root.at("colors").at(2).as_string() == "green");
|
||||
|
||||
assert(root.at("nested_arrays_of_ints").at(0).at(0).as_integer() == 1);
|
||||
assert(root.at("nested_arrays_of_ints").at(0).at(1).as_integer() == 2);
|
||||
assert(root.at("nested_arrays_of_ints").at(1).at(0).as_integer() == 3);
|
||||
assert(root.at("nested_arrays_of_ints").at(1).at(1).as_integer() == 4);
|
||||
assert(root.at("nested_arrays_of_ints").at(1).at(2).as_integer() == 5);
|
||||
|
||||
assert(root.at("nested_mixed_array").at(0).at(0).as_integer() == 1);
|
||||
assert(root.at("nested_mixed_array").at(0).at(1).as_integer() == 2);
|
||||
assert(root.at("nested_mixed_array").at(1).at(0).as_string() == "a");
|
||||
assert(root.at("nested_mixed_array").at(1).at(1).as_string() == "b");
|
||||
assert(root.at("nested_mixed_array").at(1).at(2).as_string() == "c");
|
||||
|
||||
assert(root.at("string_array").at(0).as_string() == "all");
|
||||
assert(root.at("string_array").at(1).as_string() == "strings");
|
||||
assert(root.at("string_array").at(2).as_string() == "are the same");
|
||||
assert(root.at("string_array").at(3).as_string() == "type");
|
||||
|
||||
assert(root.at("numbers").at(0).as_floating() == std::stod("0.1"));
|
||||
assert(root.at("numbers").at(1).as_floating() == std::stod("0.2"));
|
||||
assert(root.at("numbers").at(2).as_floating() == std::stod("0.5"));
|
||||
assert(root.at("numbers").at(3).as_integer() == 1);
|
||||
assert(root.at("numbers").at(4).as_integer() == 2);
|
||||
assert(root.at("numbers").at(5).as_integer() == 5);
|
||||
|
||||
assert(root.at("contributors").at(0).as_string() == "Foo Bar <foo@example.com>");
|
||||
assert(root.at("contributors").at(1).at("name" ).as_string() == "Baz Qux");
|
||||
assert(root.at("contributors").at(1).at("email").as_string() == "bazqux@example.com");
|
||||
assert(root.at("contributors").at(1).at("url" ).as_string() == "https://example.com/bazqux");
|
||||
}
|
||||
|
||||
// using toml::find
|
||||
{
|
||||
assert(toml::find<int>(root, "integers", 0) == 1);
|
||||
assert(toml::find<int>(root, "integers", 1) == 2);
|
||||
assert(toml::find<int>(root, "integers", 2) == 3);
|
||||
|
||||
const auto integers = toml::find<std::vector<int>>(root, "integers");
|
||||
assert(integers.at(0) == 1);
|
||||
assert(integers.at(1) == 2);
|
||||
assert(integers.at(2) == 3);
|
||||
|
||||
assert(toml::find<std::string>(root, "colors", 0) == "red");
|
||||
assert(toml::find<std::string>(root, "colors", 1) == "yellow");
|
||||
assert(toml::find<std::string>(root, "colors", 2) == "green");
|
||||
|
||||
const auto colors = toml::find<std::array<std::string, 3>>(root, "colors");
|
||||
assert(colors.at(0) == "red");
|
||||
assert(colors.at(1) == "yellow");
|
||||
assert(colors.at(2) == "green");
|
||||
|
||||
assert(toml::find<int>(root, "nested_arrays_of_ints", 0, 0) == 1);
|
||||
assert(toml::find<int>(root, "nested_arrays_of_ints", 0, 1) == 2);
|
||||
assert(toml::find<int>(root, "nested_arrays_of_ints", 1, 0) == 3);
|
||||
assert(toml::find<int>(root, "nested_arrays_of_ints", 1, 1) == 4);
|
||||
assert(toml::find<int>(root, "nested_arrays_of_ints", 1, 2) == 5);
|
||||
|
||||
const auto nested_arrays_of_ints = toml::find<std::vector<std::vector<int>>>(root, "nested_arrays_of_ints");
|
||||
assert(nested_arrays_of_ints.at(0).at(0) == 1);
|
||||
assert(nested_arrays_of_ints.at(0).at(1) == 2);
|
||||
assert(nested_arrays_of_ints.at(1).at(0) == 3);
|
||||
assert(nested_arrays_of_ints.at(1).at(1) == 4);
|
||||
assert(nested_arrays_of_ints.at(1).at(2) == 5);
|
||||
|
||||
assert(toml::find<int >(root, "nested_mixed_array", 0, 0) == 1);
|
||||
assert(toml::find<int >(root, "nested_mixed_array", 0, 1) == 2);
|
||||
assert(toml::find<std::string>(root, "nested_mixed_array", 1, 0) == "a");
|
||||
assert(toml::find<std::string>(root, "nested_mixed_array", 1, 1) == "b");
|
||||
assert(toml::find<std::string>(root, "nested_mixed_array", 1, 2) == "c");
|
||||
|
||||
const auto nested_mixed_array = toml::find<
|
||||
std::pair<std::vector<int>, std::vector<std::string>>
|
||||
>(root, "nested_mixed_array");
|
||||
|
||||
assert(nested_mixed_array.first .at(0) == 1);
|
||||
assert(nested_mixed_array.first .at(1) == 2);
|
||||
assert(nested_mixed_array.second.at(0) == "a");
|
||||
assert(nested_mixed_array.second.at(1) == "b");
|
||||
assert(nested_mixed_array.second.at(2) == "c");
|
||||
|
||||
assert(toml::find<std::string>(root, "string_array", 0) == "all");
|
||||
assert(toml::find<std::string>(root, "string_array", 1) == "strings");
|
||||
assert(toml::find<std::string>(root, "string_array", 2) == "are the same");
|
||||
assert(toml::find<std::string>(root, "string_array", 3) == "type");
|
||||
|
||||
const auto numbers = toml::find<
|
||||
std::tuple<double, double, double, int, int, int>
|
||||
>(root, "numbers");
|
||||
|
||||
assert(std::get<0>(numbers) == std::stod("0.1"));
|
||||
assert(std::get<1>(numbers) == std::stod("0.2"));
|
||||
assert(std::get<2>(numbers) == std::stod("0.5"));
|
||||
assert(std::get<3>(numbers) == 1);
|
||||
assert(std::get<4>(numbers) == 2);
|
||||
assert(std::get<5>(numbers) == 5);
|
||||
|
||||
struct contributor_t
|
||||
{
|
||||
contributor_t(const toml::value& v)
|
||||
{
|
||||
if(v.is_string())
|
||||
{
|
||||
name = v.as_string();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(v.is_table());
|
||||
name = toml::find<std::string>(v, "name");
|
||||
email = toml::find_or(v, "email", std::string(""));
|
||||
url = toml::find_or(v, "url" , std::string(""));
|
||||
}
|
||||
}
|
||||
|
||||
std::string name;
|
||||
std::string email;
|
||||
std::string url;
|
||||
};
|
||||
|
||||
const auto contributors = toml::find<std::vector<contributor_t>>(root, "contributors");
|
||||
|
||||
assert(contributors.at(0).name == "Foo Bar <foo@example.com>");
|
||||
assert(contributors.at(0).email == "");
|
||||
assert(contributors.at(0).url == "");
|
||||
assert(contributors.at(1).name == "Baz Qux");
|
||||
assert(contributors.at(1).email == "bazqux@example.com");
|
||||
assert(contributors.at(1).url == "https://example.com/bazqux");
|
||||
}
|
||||
|
||||
std::cout << "ok." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
12
examples/parse_file/array_example.toml
Normal file
12
examples/parse_file/array_example.toml
Normal file
@ -0,0 +1,12 @@
|
||||
integers = [ 1, 2, 3 ]
|
||||
colors = [ "red", "yellow", "green" ]
|
||||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||
|
||||
# Mixed-type arrays are allowed
|
||||
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||
contributors = [
|
||||
"Foo Bar <foo@example.com>",
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
]
|
135
examples/parse_file/array_of_tables_example.cpp
Normal file
135
examples/parse_file/array_of_tables_example.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
#include <toml.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
const auto root = toml::parse("array_of_tables_example.toml");
|
||||
|
||||
// using member functions
|
||||
{
|
||||
assert(root.at("points").is_array());
|
||||
assert(root.at("points").at(0).is_table());
|
||||
assert(root.at("points").at(1).is_table());
|
||||
assert(root.at("points").at(2).is_table());
|
||||
|
||||
assert(root.at("points").at(0).at("x").as_integer() == 1);
|
||||
assert(root.at("points").at(0).at("y").as_integer() == 2);
|
||||
assert(root.at("points").at(0).at("z").as_integer() == 3);
|
||||
|
||||
assert(root.at("points").at(1).at("x").as_integer() == 7);
|
||||
assert(root.at("points").at(1).at("y").as_integer() == 8);
|
||||
assert(root.at("points").at(1).at("z").as_integer() == 9);
|
||||
|
||||
assert(root.at("points").at(2).at("x").as_integer() == 2);
|
||||
assert(root.at("points").at(2).at("y").as_integer() == 4);
|
||||
assert(root.at("points").at(2).at("z").as_integer() == 8);
|
||||
|
||||
|
||||
assert(root.at("products").at(0).at("name").as_string() == "Hammer");
|
||||
assert(root.at("products").at(0).at("sku" ).as_integer() == 738594937);
|
||||
|
||||
assert(root.at("products").at(1).as_table().empty());
|
||||
|
||||
assert(root.at("products").at(2).at("name" ).as_string() == "Nail");
|
||||
assert(root.at("products").at(2).at("sku" ).as_integer() == 284758393);
|
||||
assert(root.at("products").at(2).at("color").as_string() == "gray");
|
||||
|
||||
assert(root.at("fruits").at(0).at("name").as_string() == "apple");
|
||||
assert(root.at("fruits").at(0).at("physical").at("color").as_string() == "red");
|
||||
assert(root.at("fruits").at(0).at("physical").at("shape").as_string() == "round");
|
||||
assert(root.at("fruits").at(0).at("varieties").at(0).at("name").as_string() == "red delicious");
|
||||
assert(root.at("fruits").at(0).at("varieties").at(1).at("name").as_string() == "granny smith");
|
||||
|
||||
assert(root.at("fruits").at(1).at("name").as_string() == "banana");
|
||||
assert(root.at("fruits").at(1).at("varieties").at(0).at("name").as_string() == "plantain");
|
||||
}
|
||||
|
||||
// using toml::find
|
||||
{
|
||||
assert(toml::find<int>(root, "points", 0, "x") == 1);
|
||||
assert(toml::find<int>(root, "points", 0, "y") == 2);
|
||||
assert(toml::find<int>(root, "points", 0, "z") == 3);
|
||||
|
||||
assert(toml::find<int>(root, "points", 1, "x") == 7);
|
||||
assert(toml::find<int>(root, "points", 1, "y") == 8);
|
||||
assert(toml::find<int>(root, "points", 1, "z") == 9);
|
||||
|
||||
assert(toml::find<int>(root, "points", 2, "x") == 2);
|
||||
assert(toml::find<int>(root, "points", 2, "y") == 4);
|
||||
assert(toml::find<int>(root, "points", 2, "z") == 8);
|
||||
|
||||
const auto points = toml::find<
|
||||
std::vector<std::map<std::string, int>>
|
||||
>(root, "points");
|
||||
|
||||
assert(points.at(0).at("x") == 1);
|
||||
assert(points.at(0).at("y") == 2);
|
||||
assert(points.at(0).at("z") == 3);
|
||||
|
||||
assert(points.at(1).at("x") == 7);
|
||||
assert(points.at(1).at("y") == 8);
|
||||
assert(points.at(1).at("z") == 9);
|
||||
|
||||
assert(points.at(2).at("x") == 2);
|
||||
assert(points.at(2).at("y") == 4);
|
||||
assert(points.at(2).at("z") == 8);
|
||||
|
||||
struct product_t
|
||||
{
|
||||
product_t(const toml::value& v)
|
||||
: name (toml::find_or<std::string >(v, "name", "")),
|
||||
sku (toml::find_or<std::uint64_t>(v, "sku", 0)),
|
||||
color(toml::find_or<std::string >(v, "color", ""))
|
||||
{}
|
||||
std::string name;
|
||||
std::uint64_t sku;
|
||||
std::string color;
|
||||
};
|
||||
|
||||
const auto products = toml::find<std::vector<product_t>>(root, "products");
|
||||
|
||||
assert(products.at(0).name == "Hammer");
|
||||
assert(products.at(0).sku == 738594937);
|
||||
assert(products.at(0).color == "");
|
||||
|
||||
assert(products.at(1).name == "");
|
||||
assert(products.at(1).sku == 0);
|
||||
assert(products.at(1).color == "");
|
||||
|
||||
assert(products.at(2).name == "Nail");
|
||||
assert(products.at(2).sku == 284758393);
|
||||
assert(products.at(2).color == "gray");
|
||||
|
||||
struct fruit_t
|
||||
{
|
||||
fruit_t(const toml::value& v)
|
||||
: name(toml::find<std::string>(v, "name")),
|
||||
physical (toml::find<std::map<std::string, std::string>>(v, "physical")),
|
||||
varieties(toml::find<std::vector<std::map<std::string, std::string>>>(v, "varieties"))
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
std::map<std::string, std::string> physical;
|
||||
std::vector<std::map<std::string, std::string>> varieties;
|
||||
};
|
||||
|
||||
const auto fruits = toml::find<std::vector<fruit_t>>(root, "fruits");
|
||||
|
||||
assert(fruits.at(0).name == "apple");
|
||||
assert(fruits.at(0).physical.at("color") == "red");
|
||||
assert(fruits.at(0).physical.at("shape") == "round");
|
||||
assert(fruits.at(0).varieties.at(0).at("name") == "red delicious");
|
||||
assert(fruits.at(0).varieties.at(1).at("name") == "granny smith");
|
||||
|
||||
assert(fruits.at(1).name == "banana");
|
||||
assert(fruits.at(1).varieties.at(0).at("name") == "plantain");
|
||||
}
|
||||
|
||||
std::cout << "ok." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
34
examples/parse_file/array_of_tables_example.toml
Normal file
34
examples/parse_file/array_of_tables_example.toml
Normal file
@ -0,0 +1,34 @@
|
||||
points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ]
|
||||
|
||||
[[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
[[products]] # empty table within the array
|
||||
|
||||
[[products]]
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
|
||||
color = "gray"
|
||||
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
|
||||
[fruits.physical] # subtable
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
[[fruits.varieties]] # nested array of tables
|
||||
name = "red delicious"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "granny smith"
|
||||
|
||||
[[fruits]]
|
||||
name = "banana"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "plantain"
|
74
examples/parse_file/key_example.cpp
Normal file
74
examples/parse_file/key_example.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include <toml.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
const auto root = toml::parse("key_example.toml");
|
||||
|
||||
assert(root.is_table());
|
||||
assert(root.comments().size() == 2);
|
||||
assert(root.comments().at(0) == " This is a TOML document.");
|
||||
assert(root.comments().at(1) == " This contains most of the examples in the spec (from https://toml.io).");
|
||||
|
||||
assert(root.size() == 1);
|
||||
assert(root.contains("key"));
|
||||
assert(root.at("key").is_table());
|
||||
|
||||
// using member functions
|
||||
{
|
||||
const toml::value& keys = root.at("key");
|
||||
assert(keys.at("key" ).as_string() == "value");
|
||||
assert(keys.at("bare_key").as_string() == "value");
|
||||
assert(keys.at("bare-key").as_string() == "value");
|
||||
assert(keys.at("1234" ).as_string() == "value");
|
||||
|
||||
assert(keys.at("127.0.0.1" ).as_string() == "value");
|
||||
assert(keys.at("character encoding").as_string() == "value");
|
||||
assert(keys.at("ʎǝʞ" ).as_string() == "value"); // requires /utf-8 in MSVC
|
||||
assert(keys.at("key2" ).as_string() == "value");
|
||||
assert(keys.at("quoted \"value\"" ).as_string() == "value");
|
||||
|
||||
assert(keys.at("").as_string() == "blank");
|
||||
|
||||
assert(keys.at("fruit").at("apple").at("skin" ).as_string() == "thin");
|
||||
assert(keys.at("fruit").at("apple").at("color").as_string() == "red");
|
||||
assert(keys.at("fruit").at("orange").at("skin" ).as_string() == "thick");
|
||||
assert(keys.at("fruit").at("orange").at("color").as_string() == "orange");
|
||||
|
||||
assert(keys.at("site").at("google.com").as_boolean() == true);
|
||||
assert(keys.at("3").at("14159").as_string() == "pi");
|
||||
}
|
||||
|
||||
// using toml::find
|
||||
{
|
||||
assert(toml::find<std::string>(root, "keys", "key" ) == "value");
|
||||
assert(toml::find<std::string>(root, "keys", "bare_key") == "value");
|
||||
assert(toml::find<std::string>(root, "keys", "bare-key") == "value");
|
||||
assert(toml::find<std::string>(root, "keys", "1234" ) == "value");
|
||||
|
||||
const toml::value& keys = toml::find(root, "keys");
|
||||
|
||||
assert(toml::find<std::string>(keys, "127.0.0.1" ) == "value");
|
||||
assert(toml::find<std::string>(keys, "character encoding") == "value");
|
||||
assert(toml::find<std::string>(keys, "ʎǝʞ" ) == "value"); // requires /utf-8 in MSVC
|
||||
assert(toml::find<std::string>(keys, "key2" ) == "value");
|
||||
assert(toml::find<std::string>(keys, "quoted \"value\"" ) == "value");
|
||||
|
||||
assert(toml::find<std::string>(keys, "") == "blank");
|
||||
|
||||
assert(toml::find<std::string>(keys, "fruit", "apple" , "skin" ) == "thin");
|
||||
assert(toml::find<std::string>(keys, "fruit", "apple" , "color") == "red");
|
||||
assert(toml::find<std::string>(keys, "fruit", "orange", "skin" ) == "thick");
|
||||
assert(toml::find<std::string>(keys, "fruit", "orange", "color") == "orange");
|
||||
|
||||
assert(toml::find<bool>(keys, "site", "google.com") == true);
|
||||
assert(toml::find<std::string>(keys, "3", "14159") == "pi");
|
||||
}
|
||||
|
||||
std::cout << "ok." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
26
examples/parse_file/key_example.toml
Normal file
26
examples/parse_file/key_example.toml
Normal file
@ -0,0 +1,26 @@
|
||||
# This is a TOML document.
|
||||
# This contains most of the examples in the spec (from https://toml.io).
|
||||
|
||||
[keys]
|
||||
|
||||
key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value"
|
||||
|
||||
"127.0.0.1" = "value"
|
||||
"character encoding" = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value"
|
||||
|
||||
"" = "blank"
|
||||
|
||||
fruits.apple.skin = "thin"
|
||||
fruits.apple.color = "red"
|
||||
|
||||
fruits.orange.skin = "thick"
|
||||
fruits.orange.color = "orange"
|
||||
|
||||
site."google.com" = true
|
||||
3.14159 = "pi"
|
86
examples/parse_file/spec_example.cpp
Normal file
86
examples/parse_file/spec_example.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include <toml.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
const auto root = toml::parse("spec_example.toml");
|
||||
|
||||
// using member functions
|
||||
{
|
||||
assert(root.at("title").as_string() == "TOML Example");
|
||||
|
||||
assert(root.at("owner").at("name").as_string() == "Tom Preston-Werner");
|
||||
|
||||
const auto dob = root.at("owner").at("dob" ).as_offset_datetime();
|
||||
assert(dob.date .year == 1979);
|
||||
assert(dob.date .month == static_cast<int>(toml::month_t::May));
|
||||
assert(dob.date .day == 27);
|
||||
assert(dob.time .hour == 7);
|
||||
assert(dob.time .minute == 32);
|
||||
assert(dob.time .second == 0);
|
||||
assert(dob.offset.hour == -8);
|
||||
assert(dob.offset.minute == 0);
|
||||
|
||||
assert(root.at("database").at("enabled").as_boolean());
|
||||
assert(root.at("database").at("ports").at(0).as_integer() == 8000);
|
||||
assert(root.at("database").at("ports").at(1).as_integer() == 8001);
|
||||
assert(root.at("database").at("ports").at(2).as_integer() == 8002);
|
||||
assert(root.at("database").at("data").at(0).at(0).as_string() == "delta");
|
||||
assert(root.at("database").at("data").at(0).at(1).as_string() == "phi");
|
||||
assert(root.at("database").at("data").at(1).at(0).as_floating() == 3.14);
|
||||
assert(root.at("database").at("temp_targets").at("cpu" ).as_floating() == 79.5);
|
||||
assert(root.at("database").at("temp_targets").at("case").as_floating() == 72.0);
|
||||
|
||||
assert(root.at("servers").at("alpha").at("ip" ).as_string() == "10.0.0.1");
|
||||
assert(root.at("servers").at("alpha").at("role").as_string() == "frontend");
|
||||
assert(root.at("servers").at("beta" ).at("ip" ).as_string() == "10.0.0.2");
|
||||
assert(root.at("servers").at("beta" ).at("role").as_string() == "backend");
|
||||
}
|
||||
|
||||
// using toml::find
|
||||
{
|
||||
assert(toml::find<std::string>(root, "title") == "TOML Example");
|
||||
|
||||
assert(toml::find<std::string>(root, "owner", "name") == "Tom Preston-Werner");
|
||||
|
||||
const auto dob = toml::find<toml::offset_datetime>(root, "owner", "dob");
|
||||
assert(dob.date .year == 1979);
|
||||
assert(dob.date .month == static_cast<int>(toml::month_t::May));
|
||||
assert(dob.date .day == 27);
|
||||
assert(dob.time .hour == 7);
|
||||
assert(dob.time .minute == 32);
|
||||
assert(dob.time .second == 0);
|
||||
assert(dob.offset.hour == -8);
|
||||
assert(dob.offset.minute == 0);
|
||||
|
||||
assert(toml::find<bool>(root, "database", "enabled"));
|
||||
|
||||
const auto ports = toml::find<std::vector<int>>(root, "database", "ports");
|
||||
assert(ports.at(0) == 8000);
|
||||
assert(ports.at(1) == 8001);
|
||||
assert(ports.at(2) == 8002);
|
||||
|
||||
const auto data = toml::find<std::pair<std::vector<std::string>, std::vector<double>>>(root, "database", "data");
|
||||
assert(data.first.at(0) == "delta");
|
||||
assert(data.first.at(1) == "phi");
|
||||
assert(data.second.at(0) == 3.14);
|
||||
|
||||
const auto temp_targets = toml::find<std::map<std::string, double>>(root, "database", "temp_targets");
|
||||
assert(temp_targets.at("cpu" ) == 79.5);
|
||||
assert(temp_targets.at("case") == 72.0);
|
||||
|
||||
const auto servers = toml::find<std::map<std::string, std::map<std::string, std::string>>>(root, "servers");
|
||||
assert(servers.at("alpha").at("ip" ) == "10.0.0.1");
|
||||
assert(servers.at("alpha").at("role") == "frontend");
|
||||
assert(servers.at("beta" ).at("ip" ) == "10.0.0.2");
|
||||
assert(servers.at("beta" ).at("role") == "backend" );
|
||||
}
|
||||
|
||||
std::cout << "ok." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
23
examples/parse_file/spec_example.toml
Normal file
23
examples/parse_file/spec_example.toml
Normal file
@ -0,0 +1,23 @@
|
||||
# This is a TOML document
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
dob = 1979-05-27T07:32:00-08:00
|
||||
|
||||
[database]
|
||||
enabled = true
|
||||
ports = [ 8000, 8001, 8002 ]
|
||||
data = [ ["delta", "phi"], [3.14] ]
|
||||
temp_targets = { cpu = 79.5, case = 72.0 }
|
||||
|
||||
[servers]
|
||||
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
role = "frontend"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
role = "backend"
|
1
examples/reflect/.gitignore
vendored
Normal file
1
examples/reflect/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
reflect
|
18
examples/reflect/CMakeLists.txt
Normal file
18
examples/reflect/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
boost_ext_reflect
|
||||
GIT_REPOSITORY https://github.com/boost-ext/reflect
|
||||
GIT_SHALLOW ON # Download the branch without its history
|
||||
GIT_TAG v1.1.1
|
||||
)
|
||||
FetchContent_MakeAvailable(boost_ext_reflect)
|
||||
|
||||
add_executable(reflect reflect.cpp)
|
||||
target_link_libraries(reflect PRIVATE toml11::toml11)
|
||||
target_include_directories(reflect PRIVATE
|
||||
${boost_ext_reflect_SOURCE_DIR}
|
||||
)
|
||||
target_compile_features(reflect PRIVATE cxx_std_20)
|
||||
set_target_properties(reflect PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
13
examples/reflect/README.md
Normal file
13
examples/reflect/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# reflect
|
||||
|
||||
Auto convert from user-defined `struct`s to `toml::value`.
|
||||
|
||||
It depends on [boost-ext/reflect](https://github.com/boost-ext/reflect).
|
||||
|
||||
## build
|
||||
|
||||
Build toml11 with `-DTOML11_BUILD_EXAMPLES=ON`.
|
||||
|
||||
```cpp
|
||||
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
|
||||
```
|
38
examples/reflect/reflect.cpp
Normal file
38
examples/reflect/reflect.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <reflect>
|
||||
#include "reflect.hpp"
|
||||
|
||||
struct Hoge
|
||||
{
|
||||
int foo;
|
||||
double bar;
|
||||
std::string baz;
|
||||
};
|
||||
TOML11_REFLECT(Hoge)
|
||||
|
||||
int main()
|
||||
{
|
||||
toml::value v(toml::table{
|
||||
{"foo", 42},
|
||||
{"bar", 3.14},
|
||||
{"baz", "fuga"},
|
||||
});
|
||||
|
||||
const Hoge h = toml::get<Hoge>(v);
|
||||
|
||||
std::cout << "Hoge.foo = " << h.foo << std::endl;
|
||||
std::cout << "Hoge.bar = " << h.bar << std::endl;
|
||||
std::cout << "Hoge.baz = " << h.baz << std::endl;
|
||||
|
||||
Hoge h2;
|
||||
h2.foo = 6 * 9;
|
||||
h2.bar = 2.718;
|
||||
h2.baz = "piyo";
|
||||
|
||||
toml::value v2(h2);
|
||||
|
||||
std::cout << toml::format(v2);
|
||||
|
||||
return 0;
|
||||
}
|
61
examples/reflect/reflect.hpp
Normal file
61
examples/reflect/reflect.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef TOML11_REFLECT_HPP
|
||||
#define TOML11_REFLECT_HPP
|
||||
|
||||
#include <reflect> // boost-ext/reflect
|
||||
|
||||
#include <toml.hpp>
|
||||
|
||||
namespace toml
|
||||
{
|
||||
namespace refl
|
||||
{
|
||||
template<typename T, typename TC>
|
||||
T from(const basic_value<TC>& v)
|
||||
{
|
||||
T x;
|
||||
reflect::for_each([&v, &x](auto I) {
|
||||
using member_type = std::remove_cvref_t<decltype(reflect::get<I>(x))>;
|
||||
const auto key = std::string(reflect::member_name<I>(x));
|
||||
reflect::get<I>(x) = toml::find<member_type>(v, key);
|
||||
}, x);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
template<typename TC = toml::type_config, typename T>
|
||||
basic_value<TC> into(const T& x)
|
||||
{
|
||||
basic_value<TC> v(toml::table{});
|
||||
reflect::for_each([&v, &x](auto I) {
|
||||
using member_type = std::remove_cvref_t<decltype(reflect::get<I>(x))>;
|
||||
const auto key = std::string(reflect::member_name<I>(x));
|
||||
v[key] = reflect::get<I>(x);
|
||||
}, x);
|
||||
return v;
|
||||
}
|
||||
} // refl
|
||||
} // toml
|
||||
|
||||
#define TOML11_REFLECT(X) \
|
||||
namespace toml { \
|
||||
template<> \
|
||||
struct into<X> \
|
||||
{ \
|
||||
template<typename TC = toml::type_config> \
|
||||
static toml::basic_value<TC> into_toml(const X& x) \
|
||||
{ \
|
||||
return refl::into(x); \
|
||||
} \
|
||||
}; \
|
||||
template<> \
|
||||
struct from<X> \
|
||||
{ \
|
||||
template<typename TC = toml::type_config> \
|
||||
static X from_toml(const toml::basic_value<TC>& v) \
|
||||
{ \
|
||||
return refl::from<X>(v); \
|
||||
} \
|
||||
}; \
|
||||
} /* toml */
|
||||
|
||||
#endif // TOML11_REFLECT_HPP
|
1
examples/unicode/.gitignore
vendored
Normal file
1
examples/unicode/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
canonicalize
|
15
examples/unicode/CMakeLists.txt
Normal file
15
examples/unicode/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(uni-algo
|
||||
GIT_REPOSITORY https://github.com/uni-algo/uni-algo.git
|
||||
GIT_SHALLOW ON # Download the branch without its history
|
||||
GIT_TAG v1.0.0) # The version you want to download
|
||||
|
||||
# Be aware that FetchContent_MakeAvailable requires CMake 3.14 or higher
|
||||
FetchContent_MakeAvailable(uni-algo)
|
||||
|
||||
add_executable(canonicalize canonicalize.cpp)
|
||||
target_link_libraries(canonicalize PRIVATE toml11::toml11 uni-algo::uni-algo)
|
||||
set_target_properties(canonicalize PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
15
examples/unicode/README.md
Normal file
15
examples/unicode/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# reflect
|
||||
|
||||
Compare TOML key after NFC canonicalization.
|
||||
|
||||
It depends on [uni-algo](https://github.com/uni-algo/uni-algo.git).
|
||||
|
||||
The example contains two keys that are different in bytewise comparison, but becomes the same after NFC normalization.
|
||||
|
||||
## build
|
||||
|
||||
Build toml11 with `-DTOML11_BUILD_EXAMPLES=ON`.
|
||||
|
||||
```cpp
|
||||
$ cmake -B ./build/ -DTOML11_BUILD_EXAMPLES=ON
|
||||
```
|
79
examples/unicode/canonicalize.cpp
Normal file
79
examples/unicode/canonicalize.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include <toml.hpp>
|
||||
#include <uni_algo/norm.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
struct nfc_comparator
|
||||
{
|
||||
using first_argument_type = std::string;
|
||||
using second_argument_type = std::string;
|
||||
using result_type = bool;
|
||||
|
||||
result_type operator()(const first_argument_type& lhs, const second_argument_type& rhs) const
|
||||
{
|
||||
return una::norm::to_nfc_utf8(lhs) < una::norm::to_nfc_utf8(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
struct nfc_equal_to
|
||||
{
|
||||
using first_argument_type = std::string;
|
||||
using second_argument_type = std::string;
|
||||
using result_type = bool;
|
||||
|
||||
result_type operator()(const first_argument_type& lhs, const second_argument_type& rhs) const
|
||||
{
|
||||
return una::norm::to_nfc_utf8(lhs) == una::norm::to_nfc_utf8(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
struct nfc_hasher
|
||||
{
|
||||
std::size_t operator()(const std::string& s) const
|
||||
{
|
||||
return std::hash<std::string>{}(una::norm::to_nfc_utf8(s));
|
||||
}
|
||||
};
|
||||
|
||||
struct nfc_config
|
||||
{
|
||||
using comment_type = toml::preserve_comments;
|
||||
|
||||
using boolean_type = bool;
|
||||
using integer_type = std::int64_t;
|
||||
using floating_type = double;
|
||||
using string_type = std::string;
|
||||
|
||||
template<typename T>
|
||||
using array_type = std::vector<T>;
|
||||
template<typename K, typename T>
|
||||
// using table_type = std::map<K, T, nfc_comparator>;
|
||||
using table_type = std::unordered_map<K, T, nfc_hasher, nfc_equal_to>;
|
||||
|
||||
static toml::result<integer_type, toml::error_info>
|
||||
parse_int(const std::string& str, const toml::source_location src, const std::uint8_t base)
|
||||
{
|
||||
return toml::read_int<integer_type>(str, src, base);
|
||||
}
|
||||
static toml::result<floating_type, toml::error_info>
|
||||
parse_float(const std::string& str, const toml::source_location src, const bool is_hex)
|
||||
{
|
||||
return toml::read_float<floating_type>(str, src, is_hex);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if(argc != 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const auto input = toml::parse<nfc_config>(argv[1]);
|
||||
|
||||
std::cout << toml::format(input) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
2
examples/unicode/input.toml
Normal file
2
examples/unicode/input.toml
Normal file
@ -0,0 +1,2 @@
|
||||
"W\u0302" = 1 # in NFC, this key is the same as the following key
|
||||
"Ŵ" = 2 # so it fails.
|
Loading…
Reference in New Issue
Block a user