From 23d4deb111bfff9c282c20989573c4b0775e4c16 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 7 Nov 2019 11:11:45 +0200 Subject: Add path_name struct, open_file_or{stdin,stdout}() functions --- libbutl/path.mxx | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) (limited to 'libbutl/path.mxx') diff --git a/libbutl/path.mxx b/libbutl/path.mxx index 114c25a..1d0ada9 100644 --- a/libbutl/path.mxx +++ b/libbutl/path.mxx @@ -29,11 +29,13 @@ export module butl.path; #ifdef __cpp_lib_modules_ts import std.core; #endif +import butl.optional; import butl.small_vector; #ifdef _WIN32 import butl.utility; #endif #else +#include #include #ifdef _WIN32 #include // *case*() @@ -488,10 +490,10 @@ LIBBUTL_MODEXPORT namespace butl }; // This implementation of a filesystem path has two types: path, which can - // represent any path (file, directory, etc.) and dir_path, which is derived + // represent any path (file, directory, etc) and dir_path, which is derived // from path. The internal representation of directories maintains a - // trailing slash. However, it is ignored in path comparison, size, and - // string spelling. For example: + // trailing directory separator (slash). However, it is ignored in path + // comparison, size, and string spelling. For example: // // path p1 ("foo"); // File path. // path p2 ("bar/"); // Directory path. @@ -527,6 +529,22 @@ LIBBUTL_MODEXPORT namespace butl template P path_cast (const basic_path&); template P path_cast (basic_path&&); + // In certain cases we may need to translate a special path (e.g., `-`) to a + // name that may not be a valid path (e.g., `` or ``), for + // example, for diagnostics. In this case we can use path_name which + // contains the original path plus an optional translation as a string. Note + // that this is a view-like type with the original path shallow-referenced + // rather than copied. + // + // Note: we could also have a copying version that derives from the view + // (and thus can be passed down as a view). + // + template + struct basic_path_name; + + using path_name = basic_path_name; + using dir_path_name = basic_path_name; + // Low-level path data storage. It is also used by the implementation to // pass around initialized/valid paths. // @@ -555,6 +573,7 @@ LIBBUTL_MODEXPORT namespace butl // Notes: // - If path_ is empty, then tsep_ can only be 0. // - We could have used a much narrower integer for tsep_. + // - We could give the rest of tsep_ to the user to use as flags, etc. // string_type path_; difference_type tsep_; @@ -600,7 +619,6 @@ LIBBUTL_MODEXPORT namespace butl } }; - template struct any_path_kind { @@ -1295,7 +1313,6 @@ LIBBUTL_MODEXPORT namespace butl return r; } - // Note that the result of (foo / "bar") is always a path, even if foo // is dir_path. An idiom to force it to dir_path is: // @@ -1319,6 +1336,31 @@ LIBBUTL_MODEXPORT namespace butl return r; } + template + struct basic_path_name + { + using path_type = P; + using string_type = typename path_type::string_type; + + const path_type* path; + optional name; + + explicit + basic_path_name (const path_type& p, optional n = nullopt) + : path (&p), name (std::move (n)) {} + + explicit + basic_path_name (path_type&&, optional = nullopt) = delete; + + explicit + basic_path_name (string_type n) + : path (nullptr), name (std::move (n)) {} + + explicit + basic_path_name (const path_type* p, optional n = nullopt) + : path (p), name (std::move (n)) {} + }; + // For operator<< (ostream) see the path-io header. } -- cgit v1.1