diff options
-rw-r--r-- | libbutl/path-io.mxx | 4 | ||||
-rw-r--r-- | libbutl/path.ixx | 38 | ||||
-rw-r--r-- | libbutl/path.mxx | 55 |
3 files changed, 94 insertions, 3 deletions
diff --git a/libbutl/path-io.mxx b/libbutl/path-io.mxx index 54d884b..5a91dac 100644 --- a/libbutl/path-io.mxx +++ b/libbutl/path-io.mxx @@ -8,6 +8,8 @@ // C includes. +#include <cassert> + #ifndef __cpp_lib_modules_ts #include <ostream> #endif @@ -45,6 +47,8 @@ LIBBUTL_MODEXPORT namespace butl inline std::basic_ostream<C>& operator<< (std::basic_ostream<C>& os, const basic_path_name<P>& pn) { + assert (!pn.empty ()); + return os << (pn.name ? *pn.name : pn.path->string ()); } } diff --git a/libbutl/path.ixx b/libbutl/path.ixx index 7786fbc..ae19b58 100644 --- a/libbutl/path.ixx +++ b/libbutl/path.ixx @@ -701,4 +701,42 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. if (!d.path_.empty () && d.tsep_ == 0) d.tsep_ = 1; // Canonical separator is always first. } + + // basic_path_name_value + // + template <typename P> + inline basic_path_name_value<P>:: + basic_path_name_value (basic_path_name_value&& p) + : basic_path_name_value (std::move (p.path_), std::move (p.name)) + { + } + + template <typename P> + inline basic_path_name_value<P>:: + basic_path_name_value (const basic_path_name_value& p) + : basic_path_name_value (p.path_, p.name) + { + } + + template <typename P> + inline basic_path_name_value<P>& basic_path_name_value<P>:: + operator= (basic_path_name_value&& p) + { + if (this != &p) + { + path_ = std::move (p.path_); + this->name = std::move (p.name); + } + } + + template <typename P> + inline basic_path_name_value<P>& basic_path_name_value<P>:: + operator= (const basic_path_name_value& p) + { + if (this != &p) + { + path_ = p.path_; + this->name = p.name; + } + } } diff --git a/libbutl/path.mxx b/libbutl/path.mxx index 1d0ada9..2374fb5 100644 --- a/libbutl/path.mxx +++ b/libbutl/path.mxx @@ -536,15 +536,21 @@ LIBBUTL_MODEXPORT namespace butl // 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 <typename P> struct basic_path_name; using path_name = basic_path_name<path>; using dir_path_name = basic_path_name<dir_path>; + // The copying version of the above that derives from the view (and thus can + // be passed down as a view). + // + template <typename P> + struct basic_path_name_value; + + using path_name_value = basic_path_name_value<path>; + using dir_name_value = basic_path_name_value<dir_path>; + // Low-level path data storage. It is also used by the implementation to // pass around initialized/valid paths. // @@ -1359,9 +1365,52 @@ LIBBUTL_MODEXPORT namespace butl explicit basic_path_name (const path_type* p, optional<string_type> n = nullopt) : path (p), name (std::move (n)) {} + + basic_path_name (): path (nullptr) {} // Create empty/NULL path name. + + bool + empty () const {return path == nullptr && !name;} }; // For operator<< (ostream) see the path-io header. + + template <typename P> + struct basic_path_name_value: basic_path_name<P> + { + using base = basic_path_name<P>; + + using path_type = typename base::path_type; + using string_type = typename base::string_type; + + explicit + basic_path_name_value (path_type p, optional<string_type> n = nullopt) + : base (&path_, std::move (n)), path_ (std::move (p)) {} + + int + compare (const basic_path_name_value& x) const + { + if (int r = path_.compare (x.path_)) + return r; + + return this->name < x.name ? -1 : this->name > x.name ? 1 : 0; + } + + basic_path_name_value (basic_path_name_value&&); + basic_path_name_value (const basic_path_name_value&); + basic_path_name_value& operator= (basic_path_name_value&&); + basic_path_name_value& operator= (const basic_path_name_value&); + + private: + P path_; + }; + + template <typename P> + inline bool + operator< (const basic_path_name_value<P>& x, + const basic_path_name_value<P>& y) + { + return x.compare (y) < 0; + } } LIBBUTL_MODEXPORT namespace std |