mirror of git://gcc.gnu.org/git/gcc.git
Refactor path construction from null terminated iterator ranges
Move duplicated code to new _S_string_from_iter function and fix constraints to accept iterators with const value type. * include/bits/fs_path.h (path::__is_encoded_char): Change from class template to alias template. (path::__value_type_is_char): Use remove_const_t. (path:_S_string_from_iter): New helper function. (path::_S_convert(InputIter, __null_terminated)) (path::_S_convert_loc(InputIter, __null_terminated, const locale&)): Use _S_string_from_iter. (path::string<_CharT, _Allocator>(const _Allocator&)): Allow sharing rep for COW strings. * include/experimental/bits/fs_path.h (path::__is_encoded_char): Change from class template to alias template. (path::__value_type_is_char): Use remove_const. (path:_S_string_from_iter): New helper function. (path::_S_convert(InputIter, __null_terminated)) (path::_S_convert_loc(InputIter, __null_terminated, const locale&)): Use _S_string_from_iter. * testsuite/27_io/filesystem/path/append/source.cc: Test appending wide strings. * testsuite/27_io/filesystem/path/concat/strings.cc: Check for exact string equality, not path equivalence. * testsuite/27_io/filesystem/path/construct/format.cc: Check construction from std::string and std::wstring and input iterators. * testsuite/27_io/filesystem/path/construct/locale.cc: Check construction from iterators. * testsuite/experimental/filesystem/path/concat/strings.cc: Check for exact string equality, not path equivalence. * testsuite/experimental/filesystem/path/construct/locale.cc: Check construction from iterators. From-SVN: r260628
This commit is contained in:
parent
2aece9c199
commit
49d729eaee
|
|
@ -1,5 +1,34 @@
|
||||||
2018-05-23 Jonathan Wakely <jwakely@redhat.com>
|
2018-05-23 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* include/bits/fs_path.h (path::__is_encoded_char): Change from class
|
||||||
|
template to alias template.
|
||||||
|
(path::__value_type_is_char): Use remove_const_t.
|
||||||
|
(path:_S_string_from_iter): New helper function.
|
||||||
|
(path::_S_convert(InputIter, __null_terminated))
|
||||||
|
(path::_S_convert_loc(InputIter, __null_terminated, const locale&)):
|
||||||
|
Use _S_string_from_iter.
|
||||||
|
(path::string<_CharT, _Allocator>(const _Allocator&)): Allow sharing
|
||||||
|
rep for COW strings.
|
||||||
|
* include/experimental/bits/fs_path.h (path::__is_encoded_char):
|
||||||
|
Change from class template to alias template.
|
||||||
|
(path::__value_type_is_char): Use remove_const.
|
||||||
|
(path:_S_string_from_iter): New helper function.
|
||||||
|
(path::_S_convert(InputIter, __null_terminated))
|
||||||
|
(path::_S_convert_loc(InputIter, __null_terminated, const locale&)):
|
||||||
|
Use _S_string_from_iter.
|
||||||
|
* testsuite/27_io/filesystem/path/append/source.cc: Test appending
|
||||||
|
wide strings.
|
||||||
|
* testsuite/27_io/filesystem/path/concat/strings.cc: Check for exact
|
||||||
|
string equality, not path equivalence.
|
||||||
|
* testsuite/27_io/filesystem/path/construct/format.cc: Check
|
||||||
|
construction from std::string and std::wstring and input iterators.
|
||||||
|
* testsuite/27_io/filesystem/path/construct/locale.cc: Check
|
||||||
|
construction from iterators.
|
||||||
|
* testsuite/experimental/filesystem/path/concat/strings.cc: Check for
|
||||||
|
exact string equality, not path equivalence.
|
||||||
|
* testsuite/experimental/filesystem/path/construct/locale.cc: Check
|
||||||
|
construction from iterators.
|
||||||
|
|
||||||
* include/bits/fs_path.h (path::_M_type): Change default member
|
* include/bits/fs_path.h (path::_M_type): Change default member
|
||||||
initializer to _Filename.
|
initializer to _Filename.
|
||||||
(path::begin): Create past-the-end iterator for empty path.
|
(path::begin): Create past-the-end iterator for empty path.
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
/// A filesystem path.
|
/// A filesystem path.
|
||||||
class path
|
class path
|
||||||
{
|
{
|
||||||
template<typename _CharT>
|
template<typename _CharT, typename _Ch = remove_const_t<_CharT>>
|
||||||
struct __is_encoded_char : std::false_type { };
|
using __is_encoded_char
|
||||||
|
= __or_<is_same<_Ch, char>, is_same<_Ch, wchar_t>,
|
||||||
|
is_same<_Ch, char16_t>, is_same<_Ch, char32_t>>;
|
||||||
|
|
||||||
template<typename _Iter,
|
template<typename _Iter,
|
||||||
typename _Iter_traits = std::iterator_traits<_Iter>>
|
typename _Iter_traits = std::iterator_traits<_Iter>>
|
||||||
|
|
@ -144,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
|
typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
|
||||||
typename _Val = typename std::iterator_traits<_Iter>::value_type>
|
typename _Val = typename std::iterator_traits<_Iter>::value_type>
|
||||||
using __value_type_is_char
|
using __value_type_is_char
|
||||||
= typename std::enable_if<std::is_same<_Val, char>::value>::type;
|
= std::enable_if_t<std::is_same_v<std::remove_const_t<_Val>, char>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
||||||
|
|
@ -391,6 +393,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
iterator begin() const;
|
iterator begin() const;
|
||||||
iterator end() const;
|
iterator end() const;
|
||||||
|
|
||||||
|
// Create a basic_string by reading until a null character.
|
||||||
|
template<typename _InputIterator,
|
||||||
|
typename _Traits = std::iterator_traits<_InputIterator>,
|
||||||
|
typename _CharT
|
||||||
|
= typename std::remove_cv_t<typename _Traits::value_type>>
|
||||||
|
static std::basic_string<_CharT>
|
||||||
|
_S_string_from_iter(_InputIterator __source)
|
||||||
|
{
|
||||||
|
std::basic_string<_CharT> __str;
|
||||||
|
for (_CharT __ch = *__source; __ch != _CharT(); __ch = *++__source)
|
||||||
|
__str.push_back(__ch);
|
||||||
|
return __str;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class _Type : unsigned char {
|
enum class _Type : unsigned char {
|
||||||
_Multi, _Root_name, _Root_dir, _Filename
|
_Multi, _Root_name, _Root_dir, _Filename
|
||||||
|
|
@ -443,11 +459,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
static string_type
|
static string_type
|
||||||
_S_convert(_InputIterator __src, __null_terminated)
|
_S_convert(_InputIterator __src, __null_terminated)
|
||||||
{
|
{
|
||||||
using _Tp = typename std::iterator_traits<_InputIterator>::value_type;
|
auto __s = _S_string_from_iter(__src);
|
||||||
std::basic_string<typename remove_cv<_Tp>::type> __tmp;
|
return _S_convert(__s.c_str(), __s.c_str() + __s.size());
|
||||||
for (; *__src != _Tp{}; ++__src)
|
|
||||||
__tmp.push_back(*__src);
|
|
||||||
return _S_convert(__tmp.c_str(), __tmp.c_str() + __tmp.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static string_type
|
static string_type
|
||||||
|
|
@ -467,10 +480,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
_S_convert_loc(_InputIterator __src, __null_terminated,
|
_S_convert_loc(_InputIterator __src, __null_terminated,
|
||||||
const std::locale& __loc)
|
const std::locale& __loc)
|
||||||
{
|
{
|
||||||
std::string __tmp;
|
std::string __s = _S_string_from_iter(__src);
|
||||||
while (*__src != '\0')
|
return _S_convert_loc(__s.data(), __s.data() + __s.size(), __loc);
|
||||||
__tmp.push_back(*__src++);
|
|
||||||
return _S_convert_loc(__tmp.data(), __tmp.data()+__tmp.size(), __loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _CharT, typename _Traits, typename _Allocator>
|
template<typename _CharT, typename _Traits, typename _Allocator>
|
||||||
|
|
@ -500,25 +511,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
_Type _M_type = _Type::_Filename;
|
_Type _M_type = _Type::_Filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<char> : std::true_type
|
|
||||||
{ using value_type = char; };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<wchar_t> : std::true_type
|
|
||||||
{ using value_type = wchar_t; };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<char16_t> : std::true_type
|
|
||||||
{ using value_type = char16_t; };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<char32_t> : std::true_type
|
|
||||||
{ using value_type = char32_t; };
|
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
struct path::__is_encoded_char<const _Tp> : __is_encoded_char<_Tp> { };
|
|
||||||
|
|
||||||
inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); }
|
inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); }
|
||||||
|
|
||||||
size_t hash_value(const path& __p) noexcept;
|
size_t hash_value(const path& __p) noexcept;
|
||||||
|
|
@ -915,11 +907,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
path::string(const _Allocator& __a) const
|
path::string(const _Allocator& __a) const
|
||||||
{
|
{
|
||||||
if constexpr (is_same_v<_CharT, value_type>)
|
if constexpr (is_same_v<_CharT, value_type>)
|
||||||
|
{
|
||||||
#if _GLIBCXX_USE_CXX11_ABI
|
#if _GLIBCXX_USE_CXX11_ABI
|
||||||
return { _M_pathname, __a };
|
return { _M_pathname, __a };
|
||||||
#else
|
#else
|
||||||
|
if constexpr (is_same_v<_Allocator, string_type::allocator_type>)
|
||||||
|
return _M_pathname;
|
||||||
|
else
|
||||||
return { _M_pathname, string_type::size_type(0), __a };
|
return { _M_pathname, string_type::size_type(0), __a };
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return _S_str_convert<_CharT, _Traits>(_M_pathname, __a);
|
return _S_str_convert<_CharT, _Traits>(_M_pathname, __a);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
/// A filesystem path.
|
/// A filesystem path.
|
||||||
class path
|
class path
|
||||||
{
|
{
|
||||||
template<typename _CharT>
|
template<typename _CharT,
|
||||||
struct __is_encoded_char : std::false_type { };
|
typename _Ch = typename remove_const<_CharT>::type>
|
||||||
|
using __is_encoded_char
|
||||||
|
= __or_<is_same<_Ch, char>, is_same<_Ch, wchar_t>,
|
||||||
|
is_same<_Ch, char16_t>, is_same<_Ch, char32_t>>;
|
||||||
|
|
||||||
template<typename _Iter,
|
template<typename _Iter,
|
||||||
typename _Iter_traits = std::iterator_traits<_Iter>>
|
typename _Iter_traits = std::iterator_traits<_Iter>>
|
||||||
|
|
@ -161,8 +164,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
template<typename _Tp,
|
template<typename _Tp,
|
||||||
typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
|
typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
|
||||||
typename _Val = typename std::iterator_traits<_Iter>::value_type>
|
typename _Val = typename std::iterator_traits<_Iter>::value_type>
|
||||||
using __value_type_is_char
|
using __value_type_is_char = typename std::enable_if<
|
||||||
= typename std::enable_if<std::is_same<_Val, char>::value>::type;
|
std::is_same<typename std::remove_const<_Val>::type, char>::value
|
||||||
|
>::type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
||||||
|
|
@ -378,6 +382,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
iterator begin() const;
|
iterator begin() const;
|
||||||
iterator end() const;
|
iterator end() const;
|
||||||
|
|
||||||
|
// Create a basic_string by reading until a null character.
|
||||||
|
template<typename _InputIterator,
|
||||||
|
typename _Traits = std::iterator_traits<_InputIterator>,
|
||||||
|
typename _CharT
|
||||||
|
= typename std::remove_cv<typename _Traits::value_type>::type>
|
||||||
|
static std::basic_string<_CharT>
|
||||||
|
_S_string_from_iter(_InputIterator __source)
|
||||||
|
{
|
||||||
|
std::basic_string<_CharT> __str;
|
||||||
|
for (_CharT __ch = *__source; __ch != _CharT(); __ch = *++__source)
|
||||||
|
__str.push_back(__ch);
|
||||||
|
return __str;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class _Type : unsigned char {
|
enum class _Type : unsigned char {
|
||||||
_Multi, _Root_name, _Root_dir, _Filename
|
_Multi, _Root_name, _Root_dir, _Filename
|
||||||
|
|
@ -427,11 +445,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
static string_type
|
static string_type
|
||||||
_S_convert(_InputIterator __src, __null_terminated)
|
_S_convert(_InputIterator __src, __null_terminated)
|
||||||
{
|
{
|
||||||
using _Tp = typename std::iterator_traits<_InputIterator>::value_type;
|
auto __s = _S_string_from_iter(__src);
|
||||||
std::basic_string<typename remove_cv<_Tp>::type> __tmp;
|
return _S_convert(__s.c_str(), __s.c_str() + __s.size());
|
||||||
for (; *__src != _Tp{}; ++__src)
|
|
||||||
__tmp.push_back(*__src);
|
|
||||||
return _S_convert(__tmp.c_str(), __tmp.c_str() + __tmp.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static string_type
|
static string_type
|
||||||
|
|
@ -451,10 +466,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
_S_convert_loc(_InputIterator __src, __null_terminated,
|
_S_convert_loc(_InputIterator __src, __null_terminated,
|
||||||
const std::locale& __loc)
|
const std::locale& __loc)
|
||||||
{
|
{
|
||||||
std::string __tmp;
|
std::string __s = _S_string_from_iter(__src);
|
||||||
while (*__src != '\0')
|
return _S_convert_loc(__s.data(), __s.data() + __s.size(), __loc);
|
||||||
__tmp.push_back(*__src++);
|
|
||||||
return _S_convert_loc(__tmp.data(), __tmp.data()+__tmp.size(), __loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _S_is_dir_sep(value_type __ch)
|
bool _S_is_dir_sep(value_type __ch)
|
||||||
|
|
@ -594,25 +607,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||||
std::string _M_what = _M_gen_what();
|
std::string _M_what = _M_gen_what();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<char> : std::true_type
|
|
||||||
{ using value_type = char; };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<wchar_t> : std::true_type
|
|
||||||
{ using value_type = wchar_t; };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<char16_t> : std::true_type
|
|
||||||
{ using value_type = char16_t; };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct path::__is_encoded_char<char32_t> : std::true_type
|
|
||||||
{ using value_type = char32_t; };
|
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
struct path::__is_encoded_char<const _Tp> : __is_encoded_char<_Tp> { };
|
|
||||||
|
|
||||||
struct path::_Cmpt : path
|
struct path::_Cmpt : path
|
||||||
{
|
{
|
||||||
_Cmpt(string_type __s, _Type __t, size_t __pos)
|
_Cmpt(string_type __s, _Type __t, size_t __pos)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ using __gnu_test::compare_paths;
|
||||||
// path::append(InputIterator first, InputIterator last)
|
// path::append(InputIterator first, InputIterator last)
|
||||||
// Equivalent to: return operator/=(path(first, last));
|
// Equivalent to: return operator/=(path(first, last));
|
||||||
|
|
||||||
void test(const path& p, std::string_view s)
|
template<typename Char>
|
||||||
|
void test(const path& p, const Char* s)
|
||||||
{
|
{
|
||||||
path expected = p;
|
path expected = p;
|
||||||
expected /= path(s);
|
expected /= path(s);
|
||||||
|
|
@ -47,8 +48,8 @@ void test(const path& p, std::string_view s)
|
||||||
path func = p;
|
path func = p;
|
||||||
func.append(s);
|
func.append(s);
|
||||||
|
|
||||||
__gnu_test::test_container<const char, __gnu_test::input_iterator_wrapper>
|
__gnu_test::test_container<const Char, __gnu_test::input_iterator_wrapper>
|
||||||
input_range(s.begin(), s.end());
|
input_range(s, s + std::char_traits<Char>::length(s));
|
||||||
path range = p;
|
path range = p;
|
||||||
range.append(input_range.begin(), input_range.end());
|
range.append(input_range.begin(), input_range.end());
|
||||||
|
|
||||||
|
|
@ -94,7 +95,21 @@ test03()
|
||||||
{
|
{
|
||||||
for (const path& p : __gnu_test::test_paths)
|
for (const path& p : __gnu_test::test_paths)
|
||||||
for (const path& q : __gnu_test::test_paths)
|
for (const path& q : __gnu_test::test_paths)
|
||||||
test(p, q.native());
|
{
|
||||||
|
test(p, q.c_str());
|
||||||
|
if constexpr (!std::is_same_v<path::value_type, char>)
|
||||||
|
test(p, q.string().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test04()
|
||||||
|
{
|
||||||
|
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||||
|
test( "foo", L"/bar" );
|
||||||
|
test( L"foo", "/bar" );
|
||||||
|
test( L"foo", L"/bar" );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -103,4 +118,5 @@ main()
|
||||||
test01();
|
test01();
|
||||||
test02();
|
test02();
|
||||||
test03();
|
test03();
|
||||||
|
test04();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_iterators.h>
|
||||||
|
|
||||||
using std::filesystem::path;
|
using std::filesystem::path;
|
||||||
|
|
||||||
|
|
@ -30,23 +31,30 @@ void
|
||||||
test01()
|
test01()
|
||||||
{
|
{
|
||||||
path p("/");
|
path p("/");
|
||||||
p += path::string_type("foo");
|
p += "foo";
|
||||||
VERIFY( p.filename() == "foo" );
|
VERIFY( p.filename().string() == "foo" );
|
||||||
p += "bar";
|
p += "bar";
|
||||||
VERIFY( p.filename() == "foobar" );
|
VERIFY( p.filename().string() == "foobar" );
|
||||||
p += '/';
|
p += '/';
|
||||||
VERIFY( p.parent_path() == "/foobar" && p.filename() == "" );
|
VERIFY( p.parent_path().string() == "/foobar" );
|
||||||
|
VERIFY( p.filename().string() == "" );
|
||||||
#if _GLIBCXX_USE_WCHAR_T
|
#if _GLIBCXX_USE_WCHAR_T
|
||||||
|
VERIFY( p.parent_path().wstring() == L"/foobar" );
|
||||||
|
VERIFY( p.filename().wstring() == L"" );
|
||||||
p += L"baz.txt";
|
p += L"baz.txt";
|
||||||
#else
|
#else
|
||||||
p += "baz.txt";
|
p += "baz.txt";
|
||||||
#endif
|
#endif
|
||||||
VERIFY( p.filename() == "baz.txt" );
|
VERIFY( p.filename().string() == "baz.txt" );
|
||||||
p.concat("/dir/");
|
p.concat("/dir/");
|
||||||
VERIFY( p.parent_path() == "/foobar/baz.txt/dir" && p.filename() == "" );
|
// N.B. on Windows p.parent_path() is "/foobar\\baz.txt\\dir"
|
||||||
std::string file = "file";
|
VERIFY( p.parent_path() == path("/foobar/baz.txt/dir") );
|
||||||
p.concat(file.begin(), file.end());
|
VERIFY( p.filename().string() == "" );
|
||||||
VERIFY( p.filename() == "file" );
|
const char file[] = "file";
|
||||||
|
__gnu_test::test_container<const char, __gnu_test::input_iterator_wrapper>
|
||||||
|
input(file, file + 4);
|
||||||
|
p.concat(input.begin(), input.end());
|
||||||
|
VERIFY( p.filename().string() == file );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,16 @@
|
||||||
// { dg-require-filesystem-ts "" }
|
// { dg-require-filesystem-ts "" }
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <string.h>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_iterators.h>
|
||||||
|
|
||||||
using std::filesystem::path;
|
using std::filesystem::path;
|
||||||
|
|
||||||
void
|
void
|
||||||
test01()
|
test01()
|
||||||
{
|
{
|
||||||
|
// path(string_type&&, format)
|
||||||
auto s = [&]() -> path::string_type { return "foo/bar"; };
|
auto s = [&]() -> path::string_type { return "foo/bar"; };
|
||||||
path p0(s());
|
path p0(s());
|
||||||
path p1(s(), path::auto_format);
|
path p1(s(), path::auto_format);
|
||||||
|
|
@ -40,6 +43,7 @@ test01()
|
||||||
void
|
void
|
||||||
test02()
|
test02()
|
||||||
{
|
{
|
||||||
|
// path(const Source&, format)
|
||||||
path::string_type s = "foo/bar";
|
path::string_type s = "foo/bar";
|
||||||
path p0(s);
|
path p0(s);
|
||||||
path p1(s, path::auto_format);
|
path p1(s, path::auto_format);
|
||||||
|
|
@ -53,7 +57,8 @@ test02()
|
||||||
void
|
void
|
||||||
test03()
|
test03()
|
||||||
{
|
{
|
||||||
const char* s = "foo/bar";
|
// path(const Source&, format)
|
||||||
|
std::string s = "foo/bar";
|
||||||
path p0(s);
|
path p0(s);
|
||||||
path p1(s, path::auto_format);
|
path p1(s, path::auto_format);
|
||||||
VERIFY( p1 == p0 );
|
VERIFY( p1 == p0 );
|
||||||
|
|
@ -66,19 +71,57 @@ test03()
|
||||||
void
|
void
|
||||||
test04()
|
test04()
|
||||||
{
|
{
|
||||||
const char s[] = "foo/bar";
|
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||||
path p0(std::begin(s), std::end(s));
|
// path(const Source&, format)
|
||||||
path p1(std::begin(s), std::end(s), path::auto_format);
|
std::wstring s = L"foo/bar";
|
||||||
|
path p0(s);
|
||||||
|
path p1(s, path::auto_format);
|
||||||
VERIFY( p1 == p0 );
|
VERIFY( p1 == p0 );
|
||||||
path p2(std::begin(s), std::end(s), path::native_format);
|
path p2(s, path::native_format);
|
||||||
VERIFY( p2 == p0 );
|
VERIFY( p2 == p0 );
|
||||||
path p3(std::begin(s), std::end(s), path::generic_format);
|
path p3(s, path::generic_format);
|
||||||
VERIFY( p3 == p0 );
|
VERIFY( p3 == p0 );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
test05()
|
test05()
|
||||||
{
|
{
|
||||||
|
// path(const Source&, format)
|
||||||
|
const char* s = "foo/bar";
|
||||||
|
path p0(s);
|
||||||
|
path p1(s, path::auto_format);
|
||||||
|
VERIFY( p1 == p0 );
|
||||||
|
path p2(s, path::native_format);
|
||||||
|
VERIFY( p2 == p0 );
|
||||||
|
path p3(s, path::generic_format);
|
||||||
|
VERIFY( p3 == p0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test06()
|
||||||
|
{
|
||||||
|
// path(InputIterator, InputIterator, format)
|
||||||
|
const char s[] = "foo/bar";
|
||||||
|
using namespace __gnu_test;
|
||||||
|
const test_container<const char, input_iterator_wrapper> c(s, s + strlen(s));
|
||||||
|
auto c0 = c;
|
||||||
|
path p0(std::begin(c0), std::end(c0));
|
||||||
|
auto c1 = c;
|
||||||
|
path p1(std::begin(c1), std::end(c1), path::auto_format);
|
||||||
|
VERIFY( p1 == p0 );
|
||||||
|
auto c2 = c;
|
||||||
|
path p2(std::begin(c2), std::end(c2), path::native_format);
|
||||||
|
VERIFY( p2 == p0 );
|
||||||
|
auto c3 = c;
|
||||||
|
path p3(std::begin(c3), std::end(c3), path::generic_format);
|
||||||
|
VERIFY( p3 == p0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test07()
|
||||||
|
{
|
||||||
|
// path(const Source&, const locale&, format)
|
||||||
const char* s = "foo/bar";
|
const char* s = "foo/bar";
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
path p0(s, loc);
|
path p0(s, loc);
|
||||||
|
|
@ -91,16 +134,23 @@ test05()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
test06()
|
test08()
|
||||||
{
|
{
|
||||||
|
// path(InputIterator, InputIterator, const locale&, format)
|
||||||
const char s[] = "foo/bar";
|
const char s[] = "foo/bar";
|
||||||
|
using namespace __gnu_test;
|
||||||
|
const test_container<const char, input_iterator_wrapper> c(s, s + strlen(s));
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
path p0(std::begin(s), std::end(s), loc);
|
auto c0 = c;
|
||||||
path p1(std::begin(s), std::end(s), loc, path::auto_format);
|
path p0(std::begin(c0), std::end(c0), loc);
|
||||||
|
auto c1 = c;
|
||||||
|
path p1(std::begin(c1), std::end(c1), loc, path::auto_format);
|
||||||
VERIFY( p1 == p0 );
|
VERIFY( p1 == p0 );
|
||||||
path p2(std::begin(s), std::end(s), loc, path::native_format);
|
auto c2 = c;
|
||||||
|
path p2(std::begin(c2), std::end(c2), loc, path::native_format);
|
||||||
VERIFY( p2 == p0 );
|
VERIFY( p2 == p0 );
|
||||||
path p3(std::begin(s), std::end(s), loc, path::generic_format);
|
auto c3 = c;
|
||||||
|
path p3(std::begin(c3), std::end(c3), loc, path::generic_format);
|
||||||
VERIFY( p3 == p0 );
|
VERIFY( p3 == p0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,4 +163,6 @@ main()
|
||||||
test04();
|
test04();
|
||||||
test05();
|
test05();
|
||||||
test06();
|
test06();
|
||||||
|
test07();
|
||||||
|
test08();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_iterators.h>
|
||||||
|
|
||||||
using std::filesystem::path;
|
using std::filesystem::path;
|
||||||
|
|
||||||
|
|
@ -33,8 +34,41 @@ test01()
|
||||||
VERIFY( p.native() == "/foo/bar" );
|
VERIFY( p.native() == "/foo/bar" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test02()
|
||||||
|
{
|
||||||
|
using __gnu_test::test_container;
|
||||||
|
using __gnu_test::input_iterator_wrapper;
|
||||||
|
// Test with input iterators and const value_types
|
||||||
|
|
||||||
|
const std::locale loc;
|
||||||
|
const std::string s = "foo/bar/";
|
||||||
|
const path p0(s);
|
||||||
|
|
||||||
|
test_container<char, input_iterator_wrapper>
|
||||||
|
r1((char*)s.c_str(), (char*)s.c_str() + s.size());
|
||||||
|
path p1(r1.begin(), r1.end(), loc);
|
||||||
|
VERIFY( p1 == p0 );
|
||||||
|
|
||||||
|
test_container<char, input_iterator_wrapper>
|
||||||
|
r2((char*)s.c_str(), (char*)s.c_str() + s.size() + 1); // includes null-terminator
|
||||||
|
path p2(r2.begin(), loc);
|
||||||
|
VERIFY( p2 == p0 );
|
||||||
|
|
||||||
|
test_container<const char, input_iterator_wrapper>
|
||||||
|
r3(s.c_str(), s.c_str() + s.size());
|
||||||
|
path p3(r3.begin(), r3.end(), loc);
|
||||||
|
VERIFY( p3 == p0 );
|
||||||
|
|
||||||
|
test_container<const char, input_iterator_wrapper>
|
||||||
|
r4(s.c_str(), s.c_str() + s.size() + 1); // includes null-terminator
|
||||||
|
path p4(r4.begin(), loc);
|
||||||
|
VERIFY( p4 == p0 );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
|
test02();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <experimental/filesystem>
|
#include <experimental/filesystem>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_iterators.h>
|
||||||
|
|
||||||
using std::experimental::filesystem::path;
|
using std::experimental::filesystem::path;
|
||||||
|
|
||||||
|
|
@ -30,23 +31,30 @@ void
|
||||||
test01()
|
test01()
|
||||||
{
|
{
|
||||||
path p("/");
|
path p("/");
|
||||||
p += path::string_type("foo");
|
p += std::string("foo");
|
||||||
VERIFY( p.filename() == "foo" );
|
VERIFY( p.filename().string() == "foo" );
|
||||||
p += "bar";
|
p += "bar";
|
||||||
VERIFY( p.filename() == "foobar" );
|
VERIFY( p.filename().string() == "foobar" );
|
||||||
p += '/';
|
p += '/';
|
||||||
VERIFY( p.parent_path() == "/foobar" && p.filename() == "." );
|
VERIFY( p.parent_path().string() == "/foobar" );
|
||||||
|
VERIFY( p.filename().string() == "." );
|
||||||
#if _GLIBCXX_USE_WCHAR_T
|
#if _GLIBCXX_USE_WCHAR_T
|
||||||
|
VERIFY( p.parent_path().wstring() == L"/foobar" );
|
||||||
|
VERIFY( p.filename().wstring() == L"." );
|
||||||
p += L"baz.txt";
|
p += L"baz.txt";
|
||||||
#else
|
#else
|
||||||
p += "baz.txt";
|
p += "baz.txt";
|
||||||
#endif
|
#endif
|
||||||
VERIFY( p.filename() == "baz.txt" );
|
VERIFY( p.filename().string() == "baz.txt" );
|
||||||
p.concat("/dir/");
|
p.concat("/dir/");
|
||||||
VERIFY( p.parent_path() == "/foobar/baz.txt/dir" && p.filename() == "." );
|
// N.B. on Windows p.parent_path() is "/foobar\\baz.txt\\dir"
|
||||||
std::string file = "file";
|
VERIFY( p.parent_path() == path("/foobar/baz.txt/dir") );
|
||||||
p.concat(file.begin(), file.end());
|
VERIFY( p.filename().string() == "." );
|
||||||
VERIFY( p.filename() == "file" );
|
const char file[] = "file";
|
||||||
|
__gnu_test::test_container<const char, __gnu_test::input_iterator_wrapper>
|
||||||
|
input(file, file + 4);
|
||||||
|
p.concat(input.begin(), input.end());
|
||||||
|
VERIFY( p.filename().string() == file );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <experimental/filesystem>
|
#include <experimental/filesystem>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_iterators.h>
|
||||||
|
|
||||||
using std::experimental::filesystem::path;
|
using std::experimental::filesystem::path;
|
||||||
|
|
||||||
|
|
@ -33,8 +34,41 @@ test01()
|
||||||
VERIFY( p.string() == "/foo/bar" );
|
VERIFY( p.string() == "/foo/bar" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test02()
|
||||||
|
{
|
||||||
|
using __gnu_test::test_container;
|
||||||
|
using __gnu_test::input_iterator_wrapper;
|
||||||
|
// Test with input iterators and const value_types
|
||||||
|
|
||||||
|
const std::locale loc;
|
||||||
|
const std::string s = "foo/bar/";
|
||||||
|
const path p0(s);
|
||||||
|
|
||||||
|
test_container<char, input_iterator_wrapper>
|
||||||
|
r1((char*)s.c_str(), (char*)s.c_str() + s.size());
|
||||||
|
path p1(r1.begin(), r1.end(), loc);
|
||||||
|
VERIFY( p1 == p0 );
|
||||||
|
|
||||||
|
test_container<char, input_iterator_wrapper>
|
||||||
|
r2((char*)s.c_str(), (char*)s.c_str() + s.size() + 1); // includes null-terminator
|
||||||
|
path p2(r2.begin(), loc);
|
||||||
|
VERIFY( p2 == p0 );
|
||||||
|
|
||||||
|
test_container<const char, input_iterator_wrapper>
|
||||||
|
r3(s.c_str(), s.c_str() + s.size());
|
||||||
|
path p3(r3.begin(), r3.end(), loc);
|
||||||
|
VERIFY( p3 == p0 );
|
||||||
|
|
||||||
|
test_container<const char, input_iterator_wrapper>
|
||||||
|
r4(s.c_str(), s.c_str() + s.size() + 1); // includes null-terminator
|
||||||
|
path p4(r4.begin(), loc);
|
||||||
|
VERIFY( p4 == p0 );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
|
test02();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue