aboutsummaryrefslogtreecommitdiff
path: root/libbutl/path.ixx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-01-19 09:05:51 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-01-19 09:05:51 +0200
commit89bc63fb386f0e4d6e2b21c0d806da1e8de0a34d (patch)
tree94e95a3a79e73e6d076f5f19fe7a5ac0e0841506 /libbutl/path.ixx
parente3bf8b04654d4131be6ea4be670e66827b489d2e (diff)
Add path::make_{directory,leaf,base}()
Diffstat (limited to 'libbutl/path.ixx')
-rw-r--r--libbutl/path.ixx73
1 files changed, 73 insertions, 0 deletions
diff --git a/libbutl/path.ixx b/libbutl/path.ixx
index f86a57e..b754bed 100644
--- a/libbutl/path.ixx
+++ b/libbutl/path.ixx
@@ -150,6 +150,10 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
inline basic_path<C, K> basic_path<C, K>::
leaf () const
{
+ // While it would have been simpler to implement this one in term of
+ // make_leaf(), this implementation is potentially more efficient
+ // (think of the small string optimization).
+ //
const string_type& s (this->path_);
size_type n (_size ());
@@ -163,9 +167,37 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
}
template <typename C, typename K>
+ inline basic_path<C, K>& basic_path<C, K>::
+ make_leaf ()
+ {
+ string_type& s (this->path_);
+ size_type n (_size ());
+
+ size_type p (n != 0
+ ? traits::rfind_separator (s, n - 1)
+ : string_type::npos);
+
+ if (p != string_type::npos)
+ {
+ s.erase (0, p + 1);
+
+ // Keep the original tsep unless the path became empty.
+ //
+ if (s.empty ())
+ this->tsep_ = 0;
+ }
+
+ return *this;
+ }
+
+ template <typename C, typename K>
inline typename basic_path<C, K>::dir_type basic_path<C, K>::
directory () const
{
+ // While it would have been simpler to implement this one in term of
+ // make_directory(), this implementation is potentially more efficient
+ // (think of the small string optimization).
+ //
const string_type& s (this->path_);
size_type n (_size ());
@@ -179,6 +211,23 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
}
template <typename C, typename K>
+ inline basic_path<C, K>& basic_path<C, K>::
+ make_directory ()
+ {
+ string_type& s (this->path_);
+ size_type n (_size ());
+
+ size_type p (n != 0
+ ? traits::rfind_separator (s, n - 1)
+ : string_type::npos);
+
+ s.resize (p != string_type::npos ? p + 1 : 0); // Include trailing slash.
+ _init ();
+
+ return *this;
+ }
+
+ template <typename C, typename K>
inline auto basic_path<C, K>::
begin () const -> iterator
{
@@ -279,6 +328,10 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
inline basic_path<C, K> basic_path<C, K>::
base () const
{
+ // While it would have been simpler to implement this one in term of
+ // make_base(), this implementation is potentially more efficient (think
+ // of the small string optimization).
+ //
const string_type& s (this->path_);
size_type p (traits::find_extension (s));
@@ -288,6 +341,26 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
}
template <typename C, typename K>
+ inline basic_path<C, K>& basic_path<C, K>::
+ make_base ()
+ {
+ string_type& s (this->path_);
+ size_type p (traits::find_extension (s));
+
+ if (p != string_type::npos)
+ {
+ s.resize (0, p);
+
+ // Keep the original tsep unless the path became empty.
+ //
+ if (s.empty ())
+ this->tsep_ = 0;
+ }
+
+ return *this;
+ }
+
+ template <typename C, typename K>
inline typename basic_path<C, K>::string_type basic_path<C, K>::
extension () const
{