diff options
Diffstat (limited to 'vendor/toml++/impl/path.inl')
| -rw-r--r-- | vendor/toml++/impl/path.inl | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/vendor/toml++/impl/path.inl b/vendor/toml++/impl/path.inl new file mode 100644 index 0000000..999d651 --- /dev/null +++ b/vendor/toml++/impl/path.inl @@ -0,0 +1,523 @@ +//# This file is a part of toml++ and is subject to the the terms of the MIT license. +//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au> +//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. +// SPDX-License-Identifier: MIT +#pragma once + +//# {{ +#include "preprocessor.hpp" +#if !TOML_IMPLEMENTATION +#error This is an implementation-only header. +#endif +//# }} + +#include "path.hpp" +#include "at_path.hpp" +#include "print_to_stream.hpp" +TOML_DISABLE_WARNINGS; +#if TOML_INT_CHARCONV +#include <charconv> +#endif +#include <sstream> +TOML_ENABLE_WARNINGS; +#include "header_start.hpp" + +//#===================================================================================================================== +//# toml::path_component +//#===================================================================================================================== + +TOML_NAMESPACE_START +{ + TOML_EXTERNAL_LINKAGE + path_component::path_component() // + : type_{ path_component_type::key } + { + store_key("", value_storage_); + } + + TOML_EXTERNAL_LINKAGE + path_component::path_component(size_t index) noexcept // + : type_(path_component_type::array_index) + { + store_index(index, value_storage_); + } + + TOML_EXTERNAL_LINKAGE + path_component::path_component(std::string_view key) // + : type_(path_component_type::key) + { + store_key(key, value_storage_); + } + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXTERNAL_LINKAGE + path_component::path_component(std::wstring_view key) // + : path_component(impl::narrow(key)) + {} + +#endif + + TOML_EXTERNAL_LINKAGE + path_component::path_component(const path_component& pc) // + : type_{ pc.type_ } + { + if (type_ == path_component_type::array_index) + store_index(pc.index(), value_storage_); + else + store_key(pc.key(), value_storage_); + } + + TOML_EXTERNAL_LINKAGE + path_component::path_component(path_component && pc) noexcept // + : type_{ pc.type_ } + { + if (type_ == path_component_type::array_index) + store_index(pc.index_ref(), value_storage_); + else + store_key(std::move(pc.key_ref()), value_storage_); + } + + TOML_EXTERNAL_LINKAGE + path_component& path_component::operator=(const path_component& rhs) + { + if (type_ != rhs.type_) + { + destroy(); + + type_ = rhs.type_; + if (type_ == path_component_type::array_index) + store_index(rhs.index(), value_storage_); + else + store_key(rhs.key(), value_storage_); + } + else + { + if (type_ == path_component_type::array_index) + index_ref() = rhs.index(); + else + key_ref() = rhs.key(); + } + return *this; + } + + TOML_EXTERNAL_LINKAGE + path_component& path_component::operator=(path_component&& rhs) noexcept + { + if (type_ != rhs.type_) + { + destroy(); + + type_ = rhs.type_; + if (type_ == path_component_type::array_index) + store_index(rhs.index(), value_storage_); + else + store_key(std::move(rhs.key_ref()), value_storage_); + } + else + { + if (type_ == path_component_type::array_index) + index_ref() = rhs.index(); + else + key_ref() = std::move(rhs.key_ref()); + } + return *this; + } + + TOML_PURE_GETTER + TOML_EXTERNAL_LINKAGE + bool TOML_CALLCONV path_component::equal(const path_component& lhs, const path_component& rhs) noexcept + { + // Different comparison depending on contents + if (lhs.type_ != rhs.type_) + return false; + + if (lhs.type_ == path_component_type::array_index) + return lhs.index() == rhs.index(); + else // path_component_type::key + return lhs.key() == rhs.key(); + } + + TOML_EXTERNAL_LINKAGE + path_component& path_component::operator=(size_t new_index) noexcept + { + // If currently a key, string will need to be destroyed regardless + destroy(); + + type_ = path_component_type::array_index; + store_index(new_index, value_storage_); + + return *this; + } + + TOML_EXTERNAL_LINKAGE + path_component& path_component::operator=(std::string_view new_key) + { + if (type_ == path_component_type::key) + key_ref() = new_key; + else + { + type_ = path_component_type::key; + store_key(new_key, value_storage_); + } + + return *this; + } + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXTERNAL_LINKAGE + path_component& path_component::operator=(std::wstring_view new_key) + { + if (type_ == path_component_type::key) + key_ref() = impl::narrow(new_key); + else + { + type_ = path_component_type::key; + store_key(impl::narrow(new_key), value_storage_); + } + + return *this; + } + +#endif +} +TOML_NAMESPACE_END; + +//#===================================================================================================================== +//# toml::path +//#===================================================================================================================== + +TOML_ANON_NAMESPACE_START +{ + TOML_INTERNAL_LINKAGE + bool parse_path_into(std::string_view path_str, std::vector<path_component> & components) + { + using components_type = std::remove_reference_t<decltype(components)>; + + const auto original_size = components.size(); + + static constexpr auto on_key = [](void* data, std::string_view key) -> bool + { + auto& comps = *static_cast<components_type*>(data); + comps.emplace_back(key); + return true; + }; + + static constexpr auto on_index = [](void* data, size_t index) -> bool + { + auto& comps = *static_cast<components_type*>(data); + comps.emplace_back(index); + return true; + }; + + if (!impl::parse_path(path_str, &components, on_key, on_index)) + { + components.resize(original_size); + return false; + } + + return true; + } +} +TOML_ANON_NAMESPACE_END; + +TOML_NAMESPACE_START +{ + TOML_EXTERNAL_LINKAGE + void path::print_to(std::ostream & os) const + { + bool root = true; + for (const auto& component : components_) + { + if (component.type() == path_component_type::key) // key + { + if (!root) + impl::print_to_stream(os, '.'); + impl::print_to_stream(os, component.key()); + } + else if (component.type() == path_component_type::array_index) // array + { + impl::print_to_stream(os, '['); + impl::print_to_stream(os, component.index()); + impl::print_to_stream(os, ']'); + } + root = false; + } + } + + TOML_PURE_GETTER + TOML_EXTERNAL_LINKAGE + bool TOML_CALLCONV path::equal(const path& lhs, const path& rhs) noexcept + { + return lhs.components_ == rhs.components_; + } + + //#=== constructors ================================================= + + TOML_EXTERNAL_LINKAGE + path::path(std::string_view str) // + { + TOML_ANON_NAMESPACE::parse_path_into(str, components_); + } + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXTERNAL_LINKAGE + path::path(std::wstring_view str) // + : path(impl::narrow(str)) + {} + +#endif + + //#=== assignment ================================================= + + TOML_EXTERNAL_LINKAGE + path& path::operator=(std::string_view rhs) + { + components_.clear(); + TOML_ANON_NAMESPACE::parse_path_into(rhs, components_); + return *this; + } + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXTERNAL_LINKAGE + path& path::operator=(std::wstring_view rhs) + { + return assign(impl::narrow(rhs)); + } + +#endif + + //#=== appending ================================================= + + TOML_EXTERNAL_LINKAGE + path& path::operator+=(const path& rhs) + { + components_.insert(components_.cend(), rhs.begin(), rhs.end()); + return *this; + } + + TOML_EXTERNAL_LINKAGE + path& path::operator+=(path&& rhs) + { + components_.insert(components_.end(), + std::make_move_iterator(rhs.components_.begin()), + std::make_move_iterator(rhs.components_.end())); + return *this; + } + + TOML_EXTERNAL_LINKAGE + path& path::operator+=(std::string_view str) + { + TOML_ANON_NAMESPACE::parse_path_into(str, components_); + return *this; + } + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXTERNAL_LINKAGE + path& path::operator+=(std::wstring_view str) + { + return *this += impl::narrow(str); + } + +#endif + + //#=== prepending ================================================= + + TOML_EXTERNAL_LINKAGE + path& path::prepend(const path& source) + { + components_.insert(components_.begin(), source.components_.begin(), source.components_.end()); + return *this; + } + + TOML_EXTERNAL_LINKAGE + path& path::prepend(path && source) + { + components_.insert(components_.begin(), + std::make_move_iterator(source.components_.begin()), + std::make_move_iterator(source.components_.end())); + return *this; + } + + TOML_EXTERNAL_LINKAGE + path& path::prepend(std::string_view source) + { + return prepend(path{ source }); + } + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXTERNAL_LINKAGE + path& path::prepend(std::wstring_view source) + { + return prepend(impl::narrow(source)); + } + +#endif + + //#=== string conversion ================================================= + + TOML_EXTERNAL_LINKAGE + std::string path::str() const + { + if (empty()) + return ""; + + std::ostringstream ss; + print_to(ss); + return std::move(ss).str(); + } + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXTERNAL_LINKAGE + std::wstring path::wide_str() const + { + return impl::widen(str()); + } + +#endif + + //#=== equality and comparison ================================================= + + TOML_EXTERNAL_LINKAGE + void path::clear() noexcept + { + components_.clear(); + } + + TOML_EXTERNAL_LINKAGE + path& path::truncate(size_t n) + { + n = n > components_.size() ? components_.size() : n; + + auto it_end = components_.end(); + components_.erase(it_end - static_cast<int>(n), it_end); + + return *this; + } + + TOML_EXTERNAL_LINKAGE + path path::truncated(size_t n) const + { + path truncated_path{}; + + n = n > components_.size() ? components_.size() : n; + + // Copy all components except one + // Need at least two path components to have a parent, since if there is + // only one path component, the parent is the root/null path "" + truncated_path.components_.insert(truncated_path.components_.begin(), + components_.begin(), + components_.end() - static_cast<int>(n)); + + return truncated_path; + } + + TOML_EXTERNAL_LINKAGE + path path::parent() const + { + return truncated(1); + } + + TOML_EXTERNAL_LINKAGE + path path::leaf(size_t n) const + { + path leaf_path{}; + + n = n > components_.size() ? components_.size() : n; + + if (n > 0) + { + leaf_path.components_.insert(leaf_path.components_.begin(), + components_.end() - static_cast<int>(n), + components_.end()); + } + + return leaf_path; + } + + TOML_EXTERNAL_LINKAGE + path path::subpath(std::vector<path_component>::const_iterator start, + std::vector<path_component>::const_iterator end) const + { + if (start >= end) + return {}; + + path subpath; + subpath.components_.insert(subpath.components_.begin(), start, end); + return subpath; + } + + TOML_EXTERNAL_LINKAGE + path path::subpath(size_t start, size_t length) const + { + return subpath(begin() + static_cast<int>(start), begin() + static_cast<int>(start + length)); + } +} +TOML_NAMESPACE_END; + +//#===================================================================================================================== +//# at_path() overloads for toml::path +//#===================================================================================================================== + +TOML_NAMESPACE_START +{ + TOML_EXTERNAL_LINKAGE + node_view<node> TOML_CALLCONV at_path(node & root, const toml::path& path) noexcept + { + // early-exit sanity-checks + if (root.is_value()) + return {}; + if (auto tbl = root.as_table(); tbl && tbl->empty()) + return {}; + if (auto arr = root.as_array(); arr && arr->empty()) + return {}; + + node* current = &root; + + for (const auto& component : path) + { + auto type = component.type(); + if (type == path_component_type::array_index) + { + const auto current_array = current->as<array>(); + if (!current_array) + return {}; // not an array, using array index doesn't work + + current = current_array->get(component.index()); + } + else if (type == path_component_type::key) + { + const auto current_table = current->as<table>(); + if (!current_table) + return {}; + + current = current_table->get(component.key()); + } + else + { + // Error: invalid component + return {}; + } + + if (!current) + return {}; // not found + } + + return node_view{ current }; + } + + TOML_EXTERNAL_LINKAGE + node_view<const node> TOML_CALLCONV at_path(const node& root, const toml::path& path) noexcept + { + return node_view<const node>{ at_path(const_cast<node&>(root), path).node() }; + } +} +TOML_NAMESPACE_END; + +#include "header_end.hpp" |
