318
+ − 1 // Copyright Toru Niina 2019.
+ − 2 // Distributed under the MIT License.
+ − 3 #ifndef TOML11_LITERAL_HPP
+ − 4 #define TOML11_LITERAL_HPP
+ − 5 #include "parser.hpp"
+ − 6
+ − 7 namespace toml
+ − 8 {
+ − 9 inline namespace literals
+ − 10 {
+ − 11 inline namespace toml_literals
+ − 12 {
+ − 13
+ − 14 // implementation
+ − 15 inline ::toml::basic_value<TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>
+ − 16 literal_internal_impl(::toml::detail::location loc)
+ − 17 {
+ − 18 using value_type = ::toml::basic_value<
+ − 19 TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>;
+ − 20 // if there are some comments or empty lines, skip them.
+ − 21 using skip_line = ::toml::detail::repeat<toml::detail::sequence<
+ − 22 ::toml::detail::maybe<::toml::detail::lex_ws>,
+ − 23 ::toml::detail::maybe<::toml::detail::lex_comment>,
+ − 24 ::toml::detail::lex_newline
+ − 25 >, ::toml::detail::at_least<1>>;
+ − 26 skip_line::invoke(loc);
+ − 27
+ − 28 // if there are some whitespaces before a value, skip them.
+ − 29 using skip_ws = ::toml::detail::repeat<
+ − 30 ::toml::detail::lex_ws, ::toml::detail::at_least<1>>;
+ − 31 skip_ws::invoke(loc);
+ − 32
+ − 33 // to distinguish arrays and tables, first check it is a table or not.
+ − 34 //
+ − 35 // "[1,2,3]"_toml; // this is an array
+ − 36 // "[table]"_toml; // a table that has an empty table named "table" inside.
+ − 37 // "[[1,2,3]]"_toml; // this is an array of arrays
+ − 38 // "[[table]]"_toml; // this is a table that has an array of tables inside.
+ − 39 //
+ − 40 // "[[1]]"_toml; // this can be both... (currently it becomes a table)
+ − 41 // "1 = [{}]"_toml; // this is a table that has an array of table named 1.
+ − 42 // "[[1,]]"_toml; // this is an array of arrays.
+ − 43 // "[[1],]"_toml; // this also.
+ − 44
+ − 45 const auto the_front = loc.iter();
+ − 46
+ − 47 const bool is_table_key = ::toml::detail::lex_std_table::invoke(loc);
+ − 48 loc.reset(the_front);
+ − 49
+ − 50 const bool is_aots_key = ::toml::detail::lex_array_table::invoke(loc);
+ − 51 loc.reset(the_front);
+ − 52
+ − 53 // If it is neither a table-key or a array-of-table-key, it may be a value.
+ − 54 if(!is_table_key && !is_aots_key)
+ − 55 {
+ − 56 if(auto data = ::toml::detail::parse_value<value_type>(loc, 0))
+ − 57 {
+ − 58 return data.unwrap();
+ − 59 }
+ − 60 }
+ − 61
+ − 62 // Note that still it can be a table, because the literal might be something
+ − 63 // like the following.
+ − 64 // ```cpp
+ − 65 // R"( // c++11 raw string literals
+ − 66 // key = "value"
+ − 67 // int = 42
+ − 68 // )"_toml;
+ − 69 // ```
+ − 70 // It is a valid toml file.
+ − 71 // It should be parsed as if we parse a file with this content.
+ − 72
+ − 73 if(auto data = ::toml::detail::parse_toml_file<value_type>(loc))
+ − 74 {
+ − 75 return data.unwrap();
+ − 76 }
+ − 77 else // none of them.
+ − 78 {
+ − 79 throw ::toml::syntax_error(data.unwrap_err(), source_location(loc));
+ − 80 }
+ − 81
+ − 82 }
+ − 83
+ − 84 inline ::toml::basic_value<TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>
+ − 85 operator"" _toml(const char* str, std::size_t len)
+ − 86 {
+ − 87 ::toml::detail::location loc(
+ − 88 std::string("TOML literal encoded in a C++ code"),
+ − 89 std::vector<char>(str, str + len));
+ − 90 // literal length does not include the null character at the end.
+ − 91 return literal_internal_impl(std::move(loc));
+ − 92 }
+ − 93
+ − 94 // value of __cplusplus in C++2a/20 mode is not fixed yet along compilers.
+ − 95 // So here we use the feature test macro for `char8_t` itself.
+ − 96 #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
+ − 97 // value of u8"" literal has been changed from char to char8_t and char8_t is
+ − 98 // NOT compatible to char
+ − 99 inline ::toml::basic_value<TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>
+ − 100 operator"" _toml(const char8_t* str, std::size_t len)
+ − 101 {
+ − 102 ::toml::detail::location loc(
+ − 103 std::string("TOML literal encoded in a C++ code"),
+ − 104 std::vector<char>(reinterpret_cast<const char*>(str),
+ − 105 reinterpret_cast<const char*>(str) + len));
+ − 106 return literal_internal_impl(std::move(loc));
+ − 107 }
+ − 108 #endif
+ − 109
+ − 110 } // toml_literals
+ − 111 } // literals
+ − 112 } // toml
+ − 113 #endif//TOML11_LITERAL_HPP