diff options
author | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2021-09-29 14:55:09 +0300 |
---|---|---|
committer | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2021-09-29 14:55:09 +0300 |
commit | 6225f5dd9afecaeea8a8b0c1d51028ad7bd66858 (patch) | |
tree | a80c97b103661edc3dd1e74b4ce7a363a240bf9f | |
parent | a5e450e67757aed69e298a1faac953877eb9e637 (diff) |
wip
21 files changed, 185 insertions, 165 deletions
diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp index c311c9e1..5c4e461e 100644 --- a/include/llfio/revision.hpp +++ b/include/llfio/revision.hpp @@ -1,4 +1,4 @@ // Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time -#define LLFIO_PREVIOUS_COMMIT_REF 721503d32fe35dbaa93bde0214ae8cd3799d14b8 -#define LLFIO_PREVIOUS_COMMIT_DATE "2021-09-17 17:12:12 +00:00" -#define LLFIO_PREVIOUS_COMMIT_UNIQUE 721503d3 +#define LLFIO_PREVIOUS_COMMIT_REF a5e450e67757aed69e298a1faac953877eb9e637 +#define LLFIO_PREVIOUS_COMMIT_DATE "2021-09-24 16:44:57 +00:00" +#define LLFIO_PREVIOUS_COMMIT_UNIQUE a5e450e6 diff --git a/include/llfio/v2.0/detail/impl/path_discovery.ipp b/include/llfio/v2.0/detail/impl/path_discovery.ipp index 9a71595d..2ea46d9f 100644 --- a/include/llfio/v2.0/detail/impl/path_discovery.ipp +++ b/include/llfio/v2.0/detail/impl/path_discovery.ipp @@ -156,7 +156,7 @@ namespace path_discovery #if 0 fprintf(stderr, "path_discovery::verified_temporary_directories() failed to open %s due to %s\n", ps.all[n].path.path().c_str(), _h.error().message().c_str()); - path_view::c_str<> zpath(ps.all[n].path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(ps.all[n].path); fprintf(stderr, "path_view::c_str says buffer = %p (%s) length = %u\n", zpath.buffer, zpath.buffer, (unsigned) zpath.length); visit(ps.all[n].path, [](auto _sv) { char buffer[1024]; diff --git a/include/llfio/v2.0/detail/impl/path_view.ipp b/include/llfio/v2.0/detail/impl/path_view.ipp index f47561ad..4d0f2976 100644 --- a/include/llfio/v2.0/detail/impl/path_view.ipp +++ b/include/llfio/v2.0/detail/impl/path_view.ipp @@ -98,7 +98,7 @@ namespace detail assert(std::codecvt_base::noconv != result); if(std::codecvt_base::noconv == result) { - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str should never do identity reencoding"); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path should never do identity reencoding"); abort(); } if(std::codecvt_base::error == result) @@ -109,7 +109,7 @@ namespace detail throw std::system_error(make_error_code(std::errc::illegal_byte_sequence)); } // Otherwise proceed anyway :) - LLFIO_LOG_WARN(nullptr, "path_view_component::c_str saw failure to completely convert input encoding"); + LLFIO_LOG_WARN(nullptr, "path_view_component::rendered_path saw failure to completely convert input encoding"); result = std::codecvt_base::ok; } if(std::codecvt_base::ok == result) @@ -139,12 +139,12 @@ namespace detail char *reencode_path_to(size_t & /*unused*/, char * /*unused*/, size_t /*unused*/, const LLFIO_V2_NAMESPACE::byte * /*unused*/, size_t /*unused*/, const std::locale * /*unused*/) { - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function should never see passthrough."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function should never see passthrough."); abort(); } char *reencode_path_to(size_t & /*unused*/, char * /*unused*/, size_t /*unused*/, const char * /*unused*/, size_t /*unused*/, const std::locale * /*unused*/) { - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function should never see identity."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function should never see identity."); abort(); } char *reencode_path_to(size_t &toallocate, char *dest_buffer, size_t dest_buffer_length, const wchar_t *src_buffer, size_t src_buffer_length, @@ -252,7 +252,7 @@ namespace detail assert(std::codecvt_base::noconv != result); if(std::codecvt_base::noconv == result) { - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str should never do identity reencoding"); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path should never do identity reencoding"); abort(); } if(std::codecvt_base::error == result) @@ -299,7 +299,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function should never see identity."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function should never see identity."); abort(); #endif } @@ -318,7 +318,7 @@ namespace detail wchar_t *reencode_path_to(size_t & /*unused*/, wchar_t * /*unused*/, size_t /*unused*/, const LLFIO_V2_NAMESPACE::byte * /*unused*/, size_t /*unused*/, const std::locale * /*unused*/) { - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function should never see passthrough."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function should never see passthrough."); abort(); } wchar_t *reencode_path_to(size_t &toallocate, wchar_t *dest_buffer, size_t dest_buffer_length, const char *src_buffer, size_t src_buffer_length, @@ -417,7 +417,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char to wchar_t conversion on libc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char to wchar_t conversion on libc++."); abort(); #elif defined(__GLIBCXX__) (void) toallocate; @@ -426,7 +426,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char to wchar_t conversion on libstdc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char to wchar_t conversion on libstdc++."); abort(); #else return _reencode_path_to(toallocate, dest_buffer, dest_buffer_length, src_buffer, src_buffer_length, loc); @@ -435,7 +435,7 @@ namespace detail wchar_t *reencode_path_to(size_t & /*unused*/, wchar_t * /*unused*/, size_t /*unused*/, const wchar_t * /*unused*/, size_t /*unused*/, const std::locale * /*unused*/) { - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function should never see identity."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function should never see identity."); abort(); } wchar_t *reencode_path_to(size_t &toallocate, wchar_t *dest_buffer, size_t dest_buffer_length, const char8_t *src_buffer, size_t src_buffer_length, @@ -449,7 +449,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char8_t to wchar_t conversion on libc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char8_t to wchar_t conversion on libc++."); abort(); #elif defined(__GLIBCXX__) (void) toallocate; @@ -458,7 +458,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char8_t to wchar_t conversion on libstdc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char8_t to wchar_t conversion on libstdc++."); abort(); #else return _reencode_path_to(toallocate, dest_buffer, dest_buffer_length, (const char *) src_buffer, src_buffer_length, loc); @@ -472,7 +472,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char8_t to wchar_t conversion on libc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char8_t to wchar_t conversion on libc++."); abort(); #elif defined(__GLIBCXX__) (void) toallocate; @@ -481,7 +481,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char8_t to wchar_t conversion on libstdc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char8_t to wchar_t conversion on libstdc++."); abort(); #else return _reencode_path_to(toallocate, dest_buffer, dest_buffer_length, src_buffer, src_buffer_length, loc); @@ -498,7 +498,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function should never see identity."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function should never see identity."); abort(); #elif defined(_LIBCPP_VERSION) (void) toallocate; @@ -507,7 +507,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char16_t to wchar_t conversion on libc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char16_t to wchar_t conversion on libc++."); abort(); #elif defined(__GLIBCXX__) (void) toallocate; @@ -516,7 +516,7 @@ namespace detail (void) src_buffer; (void) src_buffer_length; (void) loc; - LLFIO_LOG_FATAL(nullptr, "path_view_component::c_str reencoding function does not support char16_t to wchar_t conversion on libstdc++."); + LLFIO_LOG_FATAL(nullptr, "path_view_component::rendered_path reencoding function does not support char16_t to wchar_t conversion on libstdc++."); abort(); #else return _reencode_path_to(toallocate, dest_buffer, dest_buffer_length, src_buffer, src_buffer_length, loc); diff --git a/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp b/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp index d9bfc2be..88ceeea0 100644 --- a/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp @@ -80,7 +80,7 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa // really ought to be cloning the handle. But let's humour him. path = "."; } - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); auto rename_random_dir_over_existing_dir = [_mode, _caching, flags](const path_handle &base, path_view_type path) -> result<directory_handle> { // Take a path handle to the directory containing the file auto path_parent = path.parent_path(); @@ -267,7 +267,7 @@ result<directory_handle::buffers_type> directory_handle::read(io_request<buffers return std::move(req.buffers); } // Is glob a single entry match? If so, this is really a stat call - path_view_type::c_str<> zglob(req.glob, path_view::zero_terminated); + path_view_type::zero_terminated_rendered_path<> zglob(req.glob); if(!req.glob.empty() && !req.glob.contains_glob()) { struct stat s diff --git a/include/llfio/v2.0/detail/impl/posix/file_handle.ipp b/include/llfio/v2.0/detail/impl/posix/file_handle.ipp index cf84c3db..a06aa88e 100644 --- a/include/llfio/v2.0/detail/impl/posix/file_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/file_handle.ipp @@ -51,7 +51,7 @@ result<file_handle> file_handle::file(const path_handle &base, file_handle::path OUTCOME_TRY(auto &&attribs, attribs_from_handle_mode_caching_and_flags(nativeh, _mode, _creation, _caching, flags)); attribs &= ~O_NONBLOCK; nativeh.behaviour &= ~native_handle_type::disposition::nonblocking; - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); if(base.is_valid()) { nativeh.fd = ::openat(base.native_handle().fd, zpath.buffer, attribs, 0x1b0 /*660*/); diff --git a/include/llfio/v2.0/detail/impl/posix/fs_handle.ipp b/include/llfio/v2.0/detail/impl/posix/fs_handle.ipp index f59638e2..cbb07c42 100644 --- a/include/llfio/v2.0/detail/impl/posix/fs_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/fs_handle.ipp @@ -131,7 +131,7 @@ namespace detail return success(std::move(currentdirh)); } // stat the same file name, and compare dev and inode - path_view::c_str<> zpath(filename, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(filename); struct stat s { }; @@ -191,7 +191,7 @@ result<void> fs_handle::relink(const path_handle &base, path_view_type path, boo { LLFIO_LOG_FUNCTION_CALL(this); auto &h = const_cast<handle &>(_get_handle()); - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); #ifdef O_TMPFILE // If the handle was created with O_TMPFILE, we need a different approach if(h.flags() & handle::flag::anonymous_inode) @@ -330,7 +330,7 @@ result<void> fs_handle::link(const path_handle &base, path_view_type path, deadl { LLFIO_LOG_FUNCTION_CALL(this); auto &h = const_cast<handle &>(_get_handle()); - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); #ifdef AT_EMPTY_PATH // Try to use the fd linking syscall if(-1 != ::linkat(h.native_handle().fd, "", base.is_valid() ? base.native_handle().fd : AT_FDCWD, zpath.buffer, AT_EMPTY_PATH)) diff --git a/include/llfio/v2.0/detail/impl/posix/path_handle.ipp b/include/llfio/v2.0/detail/impl/posix/path_handle.ipp index 47b242f5..fcad635d 100644 --- a/include/llfio/v2.0/detail/impl/posix/path_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/path_handle.ipp @@ -32,7 +32,7 @@ result<bool> path_handle::exists(path_view_type path) const noexcept { try { LLFIO_LOG_FUNCTION_CALL(this); - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); int x = ::faccessat(native_handle().fd, zpath.buffer, F_OK, AT_SYMLINK_NOFOLLOW); if(x < 0) { @@ -66,7 +66,7 @@ result<path_handle> path_handle::path(const path_handle &base, path_handle::path // Linux provides this extension opening a super light weight fd to just an anchor on the filing system attribs |= O_PATH; #endif - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); if(base.is_valid()) { nativeh.fd = ::openat(base.native_handle().fd, zpath.buffer, attribs); diff --git a/include/llfio/v2.0/detail/impl/posix/process_handle.ipp b/include/llfio/v2.0/detail/impl/posix/process_handle.ipp index 63070099..12c79cc6 100644 --- a/include/llfio/v2.0/detail/impl/posix/process_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/process_handle.ipp @@ -243,15 +243,15 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<process_handle> process_handle::launch_pr return posix_error(); } - using small_path_view_c_str = path_view::c_str<filesystem::path::value_type, std::default_delete<filesystem::path::value_type[]>, 1>; + using small_path_view_c_str = path_view::zero_terminated_rendered_path<filesystem::path::value_type, std::default_delete<filesystem::path::value_type[]>, 1>; std::vector<const char *> argptrs(args.size() + 2); std::vector<small_path_view_c_str> _args; _args.reserve(args.size() + 1); - _args.emplace_back(path, path_view::zero_terminated); + _args.emplace_back(path); argptrs[0] = _args[0].buffer; for(size_t n = 0; n < args.size(); ++n) { - _args.emplace_back(args[n], path_view::zero_terminated); + _args.emplace_back(args[n]); argptrs[n + 1] = _args[n + 1].buffer; } std::vector<small_path_view_c_str> _envs; @@ -260,7 +260,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<process_handle> process_handle::launch_pr envptrs.reserve(env.size() + 1); for(const auto &i : env) { - _envs.emplace_back(i, path_view::zero_terminated); + _envs.emplace_back(i); envptrs.push_back(_envs.back().buffer); } envptrs.push_back(nullptr); diff --git a/include/llfio/v2.0/detail/impl/posix/symlink_handle.ipp b/include/llfio/v2.0/detail/impl/posix/symlink_handle.ipp index fad232ec..34a80dd6 100644 --- a/include/llfio/v2.0/detail/impl/posix/symlink_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/symlink_handle.ipp @@ -63,7 +63,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<void> symlink_handle::_create_symlink(con end_utc = d.to_time_point(); } } - path_view::c_str<> zpath(target, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(target); try { if(atomic_replace) diff --git a/include/llfio/v2.0/detail/impl/reduce.ipp b/include/llfio/v2.0/detail/impl/reduce.ipp index 1ed837cd..5966ae3e 100644 --- a/include/llfio/v2.0/detail/impl/reduce.ipp +++ b/include/llfio/v2.0/detail/impl/reduce.ipp @@ -65,7 +65,7 @@ namespace algorithm const DWORD deletedir_ntflags = 0x20 /*FILE_SYNCHRONOUS_IO_NONALERT*/ | 0x00200000 /*FILE_OPEN_REPARSE_POINT*/ | 0x00001000 /*FILE_DELETE_ON_CLOSE*/ | 0x01 /*FILE_DIRECTORY_FILE*/; IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(leafname, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(leafname); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -140,7 +140,7 @@ namespace algorithm } return ntkernel_error(ntstat); #else - path_view::c_str<> zpath(leafname, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(leafname); errno = 0; if(is_dir || -1 == ::unlinkat(dirh.native_handle().fd, zpath.buffer, 0)) { @@ -173,7 +173,7 @@ namespace algorithm const DWORD renamefile_ntflags = 0x20 /*FILE_SYNCHRONOUS_IO_NONALERT*/ | 0x00200000 /*FILE_OPEN_REPARSE_POINT*/ | 0x040 /*FILE_NON_DIRECTORY_FILE*/; const DWORD renamedir_ntflags = 0x20 /*FILE_SYNCHRONOUS_IO_NONALERT*/ | 0x00200000 /*FILE_OPEN_REPARSE_POINT*/ | 0x01 /*FILE_DIRECTORY_FILE*/; IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(leafname, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(leafname); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -245,7 +245,7 @@ namespace algorithm return success(); #else (void) is_dir; - path_view::c_str<> zpath(leafname, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(leafname); if(dirh.unique_id() != topdirh.unique_id()) { // Try renaming it into topdirh diff --git a/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp b/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp index 17eaf0fb..8b19e873 100644 --- a/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp +++ b/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp @@ -379,7 +379,7 @@ namespace algorithm { try { - path_view::c_str<> zpath(lockfile, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(lockfile); struct stat s { }; diff --git a/include/llfio/v2.0/detail/impl/traverse.ipp b/include/llfio/v2.0/detail/impl/traverse.ipp index 7c4be156..1d4b86ce 100644 --- a/include/llfio/v2.0/detail/impl/traverse.ipp +++ b/include/llfio/v2.0/detail/impl/traverse.ipp @@ -261,7 +261,7 @@ namespace algorithm { struct ::stat stat; memset(&stat, 0, sizeof(stat)); - path_view::c_str<> zpath(entry.leafname, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(entry.leafname); if(::fstatat(mydirh->native_handle().fd, zpath.buffer, &stat, AT_SYMLINK_NOFOLLOW) >= 0) { entry.stat.st_type = [](uint16_t mode) { diff --git a/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp b/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp index f8719e0c..2071fe4d 100644 --- a/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp @@ -89,7 +89,7 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa ntflags |= 0x01 /*FILE_DIRECTORY_FILE*/; // required to open a directory IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -164,7 +164,7 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa break; } attribs |= FILE_FLAG_BACKUP_SEMANTICS; // required to open a directory - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); if(INVALID_HANDLE_VALUE == (nativeh.h = CreateFileW_(zpath.buffer, access, fileshare, nullptr, creation, attribs, nullptr, true))) // NOLINT { DWORD errcode = GetLastError(); @@ -303,7 +303,7 @@ result<directory_handle::buffers_type> directory_handle::read(io_request<buffers } UNICODE_STRING _glob{}; memset(&_glob, 0, sizeof(_glob)); - path_view_type::c_str<> zglob(req.glob, path_view::not_zero_terminated); + path_view_type::not_zero_terminated_rendered_path<> zglob(req.glob); if(!req.glob.empty()) { _glob.Buffer = const_cast<wchar_t *>(zglob.buffer); diff --git a/include/llfio/v2.0/detail/impl/windows/file_handle.ipp b/include/llfio/v2.0/detail/impl/windows/file_handle.ipp index 5b36810f..4d796a55 100644 --- a/include/llfio/v2.0/detail/impl/windows/file_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/file_handle.ipp @@ -71,7 +71,7 @@ result<file_handle> file_handle::file(const path_handle &base, file_handle::path ntflags |= 0x040 /*FILE_NON_DIRECTORY_FILE*/; // do not open a directory IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -139,7 +139,7 @@ result<file_handle> file_handle::file(const path_handle &base, file_handle::path creation = CREATE_ALWAYS; break; } - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); if(INVALID_HANDLE_VALUE == (nativeh.h = CreateFileW_(zpath.buffer, access, fileshare, nullptr, creation, attribs, nullptr))) // NOLINT { DWORD errcode = GetLastError(); diff --git a/include/llfio/v2.0/detail/impl/windows/fs_handle.ipp b/include/llfio/v2.0/detail/impl/windows/fs_handle.ipp index 9365a363..c8ae0daf 100644 --- a/include/llfio/v2.0/detail/impl/windows/fs_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/fs_handle.ipp @@ -83,7 +83,7 @@ result<path_handle> fs_handle::parent_path_handle(deadline d) const noexcept DWORD fileshare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(filename, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(filename); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -139,7 +139,7 @@ result<void> fs_handle::relink(const path_handle &base, path_view_type path, boo // If the target is a win32 path, we need to convert to NT path and call ourselves if(!base.is_valid() && !path.is_ntpath()) { - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); UNICODE_STRING NtPath{}; if(RtlDosPathNameToNtPathName_U(zpath.buffer, &NtPath, nullptr, nullptr) == 0u) { @@ -188,7 +188,7 @@ result<void> fs_handle::relink(const path_handle &base, path_view_type path, boo duph = h.native_handle().h; } - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -227,7 +227,7 @@ result<void> fs_handle::link(const path_handle &base, path_view_type path, deadl // If the target is a win32 path, we need to convert to NT path and call ourselves if(!base.is_valid() && !path.is_ntpath()) { - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); UNICODE_STRING NtPath{}; if(RtlDosPathNameToNtPathName_U(zpath.buffer, &NtPath, nullptr, nullptr) == 0u) { @@ -245,7 +245,7 @@ result<void> fs_handle::link(const path_handle &base, path_view_type path, deadl HANDLE duph = h.native_handle().h; - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); diff --git a/include/llfio/v2.0/detail/impl/windows/path_handle.ipp b/include/llfio/v2.0/detail/impl/windows/path_handle.ipp index 2d394c8f..7da388fb 100644 --- a/include/llfio/v2.0/detail/impl/windows/path_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/path_handle.ipp @@ -34,7 +34,7 @@ result<bool> path_handle::exists(path_view_type path) const noexcept windows_nt_kernel::init(); using namespace windows_nt_kernel; LLFIO_LOG_FUNCTION_CALL(this); - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -99,7 +99,7 @@ result<path_handle> path_handle::path(const path_handle &base, path_handle::path ntflags |= 0x01 /*FILE_DIRECTORY_FILE*/; // required to open a directory IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -135,7 +135,7 @@ result<path_handle> path_handle::path(const path_handle &base, path_handle::path { DWORD creation = OPEN_EXISTING; attribs |= FILE_FLAG_BACKUP_SEMANTICS; // required to open a directory - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); if(INVALID_HANDLE_VALUE == (nativeh.h = CreateFileW_(zpath.buffer, access, fileshare, nullptr, creation, attribs, nullptr))) // NOLINT { DWORD errcode = GetLastError(); diff --git a/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp b/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp index 6f8c5d1f..00db0d8a 100644 --- a/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp @@ -72,7 +72,7 @@ result<pipe_handle> pipe_handle::pipe(pipe_handle::path_view_type path, pipe_han ntflags &= ~0x00000008 /*FILE_NO_INTERMEDIATE_BUFFERING*/; // pipes always buffer IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; if(path.empty()) { diff --git a/include/llfio/v2.0/detail/impl/windows/process_handle.ipp b/include/llfio/v2.0/detail/impl/windows/process_handle.ipp index ebc63d00..02f53453 100644 --- a/include/llfio/v2.0/detail/impl/windows/process_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/process_handle.ipp @@ -268,7 +268,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<process_handle> process_handle::launch_pr })); } *envbuffere = 0; - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); PROCESS_INFORMATION pi; if(!CreateProcessW(zpath.buffer, argsbuffer, nullptr, nullptr, true, CREATE_UNICODE_ENVIRONMENT, envbuffer, nullptr, &si, &pi)) return win32_error(); diff --git a/include/llfio/v2.0/detail/impl/windows/symlink_handle.ipp b/include/llfio/v2.0/detail/impl/windows/symlink_handle.ipp index 97dde7b3..d8c499d0 100644 --- a/include/llfio/v2.0/detail/impl/windows/symlink_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/symlink_handle.ipp @@ -108,7 +108,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<symlink_handle> symlink_handle::symlink(c ntflags |= 0x4000 /*FILE_OPEN_FOR_BACKUP_INTENT*/ | 0x00200000 /*FILE_OPEN_REPARSE_POINT*/; IO_STATUS_BLOCK isb = make_iostatus(); - path_view::c_str<> zpath(path, path_view::not_zero_terminated); + path_view::not_zero_terminated_rendered_path<> zpath(path); UNICODE_STRING _path{}; _path.Buffer = const_cast<wchar_t *>(zpath.buffer); _path.MaximumLength = (_path.Length = static_cast<USHORT>(zpath.length * sizeof(wchar_t))) + sizeof(wchar_t); @@ -162,7 +162,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<symlink_handle> symlink_handle::symlink(c } // required to open a symlink attribs |= FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT; - path_view::c_str<> zpath(path, path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(path); if(INVALID_HANDLE_VALUE == (nativeh.h = CreateFileW_(zpath.buffer, access, fileshare, nullptr, creation, attribs, nullptr))) // NOLINT { DWORD errcode = GetLastError(); @@ -254,7 +254,7 @@ result<symlink_handle::const_buffers_type> symlink_handle::write(symlink_handle: auto *buffer = req.kernelbuffer.empty() ? alloca(buffersize) : req.kernelbuffer.data(); memset(buffer, 0, sizeof(REPARSE_DATA_BUFFER)); auto *rpd = (REPARSE_DATA_BUFFER *) buffer; - path_view::c_str<> zpath(req.buffers.path(), path_view::zero_terminated); + path_view::zero_terminated_rendered_path<> zpath(req.buffers.path()); switch(req.buffers.type()) { case symlink_type::none: diff --git a/include/llfio/v2.0/path_view.hpp b/include/llfio/v2.0/path_view.hpp index 48618e3d..cf35a013 100644 --- a/include/llfio/v2.0/path_view.hpp +++ b/include/llfio/v2.0/path_view.hpp @@ -1,5 +1,5 @@ /* A view of a path to something -(C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (20 commits) +(C) 2017-2021 Niall Douglas <http://www.nedproductions.biz/> (20 commits) File Created: Jul 2017 @@ -215,7 +215,7 @@ public: //! i.e. `is_source_chartype_acceptable`, or is `byte` template <class Char> static constexpr bool is_source_acceptable = detail::is_source_acceptable<Char>::value; - //! The default internal buffer size used by `c_str`. + //! The default internal buffer size used by `rendered_path`. static constexpr size_t default_internal_buffer_size = 1024; // 2Kb for wchar_t, 1Kb for char //! How to interpret separators @@ -229,14 +229,21 @@ public: }; //! The zero termination to use +#ifdef _MSC_VER + enum _msvc_zero_termination_enum +#else enum zero_termination +#endif { zero_terminated, //!< The input is zero terminated, or requested output ought to be zero terminated. not_zero_terminated, //!< The input is not zero terminated, or requested output ought to not be zero terminated. }; +#ifndef _MSC_VER + using _msvc_zero_termination_enum = zero_termination; +#endif //! The default deleter to use - template <class T> using default_c_str_deleter = std::default_delete<T>; + template <class T> using default_rendered_path_deleter = std::default_delete<T>; private: static constexpr auto _npos = string_view::npos; @@ -304,7 +311,7 @@ public: /*! 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. */ - constexpr path_view_component(const char *b, size_t l, enum zero_termination zt, format fmt = binary_format) noexcept + constexpr path_view_component(const char *b, size_t l, _msvc_zero_termination_enum zt, format fmt = binary_format) noexcept : _charstr((l == 0) ? nullptr : b) , _length((l == 0) ? 0 : l) , _zero_terminated((l == 0) ? false : (zt == zero_terminated)) @@ -320,7 +327,7 @@ public: /*! 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. */ - constexpr path_view_component(const wchar_t *b, size_t l, enum zero_termination zt, format fmt = binary_format) noexcept + constexpr path_view_component(const wchar_t *b, size_t l, _msvc_zero_termination_enum zt, format fmt = binary_format) noexcept : _wcharstr((l == 0) ? nullptr : b) , _length((l == 0) ? 0 : l) , _zero_terminated((l == 0) ? false : (zt == zero_terminated)) @@ -336,7 +343,7 @@ public: /*! 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. */ - constexpr path_view_component(const char8_t *b, size_t l, enum zero_termination zt, format fmt = binary_format) noexcept + constexpr path_view_component(const char8_t *b, size_t l, _msvc_zero_termination_enum zt, format fmt = binary_format) noexcept : _char8str((l == 0) ? nullptr : b) , _length((l == 0) ? 0 : l) , _zero_terminated((l == 0) ? false : (zt == zero_terminated)) @@ -352,7 +359,7 @@ public: /*! 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. */ - constexpr path_view_component(const char16_t *b, size_t l, enum zero_termination zt, format fmt = binary_format) noexcept + constexpr path_view_component(const char16_t *b, size_t l, _msvc_zero_termination_enum zt, format fmt = binary_format) noexcept : _char16str((l == 0) ? nullptr : b) , _length((l == 0) ? 0 : l) , _zero_terminated((l == 0) ? false : (zt == zero_terminated)) @@ -368,7 +375,7 @@ public: /*! Constructs from a lengthed array of `byte`. The input array MUST continue to exist for this view to be valid. */ - constexpr path_view_component(const byte *b, size_t l, enum zero_termination zt) noexcept + constexpr path_view_component(const byte *b, size_t l, _msvc_zero_termination_enum zt) noexcept : _bytestr((l == 0) ? nullptr : b) , _length((l == 0) ? 0 : l) , _zero_terminated((l == 0) ? false : (zt == zero_terminated)) @@ -405,13 +412,13 @@ public: */ LLFIO_TEMPLATE(class Char) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_chartype_acceptable<Char>)) - constexpr path_view_component(basic_string_view<Char> v, enum zero_termination zt, format fmt = binary_format) noexcept + constexpr path_view_component(basic_string_view<Char> v, _msvc_zero_termination_enum zt, format fmt = binary_format) noexcept : path_view_component(v.data(), v.size(), zt, fmt) { } /*! Constructs from a `span<const byte>`. */ - constexpr path_view_component(span<const byte> v, enum zero_termination zt) noexcept + constexpr path_view_component(span<const byte> v, _msvc_zero_termination_enum zt) noexcept : path_view_component(v.data(), v.size(), zt) { } @@ -423,14 +430,14 @@ public: */ LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_chartype_acceptable<typename It::value_type>), LLFIO_TPRED(is_source_chartype_acceptable<typename End::value_type>)) - constexpr path_view_component(It b, End e, enum zero_termination zt, format fmt = binary_format) noexcept + constexpr path_view_component(It b, End e, _msvc_zero_termination_enum zt, format fmt = binary_format) noexcept : path_view_component(addressof(*b), e - b, zt, fmt) { } //! \overload LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_chartype_acceptable<std::decay_t<It>>), LLFIO_TPRED(is_source_chartype_acceptable<std::decay_t<End>>)) - constexpr path_view_component(It *b, End *e, enum zero_termination zt, format fmt = binary_format) noexcept + constexpr path_view_component(It *b, End *e, _msvc_zero_termination_enum zt, format fmt = binary_format) noexcept : path_view_component(b, e - b, zt, fmt) { } @@ -441,14 +448,14 @@ public: */ LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(std::is_same<typename It::value_type, byte>::value), LLFIO_TPRED(std::is_same<typename End::value_type, byte>::value)) - constexpr path_view_component(It b, End e, enum zero_termination zt) noexcept + constexpr path_view_component(It b, End e, _msvc_zero_termination_enum zt) noexcept : path_view_component(addressof(*b), e - b, zt, binary_format) { } //! \overload LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(std::is_same<std::decay_t<It>, byte>::value), LLFIO_TPRED(std::is_same<std::decay_t<End>, byte>::value)) - constexpr path_view_component(It *b, End *e, enum zero_termination zt) noexcept + constexpr path_view_component(It *b, End *e, _msvc_zero_termination_enum zt) noexcept : path_view_component(b, e - b, zt, binary_format) { } @@ -614,7 +621,7 @@ public: //! True if input is declared to be zero terminated constexpr bool has_zero_termination() const noexcept { return _zero_terminated; } //! The zero termination during construction - constexpr enum zero_termination zero_termination() const noexcept { return _zero_terminated ? zero_terminated : not_zero_terminated; } + constexpr _msvc_zero_termination_enum zero_termination() const noexcept { return _zero_terminated ? zero_terminated : not_zero_terminated; } //! True if `stem()` returns a non-empty path. LLFIO_PATH_VIEW_CONSTEXPR bool has_stem() const noexcept { return !stem().empty(); } @@ -713,20 +720,20 @@ private: } // Identical source encodings compare lexiographically template <class DestT, class Deleter, size_t _internal_buffer_size, class CharT> - static int _compare(basic_string_view<CharT> a, enum zero_termination /*unused*/, basic_string_view<CharT> b, enum zero_termination /*unused*/, + static int _compare(basic_string_view<CharT> a, _msvc_zero_termination_enum /*unused*/, basic_string_view<CharT> b, _msvc_zero_termination_enum /*unused*/, const std::locale * /*unused*/) noexcept { return a.compare(b); } - // Disparate source encodings compare via c_str + // Disparate source encodings compare via rendered_path template <class DestT, class Deleter, size_t _internal_buffer_size, class Char1T, class Char2T> - static int _compare(basic_string_view<Char1T> a, enum zero_termination a_zt, basic_string_view<Char2T> b, enum zero_termination b_zt, + static int _compare(basic_string_view<Char1T> a, _msvc_zero_termination_enum a_zt, basic_string_view<Char2T> b, _msvc_zero_termination_enum b_zt, const std::locale *loc) noexcept { path_view_component _a_(a.data(), a.size(), a_zt); path_view_component _b_(b.data(), b.size(), b_zt); - c_str<DestT, Deleter, _internal_buffer_size> _a(_a_, not_zero_terminated, loc); - c_str<DestT, Deleter, _internal_buffer_size> _b(_b_, not_zero_terminated, loc); + rendered_path<_msvc_zero_termination_enum::not_zero_terminated, DestT, Deleter, _internal_buffer_size> _a(_a_, loc); + rendered_path<_msvc_zero_termination_enum::not_zero_terminated, DestT, Deleter, _internal_buffer_size> _b(_b_, loc); if(_a.length < _b.length) { return -1; @@ -772,17 +779,17 @@ public: 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 `c_str<T, Delete, _internal_buffer_size>`, and then a + 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 `c_str` does. + exceptions, as `rendered_path` does. If the destination encoding is `byte`, `memcmp()` is used, - and `c_str` is never invoked as the two sources are byte + and `rendered_path` is never invoked as the two sources are byte compared directly. */ - LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_c_str_deleter<T[]>, + LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_acceptable<T>)) constexpr int compare(path_view_component p, const std::locale &loc) const @@ -793,7 +800,7 @@ public: }); } //! \overload - LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_c_str_deleter<T[]>, + LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_acceptable<T>)) constexpr int compare(path_view_component p) const @@ -820,19 +827,20 @@ public: and the source is not zero terminated, a straight memory copy is performed into the temporary buffer. - `c_str` contains a temporary buffer sized according to the template parameter. Output + `rendered_path` contains a temporary buffer sized according to the template parameter. Output below that amount involves no dynamic memory allocation. Output above that amount calls `operator new[]`. You can use an externally supplied larger temporary buffer to avoid dynamic memory allocation in all situations. */ - LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class AllocatorOrDeleter = default_c_str_deleter<T[]>, - size_t _internal_buffer_size = default_internal_buffer_size) + LLFIO_TEMPLATE(_msvc_zero_termination_enum ZeroTermination, class T = typename filesystem::path::value_type, + class AllocatorOrDeleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_acceptable<T>)) - struct c_str + struct rendered_path { - static_assert(is_source_acceptable<T>, "path_view_component::c_str<T> does not have a T which is one of byte, char, wchar_t, char8_t nor char16_t"); + static_assert(is_source_acceptable<T>, "path_view_component::rendered_path<T> does not have a T which is one of byte, char, wchar_t, char8_t nor char16_t"); template <class DestT, class _Deleter, size_t _internal_buffer_size_, class Char1T, class Char2T> - friend int path_view_component::_compare(basic_string_view<Char1T> a, enum zero_termination a_zt, basic_string_view<Char2T> b, enum zero_termination b_zt, + friend int path_view_component::_compare(basic_string_view<Char1T> a, _msvc_zero_termination_enum a_zt, basic_string_view<Char2T> b, + _msvc_zero_termination_enum b_zt, const std::locale *loc) noexcept; //! Type of the value type @@ -841,8 +849,6 @@ public: using allocator_type = decltype(detail::is_allocator(std::declval<AllocatorOrDeleter>())); //! Type of the deleter, or `void` if that was not configured using deleter_type = decltype(detail::is_deleter<value_type>(std::declval<AllocatorOrDeleter>())); - //! The size of the internal temporary buffer - static constexpr size_t internal_buffer_size = (_internal_buffer_size == 0) ? 1 : _internal_buffer_size; //! Pointer to the possibly-converted path const value_type *buffer{nullptr}; @@ -856,12 +862,12 @@ public: LLFIO_TEMPLATE(class U, class source_type) LLFIO_TREQUIRES(LLFIO_TPRED(!std::is_same<source_type, value_type>::value)) - void _make_passthrough(path_view_component /*unused*/, enum zero_termination /*unused*/, U & /*unused*/, const source_type * /*unused*/) + void _make_passthrough(path_view_component /*unused*/, U & /*unused*/, const source_type * /*unused*/) { LLFIO_LOG_FATAL(nullptr, "Passthrough to non-identity type ought to never be called!"); abort(); } - template <class U> void _make_passthrough(path_view_component view, enum zero_termination output_zero_termination, U &allocate, const value_type *source) + template <class U> void _make_passthrough(path_view_component view, U &allocate, const value_type *source) { using LLFIO_V2_NAMESPACE::basic_string_view; // If the consuming API is a NT kernel API, and we have / in the path, we shall need to do slash conversion @@ -869,7 +875,7 @@ public: (view.formatting() == format::auto_format || view.formatting() == format::generic_format) && view._invoke([](auto sv) { return sv.find('/') != _npos; }); length = view._length; - if(!needs_slash_translation && (output_zero_termination == not_zero_terminated || view._zero_terminated)) + if(!needs_slash_translation && (this->zero_termination() == not_zero_terminated || view._zero_terminated)) { buffer = source; } @@ -922,13 +928,13 @@ public: } public: - constexpr c_str() {} + constexpr rendered_path() {} #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant #endif private: - template <class U> void _init(path_view_component view, enum zero_termination output_zero_termination, const std::locale *loc, U &&allocate) + template <class U> void _init(path_view_component view, const std::locale *loc, U &&allocate) { if(0 == view._length) { @@ -945,36 +951,36 @@ public: } if(std::is_same<T, char>::value && view._char) { - _make_passthrough(view, output_zero_termination, allocate, view._charstr); + _make_passthrough(view, allocate, view._charstr); return; } if(std::is_same<T, wchar_t>::value && view._wchar) { - _make_passthrough(view, output_zero_termination, allocate, view._wcharstr); + _make_passthrough(view, allocate, view._wcharstr); return; } if(std::is_same<T, char8_t>::value && view._utf8) { - _make_passthrough(view, output_zero_termination, allocate, view._char8str); + _make_passthrough(view, allocate, view._char8str); return; } if(std::is_same<T, char16_t>::value && view._utf16) { - _make_passthrough(view, output_zero_termination, allocate, view._char16str); + _make_passthrough(view, allocate, view._char16str); return; } #ifdef _WIN32 // On Windows, consider char16_t input equivalent to wchar_t if(std::is_same<T, wchar_t>::value && view._utf16) { - _make_passthrough(view, output_zero_termination, allocate, view._wcharstr); + _make_passthrough(view, allocate, view._wcharstr); return; } #else // On POSIX, consider char8_t input equivalent to char if(std::is_same<T, char>::value && view._utf8) { - _make_passthrough(view, output_zero_termination, allocate, view._charstr); + _make_passthrough(view, allocate, view._charstr); return; } #endif @@ -1121,11 +1127,11 @@ public: } // used by compare() - c_str(path_view_component view, enum zero_termination output_zero_termination, const std::locale *loc) + rendered_path(path_view_component view, const std::locale *loc) : _deleter1(_default_deleter) , _deleter1arg(&_deleter2) { - _init(view, output_zero_termination, loc, _default_allocate<AllocatorOrDeleter>(&_deleter2)); + _init(view, loc, _default_allocate<AllocatorOrDeleter>(&_deleter2)); } public: @@ -1135,7 +1141,7 @@ public: \param loc The locale to use to perform reencoding. \param allocate Either a callable with prototype `value_type *(size_t length)` which is defaulted to `return static_cast<value_type *>(::operator new[](length * sizeof(value_type)));`, - or a `pmr::memory_resource *`. You can return `nullptr` if you wish, the consumer of `c_str` will + or a `pmr::memory_resource *`. You can return `nullptr` if you wish, the consumer of `rendered_path` will see a `buffer` set to `nullptr`. If `loc` is defaulted, and an error occurs during any conversion from UTF-8 or UTF-16, an exception of @@ -1146,78 +1152,76 @@ public: */ LLFIO_TEMPLATE(class U, class V) LLFIO_TREQUIRES(LLFIO_TPRED(_is_deleter_based<U>), LLFIO_TEXPR(std::declval<U>()((size_t) 1)), LLFIO_TEXPR(std::declval<V>()((value_type *) nullptr))) - c_str(path_view_component view, enum zero_termination output_zero_termination, const std::locale &loc, U &&allocate, V &&deleter = AllocatorOrDeleter(), - _custom_callable_deleter_tag = {}) + rendered_path(path_view_component view, const std::locale &loc, U &&allocate, V &&deleter = AllocatorOrDeleter(), _custom_callable_deleter_tag = {}) : _deleter1(_invoke_deleter) , _deleter1arg(&_deleter2) , _deleter2(static_cast<V &&>(deleter)) { - _init(view, output_zero_termination, loc, static_cast<U &&>(allocate)); + _init(view, loc, static_cast<U &&>(allocate)); } //! \overload LLFIO_TEMPLATE(class U, class V) LLFIO_TREQUIRES(LLFIO_TPRED(_is_deleter_based<U>), LLFIO_TEXPR(std::declval<U>()((size_t) 1)), LLFIO_TEXPR(std::declval<V>()((value_type *) nullptr))) - c_str(path_view_component view, enum zero_termination output_zero_termination, U &&allocate, V &&deleter = AllocatorOrDeleter(), - _custom_callable_deleter_tag = {}) + rendered_path(path_view_component view, U &&allocate, V &&deleter = AllocatorOrDeleter(), _custom_callable_deleter_tag = {}) : _deleter1(_invoke_deleter) , _deleter1arg(&_deleter2) , _deleter2(static_cast<V &&>(deleter)) { - _init(view, output_zero_termination, (const std::locale *) nullptr, static_cast<U &&>(allocate)); + _init(view, (const std::locale *) nullptr, static_cast<U &&>(allocate)); } //! \overload memory_resource - c_str(path_view_component view, enum zero_termination output_zero_termination, const std::locale &loc, pmr::memory_resource &mr, _memory_resource_tag = {}) + rendered_path(path_view_component view, const std::locale &loc, pmr::memory_resource &mr, _memory_resource_tag = {}) : _deleter1(_memory_resouce_deallocate) , _deleter1arg(&mr) { - _init(view, output_zero_termination, &loc, _memory_resource_allocate{&mr}); + _init(view, &loc, _memory_resource_allocate{&mr}); } //! \overload memory_resource - c_str(path_view_component view, enum zero_termination output_zero_termination, pmr::memory_resource &mr, _memory_resource_tag = {}) + rendered_path(path_view_component view, pmr::memory_resource &mr, _memory_resource_tag = {}) : _deleter1(_memory_resouce_deallocate) , _deleter1arg(&mr) { - _init(view, output_zero_termination, (const std::locale *) nullptr, _memory_resource_allocate{&mr}); + _init(view, (const std::locale *) nullptr, _memory_resource_allocate{&mr}); } //! \overload STL allocator LLFIO_TEMPLATE(class U) LLFIO_TREQUIRES(LLFIO_TPRED(_is_allocator_based<U>), LLFIO_TEXPR(std::declval<U>().allocate((size_t) 1))) - c_str(path_view_component view, enum zero_termination output_zero_termination, const std::locale &loc, U &&allocate, _stl_allocator_tag = {}) + rendered_path(path_view_component view, const std::locale &loc, U &&allocate, _stl_allocator_tag = {}) : _deleter1(_stl_allocator_deallocate<allocator_type>) , _deleter1arg(&_deleter2) , _deleter2(static_cast<U &&>(allocate)) { - _init(view, output_zero_termination, &loc, _stl_allocator_allocate<std::decay_t<U>>(static_cast<std::decay_t<U> *>(&_deleter2))); + _init(view, &loc, _stl_allocator_allocate<std::decay_t<U>>(static_cast<std::decay_t<U> *>(&_deleter2))); } //! \overload STL allocator LLFIO_TEMPLATE(class U) LLFIO_TREQUIRES(LLFIO_TPRED(_is_allocator_based<U>), LLFIO_TEXPR(std::declval<U>().allocate((size_t) 1))) - c_str(path_view_component view, enum zero_termination output_zero_termination, U &&allocate, _stl_allocator_tag = {}) + rendered_path(path_view_component view, U &&allocate, _stl_allocator_tag = {}) : _deleter1(_stl_allocator_deallocate<allocator_type>) , _deleter1arg(&_deleter2) , _deleter2(static_cast<U &&>(allocate)) { - _init(view, output_zero_termination, (const std::locale *) nullptr, _stl_allocator_allocate<std::decay_t<U>>(static_cast<std::decay_t<U> *>(&_deleter2))); + _init(view, (const std::locale *) nullptr, _stl_allocator_allocate<std::decay_t<U>>(static_cast<std::decay_t<U> *>(&_deleter2))); } //! \overload default allocation - c_str(path_view_component view, enum zero_termination output_zero_termination, const std::locale &loc) + rendered_path(path_view_component view, const std::locale &loc) : _deleter1(_default_deleter) , _deleter1arg(&_deleter2) { - _init(view, output_zero_termination, &loc, _default_allocate<AllocatorOrDeleter>(&_deleter2)); + _init(view, &loc, _default_allocate<AllocatorOrDeleter>(&_deleter2)); } //! \overload - c_str(path_view_component view, enum zero_termination output_zero_termination) + explicit rendered_path(path_view_component view) : _deleter1(_default_deleter) , _deleter1arg(&_deleter2) { - _init(view, output_zero_termination, nullptr, _default_allocate<AllocatorOrDeleter>(&_deleter2)); + _init(view, nullptr, _default_allocate<AllocatorOrDeleter>(&_deleter2)); } - //! Construct from a compatible `c_str`. + //! Construct from a compatible `rendered_path`. LLFIO_TEMPLATE(class AllocatorOrDeleter2, size_t _internal_buffer_size2) - LLFIO_TREQUIRES(LLFIO_TPRED(!std::is_same<c_str, c_str<T, AllocatorOrDeleter2, _internal_buffer_size2>>::value), + LLFIO_TREQUIRES(LLFIO_TPRED(!std::is_same<rendered_path, rendered_path<ZeroTermination, T, AllocatorOrDeleter2, _internal_buffer_size2>>::value), LLFIO_TPRED(std::is_constructible<AllocatorOrDeleter, AllocatorOrDeleter2>::value)) - explicit c_str(c_str<T, AllocatorOrDeleter2, _internal_buffer_size2> &&o) noexcept + explicit rendered_path(rendered_path<ZeroTermination, T, AllocatorOrDeleter2, _internal_buffer_size2> &&o) noexcept : buffer(o.buffer) , length(o.length) , _bytes_to_delete(o._bytes_to_delete) @@ -1226,9 +1230,9 @@ public: , _deleter2(std::move(o._deleter2)) { } - ~c_str() { reset(); } - c_str(const c_str &) = delete; - c_str(c_str &&o) noexcept + ~rendered_path() { reset(); } + rendered_path(const rendered_path &) = delete; + rendered_path(rendered_path &&o) noexcept : buffer(o.buffer) , length(o.length) , _bytes_to_delete(o._bytes_to_delete) @@ -1253,15 +1257,15 @@ public: o._deleter1arg = nullptr; } } - c_str &operator=(const c_str &) = delete; - c_str &operator=(c_str &&o) noexcept + rendered_path &operator=(const rendered_path &) = delete; + rendered_path &operator=(rendered_path &&o) noexcept { if(this == &o) { return *this; } - this->~c_str(); - new(this) c_str(std::move(o)); + this->~rendered_path(); + new(this) rendered_path(std::move(o)); return *this; } @@ -1290,6 +1294,11 @@ public: return nullptr; } + //! The zero termination of this rendered path + static constexpr _msvc_zero_termination_enum zero_termination() noexcept { return ZeroTermination; } + //! The size of the internal buffer + static constexpr size_t internal_buffer_size() noexcept { return (_internal_buffer_size > 0) ? _internal_buffer_size : 1; } + //! Access the custom deleter instance passed to the constructor const AllocatorOrDeleter &deleter() const noexcept { return _deleter2; } //! Access the custom deleter instance passed to the constructor @@ -1310,17 +1319,28 @@ public: AllocatorOrDeleter _deleter2; // MAKE SURE this is the final item in storage, the compiler will elide the storage // under optimisation if it can prove it is never used. - value_type _buffer[internal_buffer_size]{}; + value_type _buffer[internal_buffer_size()]{}; }; + +public: + //! 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 zero_terminated_rendered_path = rendered_path<_msvc_zero_termination_enum::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<_msvc_zero_termination_enum::not_zero_terminated, T, AllocatorOrDeleter, _internal_buffer_size>; #ifdef __cpp_concepts - template <class T, class Deleter, size_t _internal_buffer_size> + template <_msvc_zero_termination_enum ZeroTermination, class T, class Deleter, size_t _internal_buffer_size> requires(is_source_acceptable<T>) #elif defined(_MSC_VER) - template <class T, class Deleter, size_t _internal_buffer_size, class> + template <_msvc_zero_termination_enum ZeroTermination, class T, class Deleter, size_t _internal_buffer_size, class> #else - template <class T, class Deleter, size_t _internal_buffer_size, typename std::enable_if<(is_source_acceptable<T>), bool>::type> + template <_msvc_zero_termination_enum ZeroTermination, class T, class Deleter, size_t _internal_buffer_size, + typename std::enable_if<(is_source_acceptable<T>), bool>::type> #endif - friend struct c_str; + friend struct rendered_path; }; static_assert(std::is_trivially_copyable<path_view_component>::value, "path_view_component is not trivially copyable!"); static_assert(sizeof(path_view_component) == 3 * sizeof(void *), "path_view_component is not three pointers in size!"); @@ -1610,35 +1630,35 @@ public: /*! 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. */ - constexpr path_view(const char *b, size_t l, enum zero_termination zt, format fmt = auto_format) noexcept + constexpr path_view(const char *b, size_t l, _msvc_zero_termination_enum zt, format fmt = auto_format) noexcept : path_view_component(b, l, zt, fmt) { } /*! 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. */ - constexpr path_view(const wchar_t *b, size_t l, enum zero_termination zt, format fmt = auto_format) noexcept + constexpr path_view(const wchar_t *b, size_t l, _msvc_zero_termination_enum zt, format fmt = auto_format) noexcept : path_view_component(b, l, zt, fmt) { } /*! 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. */ - constexpr path_view(const char8_t *b, size_t l, enum zero_termination zt, format fmt = auto_format) noexcept + constexpr path_view(const char8_t *b, size_t l, _msvc_zero_termination_enum zt, format fmt = auto_format) noexcept : path_view_component(b, l, zt, fmt) { } /*! 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. */ - constexpr path_view(const char16_t *b, size_t l, enum zero_termination zt, format fmt = auto_format) noexcept + constexpr path_view(const char16_t *b, size_t l, _msvc_zero_termination_enum zt, format fmt = auto_format) noexcept : path_view_component(b, l, zt, fmt) { } /*! Constructs from a lengthed array of `byte`. The input array MUST continue to exist for this view to be valid. */ - constexpr path_view(const byte *b, size_t l, enum zero_termination zt) noexcept + constexpr path_view(const byte *b, size_t l, _msvc_zero_termination_enum zt) noexcept : path_view_component(b, l, zt) { } @@ -1666,13 +1686,13 @@ public: */ LLFIO_TEMPLATE(class Char) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_chartype_acceptable<Char>)) - constexpr path_view(basic_string_view<Char> v, enum zero_termination zt, format fmt = auto_format) noexcept + constexpr path_view(basic_string_view<Char> v, _msvc_zero_termination_enum zt, format fmt = auto_format) noexcept : path_view_component(v.data(), v.size(), zt, fmt) { } /*! Constructs from a `span<const byte>`. */ - constexpr path_view(span<const byte> v, enum zero_termination zt) noexcept + constexpr path_view(span<const byte> v, _msvc_zero_termination_enum zt) noexcept : path_view_component(v, zt) { } @@ -1684,14 +1704,14 @@ public: */ LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_chartype_acceptable<typename It::value_type>), LLFIO_TPRED(is_source_chartype_acceptable<typename End::value_type>)) - constexpr path_view(It b, End e, enum zero_termination zt, format fmt = auto_format) noexcept + constexpr path_view(It b, End e, _msvc_zero_termination_enum zt, format fmt = auto_format) noexcept : path_view_component(addressof(*b), e - b, zt, fmt) { } //! \overload LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(is_source_chartype_acceptable<std::decay_t<It>>), LLFIO_TPRED(is_source_chartype_acceptable<std::decay_t<End>>)) - constexpr path_view(It *b, End *e, enum zero_termination zt, format fmt = auto_format) noexcept + constexpr path_view(It *b, End *e, _msvc_zero_termination_enum zt, format fmt = auto_format) noexcept : path_view_component(b, e - b, zt, fmt) { } @@ -1702,14 +1722,14 @@ public: */ LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(std::is_same<typename It::value_type, byte>::value), LLFIO_TPRED(std::is_same<typename End::value_type, byte>::value)) - constexpr path_view(It b, End e, enum zero_termination zt) noexcept + constexpr path_view(It b, End e, _msvc_zero_termination_enum zt) noexcept : path_view_component(addressof(*b), e - b, zt, binary_format) { } //! \overload LLFIO_TEMPLATE(class It, class End) LLFIO_TREQUIRES(LLFIO_TPRED(std::is_same<std::decay_t<It>, byte>::value), LLFIO_TPRED(std::is_same<std::decay_t<End>, byte>::value)) - constexpr path_view(It *b, End *e, enum zero_termination zt) noexcept + constexpr path_view(It *b, End *e, _msvc_zero_termination_enum zt) noexcept : path_view_component(b, e - b, zt, binary_format) { } @@ -2041,22 +2061,22 @@ public: 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 `c_str<T, Delete, _internal_buffer_size>`, and then a + 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 `c_str` does. + exceptions, as `rendered_path` does. If the destination encoding is `byte`, `memcmp()` is used, - and `c_str` is never invoked as the two sources are byte + and `rendered_path` is never invoked as the two sources are byte compared directly. */ - LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_c_str_deleter<T[]>, + LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size) LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<T>)) constexpr inline int compare(path_view p, const std::locale &loc) const; //! \overload - LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_c_str_deleter<T[]>, + LLFIO_TEMPLATE(class T = typename filesystem::path::value_type, class Deleter = default_rendered_path_deleter<T[]>, size_t _internal_buffer_size = default_internal_buffer_size) LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<T>)) constexpr inline int compare(path_view p) const; @@ -2385,7 +2405,7 @@ constexpr inline int path_view::compare(path_view o) const //! Append a path view component to a path inline filesystem::path &operator+=(filesystem::path &a, path_view_component b) { - path_view_component::c_str<> zpath(b, path_view_component::not_zero_terminated); + path_view_component::not_zero_terminated_rendered_path<> zpath(b); basic_string_view<filesystem::path::value_type> _(zpath.buffer, zpath.length); a.concat(_.begin(), _.end()); return a; @@ -2393,7 +2413,7 @@ inline filesystem::path &operator+=(filesystem::path &a, path_view_component b) //! Append a path view component to a path inline filesystem::path &operator/=(filesystem::path &a, path_view_component b) { - path_view_component::c_str<> zpath(b, path_view_component::not_zero_terminated); + path_view_component::not_zero_terminated_rendered_path<> zpath(b); basic_string_view<filesystem::path::value_type> _(zpath.buffer, zpath.length); a.append(_.begin(), _.end()); return a; diff --git a/test/tests/path_view.cpp b/test/tests/path_view.cpp index 6a9f7993..229e9eec 100644 --- a/test/tests/path_view.cpp +++ b/test/tests/path_view.cpp @@ -130,9 +130,9 @@ static inline void TestPathView() BOOST_CHECK(0 == llfio::path_view("/").without_trailing_separator().compare<>("/")); #ifndef _WIN32 // cstr - llfio::path_view::c_str<> g(e, llfio::path_view::zero_terminated); + llfio::path_view::zero_terminated_rendered_path<> g(e); BOOST_CHECK(g.buffer != p); // NOLINT - llfio::path_view::c_str<> h(f, llfio::path_view::zero_terminated); + llfio::path_view::zero_terminated_rendered_path<> h(f); BOOST_CHECK(h.buffer == p + 70); // NOLINT #endif CheckPathView("/mnt/c/Users/ned/Documents/boostish/afio/programs/build_posix/testdir"); @@ -180,11 +180,11 @@ static inline void TestPathView() #endif BOOST_CHECK(0 == h.compare<>("0")); // cstr - llfio::path_view::c_str<> i(g, llfio::path_view::zero_terminated); + llfio::path_view::zero_terminated_rendered_path<> i(g); BOOST_CHECK(i.buffer != p2); - llfio::path_view::c_str<> j(g, llfio::path_view::not_zero_terminated); + llfio::path_view::not_zero_terminated_rendered_path<> j(g); BOOST_CHECK(j.buffer == p2); - llfio::path_view::c_str<> k(h, llfio::path_view::not_zero_terminated); + llfio::path_view::not_zero_terminated_rendered_path<> k(h); BOOST_CHECK(k.buffer == p2 + 70); CheckPathView(L"\\"); @@ -253,7 +253,7 @@ static inline void TestPathView() void operator()(char * /*unused*/) const { called++; } } deleter{5}; llfio::path_view v("foo", 3, llfio::path_view::not_zero_terminated); - llfio::path_view::c_str<char, custom_delete, 0> zbuff(v, llfio::path_view::zero_terminated, allocator, deleter); + llfio::path_view::zero_terminated_rendered_path<char, custom_delete, 0> zbuff(v, allocator, deleter); zbuff.reset(); BOOST_CHECK(allocator.called == 1); // copy must not be taken BOOST_CHECK(deleter.called == 0); // copy must be taken @@ -275,7 +275,7 @@ static inline void TestPathView() bool do_is_equal(const llfio::pmr::memory_resource & /*unused*/) const noexcept override { return false; } } resource; llfio::path_view v("foo", 3, llfio::path_view::not_zero_terminated); - llfio::path_view::c_str<char, std::default_delete<char[]>, 0> zbuff(v, llfio::path_view::zero_terminated, resource); + llfio::path_view::zero_terminated_rendered_path<char, std::default_delete<char[]>, 0> zbuff(v, resource); zbuff.reset(); BOOST_CHECK(resource.allocated == 1); BOOST_CHECK(resource.deleted == 1); @@ -297,7 +297,7 @@ static inline void TestPathView() void deallocate(void * /*unused*/, size_t /*unused*/) { deleted++; } } allocator{5}; llfio::path_view v("foo", 3, llfio::path_view::not_zero_terminated); - llfio::path_view::c_str<char, custom_allocator, 0> zbuff(v, llfio::path_view::zero_terminated, allocator); + llfio::path_view::zero_terminated_rendered_path<char, custom_allocator, 0> zbuff(v, allocator); zbuff.reset(); BOOST_CHECK(allocator.allocated == 0); // copy must be taken BOOST_CHECK(allocator.deleted == 0); // copy must be taken @@ -321,7 +321,7 @@ static inline void TestPathView() void deallocate(void * /*unused*/, size_t /*unused*/) { deleted++; } } allocator{5}; llfio::path_view v("foo", 3, llfio::path_view::not_zero_terminated); - llfio::path_view::c_str<char, custom_allocator, 0> zbuff(v, llfio::path_view::zero_terminated); + llfio::path_view::zero_terminated_rendered_path<char, custom_allocator, 0> zbuff(v); zbuff.reset(); BOOST_CHECK(allocator.allocated == 0); // copy must be taken BOOST_CHECK(allocator.deleted == 0); // copy must be taken |