diff --git a/toml/parser.hpp b/toml/parser.hpp index ff2a57f..966f8a1 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -12,6 +12,13 @@ #include #include +#if __cplusplus >= 201703L +#if __has_include() +#define TOML11_HAS_STD_FILESYSTEM +#include +#endif // has_include() +#endif // cplusplus >= C++17 + namespace toml { namespace detail @@ -2102,5 +2109,39 @@ basic_value parse(const std::string& fname) return parse(ifs, fname); } +#ifdef TOML11_HAS_STD_FILESYSTEM +// This function just forwards `parse("filename.toml")` to std::string version +// to avoid the ambiguity in overload resolution. +// +// Both std::string and std::filesystem::path are convertible from const char[]. +// Without this, both parse(std::string) and parse(std::filesystem::path) +// matches to parse("filename.toml"). This breaks the existing code. +// +// This function exactly matches to the invokation with string literal. +// So this function is preferred than others and the ambiguity disappears. +template class Table = std::unordered_map, + template class Array = std::vector, + std::size_t N> +basic_value parse(const char (&fname)[N]) +{ + return parse(std::string(fname)); +} + +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value parse(const std::filesystem::path& fpath) +{ + std::ifstream ifs(fpath, std::ios_base::binary); + if(!ifs.good()) + { + throw std::runtime_error("toml::parse: file open error -> " + + fpath.string()); + } + return parse(ifs, fpath.string()); +} +#endif // TOML11_HAS_STD_FILESYSTEM + } // toml #endif// TOML11_PARSER_HPP