9#if !TOML_IMPLEMENTATION
10#error This is an implementation-only header.
32 : type_{path_component_type::key} {
33 store_key(
"", value_storage_);
38 : type_(path_component_type::array_index) {
39 store_index(index, value_storage_);
44 : type_(path_component_type::key) {
45 store_key(key, value_storage_);
48#if TOML_ENABLE_WINDOWS_COMPAT
59 if (type_ == path_component_type::array_index)
60 store_index(pc.
index(), value_storage_);
62 store_key(pc.
key(), value_storage_);
68 if (type_ == path_component_type::array_index)
69 store_index(pc.index_ref(), value_storage_);
71 store_key(std::move(pc.key_ref()), value_storage_);
76 if (type_ != rhs.type_) {
80 if (type_ == path_component_type::array_index)
81 store_index(rhs.
index(), value_storage_);
83 store_key(rhs.
key(), value_storage_);
85 if (type_ == path_component_type::array_index)
86 index_ref() = rhs.
index();
88 key_ref() = rhs.
key();
95 if (type_ != rhs.type_) {
99 if (type_ == path_component_type::array_index)
100 store_index(rhs.
index(), value_storage_);
102 store_key(std::move(rhs.key_ref()), value_storage_);
104 if (type_ == path_component_type::array_index)
105 index_ref() = rhs.
index();
107 key_ref() = std::move(rhs.key_ref());
117 if (lhs.type_ != rhs.type_)
return false;
119 if (lhs.type_ == path_component_type::array_index)
122 return lhs.
key() == rhs.
key();
130 type_ = path_component_type::array_index;
131 store_index(new_index, value_storage_);
138 if (type_ == path_component_type::key)
141 type_ = path_component_type::key;
142 store_key(new_key, value_storage_);
148#if TOML_ENABLE_WINDOWS_COMPAT
152 if (type_ == path_component_type::key)
153 key_ref() = impl::narrow(new_key);
155 type_ = path_component_type::key;
156 store_key(impl::narrow(new_key), value_storage_);
172 bool parse_path_into(std::string_view path_str, std::vector<path_component> & components) {
173 using components_type = std::remove_reference_t<
decltype(components)>;
175 const auto original_size = components.size();
177 static constexpr auto on_key = [](
void* data, std::string_view key) ->
bool {
178 auto& comps = *
static_cast<components_type*
>(data);
179 comps.emplace_back(key);
183 static constexpr auto on_index = [](
void* data,
size_t index) ->
bool {
184 auto& comps = *
static_cast<components_type*
>(data);
185 comps.emplace_back(index);
189 if (!impl::parse_path(path_str, &components, on_key, on_index)) {
190 components.resize(original_size);
201 void path::print_to(std::ostream & os)
const {
203 for (
const auto& component : components_) {
204 if (component.type() == path_component_type::key)
206 if (!root) impl::print_to_stream(os,
'.');
207 impl::print_to_stream(os, component.key());
208 }
else if (component.type() == path_component_type::array_index)
210 impl::print_to_stream(os,
'[');
211 impl::print_to_stream(os, component.index());
212 impl::print_to_stream(os,
']');
221 return lhs.components_ == rhs.components_;
229 TOML_ANON_NAMESPACE::parse_path_into(
str, components_);
232#if TOML_ENABLE_WINDOWS_COMPAT
236 :
path(impl::narrow(str)) {}
245 TOML_ANON_NAMESPACE::parse_path_into(rhs, components_);
249#if TOML_ENABLE_WINDOWS_COMPAT
253 return assign(impl::narrow(rhs));
262 components_.insert(components_.cend(), rhs.
begin(), rhs.
end());
268 components_.insert(components_.end(), std::make_move_iterator(rhs.components_.
begin()),
269 std::make_move_iterator(rhs.components_.
end()));
275 TOML_ANON_NAMESPACE::parse_path_into(
str, components_);
279#if TOML_ENABLE_WINDOWS_COMPAT
283 return *
this += impl::narrow(
str);
292 components_.insert(components_.begin(), source.components_.
begin(), source.components_.
end());
298 components_.insert(components_.begin(), std::make_move_iterator(source.components_.
begin()),
299 std::make_move_iterator(source.components_.
end()));
308#if TOML_ENABLE_WINDOWS_COMPAT
312 return prepend(impl::narrow(source));
321 if (
empty())
return "";
323 std::ostringstream ss;
325 return std::move(ss).str();
328#if TOML_ENABLE_WINDOWS_COMPAT
332 return impl::widen(
str());
346 n = n > components_.
size() ? components_.size() : n;
348 auto it_end = components_.end();
349 components_.erase(it_end -
static_cast<int>(n), it_end);
356 path truncated_path{};
358 n = n > components_.
size() ? components_.size() : n;
363 truncated_path.components_.insert(truncated_path.components_.begin(), components_.begin(),
364 components_.end() -
static_cast<int>(n));
366 return truncated_path;
378 n = n > components_.
size() ? components_.size() : n;
381 leaf_path.components_.insert(leaf_path.components_.begin(),
382 components_.end() -
static_cast<int>(n), components_.end());
390 std::vector<path_component>::const_iterator end)
const {
391 if (start >=
end)
return {};
400 return subpath(
begin() +
static_cast<int>(start),
begin() +
static_cast<int>(start + length));
413 if (root.is_value())
return {};
414 if (
auto tbl = root.as_table(); tbl && tbl->empty())
return {};
415 if (
auto arr = root.as_array(); arr && arr->empty())
return {};
417 node* current = &root;
419 for (
const auto& component :
path) {
420 auto type = component.type();
421 if (type == path_component_type::array_index) {
422 const auto current_array = current->as<
array>();
423 if (!current_array)
return {};
425 current = current_array->
get(component.index());
426 }
else if (type == path_component_type::key) {
427 const auto current_table = current->as<
table>();
428 if (!current_table)
return {};
430 current = current_table->
get(component.key());
436 if (!current)
return {};
439 return node_view{current};
444 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".
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
Represents a single component of a complete 'TOML-path': either a key or an array index.
Definition path.hpp:22
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION path_component()
Default constructor (creates an empty key).
TOML_EXPORTED_MEMBER_FUNCTION path_component & operator=(const path_component &rhs)
Copy-assignment operator.
TOML_PURE_GETTER const std::string & key() const noexcept
Returns the key string.
Definition path.hpp:177
TOML_PURE_GETTER size_t index() const noexcept
Returns the array index (const lvalue overload).
Definition path.hpp:155
A TOML path.
Definition path.hpp:239
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION std::wstring wide_str() const
Returns a string representation of this path.
TOML_EXPORTED_MEMBER_FUNCTION void clear() noexcept
Erases the contents of the path.
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path parent() const
Returns a toml::path object representing the path of the parent node.
TOML_EXPORTED_MEMBER_FUNCTION path & truncate(size_t n)
Removes the number of terminal path components specified by n.
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path truncated(size_t n) const
Returns a toml::path object which has had n terminal path components removed.
TOML_PURE_INLINE_GETTER iterator end() noexcept
Returns an iterator to one-past-the-last component in the path.
Definition path.hpp:692
TOML_PURE_INLINE_GETTER size_t size() const noexcept
Returns the number of components in the path.
Definition path.hpp:288
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION std::string str() const
Returns a string representation of this path.
TOML_NODISCARD_CTOR path() noexcept=default
Default constructor.
TOML_PURE_INLINE_GETTER iterator begin() noexcept
Returns an iterator to the first component in the path.
Definition path.hpp:684
TOML_EXPORTED_MEMBER_FUNCTION path & prepend(const path &)
Prepends another path onto the beginning of this one.
TOML_EXPORTED_MEMBER_FUNCTION path & operator+=(const path &)
Appends another path onto the end of this one.
TOML_PURE_INLINE_GETTER bool empty() const noexcept
Whether (true) or not (false) the path is empty.
Definition path.hpp:302
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path leaf(size_t n=1) const
Returns a toml::path object representing terminal n-parts of a TOML path.
TOML_ALWAYS_INLINE path & assign(const path &p)
Replaces the contents of the path with that of another.
Definition path.hpp:348
path & operator=(const path &)=default
Copy-assignment operator.
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path subpath(const_iterator start, const_iterator end) const
Returns a toml::path object that is a specified subpath of the current path, representing the range o...
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
TOML_NAMESPACE_START
Definition path.inl:29
TOML_ANON_NAMESPACE_START
Definition path.inl:170
TOML_ENABLE_WARNINGS
Definition path.inl:22
TOML_DISABLE_WARNINGS
Definition path.inl:17
#define TOML_ANON_NAMESPACE_END
Definition preprocessor.hpp:1337
#define TOML_INTERNAL_LINKAGE
Definition preprocessor.hpp:1340
#define TOML_EXTERNAL_LINKAGE
Definition preprocessor.hpp:1339
#define TOML_PURE_GETTER
Definition preprocessor.hpp:474
#define TOML_NAMESPACE_END
Definition preprocessor.hpp:1320