mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-24 20:29:39 +08:00
Implement P0392r0. Integrate filesystem::path and string_view.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@276511 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -228,7 +228,7 @@
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <iomanip> // for quoted
|
||||
#include <experimental/string_view>
|
||||
#include <string_view>
|
||||
|
||||
#include <__debug>
|
||||
|
||||
@@ -498,6 +498,21 @@ struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class _ECharT, class _Traits>
|
||||
struct __is_pathable_string<basic_string_view<_ECharT, _Traits>,
|
||||
_Void<typename __can_convert_char<_ECharT>::__char_type>>
|
||||
: public __can_convert_char<_ECharT>
|
||||
{
|
||||
using _Str = basic_string_view<_ECharT, _Traits>;
|
||||
using _Base = __can_convert_char<_ECharT>;
|
||||
static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
|
||||
static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
|
||||
static _ECharT __first_or_null(_Str const& __s) {
|
||||
return __s.empty() ? _ECharT{} : __s[0];
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Source,
|
||||
class _DS = typename decay<_Source>::type,
|
||||
class _UnqualPtrType = typename remove_const<
|
||||
@@ -642,6 +657,7 @@ class _LIBCPP_TYPE_VIS path
|
||||
public:
|
||||
typedef char value_type;
|
||||
typedef basic_string<value_type> string_type;
|
||||
typedef _VSTD::string_view __string_view;
|
||||
static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
|
||||
|
||||
// constructors and destructor
|
||||
@@ -787,6 +803,12 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
path& operator+=(__string_view __x) {
|
||||
__pn_ += __x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
path& operator+=(const value_type* __x) {
|
||||
__pn_ += __x;
|
||||
@@ -799,7 +821,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class _ECharT>
|
||||
typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
|
||||
operator+=(_ECharT __x)
|
||||
@@ -896,30 +917,31 @@ public:
|
||||
std::u32string generic_u32string() const { return string<char32_t>(); }
|
||||
|
||||
private:
|
||||
_LIBCPP_FUNC_VIS int __compare(const value_type*) const;
|
||||
_LIBCPP_FUNC_VIS string_view __root_name() const;
|
||||
_LIBCPP_FUNC_VIS string_view __root_directory() const;
|
||||
_LIBCPP_FUNC_VIS string_view __relative_path() const;
|
||||
_LIBCPP_FUNC_VIS string_view __parent_path() const;
|
||||
_LIBCPP_FUNC_VIS string_view __filename() const;
|
||||
_LIBCPP_FUNC_VIS string_view __stem() const;
|
||||
_LIBCPP_FUNC_VIS string_view __extension() const;
|
||||
_LIBCPP_FUNC_VIS int __compare(__string_view) const;
|
||||
_LIBCPP_FUNC_VIS __string_view __root_name() const;
|
||||
_LIBCPP_FUNC_VIS __string_view __root_directory() const;
|
||||
_LIBCPP_FUNC_VIS __string_view __relative_path() const;
|
||||
_LIBCPP_FUNC_VIS __string_view __parent_path() const;
|
||||
_LIBCPP_FUNC_VIS __string_view __filename() const;
|
||||
_LIBCPP_FUNC_VIS __string_view __stem() const;
|
||||
_LIBCPP_FUNC_VIS __string_view __extension() const;
|
||||
|
||||
public:
|
||||
// compare
|
||||
_LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.c_str());}
|
||||
_LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s.c_str()); }
|
||||
_LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);}
|
||||
_LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); }
|
||||
_LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); }
|
||||
_LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); }
|
||||
|
||||
// decomposition
|
||||
_LIBCPP_INLINE_VISIBILITY path root_name() const { return __root_name().to_string(); }
|
||||
_LIBCPP_INLINE_VISIBILITY path root_directory() const { return __root_directory().to_string(); }
|
||||
_LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(__root_directory().to_string()); }
|
||||
_LIBCPP_INLINE_VISIBILITY path relative_path() const { return __relative_path().to_string(); }
|
||||
_LIBCPP_INLINE_VISIBILITY path parent_path() const { return __parent_path().to_string(); }
|
||||
_LIBCPP_INLINE_VISIBILITY path filename() const { return __filename().to_string(); }
|
||||
_LIBCPP_INLINE_VISIBILITY path stem() const { return __stem().to_string();}
|
||||
_LIBCPP_INLINE_VISIBILITY path extension() const { return __extension().to_string(); }
|
||||
_LIBCPP_INLINE_VISIBILITY path root_name() const { return string_type(__root_name()); }
|
||||
_LIBCPP_INLINE_VISIBILITY path root_directory() const { return string_type(__root_directory()); }
|
||||
_LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(string_type(__root_directory())); }
|
||||
_LIBCPP_INLINE_VISIBILITY path relative_path() const { return string_type(__relative_path()); }
|
||||
_LIBCPP_INLINE_VISIBILITY path parent_path() const { return string_type(__parent_path()); }
|
||||
_LIBCPP_INLINE_VISIBILITY path filename() const { return string_type(__filename()); }
|
||||
_LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem());}
|
||||
_LIBCPP_INLINE_VISIBILITY path extension() const { return string_type(__extension()); }
|
||||
|
||||
// query
|
||||
_LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT { return __pn_.empty(); }
|
||||
@@ -945,7 +967,7 @@ public:
|
||||
|
||||
private:
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path& __assign_view(string_view const& __s) noexcept { __pn_ = __s.to_string(); return *this; }
|
||||
path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; }
|
||||
string_type __pn_;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,20 +7,21 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "experimental/filesystem"
|
||||
#include "experimental/string_view"
|
||||
#include "string_view"
|
||||
#include "utility"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
|
||||
|
||||
_LIBCPP_CONSTEXPR path::value_type path::preferred_separator;
|
||||
|
||||
|
||||
using string_view_t = path::__string_view;
|
||||
|
||||
namespace { namespace parser
|
||||
{
|
||||
|
||||
using string_type = string_view;
|
||||
using value_type = path::value_type;
|
||||
|
||||
using string_view_pair = pair<string_view, string_view>;
|
||||
using string_view_pair = pair<string_view_t, string_view_t>;
|
||||
|
||||
// status reporting
|
||||
constexpr size_t npos = static_cast<size_t>(-1);
|
||||
@@ -33,43 +34,43 @@ constexpr value_type const * preferred_separator_str = "/";
|
||||
constexpr value_type const * dot = ".";
|
||||
|
||||
// forward //
|
||||
bool is_separator(string_type const &, size_t);
|
||||
bool is_root_name(const string_type&, size_t);
|
||||
bool is_root_directory(string_type const &, size_t);
|
||||
bool is_trailing_separator(string_type const &, size_t);
|
||||
bool is_separator(string_view_t const &, size_t);
|
||||
bool is_root_name(const string_view_t&, size_t);
|
||||
bool is_root_directory(string_view_t const &, size_t);
|
||||
bool is_trailing_separator(string_view_t const &, size_t);
|
||||
|
||||
size_t start_of(string_type const &, size_t);
|
||||
size_t end_of(string_type const &, size_t);
|
||||
size_t start_of(string_view_t const &, size_t);
|
||||
size_t end_of(string_view_t const &, size_t);
|
||||
|
||||
size_t root_name_start(const string_type& s);
|
||||
size_t root_name_end(const string_type&);
|
||||
size_t root_name_start(const string_view_t& s);
|
||||
size_t root_name_end(const string_view_t&);
|
||||
|
||||
size_t root_directory_start(string_type const &);
|
||||
size_t root_directory_end(string_type const &);
|
||||
size_t root_directory_start(string_view_t const &);
|
||||
size_t root_directory_end(string_view_t const &);
|
||||
|
||||
string_view_pair separate_filename(string_type const &);
|
||||
string_view extract_raw(string_type const &, size_t);
|
||||
string_view extract_preferred(string_type const &, size_t);
|
||||
string_view_pair separate_filename(string_view_t const &);
|
||||
string_view extract_raw(string_view_t const &, size_t);
|
||||
string_view extract_preferred(string_view_t const &, size_t);
|
||||
|
||||
inline bool is_separator(const string_type& s, size_t pos) {
|
||||
inline bool is_separator(const string_view_t& s, size_t pos) {
|
||||
return (pos < s.size() && s[pos] == preferred_separator);
|
||||
}
|
||||
|
||||
inline bool is_root_name(const string_type& s, size_t pos) {
|
||||
inline bool is_root_name(const string_view_t& s, size_t pos) {
|
||||
return good(pos) && pos == 0 ? root_name_start(s) == pos : false;
|
||||
}
|
||||
|
||||
inline bool is_root_directory(const string_type& s, size_t pos) {
|
||||
inline bool is_root_directory(const string_view_t& s, size_t pos) {
|
||||
return good(pos) ? root_directory_start(s) == pos : false;
|
||||
}
|
||||
|
||||
inline bool is_trailing_separator(const string_type& s, size_t pos) {
|
||||
inline bool is_trailing_separator(const string_view_t& s, size_t pos) {
|
||||
return (pos < s.size() && is_separator(s, pos) &&
|
||||
end_of(s, pos) == s.size()-1 &&
|
||||
!is_root_directory(s, pos) && !is_root_name(s, pos));
|
||||
}
|
||||
|
||||
size_t start_of(const string_type& s, size_t pos) {
|
||||
size_t start_of(const string_view_t& s, size_t pos) {
|
||||
if (pos >= s.size()) return npos;
|
||||
bool in_sep = (s[pos] == preferred_separator);
|
||||
while (pos - 1 < s.size() &&
|
||||
@@ -81,7 +82,7 @@ size_t start_of(const string_type& s, size_t pos) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t end_of(const string_type& s, size_t pos) {
|
||||
size_t end_of(const string_view_t& s, size_t pos) {
|
||||
if (pos >= s.size()) return npos;
|
||||
// special case for root name
|
||||
if (pos == 0 && is_root_name(s, pos)) return root_name_end(s);
|
||||
@@ -91,11 +92,11 @@ size_t end_of(const string_type& s, size_t pos) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
inline size_t root_name_start(const string_type& s) {
|
||||
inline size_t root_name_start(const string_view_t& s) {
|
||||
return good(root_name_end(s)) ? 0 : npos;
|
||||
}
|
||||
|
||||
size_t root_name_end(const string_type& s) {
|
||||
size_t root_name_end(const string_view_t& s) {
|
||||
if (s.size() < 2 || s[0] != preferred_separator
|
||||
|| s[1] != preferred_separator) {
|
||||
return npos;
|
||||
@@ -113,14 +114,14 @@ size_t root_name_end(const string_type& s) {
|
||||
return index;
|
||||
}
|
||||
|
||||
size_t root_directory_start(const string_type& s) {
|
||||
size_t root_directory_start(const string_view_t& s) {
|
||||
size_t e = root_name_end(s);
|
||||
if (!good(e))
|
||||
return is_separator(s, 0) ? 0 : npos;
|
||||
return is_separator(s, e + 1) ? e + 1 : npos;
|
||||
}
|
||||
|
||||
size_t root_directory_end(const string_type& s) {
|
||||
size_t root_directory_end(const string_view_t& s) {
|
||||
size_t st = root_directory_start(s);
|
||||
if (!good(st)) return npos;
|
||||
size_t index = st;
|
||||
@@ -129,20 +130,20 @@ size_t root_directory_end(const string_type& s) {
|
||||
return index;
|
||||
}
|
||||
|
||||
string_view_pair separate_filename(string_type const & s) {
|
||||
string_view_pair separate_filename(string_view_t const & s) {
|
||||
if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""};
|
||||
auto pos = s.find_last_of('.');
|
||||
if (pos == string_type::npos) return string_view_pair{s, string_view{}};
|
||||
if (pos == string_view_t::npos) return string_view_pair{s, string_view{}};
|
||||
return string_view_pair{s.substr(0, pos), s.substr(pos)};
|
||||
}
|
||||
|
||||
inline string_view extract_raw(const string_type& s, size_t pos) {
|
||||
inline string_view extract_raw(const string_view_t& s, size_t pos) {
|
||||
size_t end_i = end_of(s, pos);
|
||||
if (!good(end_i)) return string_view{};
|
||||
return string_view(s).substr(pos, end_i - pos + 1);
|
||||
}
|
||||
|
||||
string_view extract_preferred(const string_type& s, size_t pos) {
|
||||
string_view extract_preferred(const string_view_t& s, size_t pos) {
|
||||
string_view raw = extract_raw(s, pos);
|
||||
if (raw.empty())
|
||||
return raw;
|
||||
@@ -260,14 +261,14 @@ path & path::replace_extension(path const & replacement)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// path.decompose
|
||||
|
||||
string_view path::__root_name() const
|
||||
string_view_t path::__root_name() const
|
||||
{
|
||||
return parser::is_root_name(__pn_, 0)
|
||||
? parser::extract_preferred(__pn_, 0)
|
||||
: string_view{};
|
||||
: string_view_t{};
|
||||
}
|
||||
|
||||
string_view path::__root_directory() const
|
||||
string_view_t path::__root_directory() const
|
||||
{
|
||||
auto start_i = parser::root_directory_start(__pn_);
|
||||
if(!parser::good(start_i)) {
|
||||
@@ -276,49 +277,49 @@ string_view path::__root_directory() const
|
||||
return parser::extract_preferred(__pn_, start_i);
|
||||
}
|
||||
|
||||
string_view path::__relative_path() const
|
||||
string_view_t path::__relative_path() const
|
||||
{
|
||||
if (empty()) {
|
||||
return {__pn_};
|
||||
return __pn_;
|
||||
}
|
||||
auto end_i = parser::root_directory_end(__pn_);
|
||||
if (not parser::good(end_i)) {
|
||||
end_i = parser::root_name_end(__pn_);
|
||||
}
|
||||
if (not parser::good(end_i)) {
|
||||
return {__pn_};
|
||||
return __pn_;
|
||||
}
|
||||
return string_view(__pn_).substr(end_i+1);
|
||||
return string_view_t(__pn_).substr(end_i+1);
|
||||
}
|
||||
|
||||
string_view path::__parent_path() const
|
||||
string_view_t path::__parent_path() const
|
||||
{
|
||||
if (empty() || pbegin(*this) == --pend(*this)) {
|
||||
return {};
|
||||
}
|
||||
auto end_it = --(--pend(*this));
|
||||
auto end_i = parser::end_of(__pn_, end_it.__pos_);
|
||||
return string_view(__pn_).substr(0, end_i+1);
|
||||
return string_view_t(__pn_).substr(0, end_i+1);
|
||||
}
|
||||
|
||||
string_view path::__filename() const
|
||||
string_view_t path::__filename() const
|
||||
{
|
||||
return empty() ? string_view{} : *--pend(*this);
|
||||
return empty() ? string_view_t{} : *--pend(*this);
|
||||
}
|
||||
|
||||
string_view path::__stem() const
|
||||
string_view_t path::__stem() const
|
||||
{
|
||||
return parser::separate_filename(__filename()).first;
|
||||
}
|
||||
|
||||
string_view path::__extension() const
|
||||
string_view_t path::__extension() const
|
||||
{
|
||||
return parser::separate_filename(__filename()).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.comparisons
|
||||
int path::__compare(const value_type* __s) const {
|
||||
int path::__compare(string_view_t __s) const {
|
||||
path_view_iterator thisIter(this->native());
|
||||
path_view_iterator sIter(__s);
|
||||
while (!thisIter.is_end() && !sIter.is_end()) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "min_allocator.h"
|
||||
#include "constexpr_char_traits.hpp"
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
@@ -59,6 +60,8 @@ struct MakeTestType {
|
||||
using value_type = CharT;
|
||||
using string_type = std::basic_string<CharT>;
|
||||
using string_type2 = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>;
|
||||
using string_view_type = std::basic_string_view<CharT>;
|
||||
using string_view_type2 = std::basic_string_view<CharT, constexpr_char_traits<CharT>>;
|
||||
using cstr_type = CharT* const;
|
||||
using const_cstr_type = const CharT*;
|
||||
using array_type = CharT[25];
|
||||
@@ -81,6 +84,8 @@ struct MakeTestType {
|
||||
static void Test() {
|
||||
AssertPathable<string_type>();
|
||||
AssertPathable<string_type2>();
|
||||
AssertPathable<string_view_type>();
|
||||
AssertPathable<string_view_type2>();
|
||||
AssertPathable<cstr_type>();
|
||||
AssertPathable<const_cstr_type>();
|
||||
AssertPathable<array_type>();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <type_traits>
|
||||
#include <string_view>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
@@ -77,6 +78,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
|
||||
using namespace fs;
|
||||
using Ptr = CharT const*;
|
||||
using Str = std::basic_string<CharT>;
|
||||
using StrView = std::basic_string_view<CharT>;
|
||||
using InputIter = input_iterator<Ptr>;
|
||||
|
||||
const Ptr L = TC.lhs;
|
||||
@@ -99,6 +101,16 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
|
||||
}
|
||||
assert(LHS == E);
|
||||
}
|
||||
// basic_string_view
|
||||
{
|
||||
path LHS(L); PathReserve(LHS, ReserveSize);
|
||||
StrView RHS(R);
|
||||
{
|
||||
DisableAllocationGuard g;
|
||||
LHS /= RHS;
|
||||
}
|
||||
assert(LHS == E);
|
||||
}
|
||||
// CharT*
|
||||
{
|
||||
path LHS(L); PathReserve(LHS, ReserveSize);
|
||||
@@ -153,6 +165,7 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC)
|
||||
using namespace fs;
|
||||
using Ptr = CharT const*;
|
||||
using Str = std::basic_string<CharT>;
|
||||
using StrView = std::basic_string_view<CharT>;
|
||||
using InputIter = input_iterator<Ptr>;
|
||||
const Ptr L = TC.lhs;
|
||||
const Ptr R = TC.rhs;
|
||||
@@ -172,6 +185,21 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC)
|
||||
assert(LHS == E);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
// basic_string_view
|
||||
{
|
||||
path LHS(L);
|
||||
StrView RHS(R);
|
||||
path& Ref = (LHS /= RHS);
|
||||
assert(LHS == E);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
{
|
||||
path LHS(L);
|
||||
StrView RHS(R);
|
||||
path& Ref = LHS.append(RHS);
|
||||
assert(LHS == E);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
// Char*
|
||||
{
|
||||
path LHS(L);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <type_traits>
|
||||
#include <string_view>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
@@ -69,6 +70,32 @@ void RunTestCase(MultiStringType const& MS) {
|
||||
assert(p.string<CharT>() == TestPath);
|
||||
assert(p.string<CharT>() == S);
|
||||
}
|
||||
// basic_string<Char, Traits, Alloc>
|
||||
{
|
||||
const std::basic_string_view<CharT> S(TestPath);
|
||||
path p; PathReserve(p, S.length() + 1);
|
||||
{
|
||||
// string provides a contigious iterator. No allocation needed.
|
||||
DisableAllocationGuard g;
|
||||
path& pref = (p = S);
|
||||
assert(&pref == &p);
|
||||
}
|
||||
assert(p.native() == Expect);
|
||||
assert(p.string<CharT>() == TestPath);
|
||||
assert(p.string<CharT>() == S);
|
||||
}
|
||||
{
|
||||
const std::basic_string_view<CharT> S(TestPath);
|
||||
path p; PathReserve(p, S.length() + 1);
|
||||
{
|
||||
DisableAllocationGuard g;
|
||||
path& pref = p.assign(S);
|
||||
assert(&pref == &p);
|
||||
}
|
||||
assert(p.native() == Expect);
|
||||
assert(p.string<CharT>() == TestPath);
|
||||
assert(p.string<CharT>() == S);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Char* pointers
|
||||
{
|
||||
|
||||
@@ -80,6 +80,7 @@ int main()
|
||||
const path p1(TC.LHS);
|
||||
const path p2(TC.RHS);
|
||||
const std::string R(TC.RHS);
|
||||
const std::string_view RV(TC.RHS);
|
||||
const int E = TC.expect;
|
||||
{ // compare(...) functions
|
||||
DisableAllocationGuard g; // none of these operations should allocate
|
||||
@@ -88,7 +89,8 @@ int main()
|
||||
int ret1 = p1.compare(p2);
|
||||
int ret2 = p1.compare(R);
|
||||
int ret3 = p1.compare(TC.RHS);
|
||||
assert(ret1 == ret2 && ret1 == ret3);
|
||||
int ret4 = p1.compare(RV);
|
||||
assert(ret1 == ret2 && ret1 == ret3 && ret1 == ret4);
|
||||
int normalized_ret = ret1 < 0 ? -1 : (ret1 > 0 ? 1 : 0);
|
||||
assert(normalized_ret == E);
|
||||
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
// class path
|
||||
|
||||
// path& operator+=(const path& x);
|
||||
// path& operator+=(const string_type& x); // Implemented as Source template
|
||||
// path& operator+=(const value_type* x); // Implemented as Source template
|
||||
// path& operator+=(const string_type& x);
|
||||
// path& operator+=(string_view x);
|
||||
// path& operator+=(const value_type* x);
|
||||
// path& operator+=(value_type x);
|
||||
// template <class Source>
|
||||
// path& operator+=(const Source& x);
|
||||
@@ -29,6 +30,8 @@
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
@@ -82,6 +85,7 @@ void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC)
|
||||
using namespace fs;
|
||||
using Ptr = CharT const*;
|
||||
using Str = std::basic_string<CharT>;
|
||||
using StrView = std::basic_string_view<CharT>;
|
||||
using InputIter = input_iterator<Ptr>;
|
||||
|
||||
const Ptr L = TC.lhs;
|
||||
@@ -98,6 +102,16 @@ void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC)
|
||||
}
|
||||
assert(LHS == E);
|
||||
}
|
||||
// basic_string_view
|
||||
{
|
||||
path LHS(L); PathReserve(LHS, ReserveSize);
|
||||
StrView RHS(R);
|
||||
{
|
||||
DisableAllocationGuard g;
|
||||
LHS += RHS;
|
||||
}
|
||||
assert(LHS == E);
|
||||
}
|
||||
// CharT*
|
||||
{
|
||||
path LHS(L); PathReserve(LHS, ReserveSize);
|
||||
@@ -152,6 +166,7 @@ void doConcatSourceTest(ConcatOperatorTestcase const& TC)
|
||||
using namespace fs;
|
||||
using Ptr = CharT const*;
|
||||
using Str = std::basic_string<CharT>;
|
||||
using StrView = std::basic_string_view<CharT>;
|
||||
using InputIter = input_iterator<Ptr>;
|
||||
const Ptr L = TC.lhs;
|
||||
const Ptr R = TC.rhs;
|
||||
@@ -171,6 +186,21 @@ void doConcatSourceTest(ConcatOperatorTestcase const& TC)
|
||||
assert(LHS == E);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
// basic_string_view
|
||||
{
|
||||
path LHS(L);
|
||||
StrView RHS(R);
|
||||
path& Ref = (LHS += RHS);
|
||||
assert(LHS == E);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
{
|
||||
path LHS(L);
|
||||
StrView RHS(R);
|
||||
path& Ref = LHS.concat(RHS);
|
||||
assert(LHS == E);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
// Char*
|
||||
{
|
||||
path LHS(L);
|
||||
@@ -246,6 +276,13 @@ int main()
|
||||
assert(LHS == (const char*)TC.expect);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
{
|
||||
path LHS((const char*)TC.lhs);
|
||||
std::string_view RHS((const char*)TC.rhs);
|
||||
path& Ref = (LHS += RHS);
|
||||
assert(LHS == (const char*)TC.expect);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
doConcatSourceTest<char> (TC);
|
||||
doConcatSourceTest<wchar_t> (TC);
|
||||
doConcatSourceTest<char16_t>(TC);
|
||||
@@ -265,6 +302,18 @@ int main()
|
||||
}
|
||||
assert(LHS == E);
|
||||
}
|
||||
{
|
||||
path LHS((const char*)TC.lhs);
|
||||
std::string_view RHS((const char*)TC.rhs);
|
||||
const char* E = TC.expect;
|
||||
PathReserve(LHS, StrLen(E) + 5);
|
||||
{
|
||||
DisableAllocationGuard g;
|
||||
path& Ref = (LHS += RHS);
|
||||
assert(&Ref == &LHS);
|
||||
}
|
||||
assert(LHS == E);
|
||||
}
|
||||
doConcatSourceAllocTest<char>(TC);
|
||||
doConcatSourceAllocTest<wchar_t>(TC);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,13 @@ void RunTestCase(MultiStringType const& MS) {
|
||||
assert(p.string<CharT>() == TestPath);
|
||||
assert(p.string<CharT>() == S);
|
||||
}
|
||||
{
|
||||
const std::basic_string_view<CharT> S(TestPath);
|
||||
path p(S);
|
||||
assert(p.native() == Expect);
|
||||
assert(p.string<CharT>() == TestPath);
|
||||
assert(p.string<CharT>() == S);
|
||||
}
|
||||
// Char* pointers
|
||||
{
|
||||
path p(TestPath);
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<tr><td><a href="http://wg21.link/p0346r1">p0346r1</a></td><td>LWG</td><td>A <random> Nomenclature Tweak</td><td>Oulu</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/p0358r1">p0358r1</a></td><td>LWG</td><td>Fixes for not_fn</td><td>Oulu</td><td>Complete</td><td>3.9</td></tr>
|
||||
<tr><td><a href="http://wg21.link/p0371r1">p0371r1</a></td><td>LWG</td><td>Temporarily discourage memory_order_consume</td><td>Oulu</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/p0392r0">p0392r0</a></td><td>LWG</td><td>Adapting string_view by filesystem paths</td><td>Oulu</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/p0392r0">p0392r0</a></td><td>LWG</td><td>Adapting string_view by filesystem paths</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
|
||||
<tr><td><a href="http://wg21.link/p0393r3">p0393r3</a></td><td>LWG</td><td>Making Variant Greater Equal</td><td>Oulu</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0394r4">P0394r4</a></td><td>LWG</td><td>Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling</td><td>Oulu</td><td></td><td></td></tr>
|
||||
<!-- <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> -->
|
||||
|
||||
Reference in New Issue
Block a user