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
|