9#if !TOML_IMPLEMENTATION
10#error This is an implementation-only header.
29 const parse_path_callback<std::string_view> on_key,
30 const parse_path_callback<size_t> on_index) {
36 bool prev_was_array_indexer =
false;
37 bool prev_was_dot =
true;
43 size_t index_start =
pos + 1u;
47 const auto c =
path[index_start];
50 else if (
c ==
' ' ||
c ==
'\t')
59 size_t index_end = index_start + 1u;
65 const auto c =
path[index_end];
66 if (
c >=
'0' &&
c <=
'9')
68 else if (
c ==
']' ||
c ==
' ' ||
c ==
'\t' ||
c ==
'.' ||
c ==
'[')
88 else if (
c ==
'\t' ||
c ==
' ')
95 auto index_str =
path.substr(index_start, index_end - index_start);
99 if (index_str.length() == 1u)
100 index =
static_cast<size_t>(index_str[0] -
'0');
105 std::from_chars(index_str.data(), index_str.data() + index_str.length(),
index);
106 if (fc_result.ec != std::errc{})
return false;
110 std::stringstream ss;
111 ss.imbue(std::locale::classic());
112 ss.write(index_str.data(),
static_cast<std::streamsize
>(index_str.length()));
113 if (!(ss >>
index))
return false;
118 prev_was_dot =
false;
119 prev_was_array_indexer =
true;
121 if (!on_index(
data,
index))
return false;
135 if (prev_was_dot && !on_key(
data,
""sv))
return false;
139 prev_was_array_indexer =
false;
148 const auto subkey_start =
pos;
149 const auto subkey_len =
150 impl::min(
path.find_first_of(
".[]"sv, subkey_start + 1u),
path.length()) - subkey_start;
151 const auto subkey =
path.substr(subkey_start, subkey_len);
160 if (prev_was_array_indexer) {
161 auto non_ws = subkey.find_first_not_of(
" \t");
162 if (non_ws == std::string_view::npos) {
164 prev_was_dot =
false;
165 prev_was_array_indexer =
false;
172 prev_was_dot =
false;
173 prev_was_array_indexer =
false;
175 if (!on_key(
data, subkey))
return false;
180 if (prev_was_dot && !on_key(
data,
""sv))
return false;
191 if (root.is_value())
return {};
192 if (
auto tbl = root.as_table(); tbl && tbl->empty())
return {};
193 if (
auto arr = root.as_array(); arr && arr->empty())
return {};
195 node* current = &root;
197 static constexpr auto on_key = [](
void*
data, std::string_view key)
noexcept ->
bool {
198 auto& curr = *
static_cast<node**
>(
data);
201 const auto current_table = curr->as<
table>();
202 if (!current_table)
return false;
204 curr = current_table->
get(key);
205 return curr !=
nullptr;
208 static constexpr auto on_index = [](
void*
data,
size_t index)
noexcept ->
bool {
209 auto& curr = *
static_cast<node**
>(
data);
212 const auto current_array = curr->as<
array>();
213 if (!current_array)
return false;
216 return curr !=
nullptr;
219 if (!impl::parse_path(
path, ¤t, on_key, on_index)) current =
nullptr;
221 return node_view{current};
226 return node_view<const node>{
at_path(
const_cast<node&
>(root),
path).node()};
229#if TOML_ENABLE_WINDOWS_COMPAT
236 if (root.is_value())
return {};
237 if (
auto tbl = root.as_table(); tbl && tbl->empty())
return {};
238 if (
auto arr = root.as_array(); arr && arr->empty())
return {};
245 return node_view<const node>{
at_path(
const_cast<node&
>(root),
path).node()};
TOML_NODISCARD TOML_EXPORTED_FREE_FUNCTION node_view< const node > TOML_CALLCONV at_path(const node &root, std::string_view path) noexcept
Returns a const view of the node matching a fully-qualified "TOML path".
TOML_IMPL_NAMESPACE_START
TOML_PURE_INLINE_GETTER node * get(size_t index) noexcept
Gets a pointer to the element at a specific index.
TOML_PURE_INLINE_GETTER bool empty() const noexcept
Whether (true) or not (false) the path is empty.
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION node * get(std::string_view key) noexcept
Gets the node at a specific key.
#define TOML_CALLCONV
Calling convention to apply to exported free/static functions. \detail Not defined by default (let th...
#define TOML_ASSERT(expr)
Sets the assert function used by the library. \detail Defaults to the standard C assert().
#define TOML_ASSERT_ASSUME(expr)
#define TOML_UNLIKELY(...)
#define TOML_EXTERNAL_LINKAGE
#define TOML_NAMESPACE_END
#define TOML_IMPL_NAMESPACE_END