aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-05-10 12:25:06 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-05-10 12:25:06 +0100
commitd7187f9ea16a5494d3d7cfd1264a40057fa9a504 (patch)
tree17e298208a900930d88a077df9aa7e7d5a57a74a /libstdc++-v3
parentcf68d92c7bb339d89426558cae2ad731ae8f0508 (diff)
downloadgcc-d7187f9ea16a5494d3d7cfd1264a40057fa9a504.zip
gcc-d7187f9ea16a5494d3d7cfd1264a40057fa9a504.tar.gz
gcc-d7187f9ea16a5494d3d7cfd1264a40057fa9a504.tar.bz2
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
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog14
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_dir.h41
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc45
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc50
4 files changed, 137 insertions, 13 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 1cdb7f4..58f6646 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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>
diff --git a/libstdc++-v3/include/experimental/bits/fs_dir.h b/libstdc++-v3/include/experimental/bits/fs_dir.h
index f128cce..5fd41c2 100644
--- a/libstdc++-v3/include/experimental/bits/fs_dir.h
+++ b/libstdc++-v3/include/experimental/bits/fs_dir.h
@@ -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:
@@ -274,18 +293,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// modifiers
recursive_directory_iterator&
- operator=(const recursive_directory_iterator& __rhs) noexcept;
+ operator=(const recursive_directory_iterator& __rhs) noexcept;
recursive_directory_iterator&
- operator=(recursive_directory_iterator&& __rhs) noexcept;
+ operator=(recursive_directory_iterator&& __rhs) noexcept;
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();
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc
index 28b948f..ce9f437 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc
@@ -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();
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
index b5f71be..fb4c31e 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
@@ -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();
}