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)
120 return lhs.index() ==
rhs.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
245 TOML_ANON_NAMESPACE::parse_path_into(
rhs, components_);
249#if TOML_ENABLE_WINDOWS_COMPAT
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 {
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()};
const char * narrow(char *dst, const char *src)
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_PURE_INLINE_GETTER node * get(size_t index) noexcept
Gets a pointer to the element at a specific index.
Represents a single component of a complete 'TOML-path': either a key or an array index.
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.
TOML_PURE_GETTER size_t index() const noexcept
Returns the array index (const lvalue overload).
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.
TOML_PURE_INLINE_GETTER size_t size() const noexcept
Returns the number of components in the path.
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.
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.
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.
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...
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...
TOML_ANON_NAMESPACE_START
#define TOML_ANON_NAMESPACE_END
#define TOML_INTERNAL_LINKAGE
#define TOML_EXTERNAL_LINKAGE
#define TOML_NAMESPACE_END