diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf4e528..e11bcf4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,5 @@
cmake_minimum_required(VERSION 3.14.0)
-project(toml VERSION 0.1)
-
-### These flags should be removed eventually
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
+project(tominal VERSION 0.1)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
@@ -17,12 +12,12 @@ set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}")
option(TOML_BUILD_EXAMPLE "Build examples" OFF)
option(TOML_BUILD_TEST "Build tests" ON)
-# Import tomlplusplus interface library
-add_library(toml INTERFACE IMPORTED)
+add_library(tominal INTERFACE IMPORTED)
set_target_properties(
- toml PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}"
+ tominal PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/include"
)
+target_compile_features(tominal INTERFACE cxx_std_17)
if(TOML_BUILD_TEST)
include(FetchContent)
@@ -35,5 +30,9 @@ if(TOML_BUILD_TEST)
FetchContent_MakeAvailable(googletest)
enable_testing()
- add_subdirectory(test)
+ add_subdirectory(tests)
+endif()
+
+if(TOML_BUILD_EXAMPLE)
+ add_subdirectory(examples)
endif()
\ No newline at end of file
diff --git a/README.md b/README.md
index 18974e7..7709649 100644
--- a/README.md
+++ b/README.md
@@ -23,39 +23,40 @@ C++ Alternatives:
To parse a TOML document from a file, you can do the following:
```cpp
-#include "toml/toml.h"
+#include "tominal/toml.h"
// ## Parsing
// `parse_file()` returns a `node_view` of a `toml::table`, which owns
// a copy of `std::shared_ptr
` so there is no lifetime issue.
// It will return an empty view if it catches an `toml::parse_error`.
-auto config = cpptoml::parse_file("examples/example.toml").ok();
+auto config = toml::parse_file("examples/example.toml").ok();
// ## Obtaining Basic Values
-auto title = config["title"].value_or(""sv); // "TOML Example"sv
-// or you want to have a `std::optional`
-auto optional_title = config["title"].value().value();
+auto title = config["title"].value_or("TOML"sv); // "TOML Example"sv
+// or to have the default `std::string_view` if node_view is empty
+auto default_title = config["title"].value_or_default();
// ## Nested Tables
// Nested tables can be queried directly by chaining `[]` operator through
// the `node_view` and you can use a `map` function to convert to your data type
-auto author = config["owner"]["name"].value_or(""sv); // "Tom Preston-Werner"
+auto author = config["owner"]["name"].value_or("TOML");
+auto enabled = config["database.enabled"].value_or_default();
-// empty `std::optional` will be mapped if node does not exist
-auto dob = config["owner"]["dob"].map([](const auto &val) {
+// map a node_view in place if it exists:
+auto dob = config["owner.dob"].map([](const auto &val) {
return val.year * 10000 + val.month * 100 + val.day;
-}); // std::optional{19790527}
+});
+config["owner.dob"].map([](const auto &val) {}); // void callback
+
// ## Arrays of Values / Tables
// Similarly to `toml::table`, you can access the `node` of a table by `[]`
// operator. The are also `collect` and `map_collect` provided for convenience:
-auto gamma = config["clients"][0]["data"][0][0].value_or(""sv);
-auto data0 = config["clients"][0]["data"][0].collect(); // std::vector{"gamma"sv, "delta"sv}
-
-auto ports = config["database"]["ports"].map_collect(
- [](const auto &val) {
- return val - 1;
- }); // std::vector{8000, 8000, 8001}
+auto gamma = config["clients"][0]["data"][1][1].value_or_default();
+auto data0 = config["clients"][1]["host"].collect(); // std::vector{"omega"sv}
+auto ports = config["database"]["ports"].map_collect([](const auto &val) {
+ return val - 8000; // std::vector{0, 0, 1}
+});
```
A problem I had with `cpptoml` was that I was not able to dereference an `rvalue` table or array:
@@ -97,12 +98,12 @@ Here are the fields of the date/time objects in cpptoml:
- minute\_offset (`offset_date_time`)
-## Test Results - TODO
+## Test Results
From [the toml-test suite][toml-test]:
```
-126 passed, 0 failed // TODO with TOML v1.0.0-rc.1
+116 passed, 12 failed // toml-test suite is only compliant with TOML v0.4.0
```
## Compilation
@@ -123,7 +124,7 @@ You can look at the files files `parse.cpp`, `parse_stdin.cpp`, and
`build_toml.cpp` in the root directory for some more examples.
`parse_stdin.cpp` shows how to use the visitor pattern to traverse an
-entire `cpptoml::table` for serialization.
+entire `toml::table` for serialization.
`build_toml.cpp` shows how to construct a TOML representation in-memory and
then serialize it to a stream.
@@ -136,4 +137,4 @@ then serialize it to a stream.
[toml11]: https://github.com/ToruNiina/toml11
[tinytoml]: https://github.com/mayah/tinytoml
[boost.toml]: https://github.com/ToruNiina/Boost.toml
-[tomlplusplus]: https://github.com/marzer/tomlplusplus
+[tomlplusplus]: https://github.com/marzer/tomlplusplus
\ No newline at end of file
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c993d54..eb881bd 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,17 +1,19 @@
+### These flags should be removed eventually
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Release)
+endif()
+
add_executable(parse parse.cpp)
-target_link_libraries(parse cpptoml)
-set_target_properties(parse PROPERTIES
- CXX_STANDARD 11
- CXX_EXTENSIONS OFF
- CXX_STANDARD_REQUIRED YES)
+target_link_libraries(parse tominal)
-add_executable(cpptoml-parser parse_stdin.cpp)
-target_link_libraries(cpptoml-parser cpptoml)
-set_target_properties(cpptoml-parser PROPERTIES
- CXX_STANDARD 11
- CXX_EXTENSIONS OFF
- CXX_STANDARD_REQUIRED YES)
+add_executable(toml-parser parse_stdin.cpp)
+target_link_libraries(toml-parser tominal)
+if(FALSE)
add_executable(cpptoml-build build_toml.cpp)
target_link_libraries(cpptoml-build cpptoml)
set_target_properties(cpptoml-build PROPERTIES
@@ -25,3 +27,4 @@ set_target_properties(cpptoml-conversions PROPERTIES
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED YES)
+endif()
\ No newline at end of file
diff --git a/examples/example.toml b/examples/example.toml
index 08d7d7b..8412255 100644
--- a/examples/example.toml
+++ b/examples/example.toml
@@ -23,13 +23,11 @@ enabled = true
ip = "10.0.0.2"
dc = "eqdc10"
-[[clients]]
-data = [ ["gamma", "delta"], [1, 2]]
-
[[clients]] # array of tables
+data = [ ["gamma", "delta"], [1, 2]]
-# Line breaks are OK when inside arrays
+[[clients]]
hosts = [
- { name = "alpha" },
+ { name = "alpha" }, # Line breaks are OK when inside arrays
"omega", # trailing comma and mixed type both allowd in array
]
\ No newline at end of file
diff --git a/examples/parse.cpp b/examples/parse.cpp
index 48bd791..d72c4b5 100644
--- a/examples/parse.cpp
+++ b/examples/parse.cpp
@@ -1,7 +1,5 @@
-#include "cpptoml.h"
-
#include
-#include
+#include "tominal/toml.h"
int main(int argc, char** argv)
{
@@ -11,14 +9,14 @@ int main(int argc, char** argv)
return 1;
}
- try
+ if (auto result = toml::parse_file(argv[1]); result.is_ok())
{
- std::shared_ptr g = cpptoml::parse_file(argv[1]);
- std::cout << (*g) << std::endl;
+ auto view = result.ok();
+ std::cout << view << std::endl;
}
- catch (const cpptoml::parse_exception& e)
+ else
{
- std::cerr << "Failed to parse " << argv[1] << ": " << e.what() << std::endl;
+ std::cerr << "Failed to parse " << argv[1] << ": " << result.err().what() << std::endl;
return 1;
}
diff --git a/examples/parse_stdin.cpp b/examples/parse_stdin.cpp
index 4c65c2c..cd6ff72 100644
--- a/examples/parse_stdin.cpp
+++ b/examples/parse_stdin.cpp
@@ -1,7 +1,6 @@
-#include "cpptoml.h"
-
#include
#include
+#include "tominal/toml.h"
/**
* A visitor for toml objects that writes to an output stream in the JSON
@@ -15,49 +14,49 @@ class toml_test_writer
// nothing
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"string\",\"value\":\""
- << cpptoml::toml_writer::escape_string(v.get()) << "\"}";
+ << toml::toml_writer::escape_string(v.get()) << "\"}";
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"integer\",\"value\":\"" << v.get() << "\"}";
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"float\",\"value\":\"" << v.get() << "\"}";
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"local_date\",\"value\":\"" << v.get() << "\"}";
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"local_time\",\"value\":\"" << v.get() << "\"}";
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"local_datetime\",\"value\":\"" << v.get()
<< "\"}";
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"datetime\",\"value\":\"" << v.get() << "\"}";
}
- void visit(const cpptoml::value& v)
+ void visit(const toml::value& v)
{
stream_ << "{\"type\":\"bool\",\"value\":\"" << v << "\"}";
}
- void visit(const cpptoml::array& arr)
+ void visit(const toml::array& arr)
{
stream_ << "{\"type\":\"array\",\"value\":[";
auto it = arr.get().begin();
@@ -70,27 +69,13 @@ class toml_test_writer
stream_ << "]}";
}
- void visit(const cpptoml::table_array& tarr)
- {
- stream_ << "[";
- auto arr = tarr.get();
- auto ait = arr.begin();
- while (ait != arr.end())
- {
- (*ait)->accept(*this);
- if (++ait != arr.end())
- stream_ << ", ";
- }
- stream_ << "]";
- }
-
- void visit(const cpptoml::table& t)
+ void visit(const toml::table& t)
{
stream_ << "{";
auto it = t.begin();
while (it != t.end())
{
- stream_ << '"' << cpptoml::toml_writer::escape_string(it->first)
+ stream_ << '"' << toml::toml_writer::escape_string(it->first)
<< "\":";
it->second->accept(*this);
if (++it != t.end())
@@ -106,15 +91,15 @@ class toml_test_writer
int main()
{
std::cout.precision(std::numeric_limits::max_digits10);
- cpptoml::parser p{std::cin};
+ toml::parser p{std::cin};
try
{
- std::shared_ptr g = p.parse();
+ std::shared_ptr g = p.parse();
toml_test_writer writer{std::cout};
g->accept(writer);
std::cout << std::endl;
}
- catch (const cpptoml::parse_exception& ex)
+ catch (const toml::parse_error& ex)
{
std::cerr << "Parsing failed: " << ex.what() << std::endl;
return 1;
diff --git a/tominal/toml.h b/include/tominal/toml.h
similarity index 97%
rename from tominal/toml.h
rename to include/tominal/toml.h
index 6f96c6d..b4850bf 100644
--- a/tominal/toml.h
+++ b/include/tominal/toml.h
@@ -8,6 +8,8 @@
{
#define TOML_NAMESPACE_END }
+#include
+
namespace toml
{
TOML_NAMESPACE_BEGIN
diff --git a/tominal/toml_array.h b/include/tominal/toml_array.h
similarity index 98%
rename from tominal/toml_array.h
rename to include/tominal/toml_array.h
index 96bd758..080f5de 100644
--- a/tominal/toml_array.h
+++ b/include/tominal/toml_array.h
@@ -1,7 +1,6 @@
#pragma once
#include
-
#include "toml_base.h"
#include "toml_node.h"
@@ -178,7 +177,8 @@ class array final : public node
}
template ::type,
- typename V = std::invoke_result_t>
+ typename V = std::invoke_result_t,
+ typename = std::enable_if_t>>
std::vector map_collect(F &&f) const
{
std::vector result;
diff --git a/tominal/toml_base.h b/include/tominal/toml_base.h
similarity index 99%
rename from tominal/toml_base.h
rename to include/tominal/toml_base.h
index 8f9af1b..e6ca80c 100644
--- a/tominal/toml_base.h
+++ b/include/tominal/toml_base.h
@@ -1,6 +1,7 @@
#pragma once
#include