aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/path-io.mxx6
-rw-r--r--libbutl/path.ixx90
-rw-r--r--libbutl/path.mxx103
3 files changed, 150 insertions, 49 deletions
diff --git a/libbutl/path-io.mxx b/libbutl/path-io.mxx
index a44d26b..54f9569 100644
--- a/libbutl/path-io.mxx
+++ b/libbutl/path-io.mxx
@@ -46,10 +46,10 @@ LIBBUTL_MODEXPORT namespace butl
template <typename C, typename P>
inline std::basic_ostream<C>&
- operator<< (std::basic_ostream<C>& os, const basic_path_name<P>& pn)
+ operator<< (std::basic_ostream<C>& os, const basic_path_name_view<P>& v)
{
- assert (!pn.empty ());
+ assert (!v.null ());
- return pn.name ? (os << *pn.name) : (os << *pn.path);
+ return v.name != nullptr && *v.name ? (os << **v.name) : (os << *v.path);
}
}
diff --git a/libbutl/path.ixx b/libbutl/path.ixx
index 165f06a..77bc9f7 100644
--- a/libbutl/path.ixx
+++ b/libbutl/path.ixx
@@ -702,6 +702,72 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
d.tsep_ = 1; // Canonical separator is always first.
}
+ template <typename C, typename K>
+ inline std::basic_ostream<C>&
+ to_stream (std::basic_ostream<C>& os,
+ const basic_path<C, K>& p,
+ bool representation)
+ {
+ os << p.string ();
+
+ if (representation)
+ {
+ C sep (p.separator ());
+
+#ifndef _WIN32
+ if (sep != 0 && !p.root ())
+ os << sep;
+#else
+ if (sep != 0)
+ os << sep;
+#endif
+ }
+
+ return os;
+ }
+
+ // basic_path_name
+ //
+ template <typename P>
+ inline basic_path_name<P>::
+ basic_path_name (basic_path_name&& p)
+ : basic_path_name (p.path, std::move (p.name))
+ {
+ }
+
+ template <typename P>
+ inline basic_path_name<P>::
+ basic_path_name (const basic_path_name& p)
+ : basic_path_name (p.path, p.name)
+ {
+ }
+
+ template <typename P>
+ inline basic_path_name<P>& basic_path_name<P>::
+ operator= (basic_path_name&& p)
+ {
+ if (this != &p)
+ {
+ this->path = p.path;
+ name = std::move (p.name);
+ }
+
+ return *this;
+ }
+
+ template <typename P>
+ inline basic_path_name<P>& basic_path_name<P>::
+ operator= (const basic_path_name& p)
+ {
+ if (this != &p)
+ {
+ this->path = p.path;
+ name = p.name;
+ }
+
+ return *this;
+ }
+
// basic_path_name_value
//
template <typename P>
@@ -743,28 +809,4 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
return *this;
}
-
- template <typename C, typename K>
- inline std::basic_ostream<C>&
- to_stream (std::basic_ostream<C>& os,
- const basic_path<C, K>& p,
- bool representation)
- {
- os << p.string ();
-
- if (representation)
- {
- C sep (p.separator ());
-
-#ifndef _WIN32
- if (sep != 0 && !p.root ())
- os << sep;
-#else
- if (sep != 0)
- os << sep;
-#endif
- }
-
- return os;
- }
}
diff --git a/libbutl/path.mxx b/libbutl/path.mxx
index 130419c..cc72549 100644
--- a/libbutl/path.mxx
+++ b/libbutl/path.mxx
@@ -552,6 +552,15 @@ LIBBUTL_MODEXPORT namespace butl
using path_name_value = basic_path_name_value<path>;
using dir_name_value = basic_path_name_value<dir_path>;
+ // A "full" view version of the above that also shallow-references the
+ // optional name. The "partial" view derives from this "full" view.
+ //
+ template <typename P>
+ struct basic_path_name_view;
+
+ using path_name_view = basic_path_name_view<path>;
+ using dir_name_view = basic_path_name_view<dir_path>;
+
// Low-level path data storage. It is also used by the implementation to
// pass around initialized/valid paths.
//
@@ -1343,44 +1352,92 @@ LIBBUTL_MODEXPORT namespace butl
return r;
}
+ template <typename C, typename K>
+ std::basic_ostream<C>&
+ to_stream (std::basic_ostream<C>&,
+ const basic_path<C, K>&,
+ bool representation);
+
+ // For operator<< (ostream) see the path-io header.
+
+ // path_name
+ //
+
template <typename P>
- struct basic_path_name
+ struct basic_path_name_view
{
using path_type = P;
using string_type = typename path_type::string_type;
- const path_type* path;
+ const path_type* path;
+ const optional<string_type>* name;
+
+ explicit
+ basic_path_name_view (const basic_path_name<P>& v)
+ : path (v.path), name (&v.name) {}
+
+ basic_path_name_view (const path_type* p, const optional<string_type>* n)
+ : path (p), name (n) {}
+
+ basic_path_name_view () // Create empty/NULL path name.
+ : path (nullptr), name (nullptr) {}
+
+
+ bool
+ null () const
+ {
+ return path == nullptr && (name == nullptr || !*name);
+ }
+
+ bool
+ empty () const
+ {
+ // assert (!null ());
+ return name != nullptr && *name ? (*name)->empty () : path->empty ();
+ }
+ };
+
+ template <typename P>
+ struct basic_path_name: basic_path_name_view<P>
+ {
+ using base = basic_path_name_view<P>;
+
+ using path_type = typename base::path_type;
+ using string_type = typename base::string_type;
+
optional<string_type> name;
+ // Note that a NULL name is converted to absent.
+ //
+ explicit
+ basic_path_name (const basic_path_name_view<P>& v)
+ : base (v.path, &name),
+ name (v.name != nullptr ? *v.name : nullopt) {}
+
explicit
basic_path_name (const path_type& p, optional<string_type> n = nullopt)
- : path (&p), name (std::move (n)) {}
+ : base (&p, &name), name (std::move (n)) {}
explicit
basic_path_name (path_type&&, optional<string_type> = nullopt) = delete;
explicit
basic_path_name (string_type n)
- : path (nullptr), name (std::move (n)) {}
+ : base (nullptr, &name), name (std::move (n)) {}
explicit
basic_path_name (const path_type* p, optional<string_type> n = nullopt)
- : path (p), name (std::move (n)) {}
+ : base (p, &name), name (std::move (n)) {}
- basic_path_name (): path (nullptr) {} // Create empty/NULL path name.
+ basic_path_name (): // Create empty/NULL path name.
+ base (nullptr, &name) {}
- bool
- empty () const {return path == nullptr && !name;}
+ basic_path_name (basic_path_name&&);
+ basic_path_name (const basic_path_name&);
+ basic_path_name& operator= (basic_path_name&&);
+ basic_path_name& operator= (const basic_path_name&);
};
- template <typename C, typename K>
- std::basic_ostream<C>&
- to_stream (std::basic_ostream<C>& os,
- const basic_path<C, K>& p,
- bool representation);
-
- // For operator<< (ostream) see the path-io header.
-
template <typename P>
struct basic_path_name_value: basic_path_name<P>
{
@@ -1391,16 +1448,18 @@ LIBBUTL_MODEXPORT namespace butl
path_type path;
+ // Note that a NULL path/name is converted to empty/absent.
+ //
+ explicit
+ basic_path_name_value (const basic_path_name_view<P>& v)
+ : base (&path, v.name != nullptr ? *v.name : nullopt),
+ path (v.path != nullptr ? *v.path : path_type ()) {}
+
explicit
basic_path_name_value (path_type p, optional<string_type> n = nullopt)
: base (&path, std::move (n)), path (std::move (p)) {}
- // Note that a NULL path is converted to empty path.
- //
- explicit
- basic_path_name_value (const basic_path_name<P>& v)
- : base (&path, v.name),
- path (v.path != nullptr ? *v.path : path_type ()) {}
+ basic_path_name_value (): base (&path) {} // Create empty/NULL path name.
basic_path_name_value (basic_path_name_value&&);
basic_path_name_value (const basic_path_name_value&);