From a50895cdfff05e0f1f831dcceb79085878b85696 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 20 Jul 2024 20:57:18 +0900 Subject: [PATCH 1/4] doc: add u8string example --- examples/CMakeLists.txt | 1 + examples/u8string/.gitignore | 1 + examples/u8string/CMakeLists.txt | 5 ++ examples/u8string/spec_example.toml | 23 ++++++ examples/u8string/u8string.cpp | 120 ++++++++++++++++++++++++++++ 5 files changed, 150 insertions(+) create mode 100644 examples/u8string/.gitignore create mode 100644 examples/u8string/CMakeLists.txt create mode 100644 examples/u8string/spec_example.toml create mode 100644 examples/u8string/u8string.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4909753..ed2d13b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(boost_container) add_subdirectory(boost_multiprecision) add_subdirectory(parse_file) add_subdirectory(reflect) +add_subdirectory(u8string) add_subdirectory(unicode) diff --git a/examples/u8string/.gitignore b/examples/u8string/.gitignore new file mode 100644 index 0000000..5df90cf --- /dev/null +++ b/examples/u8string/.gitignore @@ -0,0 +1 @@ +u8string diff --git a/examples/u8string/CMakeLists.txt b/examples/u8string/CMakeLists.txt new file mode 100644 index 0000000..c550092 --- /dev/null +++ b/examples/u8string/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(u8string u8string.cpp) +target_link_libraries(u8string PRIVATE toml11::toml11) +target_compile_features(u8string PRIVATE cxx_std_20) +set_target_properties(u8string PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/examples/u8string/spec_example.toml b/examples/u8string/spec_example.toml new file mode 100644 index 0000000..3fe43f0 --- /dev/null +++ b/examples/u8string/spec_example.toml @@ -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" diff --git a/examples/u8string/u8string.cpp b/examples/u8string/u8string.cpp new file mode 100644 index 0000000..c6388a5 --- /dev/null +++ b/examples/u8string/u8string.cpp @@ -0,0 +1,120 @@ +#include + +#include +#include + +#include + +struct u8config +{ + using comment_type = toml::preserve_comments; + + using boolean_type = bool; + using integer_type = std::int64_t; + using floating_type = double; + using string_type = std::u8string; // XXX + + template + using array_type = std::vector; + template + using table_type = std::unordered_map; + + static toml::result + parse_int(const std::string& str, const toml::source_location src, const std::uint8_t base) + { + return toml::read_int(str, src, base); + } + static toml::result + parse_float(const std::string& str, const toml::source_location src, const bool is_hex) + { + return toml::read_float(str, src, is_hex); + } +}; + +int main() +{ + const auto root = toml::parse("spec_example.toml"); + + // using member functions + { + assert(root.at(u8"title").as_string() == u8"TOML Example"); + + assert(root.at(u8"owner").at(u8"name").as_string() == u8"Tom Preston-Werner"); + + const auto dob = root.at(u8"owner").at(u8"dob" ).as_offset_datetime(); + assert(dob.date .year == 1979); + assert(dob.date .month == static_cast(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(u8"database").at(u8"enabled").as_boolean()); + assert(root.at(u8"database").at(u8"ports").at(0).as_integer() == 8000); + assert(root.at(u8"database").at(u8"ports").at(1).as_integer() == 8001); + assert(root.at(u8"database").at(u8"ports").at(2).as_integer() == 8002); + assert(root.at(u8"database").at(u8"data").at(0).at(0).as_string() == u8"delta"); + assert(root.at(u8"database").at(u8"data").at(0).at(1).as_string() == u8"phi"); + assert(root.at(u8"database").at(u8"data").at(1).at(0).as_floating() == 3.14); + assert(root.at(u8"database").at(u8"temp_targets").at(u8"cpu" ).as_floating() == 79.5); + assert(root.at(u8"database").at(u8"temp_targets").at(u8"case").as_floating() == 72.0); + + assert(root.at(u8"servers").at(u8"alpha").at(u8"ip" ).as_string() == u8"10.0.0.1"); + assert(root.at(u8"servers").at(u8"alpha").at(u8"role").as_string() == u8"frontend"); + assert(root.at(u8"servers").at(u8"beta" ).at(u8"ip" ).as_string() == u8"10.0.0.2"); + assert(root.at(u8"servers").at(u8"beta" ).at(u8"role").as_string() == u8"backend"); + } + + // using toml::find + { + // you can get as std::string from u8string, using toml::get/find + assert(toml::find(root, u8"title") == "TOML Example"); + + assert(toml::find(root, u8"owner", u8"name") == "Tom Preston-Werner"); + + const auto dob = toml::find(root, u8"owner", u8"dob"); + assert(dob.date .year == 1979); + assert(dob.date .month == static_cast(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(root, u8"database", u8"enabled")); + + const auto ports = toml::find>(root, u8"database", u8"ports"); + assert(ports.at(0) == 8000); + assert(ports.at(1) == 8001); + assert(ports.at(2) == 8002); + + const auto data = toml::find, std::vector>>(root, u8"database", u8"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>(root, u8"database", u8"temp_targets"); + assert(temp_targets.at("cpu" ) == 79.5); + assert(temp_targets.at("case") == 72.0); + + const auto servers = toml::find>>(root, u8"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" ); + } + + const std::u8string out = toml::format(root); + + std::string printable; + std::transform(out.begin(), out.end(), std::back_inserter(printable), + [](const char8_t c) {return static_cast(c);}); + std::cout << printable << std::endl; + + std::cout << "ok." << std::endl; + + return 0; +} From 96460a15d491bc2843ced103ca22bda5fb4dcd0c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 20 Jul 2024 20:57:42 +0900 Subject: [PATCH 2/4] feat: support key string conversion in get --- include/toml11/get.hpp | 49 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/include/toml11/get.hpp b/include/toml11/get.hpp index 8cdad9c..3805d09 100644 --- a/include/toml11/get.hpp +++ b/include/toml11/get.hpp @@ -218,16 +218,33 @@ template cxx::enable_if_t::value, T> get(const basic_value&); -// map-like +// std::map (key is convertible from toml::value::key_type) template cxx::enable_if_t, // T is map detail::is_not_toml_type>, // but not toml::table + std::is_convertible::key_type, + typename T::key_type>, // keys are convertible cxx::negation>, // no T.from_toml() cxx::negation>, // no toml::from cxx::negation&>> >::value, T> -get(const basic_value&); +get(const basic_value& v); + +// std::map (key is not convertible from toml::value::key_type, but +// is a std::basic_string) +template +cxx::enable_if_t, // T is map + detail::is_not_toml_type>, // but not toml::table + cxx::negation::key_type, + typename T::key_type>>, // keys are NOT convertible + detail::is_1byte_std_basic_string, // is std::basic_string + cxx::negation>, // no T.from_toml() + cxx::negation>, // no toml::from + cxx::negation&>> + >::value, T> +get(const basic_value& v); // toml::from::from_toml(v) template @@ -384,10 +401,13 @@ get(const basic_value& v) // ============================================================================ // map-like types; most likely STL map, like std::map or std::unordered_map. +// key is convertible from toml::value::key_type template cxx::enable_if_t, // T is map detail::is_not_toml_type>, // but not toml::table + std::is_convertible::key_type, + typename T::key_type>, // keys are convertible cxx::negation>, // no T.from_toml() cxx::negation>, // no toml::from cxx::negation&>> @@ -409,6 +429,31 @@ get(const basic_value& v) return m; } +// key is NOT convertible from toml::value::key_type but std::basic_string +template +cxx::enable_if_t, // T is map + detail::is_not_toml_type>, // but not toml::table + cxx::negation::key_type, + typename T::key_type>>, // keys are NOT convertible + detail::is_1byte_std_basic_string, // is std::basic_string + cxx::negation>, // no T.from_toml() + cxx::negation>, // no toml::from + cxx::negation&>> + >::value, T> +get(const basic_value& v) +{ + using key_type = typename T::key_type; + using mapped_type = typename T::mapped_type; + + T m; + for(const auto& kv : v.as_table()) + { + m.emplace(detail::string_conv(kv.first), get(kv.second)); + } + return m; +} + // ============================================================================ // user-defined, but convertible types. From 4d0ad7335bf48c1508c4b3e782bb328a51feca97 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 20 Jul 2024 21:12:09 +0900 Subject: [PATCH 3/4] ci: build examples in each cases --- .github/workflows/main.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 36a68be..bdca5e2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: sudo apt-get install ${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} + cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -56,7 +56,7 @@ jobs: sudo apt-get install clang-${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} + cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -86,7 +86,7 @@ jobs: sudo apt-get install ${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} + cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -118,7 +118,7 @@ jobs: sudo apt-get install clang-${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} + cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -139,7 +139,7 @@ jobs: submodules: true - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} + cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -160,7 +160,7 @@ jobs: submodules: true - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} + cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -184,7 +184,7 @@ jobs: - name: Configure shell: cmd run: | - cmake -B build/ -G "NMake Makefiles" -DTOML11_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_PRECOMPILE=${{ matrix.precompile }} + cmake -B build/ -G "NMake Makefiles" -DTOML11_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON - name: Build run: | cmake --build ./build --config "${{ matrix.config }}" -j${{ steps.cpu-cores.outputs.count }} From 88aaefd7470d5a58b11cfef16d13fd7574b166cb Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 20 Jul 2024 22:43:00 +0900 Subject: [PATCH 4/4] Revert "ci: build examples in each cases" This reverts commit 4d0ad7335bf48c1508c4b3e782bb328a51feca97. --- .github/workflows/main.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bdca5e2..36a68be 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: sudo apt-get install ${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON + cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -56,7 +56,7 @@ jobs: sudo apt-get install clang-${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON + cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -86,7 +86,7 @@ jobs: sudo apt-get install ${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON + cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -118,7 +118,7 @@ jobs: sudo apt-get install clang-${{ matrix.compiler }} - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON + cmake -B build/ -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -139,7 +139,7 @@ jobs: submodules: true - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON + cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -160,7 +160,7 @@ jobs: submodules: true - name: Configure run: | - cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON + cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} - name: Build run: | cmake --build build/ -j${{ steps.cpu-cores.outputs.count }} @@ -184,7 +184,7 @@ jobs: - name: Configure shell: cmd run: | - cmake -B build/ -G "NMake Makefiles" -DTOML11_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_BUILD_EXAMPLES=ON + cmake -B build/ -G "NMake Makefiles" -DTOML11_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_PRECOMPILE=${{ matrix.precompile }} - name: Build run: | cmake --build ./build --config "${{ matrix.config }}" -j${{ steps.cpu-cores.outputs.count }}