libstdc++/71005 fix post-increment for filesystem iterators
PR libstdc++/71005 * include/experimental/bits/fs_dir.h (__directory_iterator_proxy): New type. (directory_iterator::operator++(int)): Return proxy. (recursive_directory_iterator::operator++(int)): Likewise. * testsuite/experimental/filesystem/iterators/directory_iterator.cc: Test post-increment. * testsuite/experimental/filesystem/iterators/ recursive_directory_iterator.cc: Likewise. From-SVN: r236072
This commit is contained in:
parent
cf68d92c7b
commit
d7187f9ea1
|
@ -1,3 +1,15 @@
|
|||
2016-05-10 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/71005
|
||||
* include/experimental/bits/fs_dir.h (__directory_iterator_proxy):
|
||||
New type.
|
||||
(directory_iterator::operator++(int)): Return proxy.
|
||||
(recursive_directory_iterator::operator++(int)): Likewise.
|
||||
* testsuite/experimental/filesystem/iterators/directory_iterator.cc:
|
||||
Test post-increment.
|
||||
* testsuite/experimental/filesystem/iterators/
|
||||
recursive_directory_iterator.cc: Likewise.
|
||||
|
||||
2016-05-09 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/71004
|
||||
|
@ -20,7 +32,7 @@
|
|||
* include/experimental/bits/fs_dir.h (recursive_directory_iterator):
|
||||
Initialize scalar member variables in default constructor.
|
||||
* testsuite/experimental/filesystem/iterators/
|
||||
recursive_directory_iterator.cc: Teste default construction.
|
||||
recursive_directory_iterator.cc: Test default construction.
|
||||
|
||||
2016-05-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
|
|
|
@ -153,8 +153,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
|||
};
|
||||
|
||||
struct _Dir;
|
||||
class directory_iterator;
|
||||
class recursive_directory_iterator;
|
||||
|
||||
struct __directory_iterator_proxy
|
||||
{
|
||||
const directory_entry& operator*() const noexcept { return _M_entry; }
|
||||
|
||||
private:
|
||||
friend class directory_iterator;
|
||||
friend class recursive_directory_iterator;
|
||||
|
||||
explicit
|
||||
__directory_iterator_proxy(const directory_entry& __e) : _M_entry(__e) { }
|
||||
|
||||
directory_entry _M_entry;
|
||||
};
|
||||
|
||||
class directory_iterator
|
||||
{
|
||||
public:
|
||||
|
@ -177,7 +192,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
|||
: directory_iterator(__p, directory_options::none, __ec) { }
|
||||
|
||||
directory_iterator(const path& __p,
|
||||
directory_options __options, error_code& __ec) noexcept
|
||||
directory_options __options,
|
||||
error_code& __ec) noexcept
|
||||
: directory_iterator(__p, __options, &__ec) { }
|
||||
|
||||
directory_iterator(const directory_iterator& __rhs) = default;
|
||||
|
@ -186,19 +202,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
|||
|
||||
~directory_iterator() = default;
|
||||
|
||||
directory_iterator& operator=(const directory_iterator& __rhs) = default;
|
||||
directory_iterator& operator=(directory_iterator&& __rhs) noexcept = default;
|
||||
directory_iterator&
|
||||
operator=(const directory_iterator& __rhs) = default;
|
||||
|
||||
directory_iterator&
|
||||
operator=(directory_iterator&& __rhs) noexcept = default;
|
||||
|
||||
const directory_entry& operator*() const;
|
||||
const directory_entry* operator->() const { return &**this; }
|
||||
directory_iterator& operator++();
|
||||
directory_iterator& increment(error_code& __ec) noexcept;
|
||||
|
||||
directory_iterator operator++(int)
|
||||
__directory_iterator_proxy operator++(int)
|
||||
{
|
||||
auto __tmp = *this;
|
||||
__directory_iterator_proxy __pr{**this};
|
||||
++*this;
|
||||
return __tmp;
|
||||
return __pr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -281,11 +300,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
|||
recursive_directory_iterator& operator++();
|
||||
recursive_directory_iterator& increment(error_code& __ec) noexcept;
|
||||
|
||||
recursive_directory_iterator operator++(int)
|
||||
__directory_iterator_proxy operator++(int)
|
||||
{
|
||||
auto __tmp = *this;
|
||||
__directory_iterator_proxy __pr{**this};
|
||||
++*this;
|
||||
return __tmp;
|
||||
return __pr;
|
||||
}
|
||||
|
||||
void pop();
|
||||
|
|
|
@ -70,8 +70,53 @@ test01()
|
|||
remove_all(p, ec);
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
bool test __attribute__((unused)) = false;
|
||||
|
||||
std::error_code ec;
|
||||
const auto p = __gnu_test::nonexistent_path();
|
||||
create_directory(p, fs::current_path(), ec);
|
||||
create_directory_symlink(p, p / "l", ec);
|
||||
VERIFY( !ec );
|
||||
|
||||
// Test post-increment (libstdc++/71005)
|
||||
auto iter = fs::directory_iterator(p, ec);
|
||||
VERIFY( !ec );
|
||||
VERIFY( iter != fs::directory_iterator() );
|
||||
const auto entry1 = *iter;
|
||||
const auto entry2 = *iter++;
|
||||
VERIFY( entry1 == entry2 );
|
||||
VERIFY( entry1.path() == p/"l" );
|
||||
VERIFY( iter == fs::directory_iterator() );
|
||||
|
||||
remove_all(p, ec);
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
bool test __attribute__((unused)) = false;
|
||||
|
||||
std::error_code ec;
|
||||
const auto p = __gnu_test::nonexistent_path();
|
||||
create_directories(p / "longer_than_small_string_buffer", ec);
|
||||
VERIFY( !ec );
|
||||
|
||||
// Test for no reallocation on each dereference (this is a GNU extension)
|
||||
auto iter = fs::directory_iterator(p, ec);
|
||||
const auto* s1 = iter->path().c_str();
|
||||
const auto* s2 = iter->path().c_str();
|
||||
VERIFY( s1 == s2 );
|
||||
|
||||
remove_all(p, ec);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
}
|
||||
|
|
|
@ -102,7 +102,53 @@ test02()
|
|||
{
|
||||
bool test __attribute__((unused)) = false;
|
||||
|
||||
// libstdc++71004
|
||||
std::error_code ec;
|
||||
const auto p = __gnu_test::nonexistent_path();
|
||||
create_directories(p / "d1/d2", ec);
|
||||
VERIFY( !ec );
|
||||
|
||||
// Test post-increment (libstdc++/71005)
|
||||
auto iter = fs::recursive_directory_iterator(p, ec);
|
||||
VERIFY( !ec );
|
||||
VERIFY( iter != fs::recursive_directory_iterator() );
|
||||
const auto entry1 = *iter;
|
||||
const auto entry2 = *iter++;
|
||||
VERIFY( entry1 == entry2 );
|
||||
VERIFY( entry1.path() == p/"d1" );
|
||||
const auto entry3 = *iter;
|
||||
const auto entry4 = *iter++;
|
||||
VERIFY( entry3 == entry4 );
|
||||
VERIFY( entry3.path() == p/"d1/d2" );
|
||||
VERIFY( iter == fs::recursive_directory_iterator() );
|
||||
|
||||
remove_all(p, ec);
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
bool test __attribute__((unused)) = false;
|
||||
|
||||
std::error_code ec;
|
||||
const auto p = __gnu_test::nonexistent_path();
|
||||
create_directories(p / "longer_than_small_string_buffer", ec);
|
||||
VERIFY( !ec );
|
||||
|
||||
// Test for no reallocation on each dereference (this is a GNU extension)
|
||||
auto iter = fs::recursive_directory_iterator(p, ec);
|
||||
const auto* s1 = iter->path().c_str();
|
||||
const auto* s2 = iter->path().c_str();
|
||||
VERIFY( s1 == s2 );
|
||||
|
||||
remove_all(p, ec);
|
||||
}
|
||||
|
||||
void
|
||||
test04()
|
||||
{
|
||||
bool test __attribute__((unused)) = false;
|
||||
|
||||
// libstdc++/71004
|
||||
const fs::recursive_directory_iterator it;
|
||||
VERIFY( it == fs::recursive_directory_iterator() );
|
||||
}
|
||||
|
@ -112,4 +158,6 @@ main()
|
|||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue