Home | History | Annotate | Download | only in rec.dir.itr.members
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03
     11 
     12 // <experimental/filesystem>
     13 
     14 // class recursive_directory_iterator
     15 
     16 // recursive_directory_iterator& operator=(recursive_directory_iterator const&);
     17 
     18 #include <experimental/filesystem>
     19 #include <type_traits>
     20 #include <set>
     21 #include <cassert>
     22 
     23 #include "test_macros.h"
     24 #include "rapid-cxx-test.hpp"
     25 #include "filesystem_test_helper.hpp"
     26 
     27 // The filesystem specification explicitly allows for self-move on
     28 // the directory iterators. Turn off this warning so we can test it.
     29 #if defined(__clang__)
     30 #pragma clang diagnostic ignored "-Wself-move"
     31 #endif
     32 
     33 using namespace std::experimental::filesystem;
     34 
     35 TEST_SUITE(recursive_directory_iterator_move_assign_tests)
     36 
     37 recursive_directory_iterator createInterestingIterator()
     38     // Create an "interesting" iterator where all fields are
     39     // in a non-default state. The returned 'it' is in a
     40     // state such that:
     41     //   it.options() == directory_options::skip_permission_denied
     42     //   it.depth() == 1
     43     //   it.recursion_pending() == true
     44 {
     45     const path testDir = StaticEnv::Dir;
     46     const recursive_directory_iterator endIt;
     47     recursive_directory_iterator it(testDir,
     48                                     directory_options::skip_permission_denied);
     49     TEST_ASSERT(it != endIt);
     50     while (it.depth() != 1) {
     51         ++it;
     52         TEST_ASSERT(it != endIt);
     53     }
     54     TEST_ASSERT(it.depth() == 1);
     55     it.disable_recursion_pending();
     56     return it;
     57 }
     58 
     59 recursive_directory_iterator createDifferentInterestingIterator()
     60     // Create an "interesting" iterator where all fields are
     61     // in a non-default state. The returned 'it' is in a
     62     // state such that:
     63     //   it.options() == directory_options::follow_directory_symlink
     64     //   it.depth() == 2
     65     //   it.recursion_pending() == false
     66 {
     67     const path testDir = StaticEnv::Dir;
     68     const recursive_directory_iterator endIt;
     69     recursive_directory_iterator it(testDir,
     70                                     directory_options::follow_directory_symlink);
     71     TEST_ASSERT(it != endIt);
     72     while (it.depth() != 2) {
     73         ++it;
     74         TEST_ASSERT(it != endIt);
     75     }
     76     TEST_ASSERT(it.depth() == 2);
     77     return it;
     78 }
     79 
     80 
     81 TEST_CASE(test_assignment_signature)
     82 {
     83     using D = recursive_directory_iterator;
     84     static_assert(std::is_nothrow_move_assignable<D>::value, "");
     85 }
     86 
     87 
     88 TEST_CASE(test_move_to_end_iterator)
     89 {
     90     const recursive_directory_iterator endIt;
     91 
     92     recursive_directory_iterator from = createInterestingIterator();
     93     const recursive_directory_iterator from_copy(from);
     94     const path entry = *from;
     95 
     96     recursive_directory_iterator to;
     97     to = std::move(from);
     98     TEST_REQUIRE(to != endIt);
     99     TEST_CHECK(*to == entry);
    100     TEST_CHECK(to.options() == from_copy.options());
    101     TEST_CHECK(to.depth() == from_copy.depth());
    102     TEST_CHECK(to.recursion_pending() == from_copy.recursion_pending());
    103     TEST_CHECK(from == endIt || from == to);
    104 }
    105 
    106 
    107 TEST_CASE(test_move_from_end_iterator)
    108 {
    109     recursive_directory_iterator from;
    110     recursive_directory_iterator to = createInterestingIterator();
    111 
    112     to = std::move(from);
    113     TEST_REQUIRE(to == from);
    114     TEST_CHECK(to == recursive_directory_iterator{});
    115 }
    116 
    117 TEST_CASE(test_move_valid_iterator)
    118 {
    119     const recursive_directory_iterator endIt;
    120 
    121     recursive_directory_iterator it = createInterestingIterator();
    122     const recursive_directory_iterator it_copy(it);
    123     const path entry = *it;
    124 
    125     recursive_directory_iterator it2 = createDifferentInterestingIterator();
    126     const recursive_directory_iterator it2_copy(it2);
    127     TEST_REQUIRE(it2 != it);
    128     TEST_CHECK(it2.options() != it.options());
    129     TEST_CHECK(it2.depth() != it.depth());
    130     TEST_CHECK(it2.recursion_pending() != it.recursion_pending());
    131     TEST_CHECK(*it2 != entry);
    132 
    133     it2 = std::move(it);
    134     TEST_REQUIRE(it2 != it2_copy && it2 != endIt);
    135     TEST_CHECK(it2.options() == it_copy.options());
    136     TEST_CHECK(it2.depth() == it_copy.depth());
    137     TEST_CHECK(it2.recursion_pending() == it_copy.recursion_pending());
    138     TEST_CHECK(*it2 == entry);
    139     TEST_CHECK(it == endIt || it == it2);
    140 }
    141 
    142 TEST_CASE(test_returns_reference_to_self)
    143 {
    144     recursive_directory_iterator it;
    145     recursive_directory_iterator it2;
    146     recursive_directory_iterator& ref = (it2 = std::move(it));
    147     TEST_CHECK(&ref == &it2);
    148 }
    149 
    150 TEST_CASE(test_self_move)
    151 {
    152     // Create two non-equal iterators that have exactly the same state.
    153     recursive_directory_iterator it = createInterestingIterator();
    154     recursive_directory_iterator it2 = createInterestingIterator();
    155     TEST_CHECK(it != it2);
    156     TEST_CHECK(it2.options()           == it.options());
    157     TEST_CHECK(it2.depth()             == it.depth());
    158     TEST_CHECK(it2.recursion_pending() == it.recursion_pending());
    159     TEST_CHECK(*it2 == *it);
    160 
    161     it = std::move(it);
    162     TEST_CHECK(it2.options()           == it.options());
    163     TEST_CHECK(it2.depth()             == it.depth());
    164     TEST_CHECK(it2.recursion_pending() == it.recursion_pending());
    165     TEST_CHECK(*it2 == *it);
    166 }
    167 
    168 
    169 TEST_SUITE_END()
    170