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) {
32 if (
path.
empty())
return on_key(data,
""sv);
35 const auto end =
path.length();
36 bool prev_was_array_indexer =
false;
37 bool prev_was_dot =
true;
41 if (
path[pos] ==
'[') {
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 ==
'[')
82 const auto c =
path[pos];
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;
125 else if (
path[pos] ==
'.') {
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;
215 curr = current_array->
get(index);
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_NAMESPACE_START
Definition at_path.inl:187
TOML_ENABLE_WARNINGS
Definition at_path.inl:23
TOML_DISABLE_WARNINGS
Definition at_path.inl:17
TOML_IMPL_NAMESPACE_START
Definition at_path.inl:26
A TOML array.
Definition array.hpp:285
TOML_PURE_INLINE_GETTER node * get(size_t index) noexcept
Gets a pointer to the element at a specific index.
Definition array.hpp:685
A TOML path.
Definition path.hpp:239
TOML_PURE_INLINE_GETTER bool empty() const noexcept
Whether (true) or not (false) the path is empty.
Definition path.hpp:302
A TOML table.
Definition table.hpp:220
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...
Definition preprocessor.hpp:1134
#define TOML_ASSERT(expr)
Sets the assert function used by the library. \detail Defaults to the standard C assert().
Definition preprocessor.hpp:1185
#define TOML_ASSERT_ASSUME(expr)
Definition preprocessor.hpp:1190
#define TOML_UNLIKELY(...)
Definition preprocessor.hpp:538
#define TOML_LIKELY(...)
Definition preprocessor.hpp:525
#define TOML_EXTERNAL_LINKAGE
Definition preprocessor.hpp:1339
#define TOML_NAMESPACE_END
Definition preprocessor.hpp:1320
#define TOML_IMPL_NAMESPACE_END
Definition preprocessor.hpp:1334