diff options
author | David Robillard <d@drobilla.net> | 2020-11-12 01:11:11 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-11-12 01:47:40 +0100 |
commit | bf9190ef628c1aa04791af1bd7cd4905e9c24658 (patch) | |
tree | 56114c93a8ec689cd15497059958dad03a1ee2ce /raul/Path.hpp | |
parent | 496e70e420811c7d744a8bcc44a2ac1b51b676b5 (diff) | |
download | raul-bf9190ef628c1aa04791af1bd7cd4905e9c24658.tar.gz raul-bf9190ef628c1aa04791af1bd7cd4905e9c24658.tar.bz2 raul-bf9190ef628c1aa04791af1bd7cd4905e9c24658.zip |
Move includes to a conventional include directory
Diffstat (limited to 'raul/Path.hpp')
-rw-r--r-- | raul/Path.hpp | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/raul/Path.hpp b/raul/Path.hpp deleted file mode 100644 index 6237ddd..0000000 --- a/raul/Path.hpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - This file is part of Raul. - Copyright 2007-2014 David Robillard <http://drobilla.net> - - Raul is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or any later version. - - Raul is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Raul. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef RAUL_PATH_HPP -#define RAUL_PATH_HPP - -#include "raul/Exception.hpp" -#include "raul/Symbol.hpp" - -#include <algorithm> -#include <string> - -namespace Raul { - -/** A restricted path of Symbols separated by, and beginning with, "/". - * - * A Path never ends with a "/", except for the root Path "/", which is the - * only valid single-character Path. - * - * @ingroup raul - */ -class Path : public std::basic_string<char> { -public: - /** Attempt to construct an invalid Path. */ - class BadPath : public Exception { - public: - explicit BadPath(const std::string& path) : Exception(path) {} - }; - - /** Construct an uninitialzed path, because the STL is annoying. */ - Path() : std::basic_string<char>("/") {} - - /** Construct a Path from a C++ string. - * - * This will throw an exception if `path` is invalid. To avoid this, use - * is_valid() first to check. - */ - explicit Path(const std::basic_string<char>& path) - : std::basic_string<char>(path) - { - if (!is_valid(path)) { - throw BadPath(path); - } - } - - /** Construct a Path from a C string. - * - * This will throw an exception if `path` is invalid. To avoid this, use - * is_valid() first to check. - */ - explicit Path(const char* path) - : std::basic_string<char>(path) - { - if (!is_valid(path)) { - throw BadPath(path); - } - } - - /** Copy a Path. - * - * Note this is faster than constructing a Path from another Path's string - * since validation is unnecessary. - */ - Path(const Path& path) = default; - - /** Return true iff `c` is a valid Path character. */ - static inline bool is_valid_char(char c) { - return c == '/' || Symbol::is_valid_char(c); - } - - /** Return true iff `str` is a valid Path. */ - static inline bool is_valid(const std::basic_string<char>& str) { - if (str.empty() || (str[0] != '/')) { - return false; // Must start with '/' - } - - if (str != "/" && *str.rbegin() == '/') { - return false; // Must not end with '/' except for the root - } - - for (size_t i = 1; i < str.length(); ++i) { - if (!is_valid_char(str[i])) { - return false; // All characters must be /, _, a-z, A-Z, 0-9 - } else if (str[i - 1] == '/') { - if (str[i] == '/') { - return false; // Must not contain "//" - } else if (!Symbol::is_valid_start_char(str[i])) { - return false; // Invalid symbol start character (digit) - } - } - } - - return true; - } - - /** Return true iff this path is the root path ("/"). */ - inline bool is_root() const { return *this == "/"; } - - /** Return true iff this path is a child of `parent` at any depth. */ - inline bool is_child_of(const Path& parent) const { - const std::string parent_base = parent.base(); - return substr(0, parent_base.length()) == parent_base; - } - - /** Return true iff this path is a parent of `child` at any depth. */ - inline bool is_parent_of(const Path& child) const { - return child.is_child_of(*this); - } - - /** Return the symbol of this path (everything after the last '/'). - * - * This is what is called the "basename" for file paths, the "method name" - * for OSC paths, and so on. Since the root path does not have a symbol, - * this does not return a Raul::Symbol but may return the empty string. - */ - inline const char* symbol() const { - if (!is_root()) { - const size_t last_sep = rfind('/'); - if (last_sep != std::string::npos) { - return c_str() + last_sep + 1; - } - } - return ""; - } - - /** Return the parent's path. - * - * Calling this on the path "/" will return "/". - * This is the (deepest) "container path" for OSC paths. - */ - inline Path parent() const { - if (is_root()) { - return *this; - } else { - const size_t first_sep = find('/'); - const size_t last_sep = find_last_of('/'); - return (first_sep == last_sep) - ? Path("/") : Path(substr(0, last_sep)); - } - } - - /** Return a child Path of this path. */ - inline Path child(const Path& p) const { - return p.is_root() ? *this : Path(base() + p.substr(1)); - } - - /** Return a direct child Path of this Path with the given Symbol. */ - inline Path child(const Raul::Symbol& symbol) const { - return Path(base() + symbol.c_str()); - } - - /** Return path with a trailing "/". - * - * The returned string is such that appending a valid Symbol to it is - * guaranteed to form a valid path. - */ - inline std::string base() const { - if (is_root()) { - return *this; - } else { - return *this + '/'; - } - } - - /** Return the lowest common ancestor of a and b. */ - static inline Path lca(const Path& a, const Path& b) { - const size_t len = std::min(a.length(), b.length()); - size_t last_sep = 0; - for (size_t i = 0; i < len; ++i) { - if (a[i] == '/' && b[i] == '/') { - last_sep = i; - } - if (a[i] != b[i]) { - break; - } - } - - if (last_sep <= 1) { - return Path("/"); - } - - return Path(a.substr(0, last_sep)); - } - - /** Return true iff `child` is equal to, or a descendant of `parent`. */ - static inline bool descendant_comparator(const Path& parent, - const Path& child) { - return (child == parent || child.is_child_of(parent)); - } -}; - -} // namespace Raul - -#endif // RAUL_PATH_HPP |