AFIO  v2.00 late alpha
afio_v2_xxx::path_view Class Reference

A borrowed view of a path. A lightweight trivial-type alternative to std::filesystem::path. More...

#include "path_view.hpp"

Classes

struct  c_str
 Instantiate from a path_view to get a zero terminated path suitable for feeding to the kernel. More...
 

Public Types

using value_type = char
 Character type.
 
using pointer = char *
 Pointer type.
 
using const_pointer = const char *
 Const pointer type.
 
using reference = char &
 Reference type.
 
using const_reference = const char &
 Const reference type.
 
using size_type = std::size_t
 Size type.
 
using difference_type = std::ptrdiff_t
 Difference type.
 

Public Member Functions

constexpr path_view ()
 Constructs an empty path view.
 
 path_view (const filesystem::path &v) noexcept
 Implicitly constructs a path view from a path. The input path MUST continue to exist for this view to be valid.
 
 path_view (const std::string &v) noexcept
 Implicitly constructs a UTF-8 path view from a string. The input string MUST continue to exist for this view to be valid.
 
constexpr path_view (const char *v) noexcept
 Implicitly constructs a UTF-8 path view from a zero terminated const char *. The input string MUST continue to exist for this view to be valid.
 
constexpr path_view (const char *v, size_t len) noexcept
 Constructs a UTF-8 path view from a lengthed const char *. The input string MUST continue to exist for this view to be valid.
 
constexpr path_view (string_view v) noexcept
 
 path_view (const path_view &)=default
 Default copy constructor.
 
 path_view (path_view &&o) noexcept=default
 Default move constructor.
 
path_viewoperator= (const path_view &p)=default
 Default copy assignment.
 
path_viewoperator= (path_view &&p) noexcept=default
 Default move assignment.
 
constexpr void swap (path_view &o) noexcept
 Swap the view with another.
 
constexpr bool empty () const noexcept
 True if empty.
 
constexpr bool has_root_path () const noexcept
 
constexpr bool has_root_name () const noexcept
 
constexpr bool has_root_directory () const noexcept
 
constexpr bool has_relative_path () const noexcept
 
constexpr bool has_parent_path () const noexcept
 
constexpr bool has_filename () const noexcept
 
constexpr bool has_stem () const noexcept
 
constexpr bool has_extension () const noexcept
 
constexpr bool is_absolute () const noexcept
 
constexpr bool is_relative () const noexcept
 
constexpr bool contains_glob () const noexcept
 
constexpr void remove_filename () noexcept
 Adjusts the end of this view to match the final separator.
 
constexpr size_t native_size () const noexcept
 Returns the size of the view in characters.
 
constexpr path_view root_name () const noexcept
 
constexpr path_view root_directory () const noexcept
 
constexpr path_view root_path () const noexcept
 
constexpr path_view relative_path () const noexcept
 
constexpr path_view parent_path () const noexcept
 
constexpr path_view filename () const noexcept
 Returns a view of the filename part of this view.
 
constexpr path_view stem () const noexcept
 
constexpr path_view extension () const noexcept
 
filesystem::path path () const
 Return the path view as a path.
 
constexpr int compare (const path_view &p) const noexcept
 
constexpr int compare (const char *s) const noexcept
 
constexpr int compare (string_view str) const noexcept
 

Friends

struct c_str
 

Detailed Description

A borrowed view of a path. A lightweight trivial-type alternative to std::filesystem::path.

AFIO is sufficiently fast that std::filesystem::path as a wrapper of an underlying std::basic_string<> can be problematically expensive for some filing system operations due to the potential memory allocation. AFIO therefore works exclusively with borrowed views of other path storage.

Some of the API for std::filesystem::path is replicated here, however any APIs which modify the path other than taking subsets are obviously not possible with borrowed views.

Todo:
Lots of member functions remain to be implemented.

Windows specific notes:

Be aware that on Microsoft Windows, the native path storage std::filesystem::path::value_type is a wchar_t referring to UTF-16. However much of AFIO path usage is a path_handle to somewhere on the filing system plus a relative const char * UTF-8 path fragment as the use of absolute paths is discouraged. Rather than complicate the ABI to handle templated path character types, on Microsoft Windows only we do the following:

  • If view input is wchar_t, the original source is passed through unmodified to the syscall without any memory allocation, copying nor slash conversion.
  • If view input is char:
    1. The original source is assumed to be in UTF-8, not ASCII like most char paths on Microsoft Windows.
    2. Use with any kernel function converts to a temporary UTF-16 internal buffer. We use the fast NT kernel UTF8 to UTF16 routine, not the slow Win32 routine.
    3. Any forward slashes are converted to backwards slashes.

AFIO calls the NT kernel API directly rather than the Win32 API for:

  • For any paths relative to a path_handle (the Win32 API does not provide a race free file system API).
  • For any paths beginning with \!!\, we pass the path + 3 characters directly through. This prefix is a pure AFIO extension, and will not be recognised by other code.
  • For any paths beginning with \??\, we pass the path + 0 characters directly through. Note the NT kernel keeps a symlink at \??\ which refers to the DosDevices namespace for the current login, so as an incorrect relation which you should not rely on, the Win32 path C:\foo probably will appear at \??\C:\foo.

These prefixes are still passed to the Win32 API:

  • \\?\ which is used to tell a Win32 API that the remaining path is longer than a DOS path.
  • \\.\ which since Windows 7 is treated exactly like \\?\.

If the NT kernel API is used directly then:

  • Paths are matched case sensitively as raw bytes via memcmp(), not case insensitively (requires slow locale conversion).
  • The path limit is 32,767 characters.

If you really care about performance, you are very strongly recommended to use the NT kernel API wherever possible. Where paths are involved, it is often three to five times faster due to the multiple memory allocations and string translations that the Win32 functions perform before calling the NT kernel routine.

If however you are taking input from some external piece of code, then for maximum compatibility you should still use the Win32 API.

Constructor & Destructor Documentation

◆ path_view()

constexpr afio_v2_xxx::path_view::path_view ( string_view  v)
inlinenoexcept

Implicitly constructs a UTF-8 path view from a string view.

Warning
The byte after the end of the view must be legal to read.
218 : _state(v) {} // NOLINT

Member Function Documentation

◆ compare() [1/3]

constexpr int afio_v2_xxx::path_view::compare ( const path_view p) const
inlinenoexcept

Compares the two string views via the view's compare() which in turn calls traits::compare(). Be aware that on Windows a conversion from UTF-8 to UTF-16 is performed if needed.

383  {
384  return _invoke([&p](const auto &v) { return -p.compare(v); });
385  }

◆ compare() [2/3]

constexpr int afio_v2_xxx::path_view::compare ( const char *  s) const
inlinenoexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

391  {
392  return compare(string_view(s));
393  }
constexpr int compare(const path_view &p) const noexcept
Definition: path_view.hpp:382

◆ compare() [3/3]

constexpr int afio_v2_xxx::path_view::compare ( string_view  str) const
inlinenoexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

399  {
400 #ifdef _WIN32
401  if(!_state._utf16.empty())
402  {
403  c_str z(path_view(str), false);
404  return _state._utf16.compare(wstring_view(z.buffer, z.length));
405  }
406 #endif
407  return _state._utf8.compare(str);
408  }
constexpr path_view()
Constructs an empty path view.
Definition: path_view.hpp:198

The documentation for this class was generated from the following file: