LLFIO
v2.00
|
A borrowed view of a path. A lightweight trivial-type alternative to std::filesystem::path
.
More...
#include "path_view.hpp"
Public Types | |
using | const_iterator = detail::path_view_iterator |
Const iterator type. | |
using | iterator = const_iterator |
iterator type | |
using | reverse_iterator = std::reverse_iterator< iterator > |
Reverse iterator. | |
using | const_reverse_iterator = std::reverse_iterator< const_iterator > |
Const reverse iterator. | |
using | size_type = path_view_component::size_type |
Size type. | |
using | difference_type = std::ptrdiff_t |
Difference type. | |
enum | format : uint8_t { unknown , native_format , generic_format , auto_format , binary_format } |
How to interpret separators. More... | |
enum | termination { zero_terminated , not_zero_terminated } |
The zero termination to use. More... | |
using | byte = llfio_v2_xxx::byte |
Character type for passthrough input. | |
using | char16_t = detail::char16_t |
template<class T > | |
using | default_rendered_path_deleter = std::default_delete< T > |
The default deleter to use. | |
template<class T = typename filesystem::path::value_type, class AllocatorOrDeleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size> | |
using | zero_terminated_rendered_path = rendered_path< termination::zero_terminated, T, AllocatorOrDeleter, _internal_buffer_size > |
Convenience type alias. | |
template<class T = typename filesystem::path::value_type, class AllocatorOrDeleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size> | |
using | not_zero_terminated_rendered_path = rendered_path< termination::not_zero_terminated, T, AllocatorOrDeleter, _internal_buffer_size > |
Convenience type alias. | |
Public Member Functions | |
constexpr | path_view () |
Constructs an empty path view. | |
constexpr | path_view (path_view_component p, format fmt=auto_format) noexcept |
Constructs a path view component identical to the input, except with different format interpretation. | |
path_view (const filesystem::path &v, format fmt=auto_format) noexcept | |
template<class Char , typename std::enable_if<(is_source_chartype_acceptable< Char >), bool >::type = true> | |
constexpr | path_view (const std::basic_string< Char > &v, format fmt=auto_format) noexcept |
constexpr | path_view (const char *b, size_t l, enum termination zt, format fmt=auto_format) noexcept |
constexpr | path_view (const wchar_t *b, size_t l, enum termination zt, format fmt=auto_format) noexcept |
constexpr | path_view (const char8_t *b, size_t l, enum termination zt, format fmt=auto_format) noexcept |
constexpr | path_view (const char16_t *b, size_t l, enum termination zt, format fmt=auto_format) noexcept |
constexpr | path_view (const byte *b, size_t l, enum termination zt) noexcept |
template<class Char , typename std::enable_if<(is_source_chartype_acceptable< Char >), bool >::type = true> | |
constexpr | path_view (const Char *s, format fmt=auto_format) noexcept |
constexpr | path_view (const byte *s) noexcept |
template<class Char , typename std::enable_if<(is_source_chartype_acceptable< Char >), bool >::type = true> | |
constexpr | path_view (basic_string_view< Char > v, enum termination zt, format fmt=auto_format) noexcept |
constexpr | path_view (span< const byte > v, enum termination zt) noexcept |
template<class It , class End , typename std::enable_if<(is_source_chartype_acceptable< typename It::value_type >), bool >::type = true, typename std::enable_if<(is_source_chartype_acceptable< typename End::value_type >), bool >::type = true> | |
constexpr | path_view (It b, End e, enum termination zt, format fmt=auto_format) noexcept |
template<class It , class End , typename std::enable_if<(is_source_chartype_acceptable< std::decay_t< It >>), bool >::type = true, typename std::enable_if<(is_source_chartype_acceptable< std::decay_t< End >>), bool >::type = true> | |
constexpr | path_view (It *b, End *e, enum termination zt, format fmt=auto_format) noexcept |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. | |
template<class It , class End , typename std::enable_if<(std::is_same< typename It::value_type, byte >::value), bool >::type = true, typename std::enable_if<(std::is_same< typename End::value_type, byte >::value), bool >::type = true> | |
constexpr | path_view (It b, End e, enum termination zt) noexcept |
template<class It , class End , typename std::enable_if<(std::is_same< std::decay_t< It >, byte >::value), bool >::type = true, typename std::enable_if<(std::is_same< std::decay_t< End >, byte >::value), bool >::type = true> | |
constexpr | path_view (It *b, End *e, enum termination zt) noexcept |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. | |
path_view (const path_view &)=default | |
Default copy constructor. | |
path_view (path_view &&o) noexcept=default | |
Default move constructor. | |
path_view & | operator= (const path_view &p)=default |
Default copy assignment. | |
path_view & | operator= (path_view &&p) noexcept=default |
Default move assignment. | |
constexpr bool | has_root_path () const noexcept |
True if has root path. | |
constexpr bool | has_root_name () const noexcept |
True if has root name. | |
constexpr bool | has_root_directory () const noexcept |
True if has root directory. | |
constexpr bool | has_relative_path () const noexcept |
True if has relative path. | |
constexpr bool | has_parent_path () const noexcept |
True if has parent path. | |
constexpr bool | has_filename () const noexcept |
True if has filename. | |
constexpr bool | is_absolute () const noexcept |
True if absolute. | |
constexpr bool | is_relative () const noexcept |
True if relative. | |
constexpr const_iterator | cbegin () const noexcept |
Returns an iterator to the first path component. | |
constexpr const_iterator | begin () const noexcept |
Returns an iterator to the first path component. | |
constexpr iterator | begin () noexcept |
Returns an iterator to the first path component. | |
constexpr const_iterator | cend () const noexcept |
Returns an iterator to after the last path component. | |
constexpr const_iterator | end () const noexcept |
Returns an iterator to after the last path component. | |
constexpr iterator | end () noexcept |
Returns an iterator to after the last path component. | |
constexpr path_view | remove_filename () const noexcept |
Returns a copy of this view with the end adjusted to match the final separator. | |
constexpr path_view | root_name () const noexcept |
Returns a view of the root name part of this view e.g. C: | |
constexpr path_view | root_directory () const noexcept |
Returns a view of the root directory, if there is one e.g. /. | |
constexpr path_view | root_path () const noexcept |
Returns, if any, a view of the root path part of this view e.g. C:/. | |
constexpr path_view | relative_path () const noexcept |
Returns a view of everything after the root path. | |
constexpr path_view | parent_path () const noexcept |
Returns a view of the everything apart from the filename part of this view. | |
constexpr path_view | filename () const noexcept |
Returns a view of the filename part of this view. | |
constexpr path_view | without_trailing_separator () const noexcept |
Returns a view of this view without a trailing separator, if there is one, unless the input is '/'. | |
template<class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size, typename std::enable_if<(path_view::is_source_acceptable< T >), bool >::type = true> | |
constexpr int | compare (path_view p, const std::locale &loc) const |
template<class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size, typename std::enable_if<(path_view::is_source_acceptable< T >), bool >::type = true> | |
constexpr int | compare (path_view p) const |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. | |
constexpr enum termination | termination () const noexcept |
The zero termination during construction. | |
const byte * | _raw_data () const noexcept |
constexpr void | swap (path_view_component &o) noexcept |
Swap the view with another. | |
constexpr QUICKCPPLIB_NODISCARD bool | empty () const noexcept |
True if empty. | |
constexpr size_t | native_size () const noexcept |
Returns the size of the view in characters. | |
constexpr format | formatting () const noexcept |
How path separators shall be interpreted. | |
constexpr bool | has_null_termination () const noexcept |
True if input is declared to be null terminated. | |
constexpr bool | has_stem () const noexcept |
True if stem() returns a non-empty path. | |
constexpr bool | has_extension () const noexcept |
True if extension() returns a non-empty path. | |
constexpr bool | contains_glob () const noexcept |
True if the view contains any of the characters * , ? , (POSIX only: [ or ] ). | |
constexpr path_view_component | stem () const noexcept |
Returns a view of the filename without any file extension. | |
constexpr path_view_component | extension () const noexcept |
Returns a view of the file extension part of this view. | |
filesystem::path | path () const |
Return the path view as a path. Allocates and copies memory! | |
template<class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size, typename std::enable_if<(is_source_acceptable< T >), bool >::type = true> | |
constexpr int | compare (path_view_component p, const std::locale &loc) const |
template<class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size, typename std::enable_if<(is_source_acceptable< T >), bool >::type = true> | |
constexpr int | compare (path_view_component p) const |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. | |
template<enum path_view_component::termination ZeroTermination, class T = typename filesystem::path::value_type, class AllocatorOrDeleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size, class... Args, typename std::enable_if<(is_source_acceptable< T >), bool >::type = true, typename = decltype( std::is_constructible<rendered_path<ZeroTermination, T, AllocatorOrDeleter, _internal_buffer_size>, path_view_component, Args...>::value )> | |
rendered_path< ZeroTermination, T, AllocatorOrDeleter, _internal_buffer_size > | render (path_view_component view, Args &&...args) const |
Convenience function. | |
template<class T = typename filesystem::path::value_type, class AllocatorOrDeleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size, class... Args, typename std::enable_if<(is_source_acceptable< T >), bool >::type = true, typename = decltype( std::is_constructible<rendered_path<termination::zero_terminated, T, AllocatorOrDeleter, _internal_buffer_size>, path_view_component, Args...>::value )> | |
rendered_path< termination::zero_terminated, T, AllocatorOrDeleter, _internal_buffer_size > | render_null_terminated (Args &&...args) const |
Convenience function. | |
template<class T = typename filesystem::path::value_type, class AllocatorOrDeleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size, class... Args, typename std::enable_if<(is_source_acceptable< T >), bool >::type = true, typename = decltype( std::is_constructible<rendered_path<termination::zero_terminated, T, AllocatorOrDeleter, _internal_buffer_size>, path_view_component, Args...>::value )> | |
rendered_path< termination::not_zero_terminated, T, AllocatorOrDeleter, _internal_buffer_size > | render_unterminated (Args &&...args) const |
Convenience function. | |
Static Public Attributes | |
static constexpr auto | preferred_separator = filesystem::path::preferred_separator |
The preferred separator type. | |
template<class Char > | |
static constexpr bool | is_source_chartype_acceptable = detail::is_source_chartype_acceptable<Char>::value |
template<class Char > | |
static constexpr bool | is_source_acceptable = detail::is_source_acceptable<Char>::value |
static constexpr size_t | default_internal_buffer_size = 1024 |
The default internal buffer size used by rendered_path . | |
Friends | |
constexpr friend bool | llfio_v2_xxx::operator== (path_view x, path_view y) noexcept |
constexpr friend bool | llfio_v2_xxx::operator!= (path_view x, path_view y) noexcept |
constexpr friend bool | llfio_v2_xxx::operator< (path_view x, path_view y) noexcept |
constexpr friend size_t | hash_value (path_view x) noexcept |
Return the combined hash of individual path components. | |
A borrowed view of a path. A lightweight trivial-type alternative to std::filesystem::path
.
LLFIO 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. LLFIO 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.
Each consumer of path_view
defines what the "native platform transport" and "native platform encoding" is. For LLFIO, the native platform transport is defined to be std::filesystem::path::value_type
, which is as follows:
char
.Microsoft Windows: The native platform transport is wchar_t
.
If** the input to path_view
equals the native platform transport, the bits supplied will be passed through to the operating system without translation (see below). If* the consuming API expects null termination, and the input to path_view
is null terminated, then you are guaranteed that the originally supplied buffer is passed through. If the input is not null terminated, a bitwise identical copy is made into temporary storage (which will be the stack for smaller strings), which is then null terminated before passing to the consuming API.
If the input to path_view
does NOT equal the native platform transport, then a translation of the input bits will be performed into temporary storage just before calling the consuming API. The rules are as follows:
char8_t
or char
, it is not translated. If the input is char16_t
, a UTF-16 to UTF-8 translation is performed.char16_t
or wchar_t
, it is not translated. If the input is char8_t
, a UTF-8 to UTF-16 translation is performed. If the input is char
, the Microsoft Windows API for ANSI to UTF-16 translation is invoked in order to match how Windows ANSI APIs are mapped onto the Windows Unicode APIs (be aware this is very slow).On Microsoft Windows, filesystem paths may require to be zero terminated, or they may not. Which is the case depends on whether LLFIO calls the NT kernel API directly rather than the Win32 API. As a general rule as to when which is used, the NT kernel API is called instead of the Win32 API when:
path_handle
(the Win32 API does not provide a race free file system API).\!!\
, we pass the path + 3 characters directly through. This prefix is a pure LLFIO extension, and will not be recognised by other code.\??\
, 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:
ThreadExplicitCaseSensitivity
privilege, or the system registry has enabled case sensitive lookup for NTFS, paths are matched case sensitively as raw bytes via memcmp()
, not case insensitively (requires slow locale conversion).handle::flag
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.
|
inherited |
How to interpret separators.
|
inherited |
The zero termination to use.
|
inlinenoexcept |
Implicitly constructs a path view from a path. The input path MUST continue to exist for this view to be valid (DEVIATES from P1030 due to filesystem::path not exposing its path formatting).
|
inlineconstexprnoexcept |
Constructs from a basic string if the character type is one of char
, wchar_t
, char8_t
or char16_t
.
|
inlineconstexprnoexcept |
Constructs from a lengthed array of one of char
, wchar_t
, char8_t
or char16_t
. The input string MUST continue to exist for this view to be valid.
|
inlineconstexprnoexcept |
Constructs from a lengthed array of one of char
, wchar_t
, char8_t
or char16_t
. The input string MUST continue to exist for this view to be valid.
|
inlineconstexprnoexcept |
Constructs from a lengthed array of one of char
, wchar_t
, char8_t
or char16_t
. The input string MUST continue to exist for this view to be valid.
|
inlineconstexprnoexcept |
Constructs from a lengthed array of one of char
, wchar_t
, char8_t
or char16_t
. The input string MUST continue to exist for this view to be valid.
|
inlineconstexprnoexcept |
Constructs from a lengthed array of byte
. The input array MUST continue to exist for this view to be valid.
|
inlineconstexprnoexcept |
Implicitly constructs a path view from a zero terminated pointer to a character array, which must be one of char
, wchar_t
, char8_t
or char16_t
. The input string MUST continue to exist for this view to be valid.
|
inlineconstexprnoexcept |
Implicitly constructs a path view from a zero terminated pointer to byte array. The input array MUST continue to exist for this view to be valid.
|
inlineconstexprnoexcept |
Constructs from a basic string view if the character type is one of char
, wchar_t
, char8_t
or char16_t
.
|
inlineconstexprnoexcept |
Constructs from a span<const byte>
.
|
inlineconstexprnoexcept |
Constructs from an iterator sequence if the iterator is contiguous, if its value type is one of char
, wchar_t
, char8_t
or char16_t
.
(DEVIATES from P1030, cannot detect contiguous iterator in SFINAE in C++ 14)
|
inlineconstexprnoexcept |
Constructs from an iterator sequence if the iterator is contiguous, if its value type is byte
.
(DEVIATES from P1030, cannot detect contiguous iterator in SFINAE in C++ 14)
|
inlineconstexpr |
Compares the two path views for equivalence or ordering using T
as the destination encoding, if necessary.
If the source encodings of the two path views are compatible, a lexicographical comparison is performed. If they are incompatible, either or both views are converted to the destination encoding using rendered_path<T, Delete, _internal_buffer_size>
, and then a lexicographical comparison is performed.
This can, for obvious reasons, be expensive. It can also throw exceptions, as rendered_path
does.
If the destination encoding is byte
, memcmp()
is used, and rendered_path
is never invoked as the two sources are byte compared directly.
|
inlineconstexprinherited |
Compares the two path views for equivalence or ordering using T
as the destination encoding, if necessary.
If the source encodings of the two path views are compatible, a lexicographical comparison is performed. If they are incompatible, either or both views are converted to the destination encoding using rendered_path<T, Delete, _internal_buffer_size>
, and then a lexicographical comparison is performed.
This can, for obvious reasons, be expensive. It can also throw exceptions, as rendered_path
does.
If the destination encoding is byte
, memcmp()
is used, and rendered_path
is never invoked as the two sources are byte compared directly.
|
staticconstexprinherited |
True if path views can be constructed from this source. i.e. is_source_chartype_acceptable
, or is byte
|
staticconstexprinherited |
True if path views can be constructed from this character type. i.e. is one of char
, wchar_t
, char8_t
, char16_t