diff options
Diffstat (limited to 'test/std/experimental')
343 files changed, 15793 insertions, 644 deletions
diff --git a/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp b/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp index 0f0784d6ee90e..1a9f9b099b201 100644 --- a/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp +++ b/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp @@ -64,12 +64,12 @@ void test() { end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is), SampleIterator(oa), os, g); - assert(&*end - oa == std::min(os, is)); + assert(end.base() - oa == std::min(os, is)); assert(std::equal(oa, oa + os, oa1)); end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is), SampleIterator(oa), os, g); - assert(&*end - oa == std::min(os, is)); + assert(end.base() - oa == std::min(os, is)); assert(std::equal(oa, oa + os, oa2)); } @@ -85,7 +85,7 @@ void test_empty_population() { SampleIterator end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia), SampleIterator(oa), os, g); - assert(&*end == oa); + assert(end.base() == oa); } template <template<class> class PopulationIteratorType, class PopulationItem, @@ -100,7 +100,7 @@ void test_empty_sample() { SampleIterator end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is), SampleIterator(oa), 0, g); - assert(&*end == oa); + assert(end.base() == oa); } template <template<class> class PopulationIteratorType, class PopulationItem, @@ -119,8 +119,8 @@ void test_small_population() { end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is), SampleIterator(oa), os, g); - assert(&*end - oa == std::min(os, is)); - assert(std::equal(oa, &*end, oa1)); + assert(end.base() - oa == std::min(os, is)); + assert(std::equal(oa, end.base(), oa1)); } int main() { diff --git a/test/std/experimental/algorithms/alg.search/search.pass.cpp b/test/std/experimental/algorithms/alg.search/search.pass.cpp index 60a44e4c26a2c..81d220ba1aed7 100644 --- a/test/std/experimental/algorithms/alg.search/search.pass.cpp +++ b/test/std/experimental/algorithms/alg.search/search.pass.cpp @@ -15,7 +15,7 @@ // ForwardIterator search(ForwardIterator first, ForwardIterator last, // const Searcher& searcher); // -// returns searcher.operator(first, last) +// returns searcher.operator(first, last).first // #include <experimental/algorithm> @@ -27,10 +27,11 @@ int searcher_called = 0; struct MySearcher { template <typename Iterator> - Iterator operator() ( Iterator b, Iterator /*e*/) const + std::pair<Iterator, Iterator> + operator() (Iterator b, Iterator e) const { ++searcher_called; - return b; + return std::make_pair(b, e); } }; diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink b/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink new file mode 120000 index 0000000000000..76646beed5ed3 --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink @@ -0,0 +1 @@ +dne
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 new file mode 120000 index 0000000000000..3979139526219 --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 @@ -0,0 +1 @@ +dir3
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 new file mode 100644 index 0000000000000..44834e586734f --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/empty_file b/test/std/experimental/filesystem/Inputs/static_test_env/empty_file new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/empty_file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file b/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file new file mode 100644 index 0000000000000..44834e586734f --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir new file mode 120000 index 0000000000000..df490f837a85c --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir @@ -0,0 +1 @@ +dir1
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file new file mode 120000 index 0000000000000..b79b689fc85ac --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file @@ -0,0 +1 @@ +empty_file
\ No newline at end of file diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp new file mode 100644 index 0000000000000..9a92f0698ba7c --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_entry + +// directory_entry() noexcept = default; +// directory_entry(const directory_entry&) = default; +// directory_entry(directory_entry&&) noexcept = default; +// explicit directory_entry(const path); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +void test_default_ctor() +{ + using namespace fs; + // Default + { + static_assert(std::is_nothrow_default_constructible<directory_entry>::value, + "directory_entry must have a nothrow default constructor"); + directory_entry e; + assert(e.path() == path()); + } +} + + +void test_copy_ctor() +{ + using namespace fs; + // Copy + { + static_assert(std::is_copy_constructible<directory_entry>::value, + "directory_entry must be copy constructible"); + static_assert(!std::is_nothrow_copy_constructible<directory_entry>::value, + "directory_entry's copy constructor cannot be noexcept"); + const path p("foo/bar/baz"); + const directory_entry e(p); + assert(e.path() == p); + directory_entry e2(e); + assert(e.path() == p); + assert(e2.path() == p); + } + +} + +void test_move_ctor() +{ + using namespace fs; + // Move + { + static_assert(std::is_nothrow_move_constructible<directory_entry>::value, + "directory_entry must be nothrow move constructible"); + const path p("foo/bar/baz"); + directory_entry e(p); + assert(e.path() == p); + directory_entry e2(std::move(e)); + assert(e2.path() == p); + assert(e.path() != p); // Testing moved from state. + } +} + +void test_path_ctor() { + using namespace fs; + { + static_assert(std::is_constructible<directory_entry, const path&>::value, + "directory_entry must be constructible from path"); + static_assert(!std::is_nothrow_constructible<directory_entry, const path&>::value, + "directory_entry constructor should not be noexcept"); + static_assert(!std::is_convertible<path const&, directory_entry>::value, + "directory_entry constructor should be explicit"); + } + { + const path p("foo/bar/baz"); + const directory_entry e(p); + assert(p == e.path()); + } +} + +int main() { + test_default_ctor(); + test_copy_ctor(); + test_move_ctor(); + test_path_ctor(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp new file mode 100644 index 0000000000000..97ecbefac42a9 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_entry + +// directory_entry& operator=(directory_entry const&) = default; +// directory_entry& operator=(directory_entry&&) noexcept = default; +// void assign(path const&); +// void replace_filename(path const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +void test_copy_assign_operator() +{ + using namespace fs; + // Copy + { + static_assert(std::is_copy_assignable<directory_entry>::value, + "directory_entry must be copy assignable"); + static_assert(!std::is_nothrow_copy_assignable<directory_entry>::value, + "directory_entry's copy assignment cannot be noexcept"); + const path p("foo/bar/baz"); + const path p2("abc"); + const directory_entry e(p); + directory_entry e2; + assert(e.path() == p && e2.path() == path()); + e2 = e; + assert(e.path() == p && e2.path() == p); + directory_entry e3(p2); + e2 = e3; + assert(e2.path() == p2 && e3.path() == p2); + } +} + + +void test_move_assign_operator() +{ + using namespace fs; + // Copy + { + static_assert(std::is_nothrow_move_assignable<directory_entry>::value, + "directory_entry is noexcept move assignable"); + const path p("foo/bar/baz"); + const path p2("abc"); + directory_entry e(p); + directory_entry e2(p2); + assert(e.path() == p && e2.path() == p2); + e2 = std::move(e); + assert(e2.path() == p); + assert(e.path() != p); // testing moved from state + } +} + +void test_path_assign_method() +{ + using namespace fs; + const path p("foo/bar/baz"); + const path p2("abc"); + directory_entry e(p); + { + static_assert(std::is_same<decltype(e.assign(p)), void>::value, + "return type should be void"); + static_assert(noexcept(e.assign(p)) == false, "operation must not be noexcept"); + } + { + assert(e.path() == p); + e.assign(p2); + assert(e.path() == p2 && e.path() != p); + e.assign(p); + assert(e.path() == p && e.path() != p2); + } +} + +void test_replace_filename_method() +{ + using namespace fs; + const path p("/path/to/foo.exe"); + const path replace("bar.out"); + const path expect("/path/to/bar.out"); + directory_entry e(p); + { + static_assert(noexcept(e.replace_filename(replace)) == false, + "operation cannot be noexcept"); + static_assert(std::is_same<decltype(e.replace_filename(replace)), void>::value, + "operation must return void"); + } + { + assert(e.path() == p); + e.replace_filename(replace); + assert(e.path() == expect); + } +} + +int main() { + test_copy_assign_operator(); + test_move_assign_operator(); + test_path_assign_method(); + test_replace_filename_method(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp new file mode 100644 index 0000000000000..96e5093002293 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_entry + +// bool operator==(directory_entry const&) const noexcept; +// bool operator!=(directory_entry const&) const noexcept; +// bool operator< (directory_entry const&) const noexcept; +// bool operator<=(directory_entry const&) const noexcept; +// bool operator> (directory_entry const&) const noexcept; +// bool operator>=(directory_entry const&) const noexcept; + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +#define CHECK_OP(Op) \ + static_assert(std::is_same<decltype(ce. operator Op (ce)), bool>::value, ""); \ + static_assert(noexcept(ce.operator Op (ce)), "Operation must be noexcept" ) + +void test_comparison_signatures() { + using namespace fs; + path const p("foo/bar/baz"); + // Check that the operators are member functions with the correct signatures. + { + directory_entry const ce(p); + CHECK_OP(==); + CHECK_OP(!=); + CHECK_OP(< ); + CHECK_OP(<=); + CHECK_OP(> ); + CHECK_OP(>=); + } +} +#undef CHECK_OP + +// The actual semantics of the comparisons are testing via paths operators. +void test_comparisons_simple() { + using namespace fs; + typedef std::pair<path, path> TestType; + TestType TestCases[] = + { + {"", ""}, + {"", "a"}, + {"a", "a"}, + {"a", "b"}, + {"foo/bar/baz", "foo/bar/baz/"} + }; + auto TestFn = [](path const& LHS, const directory_entry& LHSE, + path const& RHS, const directory_entry& RHSE) { + assert((LHS == RHS) == (LHSE == RHSE)); + assert((LHS != RHS) == (LHSE != RHSE)); + assert((LHS < RHS) == (LHSE < RHSE)); + assert((LHS <= RHS) == (LHSE <= RHSE)); + assert((LHS > RHS) == (LHSE > RHSE)); + assert((LHS >= RHS) == (LHSE >= RHSE)); + }; + for (auto const& TC : TestCases) { + const directory_entry L(TC.first); + const directory_entry R(TC.second); + TestFn(TC.first, L, TC.second, R); + TestFn(TC.second, R, TC.first, L); + } +} + +int main() { + test_comparison_signatures(); + test_comparisons_simple(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp new file mode 100644 index 0000000000000..d228a3d926413 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_entry + +// const path& path() const noexcept; +// operator const path&() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +void test_path_method() { + using namespace fs; + const path p("foo/bar/baz.exe"); + const path p2("abc"); + { + directory_entry nce; + const directory_entry e(""); + static_assert(std::is_same<decltype(e.path()), const path&>::value, ""); + static_assert(std::is_same<decltype(nce.path()), const path&>::value, ""); + static_assert(noexcept(e.path()) && noexcept(nce.path()), ""); + } + { + directory_entry e(p); + path const& pref = e.path(); + assert(pref == p); + assert(&pref == &e.path()); + e.assign(p2); + assert(pref == p2); + assert(&pref == &e.path()); + } +} + +void test_path_conversion() { + using namespace fs; + const path p("foo/bar/baz.exe"); + const path p2("abc"); + { + directory_entry nce; + const directory_entry e(""); + // Check conversions exist + static_assert(std::is_convertible<directory_entry&, path const&>::value, ""); + static_assert(std::is_convertible<directory_entry const&, path const&>::value, ""); + static_assert(std::is_convertible<directory_entry &&, path const&>::value, ""); + static_assert(std::is_convertible<directory_entry const&&, path const&>::value, ""); + // Not convertible to non-const + static_assert(!std::is_convertible<directory_entry&, path&>::value, ""); + static_assert(!std::is_convertible<directory_entry const&, path&>::value, ""); + static_assert(!std::is_convertible<directory_entry &&, path&>::value, ""); + static_assert(!std::is_convertible<directory_entry const&&, path&>::value, ""); + // conversions are noexcept + static_assert(noexcept(e.operator fs::path const&()) && + noexcept(e.operator fs::path const&()), ""); + } + // const + { + directory_entry const e(p); + path const& pref = e; + assert(&pref == &e.path()); + } + // non-const + { + directory_entry e(p); + path const& pref = e; + assert(&pref == &e.path()); + + e.assign(p2); + assert(pref == p2); + assert(&pref == &e.path()); + } +} + +int main() { + test_path_method(); + test_path_conversion(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp new file mode 100644 index 0000000000000..54c5172ebce46 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_entry + +// file_status status() const; +// file_status status(error_code const&) const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "filesystem_test_helper.hpp" + +int main() +{ + using namespace fs; + { + const directory_entry e("foo"); + std::error_code ec; + static_assert(std::is_same<decltype(e.status()), file_status>::value, ""); + static_assert(std::is_same<decltype(e.status(ec)), file_status>::value, ""); + static_assert(noexcept(e.status()) == false, ""); + static_assert(noexcept(e.status(ec)) == true, ""); + } + auto TestFn = [](path const& p) { + const directory_entry e(p); + std::error_code pec, eec; + file_status ps = fs::status(p, pec); + file_status es = e.status(eec); + assert(ps.type() == es.type()); + assert(ps.permissions() == es.permissions()); + assert(pec == eec); + }; + { + TestFn(StaticEnv::File); + TestFn(StaticEnv::Dir); + TestFn(StaticEnv::SymlinkToFile); + TestFn(StaticEnv::DNE); + } +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp new file mode 100644 index 0000000000000..3a99eb671b44e --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_entry + +// file_status symlink_status() const; +// file_status symlink_status(error_code&) const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "filesystem_test_helper.hpp" + +int main() { + using namespace fs; + { + const directory_entry e("foo"); + std::error_code ec; + static_assert(std::is_same<decltype(e.symlink_status()), file_status>::value, ""); + static_assert(std::is_same<decltype(e.symlink_status(ec)), file_status>::value, ""); + static_assert(noexcept(e.symlink_status()) == false, ""); + static_assert(noexcept(e.symlink_status(ec)) == true, ""); + } + auto TestFn = [](path const& p) { + const directory_entry e(p); + std::error_code pec, eec; + file_status ps = fs::symlink_status(p, pec); + file_status es = e.symlink_status(eec); + assert(ps.type() == es.type()); + assert(ps.permissions() == es.permissions()); + assert(pec == eec); + }; + { + TestFn(StaticEnv::File); + TestFn(StaticEnv::Dir); + TestFn(StaticEnv::SymlinkToFile); + TestFn(StaticEnv::DNE); + } +} diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp new file mode 100644 index 0000000000000..5c4583391e74f --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator(directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_copy_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = directory_iterator; + static_assert(std::is_copy_constructible<D>::value, ""); +} + +TEST_CASE(test_copy_end_iterator) +{ + const directory_iterator endIt; + directory_iterator it(endIt); + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + const directory_iterator it(testDir); + TEST_REQUIRE(it != endIt); + const path entry = *it; + + const directory_iterator it2(it); + TEST_REQUIRE(it2 == it); + TEST_CHECK(*it2 == entry); + TEST_CHECK(*it == entry); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp new file mode 100644 index 0000000000000..0d5ebf3ebe964 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator& operator=(directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_copy_assign_tests) + +TEST_CASE(test_assignment_signature) +{ + using D = directory_iterator; + static_assert(std::is_copy_assignable<D>::value, ""); +} + +TEST_CASE(test_copy_to_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + const directory_iterator from(testDir); + TEST_REQUIRE(from != directory_iterator{}); + const path entry = *from; + + directory_iterator to{}; + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(*to == entry); + TEST_CHECK(*from == entry); +} + + +TEST_CASE(test_copy_from_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + const directory_iterator from{}; + + directory_iterator to(testDir); + TEST_REQUIRE(to != directory_iterator{}); + + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(to == directory_iterator{}); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + directory_iterator it_obj(testDir); + const directory_iterator& it = it_obj; + TEST_REQUIRE(it != endIt); + ++it_obj; + TEST_REQUIRE(it != endIt); + const path entry = *it; + + directory_iterator it2(testDir); + TEST_REQUIRE(it2 != it); + const path entry2 = *it2; + TEST_CHECK(entry2 != entry); + + it2 = it; + TEST_REQUIRE(it2 == it); + TEST_CHECK(*it2 == entry); +} + +TEST_CASE(test_returns_reference_to_self) +{ + const directory_iterator it; + directory_iterator it2; + directory_iterator& ref = (it2 = it); + TEST_CHECK(&ref == &it2); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp new file mode 100644 index 0000000000000..a6becb1bafaa7 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp @@ -0,0 +1,246 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// explicit directory_iterator(const path& p); +// directory_iterator(const path& p, directory_options options); +// directory_iterator(const path& p, error_code& ec) noexcept; +// directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_constructor_tests) + +TEST_CASE(test_constructor_signatures) +{ + using D = directory_iterator; + + // explicit directory_iterator(path const&); + static_assert(!std::is_convertible<path, D>::value, ""); + static_assert(std::is_constructible<D, path>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path>::value, ""); + + // directory_iterator(path const&, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, ""); + + // directory_iterator(path const&, directory_options); + static_assert(std::is_constructible<D, path, directory_options>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, ""); + + // directory_iterator(path const&, directory_options, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, ""); +} + +TEST_CASE(test_construction_from_bad_path) +{ + std::error_code ec; + directory_options opts = directory_options::none; + const directory_iterator endIt; + + const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink }; + for (path const& testPath : testPaths) + { + { + directory_iterator it(testPath, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + directory_iterator it(testPath, opts, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath)); + TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath, opts)); + } + } +} + +TEST_CASE(access_denied_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testDir = env.make_env_path("dir1"); + path const testFile = testDir / "testFile"; + env.create_dir(testDir); + env.create_file(testFile, 42); + + // Test that we can iterator over the directory before changing the perms + directory_iterator it(testDir); + TEST_REQUIRE(it != directory_iterator{}); + + // Change the permissions so we can no longer iterate + permissions(testDir, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == directory_iterator{}); + } + // Check that construction does not report an error when + // 'skip_permissions_denied' is given. + { + std::error_code ec; + directory_iterator it(testDir, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it == directory_iterator{}); + } +} + + +TEST_CASE(access_denied_to_file_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testFile = env.make_env_path("file1"); + env.create_file(testFile, 42); + + // Change the permissions so we can no longer iterate + permissions(testFile, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + directory_iterator it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == directory_iterator{}); + } + // Check that construction still fails when 'skip_permissions_denied' is given + // because we tried to open a file and not a directory. + { + std::error_code ec; + directory_iterator it(testFile, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == directory_iterator{}); + } +} + +TEST_CASE(test_open_on_empty_directory_equals_end) +{ + scoped_test_env env; + const path testDir = env.make_env_path("dir1"); + env.create_dir(testDir); + + const directory_iterator endIt; + { + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_CHECK(!ec); + TEST_CHECK(it == endIt); + } + { + directory_iterator it(testDir); + TEST_CHECK(it == endIt); + } +} + +TEST_CASE(test_open_on_directory_succeeds) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + { + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } + { + directory_iterator it(testDir); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } +} + +TEST_CASE(test_open_on_file_fails) +{ + const path testFile = StaticEnv::File; + const directory_iterator endIt{}; + { + std::error_code ec; + directory_iterator it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, directory_iterator(testFile)); + } +} + +TEST_CASE(test_open_on_empty_string) +{ + const path testPath = ""; + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testPath, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_open_on_dot_dir) +{ + const path testPath = "."; + + std::error_code ec; + directory_iterator it(testPath, ec); + TEST_CHECK(!ec); +} + +TEST_CASE(test_open_on_symlink) +{ + const path symlinkToDir = StaticEnv::SymlinkToDir; + std::set<path> dir_contents; + for (path const& p : StaticEnv::DirIterationList) { + dir_contents.insert(p.filename()); + } + const directory_iterator endIt{}; + + { + std::error_code ec; + directory_iterator it(symlinkToDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + path const& entry = *it; + TEST_CHECK(dir_contents.count(entry.filename())); + } + { + std::error_code ec; + directory_iterator it(symlinkToDir, + directory_options::follow_directory_symlink, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + path const& entry = *it; + TEST_CHECK(dir_contents.count(entry.filename())); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp new file mode 100644 index 0000000000000..94ace185a6aa8 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator::directory_iterator() noexcept + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + { + static_assert(std::is_nothrow_default_constructible<fs::directory_iterator>::value, ""); + } + { + fs::directory_iterator d1; + const fs::directory_iterator d2; + assert(d1 == d2); + } +} diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp new file mode 100644 index 0000000000000..589b4eca7efa2 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator& operator++(); +// directory_iterator& increment(error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_increment_tests) + +TEST_CASE(test_increment_signatures) +{ + using D = directory_iterator; + directory_iterator d; ((void)d); + std::error_code ec; ((void)ec); + + ASSERT_SAME_TYPE(decltype(++d), directory_iterator&); + ASSERT_NOT_NOEXCEPT(++d); + + ASSERT_SAME_TYPE(decltype(d.increment(ec)), directory_iterator&); + ASSERT_NOEXCEPT(d.increment(ec)); +} + +TEST_CASE(test_prefix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + directory_iterator& it_ref = ++it; + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_postfix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + const path entry2 = *it++; + TEST_CHECK(entry2 == entry); + } + + TEST_CHECK(it == endIt); +} + + +TEST_CASE(test_increment_method) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + directory_iterator& it_ref = it.increment(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp new file mode 100644 index 0000000000000..f6c94e18eb0e8 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator(directory_iterator&&) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_move_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = directory_iterator; + static_assert(std::is_nothrow_move_constructible<D>::value, ""); +} + +TEST_CASE(test_move_end_iterator) +{ + const directory_iterator endIt; + directory_iterator endIt2{}; + + directory_iterator it(std::move(endIt2)); + TEST_CHECK(it == endIt); + TEST_CHECK(endIt2 == endIt); +} + +TEST_CASE(test_move_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + directory_iterator it(testDir); + TEST_REQUIRE(it != endIt); + const path entry = *it; + + const directory_iterator it2(std::move(it)); + TEST_CHECK(*it2 == entry); + + TEST_CHECK(it == it2 || it == endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp new file mode 100644 index 0000000000000..445f05a3c3e1e --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator& operator=(directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +// The filesystem specification explicitly allows for self-move on +// the directory iterators. Turn off this warning so we can test it. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wself-move" +#endif + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_move_assign_tests) + +TEST_CASE(test_assignment_signature) +{ + using D = directory_iterator; + static_assert(std::is_nothrow_move_assignable<D>::value, ""); +} + +TEST_CASE(test_move_to_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + directory_iterator from(testDir); + TEST_REQUIRE(from != directory_iterator{}); + const path entry = *from; + + directory_iterator to{}; + to = std::move(from); + TEST_REQUIRE(to != directory_iterator{}); + TEST_CHECK(*to == entry); +} + + +TEST_CASE(test_move_from_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + directory_iterator from{}; + + directory_iterator to(testDir); + TEST_REQUIRE(to != from); + + to = std::move(from); + TEST_REQUIRE(to == directory_iterator{}); + TEST_REQUIRE(from == directory_iterator{}); +} + +TEST_CASE(test_move_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + directory_iterator it(testDir); + TEST_REQUIRE(it != endIt); + ++it; + TEST_REQUIRE(it != endIt); + const path entry = *it; + + directory_iterator it2(testDir); + TEST_REQUIRE(it2 != it); + const path entry2 = *it2; + TEST_CHECK(entry2 != entry); + + it2 = std::move(it); + TEST_REQUIRE(it2 != directory_iterator{}); + TEST_CHECK(*it2 == entry); +} + +TEST_CASE(test_returns_reference_to_self) +{ + directory_iterator it; + directory_iterator it2; + directory_iterator& ref = (it2 = it); + TEST_CHECK(&ref == &it2); +} + + +TEST_CASE(test_self_move) +{ + // Create two non-equal iterators that have exactly the same state. + directory_iterator it(StaticEnv::Dir); + directory_iterator it2(StaticEnv::Dir); + ++it; ++it2; + TEST_CHECK(it != it2); + TEST_CHECK(*it2 == *it); + + it = std::move(it); + TEST_CHECK(*it2 == *it); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp new file mode 100644 index 0000000000000..f93a184521895 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator begin(directory_iterator iter) noexcept; +// directory_iterator end(directory_iterator iter) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_begin_end_tests) + +TEST_CASE(test_function_signatures) +{ + using D = directory_iterator; + directory_iterator d; ((void)d); + + ASSERT_SAME_TYPE(decltype(begin(d)), directory_iterator); + ASSERT_NOEXCEPT(begin(std::move(d))); + + ASSERT_SAME_TYPE(decltype(end(d)), directory_iterator); + ASSERT_NOEXCEPT(end(std::move(d))); +} + +TEST_CASE(test_ranged_for_loop) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + for (auto& elem : it) { + TEST_CHECK(dir_contents.erase(elem) == 1); + } + TEST_CHECK(dir_contents.empty()); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp new file mode 100644 index 0000000000000..dad278f43d79d --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// typedef ... value_type; +// typedef ... difference_type; +// typedef ... pointer; +// typedef ... reference; +// typedef ... iterator_category + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + using D = directory_iterator; + ASSERT_SAME_TYPE(D::value_type, directory_entry); + ASSERT_SAME_TYPE(D::difference_type, std::ptrdiff_t); + ASSERT_SAME_TYPE(D::pointer, const directory_entry*); + ASSERT_SAME_TYPE(D::reference, const directory_entry&); + ASSERT_SAME_TYPE(D::iterator_category, std::input_iterator_tag); +} diff --git a/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp b/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp new file mode 100644 index 0000000000000..585b0bb1dd5ee --- /dev/null +++ b/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class file_status + +// explicit file_status() noexcept; +// explicit file_status(file_type, perms prms = perms::unknown) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_convertible.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + // Default ctor + { + static_assert(std::is_nothrow_default_constructible<file_status>::value, + "The default constructor must be noexcept"); + static_assert(!test_convertible<file_status>(), + "The default constructor must be explicit"); + const file_status f; + assert(f.type() == file_type::none); + assert(f.permissions() == perms::unknown); + } + + // Unary ctor + { + static_assert(std::is_nothrow_constructible<file_status, file_type>::value, + "This constructor must be noexcept"); + static_assert(!test_convertible<file_status, file_type>(), + "This constructor must be explicit"); + + const file_status f(file_type::not_found); + assert(f.type() == file_type::not_found); + assert(f.permissions() == perms::unknown); + } + // Binary ctor + { + static_assert(std::is_nothrow_constructible<file_status, file_type, perms>::value, + "This constructor must be noexcept"); + static_assert(!test_convertible<file_status, file_type, perms>(), + "This constructor must b explicit"); + const file_status f(file_type::regular, perms::owner_read); + assert(f.type() == file_type::regular); + assert(f.permissions() == perms::owner_read); + } +} diff --git a/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp b/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp new file mode 100644 index 0000000000000..8681b2dc50d6f --- /dev/null +++ b/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class file_status + +// void type(file_type) noexcept; +// void permissions(perms) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + + file_status st; + + // type test + { + static_assert(noexcept(st.type(file_type::regular)), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.type(file_type::regular)), void>::value, + "operation must return void"); + assert(st.type() != file_type::regular); + st.type(file_type::regular); + assert(st.type() == file_type::regular); + } + // permissions test + { + static_assert(noexcept(st.permissions(perms::owner_read)), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.permissions(perms::owner_read)), void>::value, + "operation must return void"); + assert(st.permissions() != perms::owner_read); + st.permissions(perms::owner_read); + assert(st.permissions() == perms::owner_read); + } +} diff --git a/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp b/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp new file mode 100644 index 0000000000000..4113dee453dc6 --- /dev/null +++ b/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class file_status + +// file_type type() const noexcept; +// perms permissions(p) const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + + const file_status st(file_type::regular, perms::owner_read); + + // type test + { + static_assert(noexcept(st.type()), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.type()), file_type>::value, + "operation must return file_type"); + assert(st.type() == file_type::regular); + } + // permissions test + { + static_assert(noexcept(st.permissions()), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.permissions()), perms>::value, + "operation must return perms"); + assert(st.permissions() == perms::owner_read); + } +} diff --git a/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp b/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp new file mode 100644 index 0000000000000..68b67ed72803b --- /dev/null +++ b/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class filesystem_error + +// filesystem_error(const string& what_arg, error_code ec); +// filesystem_error(const string& what_arg, const path& p1, error_code ec); +// filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec); +// const std::error_code& code() const; +// const char* what() const noexcept; +// const path& path1() const noexcept; +// const path& path2() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +void test_constructors() { + using namespace fs; + + // The string returned by "filesystem_error::what() must contain runtime_error::what() + const std::string what_arg = "Hello World"; + const std::string what_contains = std::runtime_error(what_arg).what(); + assert(what_contains.find(what_arg) != std::string::npos); + auto CheckWhat = [what_contains](filesystem_error const& e) { + std::string s = e.what(); + assert(s.find(what_contains) != std::string::npos); + }; + + std::error_code ec = std::make_error_code(std::errc::file_exists); + const path p1("foo"); + const path p2("bar"); + + // filesystem_error(const string& what_arg, error_code ec); + { + ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, ec)); + filesystem_error e(what_arg, ec); + CheckWhat(e); + assert(e.code() == ec); + assert(e.path1().empty() && e.path2().empty()); + } + // filesystem_error(const string& what_arg, const path&, error_code ec); + { + ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, p1, ec)); + filesystem_error e(what_arg, p1, ec); + CheckWhat(e); + assert(e.code() == ec); + assert(e.path1() == p1); + assert(e.path2().empty()); + } + // filesystem_error(const string& what_arg, const path&, const path&, error_code ec); + { + ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, p1, p2, ec)); + filesystem_error e(what_arg, p1, p2, ec); + CheckWhat(e); + assert(e.code() == ec); + assert(e.path1() == p1); + assert(e.path2() == p2); + } +} + +void test_signatures() +{ + using namespace fs; + const path p; + std::error_code ec; + const filesystem_error e("lala", ec); + // const path& path1() const noexcept; + { + ASSERT_SAME_TYPE(path const&, decltype(e.path1())); + ASSERT_NOEXCEPT(e.path1()); + } + // const path& path2() const noexcept + { + ASSERT_SAME_TYPE(path const&, decltype(e.path2())); + ASSERT_NOEXCEPT(e.path2()); + } + // const char* what() const noexcept + { + ASSERT_SAME_TYPE(const char*, decltype(e.what())); + ASSERT_NOEXCEPT(e.what()); + } +} + +int main() { + static_assert(std::is_base_of<std::system_error, fs::filesystem_error>::value, ""); + test_constructors(); + test_signatures(); +} diff --git a/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp b/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp new file mode 100644 index 0000000000000..12330ebb5ca8c --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class Source> +// path(const Source& source); +// template <class InputIterator> +// path(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <iterator> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + + +template <class It> +std::reverse_iterator<It> mkRev(It it) { + return std::reverse_iterator<It>(it); +} + +void checkIteratorConcepts() { + using namespace fs; + using It = path::iterator; + using Traits = std::iterator_traits<It>; + ASSERT_SAME_TYPE(Traits::iterator_category, std::bidirectional_iterator_tag); + ASSERT_SAME_TYPE(Traits::value_type, path); + ASSERT_SAME_TYPE(Traits::pointer, path const*); + ASSERT_SAME_TYPE(Traits::reference, path const&); + { + It it; + ASSERT_SAME_TYPE(It&, decltype(++it)); + ASSERT_SAME_TYPE(It, decltype(it++)); + ASSERT_SAME_TYPE(It&, decltype(--it)); + ASSERT_SAME_TYPE(It, decltype(it--)); + ASSERT_SAME_TYPE(Traits::reference, decltype(*it)); + ASSERT_SAME_TYPE(Traits::pointer, decltype(it.operator->())); + ASSERT_SAME_TYPE(std::string const&, decltype(it->native())); + ASSERT_SAME_TYPE(bool, decltype(it == it)); + ASSERT_SAME_TYPE(bool, decltype(it != it)); + } + { + path const p; + ASSERT_SAME_TYPE(It, decltype(p.begin())); + ASSERT_SAME_TYPE(It, decltype(p.end())); + assert(p.begin() == p.end()); + } +} + +void checkBeginEndBasic() { + using namespace fs; + using It = path::iterator; + { + path const p; + ASSERT_SAME_TYPE(It, decltype(p.begin())); + ASSERT_SAME_TYPE(It, decltype(p.end())); + assert(p.begin() == p.end()); + } + { + path const p("foo"); + It default_constructed; + default_constructed = p.begin(); + assert(default_constructed == p.begin()); + assert(default_constructed != p.end()); + default_constructed = p.end(); + assert(default_constructed == p.end()); + assert(default_constructed != p.begin()); + } + { + path p("//root_name//first_dir////second_dir"); + const path expect[] = {"//root_name", "/", "first_dir", "second_dir"}; + assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect))); + assert(checkCollectionsEqualBackwards(p.begin(), p.end(), std::begin(expect), std::end(expect))); + + } + { + path p("////foo/bar/baz///"); + const path expect[] = {"/", "foo", "bar", "baz", "."}; + assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect))); + assert(checkCollectionsEqualBackwards(p.begin(), p.end(), std::begin(expect), std::end(expect))); + + } + +} + +int main() { + using namespace fs; + checkIteratorConcepts(); + checkBeginEndBasic(); // See path.decompose.pass.cpp for more tests. +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp new file mode 100644 index 0000000000000..1118497e06a86 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp @@ -0,0 +1,241 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& operator/=(path const&) +// template <class Source> +// path& operator/=(Source const&); +// template <class Source> +// path& append(Source const&); +// template <class InputIterator> +// path& append(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct AppendOperatorTestcase { + MultiStringType lhs; + MultiStringType rhs; + MultiStringType expect; +}; + +#define S(Str) MKSTR(Str) +const AppendOperatorTestcase Cases[] = + { + {S(""), S(""), S("")} + , {S("p1"), S("p2"), S("p1/p2")} + , {S("p1/"), S("p2"), S("p1/p2")} + , {S("p1"), S("/p2"), S("p1/p2")} + , {S("p1/"), S("/p2"), S("p1//p2")} + , {S("p1"), S("\\p2"), S("p1/\\p2")} + , {S("p1\\"), S("p2"), S("p1\\/p2")} + , {S("p1\\"), S("\\p2"), S("p1\\/\\p2")} + , {S("p1"), S(""), S("p1")} + , {S(""), S("p2"), S("p2")} + }; + + +const AppendOperatorTestcase LongLHSCases[] = + { + {S("p1"), S("p2"), S("p1/p2")} + , {S("p1/"), S("p2"), S("p1/p2")} + , {S("p1"), S("/p2"), S("p1/p2")} + }; +#undef S + + +// The append operator may need to allocate a temporary buffer before a code_cvt +// conversion. Test if this allocation occurs by: +// 1. Create a path, `LHS`, and reserve enough space to append `RHS`. +// This prevents `LHS` from allocating during the actual appending. +// 2. Create a `Source` object `RHS`, which represents a "large" string. +// (The string must not trigger the SSO) +// 3. Append `RHS` to `LHS` and check for the expected allocation behavior. +template <class CharT> +void doAppendSourceAllocTest(AppendOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + + const Ptr L = TC.lhs; + Str RShort = (Ptr)TC.rhs; + Str EShort = (Ptr)TC.expect; + assert(RShort.size() >= 2); + CharT c = RShort.back(); + RShort.append(100, c); + EShort.append(100, c); + const Ptr R = RShort.data(); + const Str& E = EShort; + std::size_t ReserveSize = E.size() + 3; + // basic_string + { + path LHS(L); PathReserve(LHS, ReserveSize); + Str RHS(R); + { + DisableAllocationGuard g; + LHS /= RHS; + } + assert(LHS == E); + } + // CharT* + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS /= RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS.append(RHS, StrEnd(RHS)); + } + assert(LHS == E); + } + // input iterator - For non-native char types, appends needs to copy the + // iterator range into a contigious block of memory before it can perform the + // code_cvt conversions. + // For "char" no allocations will be performed because no conversion is + // required. + bool DisableAllocations = std::is_same<CharT, char>::value; + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + { + RequireAllocationGuard g; // requires 1 or more allocations occur by default + if (DisableAllocations) g.requireExactly(0); + LHS /= RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + { + RequireAllocationGuard g; + if (DisableAllocations) g.requireExactly(0); + LHS.append(RHS, REnd); + } + assert(LHS == E); + } +} + +template <class CharT> +void doAppendSourceTest(AppendOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + const Ptr L = TC.lhs; + const Ptr R = TC.rhs; + const Ptr E = TC.expect; + // basic_string + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS /= RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Str RHS(R); + path& Ref = LHS.append(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + // Char* + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS /= RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.append(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.append(RHS, StrEnd(RHS)); + assert(LHS == E); + assert(&Ref == &LHS); + } + // iterators + { + path LHS(L); + InputIter RHS(R); + path& Ref = (LHS /= RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); InputIter RHS(R); + path& Ref = LHS.append(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + path& Ref = LHS.append(RHS, REnd); + assert(LHS == E); + assert(&Ref == &LHS); + } +} + +int main() +{ + using namespace fs; + for (auto const & TC : Cases) { + { + path LHS((const char*)TC.lhs); + path RHS((const char*)TC.rhs); + path& Ref = (LHS /= RHS); + assert(LHS == (const char*)TC.expect); + assert(&Ref == &LHS); + } + doAppendSourceTest<char> (TC); + doAppendSourceTest<wchar_t> (TC); + doAppendSourceTest<char16_t>(TC); + doAppendSourceTest<char32_t>(TC); + } + for (auto const & TC : LongLHSCases) { + doAppendSourceAllocTest<char>(TC); + doAppendSourceAllocTest<wchar_t>(TC); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp new file mode 100644 index 0000000000000..5c26f8464c121 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& operator=(path const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_copy_assignable<path>::value, ""); + static_assert(!std::is_nothrow_copy_assignable<path>::value, "should not be noexcept"); + const std::string s("foo"); + const path p(s); + path p2; + path& pref = (p2 = p); + assert(p.native() == s); + assert(p2.native() == s); + assert(&pref == &p2); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp new file mode 100644 index 0000000000000..7263424ad252f --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& operator=(path&&) noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_nothrow_move_assignable<path>::value, ""); + assert(globalMemCounter.checkOutstandingNewEq(0)); + const std::string s("we really really really really really really really " + "really really long string so that we allocate"); + assert(globalMemCounter.checkOutstandingNewEq(1)); + path p(s); + { + DisableAllocationGuard g; + path p2; + path& pref = (p2 = std::move(p)); + assert(p2.native() == s); + assert(p.native() != s); // Testing moved from state + assert(&pref == &p2); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp new file mode 100644 index 0000000000000..4c2d5112d10ba --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp @@ -0,0 +1,153 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class Source> +// path& operator=(Source const&); +// template <class Source> +// path& assign(Source const&); +// template <class InputIterator> +// path& assign(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +namespace fs = std::experimental::filesystem; + +template <class CharT> +void RunTestCase(MultiStringType const& MS) { + using namespace fs; + const char* Expect = MS; + const CharT* TestPath = MS; + const CharT* TestPathEnd = StrEnd(TestPath); + const std::size_t Size = TestPathEnd - TestPath; + const std::size_t SSize = StrEnd(Expect) - Expect; + assert(Size == SSize); + ////////////////////////////////////////////////////////////////////////////// + // basic_string<Char, Traits, Alloc> + { + const std::basic_string<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<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 + { + path p; PathReserve(p, Size + 1); + { + // char* pointers are contigious and can be used with code_cvt directly. + // no allocations needed. + DisableAllocationGuard g; + path& pref = (p = TestPath); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + path p; PathReserve(p, Size + 1); + { + DisableAllocationGuard g; + path& pref = p.assign(TestPath); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + path p; PathReserve(p, Size + 1); + { + DisableAllocationGuard g; + path& pref = p.assign(TestPath, TestPathEnd); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + ////////////////////////////////////////////////////////////////////////////// + // Iterators + { + using It = input_iterator<const CharT*>; + path p; PathReserve(p, Size + 1); + It it(TestPath); + { + // Iterators cannot be used with code_cvt directly. This assignment + // may allocate if it's larger than a "short-string". + path& pref = (p = it); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + using It = input_iterator<const CharT*>; + path p; PathReserve(p, Size + 1); + It it(TestPath); + { + path& pref = p.assign(it); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + using It = input_iterator<const CharT*>; + path p; PathReserve(p, Size + 1); + It it(TestPath); + It e(TestPathEnd); + { + path& pref = p.assign(it, e); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } +} + +int main() { + for (auto const& MS : PathList) { + RunTestCase<char>(MS); + RunTestCase<wchar_t>(MS); + RunTestCase<char16_t>(MS); + RunTestCase<char32_t>(MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp new file mode 100644 index 0000000000000..557c1b24d88f1 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// int compare(path const&) const noexcept; +// int compare(string_type const&) const; +// int compare(value_type const*) const; +// +// bool operator==(path const&, path const&) noexcept; +// bool operator!=(path const&, path const&) noexcept; +// bool operator< (path const&, path const&) noexcept; +// bool operator<=(path const&, path const&) noexcept; +// bool operator> (path const&, path const&) noexcept; +// bool operator>=(path const&, path const&) noexcept; +// +// size_t hash_value(path const&) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <vector> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct PathCompareTest { + const char* LHS; + const char* RHS; + int expect; +}; + +#define LONGA "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +#define LONGB "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" +#define LONGC "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" +#define LONGD "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" +const PathCompareTest CompareTestCases[] = +{ + {"", "", 0}, + {"a", "", 1}, + {"", "a", -1}, + {"a/b/c", "a/b/c", 0}, + {"b/a/c", "a/b/c", 1}, + {"a/b/c", "b/a/c", -1}, + {"a/b", "a/b/c", -1}, + {"a/b/c", "a/b", 1}, + {"a/b/", "a/b/.", 0}, + {"a/b//////", "a/b/////.", 0}, + {"a/.././b", "a///..//.////b", 0}, + {"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators + {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory + {"/foo/bar/", "/foo/bar", 1}, // trailing separator + {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0}, + { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1} + +}; +#undef LONGA +#undef LONGB +#undef LONGC +#undef LONGD + +int main() +{ + using namespace fs; + for (auto const & TC : CompareTestCases) { + const path p1(TC.LHS); + const path p2(TC.RHS); + const std::string R(TC.RHS); + const int E = TC.expect; + { // compare(...) functions + DisableAllocationGuard g; // none of these operations should allocate + + // check runtime results + int ret1 = p1.compare(p2); + int ret2 = p1.compare(R); + int ret3 = p1.compare(TC.RHS); + assert(ret1 == ret2 && ret1 == ret3); + int normalized_ret = ret1 < 0 ? -1 : (ret1 > 0 ? 1 : 0); + assert(normalized_ret == E); + + // check signatures + ASSERT_NOEXCEPT(p1.compare(p2)); + } + { // comparison operators + DisableAllocationGuard g; // none of these operations should allocate + + // Check runtime result + assert((p1 == p2) == (E == 0)); + assert((p1 != p2) == (E != 0)); + assert((p1 < p2) == (E < 0)); + assert((p1 <= p2) == (E <= 0)); + assert((p1 > p2) == (E > 0)); + assert((p1 >= p2) == (E >= 0)); + + // Check signatures + ASSERT_NOEXCEPT(p1 == p2); + ASSERT_NOEXCEPT(p1 != p2); + ASSERT_NOEXCEPT(p1 < p2); + ASSERT_NOEXCEPT(p1 <= p2); + ASSERT_NOEXCEPT(p1 > p2); + ASSERT_NOEXCEPT(p1 >= p2); + } + { // check hash values + auto h1 = hash_value(p1); + auto h2 = hash_value(p2); + assert((h1 == h2) == (p1 == p2)); + // check signature + ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1))); + ASSERT_NOEXCEPT(hash_value(p1)); + } + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp new file mode 100644 index 0000000000000..6e00afe0b49c3 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp @@ -0,0 +1,277 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// 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+=(value_type x); +// template <class Source> +// path& operator+=(const Source& x); +// template <class EcharT> +// path& operator+=(EcharT x); +// template <class Source> +// path& concat(const Source& x); +// template <class InputIterator> +// path& concat(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct ConcatOperatorTestcase { + MultiStringType lhs; + MultiStringType rhs; + MultiStringType expect; +}; + +#define LONGSTR "LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR" +#define S(Str) MKSTR(Str) +const ConcatOperatorTestcase Cases[] = + { + {S(""), S(""), S("")} + , {S("p1"), S("p2"), S("p1p2")} + , {S("p1/"), S("/p2"), S("p1//p2")} + , {S(""), S("\\foo/bar/baz"), S("\\foo/bar/baz")} + , {S("c:\\foo"), S(""), S("c:\\foo")} + , {S(LONGSTR), S("foo"), S(LONGSTR "foo")} + , {S("abcdefghijklmnopqrstuvwxyz/\\"), S("/\\123456789"), S("abcdefghijklmnopqrstuvwxyz/\\/\\123456789")} + }; +const ConcatOperatorTestcase LongLHSCases[] = + { + {S(""), S(LONGSTR), S(LONGSTR)} + , {S("p1/"), S(LONGSTR), S("p1/" LONGSTR)} + }; +const ConcatOperatorTestcase CharTestCases[] = + { + {S(""), S("P"), S("P")} + , {S("/fooba"), S("r"), S("/foobar")} + }; +#undef S +#undef LONGSTR + +// The concat operator may need to allocate a temporary buffer before a code_cvt +// conversion. Test if this allocation occurs by: +// 1. Create a path, `LHS`, and reserve enough space to append `RHS`. +// This prevents `LHS` from allocating during the actual appending. +// 2. Create a `Source` object `RHS`, which represents a "large" string. +// (The string must not trigger the SSO) +// 3. Concat `RHS` to `LHS` and check for the expected allocation behavior. +template <class CharT> +void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + + const Ptr L = TC.lhs; + const Ptr R = TC.rhs; + const Ptr E = TC.expect; + std::size_t ReserveSize = StrLen(E) + 1; + // basic_string + { + path LHS(L); PathReserve(LHS, ReserveSize); + Str RHS(R); + { + DisableAllocationGuard g; + LHS += RHS; + } + assert(LHS == E); + } + // CharT* + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS += RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS.concat(RHS, StrEnd(RHS)); + } + assert(LHS == E); + } + // input iterator - For non-native char types, appends needs to copy the + // iterator range into a contigious block of memory before it can perform the + // code_cvt conversions. + // For "char" no allocations will be performed because no conversion is + // required. + bool DisableAllocations = std::is_same<CharT, char>::value; + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + { + RequireAllocationGuard g; // requires 1 or more allocations occur by default + if (DisableAllocations) g.requireExactly(0); + LHS += RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + { + RequireAllocationGuard g; + if (DisableAllocations) g.requireExactly(0); + LHS.concat(RHS, REnd); + } + assert(LHS == E); + } +} + +template <class CharT> +void doConcatSourceTest(ConcatOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + const Ptr L = TC.lhs; + const Ptr R = TC.rhs; + const Ptr E = TC.expect; + // basic_string + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS += RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Str RHS(R); + path& Ref = LHS.concat(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + // Char* + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS += RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.concat(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.concat(RHS, StrEnd(RHS)); + assert(LHS == E); + assert(&Ref == &LHS); + } + // iterators + { + path LHS(L); + InputIter RHS(R); + path& Ref = (LHS += RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); InputIter RHS(R); + path& Ref = LHS.concat(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + path& Ref = LHS.concat(RHS, REnd); + assert(LHS == E); + assert(&Ref == &LHS); + } +} + +template <class CharT> +void doConcatECharTest(ConcatOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + const Ptr RStr = TC.rhs; + assert(StrLen(RStr) == 1); + const Ptr L = TC.lhs; + const CharT R = RStr[0]; + const Ptr E = TC.expect; + { + path LHS(L); + path& Ref = (LHS += R); + assert(LHS == E); + assert(&Ref == &LHS); + } +} + +int main() +{ + using namespace fs; + for (auto const & TC : Cases) { + { + path LHS((const char*)TC.lhs); + path 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); + doConcatSourceTest<char32_t>(TC); + } + for (auto const & TC : LongLHSCases) { + // Do path test + { + path LHS((const char*)TC.lhs); + path 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); + } + for (auto const& TC : CharTestCases) { + doConcatECharTest<char>(TC); + doConcatECharTest<wchar_t>(TC); + doConcatECharTest<char16_t>(TC); + doConcatECharTest<char32_t>(TC); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp new file mode 100644 index 0000000000000..67b8a04049ecc --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path(path const&) + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_copy_constructible<path>::value, ""); + static_assert(!std::is_nothrow_copy_constructible<path>::value, "should not be noexcept"); + const std::string s("foo"); + const path p(s); + path p2(p); + assert(p.native() == s); + assert(p2.native() == s); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp new file mode 100644 index 0000000000000..f26504616d50b --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path() noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_nothrow_default_constructible<path>::value, ""); + const path p; + assert(p.empty()); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp new file mode 100644 index 0000000000000..b8ac4b307005a --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path(path&&) noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_nothrow_move_constructible<path>::value, ""); + assert(globalMemCounter.checkOutstandingNewEq(0)); + const std::string s("we really really really really really really really " + "really really long string so that we allocate"); + assert(globalMemCounter.checkOutstandingNewEq(1)); + path p(s); + { + DisableAllocationGuard g; + path p2(std::move(p)); + assert(p2.native() == s); + assert(p.native() != s); // Testing moved from state + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp new file mode 100644 index 0000000000000..d89e7c815efb9 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class Source> +// path(const Source& source); +// template <class InputIterator> +// path(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +template <class CharT> +void RunTestCase(MultiStringType const& MS) { + using namespace fs; + const char* Expect = MS; + const CharT* TestPath = MS; + const CharT* TestPathEnd = StrEnd(TestPath); + const std::size_t Size = TestPathEnd - TestPath; + const std::size_t SSize = StrEnd(Expect) - Expect; + assert(Size == SSize); + // StringTypes + { + const std::basic_string<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); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + path p(TestPath, TestPathEnd); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + // Iterators + { + using It = input_iterator<const CharT*>; + path p(It{TestPath}); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + using It = input_iterator<const CharT*>; + path p(It{TestPath}, It{TestPathEnd}); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } +} + +int main() { + for (auto const& MS : PathList) { + RunTestCase<char>(MS); + RunTestCase<wchar_t>(MS); + RunTestCase<char16_t>(MS); + RunTestCase<char32_t>(MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp new file mode 100644 index 0000000000000..4c83481aaf2d8 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp @@ -0,0 +1,198 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// 8.4.9 path decomposition [path.decompose] +//------------------------------------------ +// path root_name() const; +// path root_directory() const; +// path root_path() const; +// path relative_path() const; +// path parent_path() const; +// path filename() const; +// path stem() const; +// path extension() const; +//------------------------------- +// 8.4.10 path query [path.query] +//------------------------------- +// bool empty() const noexcept; +// bool has_root_path() const; +// bool has_root_name() const; +// bool has_root_directory() const; +// bool has_relative_path() const; +// bool has_parent_path() const; +// bool has_filename() const; +// bool has_stem() const; +// bool has_extension() const; +// bool is_absolute() const; +// bool is_relative() const; +//------------------------------- +// 8.5 path iterators [path.itr] +//------------------------------- +// iterator begin() const; +// iterator end() const; + + +#include <experimental/filesystem> +#include <type_traits> +#include <vector> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +template <class It> +std::reverse_iterator<It> mkRev(It it) { + return std::reverse_iterator<It>(it); +} + + +namespace fs = std::experimental::filesystem; +struct PathDecomposeTestcase +{ + std::string raw; + std::vector<std::string> elements; + std::string root_path; + std::string root_name; + std::string root_directory; + std::string relative_path; + std::string parent_path; + std::string filename; +}; + +const PathDecomposeTestcase PathTestCases[] = + { + {"", {}, "", "", "", "", "", ""} + , {".", {"."}, "", "", "", ".", "", "."} + , {"..", {".."}, "", "", "", "..", "", ".."} + , {"foo", {"foo"}, "", "", "", "foo", "", "foo"} + , {"/", {"/"}, "/", "", "/", "", "", "/"} + , {"/foo", {"/", "foo"}, "/", "", "/", "foo", "/", "foo"} + , {"foo/", {"foo", "."}, "", "", "", "foo/", "foo", "."} + , {"/foo/", {"/", "foo", "."}, "/", "", "/", "foo/", "/foo", "."} + , {"foo/bar", {"foo","bar"}, "", "", "", "foo/bar", "foo", "bar"} + , {"/foo//bar", {"/","foo","bar"}, "/", "", "/", "foo/bar", "/foo", "bar"} + , {"//net", {"//net"}, "//net", "//net", "", "", "", "//net"} + , {"//net/foo", {"//net", "/", "foo"}, "//net/", "//net", "/", "foo", "//net/", "foo"} + , {"///foo///", {"/", "foo", "."}, "/", "", "/", "foo///", "///foo", "."} + , {"///foo///bar", {"/", "foo", "bar"}, "/", "", "/", "foo///bar", "///foo", "bar"} + , {"/.", {"/", "."}, "/", "", "/", ".", "/", "."} + , {"./", {".", "."}, "", "", "", "./", ".", "."} + , {"/..", {"/", ".."}, "/", "", "/", "..", "/", ".."} + , {"../", {"..", "."}, "", "", "", "../", "..", "."} + , {"foo/.", {"foo", "."}, "", "", "", "foo/.", "foo", "."} + , {"foo/..", {"foo", ".."}, "", "", "", "foo/..", "foo", ".."} + , {"foo/./", {"foo", ".", "."}, "", "", "", "foo/./", "foo/.", "."} + , {"foo/./bar", {"foo", ".", "bar"}, "", "", "", "foo/./bar", "foo/.", "bar"} + , {"foo/../", {"foo", "..", "."}, "", "", "", "foo/../", "foo/..", "."} + , {"foo/../bar", {"foo", "..", "bar"}, "", "", "", "foo/../bar", "foo/..", "bar"} + , {"c:", {"c:"}, "", "", "", "c:", "", "c:"} + , {"c:/", {"c:", "."}, "", "", "", "c:/", "c:", "."} + , {"c:foo", {"c:foo"}, "", "", "", "c:foo", "", "c:foo"} + , {"c:/foo", {"c:", "foo"}, "", "", "", "c:/foo", "c:", "foo"} + , {"c:foo/", {"c:foo", "."}, "", "", "", "c:foo/", "c:foo", "."} + , {"c:/foo/", {"c:", "foo", "."}, "", "", "", "c:/foo/", "c:/foo", "."} + , {"c:/foo/bar", {"c:", "foo", "bar"}, "", "", "", "c:/foo/bar", "c:/foo", "bar"} + , {"prn:", {"prn:"}, "", "", "", "prn:", "", "prn:"} + , {"c:\\", {"c:\\"}, "", "", "", "c:\\", "", "c:\\"} + , {"c:\\foo", {"c:\\foo"}, "", "", "", "c:\\foo", "", "c:\\foo"} + , {"c:foo\\", {"c:foo\\"}, "", "", "", "c:foo\\", "", "c:foo\\"} + , {"c:\\foo\\", {"c:\\foo\\"}, "", "", "", "c:\\foo\\", "", "c:\\foo\\"} + , {"c:\\foo/", {"c:\\foo", "."}, "", "", "", "c:\\foo/", "c:\\foo", "."} + , {"c:/foo\\bar", {"c:", "foo\\bar"}, "", "", "", "c:/foo\\bar", "c:", "foo\\bar"} + , {"//", {"//"}, "//", "//", "", "", "", "//"} + }; + +void decompPathTest() +{ + using namespace fs; + for (auto const & TC : PathTestCases) { + path p(TC.raw); + assert(p == TC.raw); + + assert(p.root_path() == TC.root_path); + assert(p.has_root_path() != TC.root_path.empty()); + + assert(p.root_name() == TC.root_name); + assert(p.has_root_name() != TC.root_name.empty()); + + assert(p.root_directory() == TC.root_directory); + assert(p.has_root_directory() != TC.root_directory.empty()); + + assert(p.relative_path() == TC.relative_path); + assert(p.has_relative_path() != TC.relative_path.empty()); + + assert(p.parent_path() == TC.parent_path); + assert(p.has_parent_path() != TC.parent_path.empty()); + + assert(p.filename() == TC.filename); + assert(p.has_filename() != TC.filename.empty()); + + assert(p.is_absolute() == p.has_root_directory()); + assert(p.is_relative() != p.is_absolute()); + + assert(checkCollectionsEqual(p.begin(), p.end(), + TC.elements.begin(), TC.elements.end())); + // check backwards + assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), + TC.elements.rbegin(), TC.elements.rend())); + } +} + + +struct FilenameDecompTestcase +{ + std::string raw; + std::string filename; + std::string stem; + std::string extension; +}; + +const FilenameDecompTestcase FilenameTestCases[] = +{ + {"", "", "", ""} + , {".", ".", ".", ""} + , {"..", "..", "..", ""} + , {"/", "/", "/", ""} + , {"foo", "foo", "foo", ""} + , {"/foo/bar.txt", "bar.txt", "bar", ".txt"} + , {"foo..txt", "foo..txt", "foo.", ".txt"} +}; + + +void decompFilenameTest() +{ + using namespace fs; + for (auto const & TC : FilenameTestCases) { + path p(TC.raw); + assert(p == TC.raw); + + assert(p.filename() == TC.filename); + assert(p.has_filename() != TC.filename.empty()); + + assert(p.stem() == TC.stem); + assert(p.has_stem() != TC.stem.empty()); + + assert(p.extension() == TC.extension); + assert(p.has_extension() != TC.extension.empty()); + } +} + +int main() +{ + decompPathTest(); + decompFilenameTest(); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp new file mode 100644 index 0000000000000..47e94c9a213f6 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class ECharT, class Traits = char_traits<ECharT>, +// class Allocator = allocator<ECharT>> +// basic_string<ECharT, Traits, Allocator> +// generic_string(const Allocator& a = Allocator()) const; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + +// generic_string<C, T, A> forwards to string<C, T, A>. Tests for +// string<C, T, A>() are in "path.native.op/string_alloc.pass.cpp". +// generic_string is minimally tested here. +int main() +{ + using namespace fs; + using CharT = wchar_t; + using Traits = std::char_traits<CharT>; + using Alloc = malloc_allocator<CharT>; + using Str = std::basic_string<CharT, Traits, Alloc>; + const wchar_t* expect = longString; + const path p((const char*)longString); + { + DisableAllocationGuard g; + Alloc a; + Alloc::disable_default_constructor = true; + Str s = p.generic_string<wchar_t, Traits, Alloc>(a); + assert(s == expect); + assert(Alloc::alloc_count > 0); + assert(Alloc::outstanding_alloc() == 1); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp new file mode 100644 index 0000000000000..81d06843640db --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// std::string generic_string() const; +// std::wstring generic_wstring() const; +// std::u8string generic_u8string() const; +// std::u16string generic_u16string() const; +// std::u32string generic_u32string() const; + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + +int main() +{ + using namespace fs; + auto const& MS = longString; + const char* value = longString; + const path p(value); + { + std::string s = p.generic_string(); + assert(s == value); + } + { + std::string s = p.generic_u8string(); + assert(s == (const char*)MS); + } + { + std::wstring s = p.generic_wstring(); + assert(s == (const wchar_t*)MS); + } + { + std::u16string s = p.generic_u16string(); + assert(s == (const char16_t*)MS); + } + { + std::u32string s = p.generic_u32string(); + assert(s == (const char32_t*)MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp new file mode 100644 index 0000000000000..5be934968c468 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// void clear() noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + const path p("/foo/bar/baz"); + { + path p; + ASSERT_NOEXCEPT(p.clear()); + ASSERT_SAME_TYPE(void, decltype(p.clear())); + p.clear(); + assert(p.empty()); + } + { + path p2(p); + assert(p == p2); + p2.clear(); + assert(p2.empty()); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp new file mode 100644 index 0000000000000..559538cf0ec42 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& make_preferred() + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct MakePreferredTestcase { + const char* value; +}; + +const MakePreferredTestcase TestCases[] = + { + {""} + , {"hello_world"} + , {"/"} + , {"/foo/bar/baz/"} + , {"\\"} + , {"\\foo\\bar\\baz\\"} + , {"\\foo\\/bar\\/baz\\"} + }; + +int main() +{ + // This operation is an identity operation on linux. + using namespace fs; + for (auto const & TC : TestCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.make_preferred()); + assert(p.native() == TC.value); + assert(&Ref == &p); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp new file mode 100644 index 0000000000000..4ad9084dbf81e --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& remove_filename() + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct RemoveFilenameTestcase { + const char* value; + const char* expect; +}; + +const RemoveFilenameTestcase TestCases[] = + { + {"", ""} + , {"/", ""} + , {"\\", ""} + , {".", ""} + , {"..", ""} + , {"/foo", "/"} + , {"/foo/", "/foo"} + , {"/foo/.", "/foo"} + , {"/foo/..", "/foo"} + , {"/foo/////", "/foo"} + , {"/foo\\\\", "/"} + , {"/foo//\\/", "/foo//\\"} + , {"file.txt", ""} + , {"bar/../baz/./file.txt", "bar/../baz/."} + }; + +int main() +{ + using namespace fs; + for (auto const & TC : TestCases) { + path const p_orig(TC.value); + path p(p_orig); + assert(p == TC.value); + path& Ref = (p.remove_filename()); + assert(p == TC.expect); + assert(&Ref == &p); + { + const path parentp = p_orig.parent_path(); + if (parentp == p_orig.root_name()) { + + assert(p.empty()); + } else { + assert(p == parentp); + } + } + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp new file mode 100644 index 0000000000000..98f6e9b88ab8c --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& replace_extension(path const& p = path()) + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct ReplaceExtensionTestcase { + const char* value; + const char* expect; + const char* extension; +}; + +const ReplaceExtensionTestcase TestCases[] = + { + {"", "", ""} + , {"foo.cpp", "foo", ""} + , {"foo.cpp", "foo.", "."} + , {"foo..cpp", "foo..txt", "txt"} + , {"", ".txt", "txt"} + , {"", ".txt", ".txt"} + , {"/foo", "/foo.txt", ".txt"} + , {"/foo", "/foo.txt", "txt"} + , {"/foo.cpp", "/foo.txt", ".txt"} + , {"/foo.cpp", "/foo.txt", "txt"} + }; +const ReplaceExtensionTestcase NoArgCases[] = + { + {"", "", ""} + , {"foo", "foo", ""} + , {"foo.cpp", "foo", ""} + , {"foo..cpp", "foo.", ""} +}; + +int main() +{ + using namespace fs; + for (auto const & TC : TestCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.replace_extension(TC.extension)); + assert(p == TC.expect); + assert(&Ref == &p); + } + for (auto const& TC : NoArgCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.replace_extension()); + assert(p == TC.expect); + assert(&Ref == &p); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp new file mode 100644 index 0000000000000..66c97218c8331 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& replace_filename() + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct ReplaceFilenameTestcase { + const char* value; + const char* expect; + const char* filename; +}; + +const ReplaceFilenameTestcase TestCases[] = + { + {"/foo", "/bar", "bar"} + , {"/foo", "/", ""} + , {"foo", "bar", "bar"} + , {"/", "bar", "bar"} + , {"\\", "bar", "bar"} + , {"///", "bar", "bar"} + , {"\\\\", "bar", "bar"} + , {"\\/\\", "\\/bar", "bar"} + , {".", "bar", "bar"} + , {"..", "bar", "bar"} + , {"/foo\\baz/bong/", "/foo\\baz/bong/bar", "bar"} + , {"/foo\\baz/bong", "/foo\\baz/bar", "bar"} + }; + +int main() +{ + using namespace fs; + for (auto const & TC : TestCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.replace_filename(TC.filename)); + assert(p == TC.expect); + assert(&Ref == &p); + // Tests Effects "as-if": remove_filename() append(filename) + { + path p2(TC.value); + path replace(TC.filename); + p2.remove_filename(); + p2 /= replace; + assert(p2 == p); + } + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp new file mode 100644 index 0000000000000..04bbe3751a59f --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// void swap(path& rhs) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct SwapTestcase { + const char* value1; + const char* value2; +}; + +#define LONG_STR1 "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG" +#define LONG_STR2 "_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2" +const SwapTestcase TestCases[] = + { + {"", ""} + , {"shortstr", LONG_STR1} + , {LONG_STR1, "shortstr"} + , {LONG_STR1, LONG_STR2} + }; +#undef LONG_STR1 +#undef LONG_STR2 + +int main() +{ + using namespace fs; + { + path p; + ASSERT_NOEXCEPT(p.swap(p)); + ASSERT_SAME_TYPE(void, decltype(p.swap(p))); + } + for (auto const & TC : TestCases) { + path p1(TC.value1); + path p2(TC.value2); + { + DisableAllocationGuard g; + p1.swap(p2); + } + assert(p1 == TC.value2); + assert(p2 == TC.value1); + { + DisableAllocationGuard g; + p1.swap(p2); + } + assert(p1 == TC.value1); + assert(p2 == TC.value2); + } + // self-swap + { + const char* Val = "aoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeu"; + path p1(Val); + assert(p1 == Val); + { + DisableAllocationGuard g; + p1.swap(p1); + } + assert(p1 == Val); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp new file mode 100644 index 0000000000000..7cf3564bb9b1b --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp @@ -0,0 +1,43 @@ + +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// const value_type* c_str() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + const char* const value = "hello world"; + const std::string str_value = value; + path p(value); + { // Check signature + ASSERT_SAME_TYPE(path::value_type const*, decltype(p.c_str())); + ASSERT_NOEXCEPT(p.c_str()); + } + { + path p(value); + assert(p.c_str() == str_value); + assert(p.native().c_str() == p.c_str()); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp new file mode 100644 index 0000000000000..2a83fef9f9e64 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// std::string string() const; +// std::wstring wstring() const; +// std::u8string u8string() const; +// std::u16string u16string() const; +// std::u32string u32string() const; + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + +int main() +{ + using namespace fs; + auto const& MS = longString; + const char* value = longString; + const path p(value); + { + std::string s = p.string(); + assert(s == value); + } + { + std::string s = p.u8string(); + assert(s == (const char*)MS); + } + { + std::wstring s = p.wstring(); + assert(s == (const wchar_t*)MS); + } + { + std::u16string s = p.u16string(); + assert(s == (const char16_t*)MS); + } + { + std::u32string s = p.u32string(); + assert(s == (const char32_t*)MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp new file mode 100644 index 0000000000000..7f8df27faf0ad --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// const string_type& native() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + const char* const value = "hello world"; + path p(value); + { // Check signature + ASSERT_SAME_TYPE(path::string_type const&, decltype(p.native())); + ASSERT_NOEXCEPT(p.native()); + } + { // native() is tested elsewhere + path p(value); + assert(p.native() == value); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp new file mode 100644 index 0000000000000..9ef83f989aa55 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp @@ -0,0 +1,47 @@ + +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// operator string_type() const; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + using string_type = path::string_type; + const char* const value = "hello world"; + path p(value); + { // Check signature + static_assert(std::is_convertible<path, string_type>::value, ""); + static_assert(std::is_constructible<string_type, path>::value, ""); + ASSERT_SAME_TYPE(string_type, decltype(p.operator string_type())); + ASSERT_NOT_NOEXCEPT(p.operator string_type()); + } + { + path p(value); + assert(p.native() == value); + string_type s = p; + assert(s == value); + assert(p == value); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp new file mode 100644 index 0000000000000..e983297350001 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp @@ -0,0 +1,138 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class ECharT, class Traits = char_traits<ECharT>, +// class Allocator = allocator<ECharT>> +// basic_string<ECharT, Traits, Allocator> +// string(const Allocator& a = Allocator()) const; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +// the SSO is always triggered for strings of size 2. +MultiStringType shortString = MKSTR("a"); +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + +template <class CharT> +void doShortStringTest(MultiStringType const& MS) { + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using Alloc = std::allocator<CharT>; + Ptr value = MS; + const path p((const char*)MS); + { + DisableAllocationGuard g; + Str s = p.string<CharT>(); + assert(s == value); + Str s2 = p.string<CharT>(Alloc{}); + assert(s2 == value); + } + using MAlloc = malloc_allocator<CharT>; + MAlloc::reset(); + { + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + AStr s = p.string<CharT, Traits, MAlloc>(); + assert(s == value); + assert(MAlloc::alloc_count == 0); + assert(MAlloc::outstanding_alloc() == 0); + } + MAlloc::reset(); + { // Other allocator - provided copy + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + MAlloc a; + // don't allow another allocator to be default constructed. + MAlloc::disable_default_constructor = true; + AStr s = p.string<CharT, Traits, MAlloc>(a); + assert(s == value); + assert(MAlloc::alloc_count == 0); + assert(MAlloc::outstanding_alloc() == 0); + } + MAlloc::reset(); +} + +template <class CharT> +void doLongStringTest(MultiStringType const& MS) { + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + Ptr value = MS; + const path p((const char*)MS); + { // Default allocator + using Alloc = std::allocator<CharT>; + Str s = p.string<CharT>(); + assert(s == value); + Str s2 = p.string<CharT>(Alloc{}); + assert(s2 == value); + } + using MAlloc = malloc_allocator<CharT>; + MAlloc::reset(); + { // Other allocator - default construct + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + AStr s = p.string<CharT, Traits, MAlloc>(); + assert(s == value); + assert(MAlloc::alloc_count > 0); + assert(MAlloc::outstanding_alloc() == 1); + } + MAlloc::reset(); + { // Other allocator - provided copy + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + MAlloc a; + // don't allow another allocator to be default constructed. + MAlloc::disable_default_constructor = true; + AStr s = p.string<CharT, Traits, MAlloc>(a); + assert(s == value); + assert(MAlloc::alloc_count > 0); + assert(MAlloc::outstanding_alloc() == 1); + } + MAlloc::reset(); + ///////////////////////////////////////////////////////////////////////////// +} + +int main() +{ + using namespace fs; + { + auto const& S = shortString; + doShortStringTest<char>(S); + doShortStringTest<wchar_t>(S); + doShortStringTest<char16_t>(S); + doShortStringTest<char32_t>(S); + } + { + auto const& S = longString; + doLongStringTest<char>(S); + doLongStringTest<wchar_t>(S); + doLongStringTest<char16_t>(S); + doLongStringTest<char32_t>(S); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp new file mode 100644 index 0000000000000..9cf37d4cd537a --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +//------------------------------- +// 8.4.10 path query [path.query] +//------------------------------- +// bool empty() const noexcept; +// bool has_root_path() const; +// bool has_root_name() const; +// bool has_root_directory() const; +// bool has_relative_path() const; +// bool has_parent_path() const; +// bool has_filename() const; +// bool has_stem() const; +// bool has_extension() const; +// bool is_absolute() const; +// bool is_relative() const; + +// tested in path.decompose +int main() {} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp new file mode 100644 index 0000000000000..58983778446a9 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// path operator/(path const&, path const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +// This is mainly tested via the member append functions. +int main() +{ + using namespace fs; + path p1("abc"); + path p2("def"); + path p3 = p1 / p2; + assert(p3 == "abc/def"); +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp new file mode 100644 index 0000000000000..28867432c61de --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp @@ -0,0 +1,14 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// The comparison operators are tested as part of [path.compare] +// in class.path/path.members/path.compare.pass.cpp +int main() {} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp new file mode 100644 index 0000000000000..b03b8008b6220 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp @@ -0,0 +1,14 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// The "hash_value" function is tested as part of [path.compare] +// in class.path/path.members/path.compare.pass.cpp +int main() {} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp new file mode 100644 index 0000000000000..4853994b49500 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// template <class Source> +// path u8path(Source const&); +// template <class InputIter> +// path u8path(InputIter, InputIter); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + const char* In1 = "abcd/efg"; + const std::string In2(In1); + const auto In3 = In2.begin(); + const auto In3End = In2.end(); + { + path p = fs::u8path(In1); + assert(p == In1); + } + { + path p = fs::u8path(In2); + assert(p == In1); + } + { + path p = fs::u8path(In3); + assert(p == In1); + } + { + path p = fs::u8path(In3, In3End); + assert(p == In1); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp new file mode 100644 index 0000000000000..e8d150f1e39df --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class charT, class traits> +// basic_ostream<charT, traits>& +// operator<<(basic_ostream<charT, traits>& os, const path& p); +// +// template <class charT, class traits> +// basic_istream<charT, traits>& +// operator>>(basic_istream<charT, traits>& is, path& p) +// + +#include <experimental/filesystem> +#include <type_traits> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789"); +MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\""); + +template <class CharT> +void doIOTest() { + using namespace fs; + using Ptr = const CharT*; + using StrStream = std::basic_stringstream<CharT>; + const char* const InCStr = InStr; + const Ptr E = OutStr; + const path p((const char*)InStr); + StrStream ss; + { // test output + auto& ret = (ss << p); + assert(ss.str() == E); + assert(&ret == &ss); + } + { // test input + path p_in; + auto& ret = ss >> p_in; + assert(p_in.native() == (const char*)InStr); + assert(&ret == &ss); + } +} + + +int main() { + doIOTest<char>(); + doIOTest<wchar_t>(); + //doIOTest<char16_t>(); + //doIOTest<char32_t>(); +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp new file mode 100644 index 0000000000000..3a9b48b2669a7 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class charT, class traits> +// basic_ostream<charT, traits>& +// operator<<(basic_ostream<charT, traits>& os, const path& p); +// +// template <class charT, class traits> +// basic_istream<charT, traits>& +// operator>>(basic_istream<charT, traits>& is, path& p) +// + +// TODO(EricWF) This test fails because "std::quoted" fails to compile +// for char16_t and char32_t types. Combine with path.io.pass.cpp when this +// passes. +// XFAIL: * + +#include <experimental/filesystem> +#include <type_traits> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789"); +MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\""); + +template <class CharT> +void doIOTest() { + using namespace fs; + using Ptr = const CharT*; + using StrStream = std::basic_stringstream<CharT>; + const char* const InCStr = InStr; + const Ptr E = OutStr; + const path p((const char*)InStr); + StrStream ss; + { // test output + auto& ret = (ss << p); + assert(ss.str() == E); + assert(&ret == &ss); + } + { // test input + path p_in; + auto& ret = ss >> p_in; + assert(p_in.native() == (const char*)InStr); + assert(&ret == &ss); + } +} + + +int main() { + doIOTest<char16_t>(); + doIOTest<char32_t>(); +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp new file mode 100644 index 0000000000000..8d180463a5776 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void swap(path& lhs, path& rhs) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +// NOTE: this is tested in path.members/path.modifiers via the member swap. +int main() +{ + using namespace fs; + const char* value1 = "foo/bar/baz"; + const char* value2 = "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG"; + path p1(value1); + path p2(value2); + { + using namespace std; using namespace fs; + ASSERT_NOEXCEPT(swap(p1, p2)); + ASSERT_SAME_TYPE(void, decltype(swap(p1, p2))); + } + { + DisableAllocationGuard g; + using namespace std; + using namespace fs; + swap(p1, p2); + assert(p1.native() == value2); + assert(p2.native() == value1); + swap(p1, p2); + assert(p1.native() == value1); + assert(p2.native() == value2); + } +} diff --git a/test/std/experimental/filesystem/class.path/synop.pass.cpp b/test/std/experimental/filesystem/class.path/synop.pass.cpp new file mode 100644 index 0000000000000..b0a7b5cd65e21 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/synop.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// typedef ... value_type; +// typedef basic_string<value_type> string_type; +// static constexpr value_type preferred_separator = ...; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + ASSERT_SAME_TYPE(path::value_type, char); + ASSERT_SAME_TYPE(path::string_type, std::basic_string<path::value_type>); + { + ASSERT_SAME_TYPE(const path::value_type, decltype(path::preferred_separator)); + static_assert(path::preferred_separator == '/', ""); + // Make preferred_separator ODR used by taking it's address. + const char* dummy = &path::preferred_separator; + ((void)dummy); + } +} diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp new file mode 100644 index 0000000000000..4dbd599e543a3 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_recursive_directory_iterator(recursive_recursive_directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_copy_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = recursive_directory_iterator; + static_assert(std::is_copy_constructible<D>::value, ""); + //static_assert(!std::is_nothrow_copy_constructible<D>::value, ""); +} + +TEST_CASE(test_copy_end_iterator) +{ + const recursive_directory_iterator endIt; + recursive_directory_iterator it(endIt); + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt{}; + + // build 'it' up with "interesting" non-default state so we can test + // that it gets copied. We want to get 'it' into a state such that: + // it.options() != directory_options::none + // it.depth() != 0 + // it.recursion_pending() != true + const directory_options opts = directory_options::skip_permission_denied; + recursive_directory_iterator it(testDir, opts); + TEST_REQUIRE(it != endIt); + while (it.depth() == 0) { + ++it; + TEST_REQUIRE(it != endIt); + } + it.disable_recursion_pending(); + TEST_CHECK(it.options() == opts); + TEST_CHECK(it.depth() == 1); + TEST_CHECK(it.recursion_pending() == false); + const path entry = *it; + + // OPERATION UNDER TEST // + const recursive_directory_iterator it2(it); + // ------------------- // + + TEST_REQUIRE(it2 == it); + TEST_CHECK(*it2 == entry); + TEST_CHECK(it2.depth() == 1); + TEST_CHECK(it2.recursion_pending() == false); + TEST_CHECK(it != endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp new file mode 100644 index 0000000000000..3e9257eac8fa1 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator& operator=(recursive_directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_copy_assign_tests) + +recursive_directory_iterator createInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::skip_permission_denied + // it.depth() == 1 + // it.recursion_pending() == true +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::skip_permission_denied); + TEST_ASSERT(it != endIt); + while (it.depth() != 1) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 1); + it.disable_recursion_pending(); + return it; +} + + +recursive_directory_iterator createDifferentInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::follow_directory_symlink + // it.depth() == 2 + // it.recursion_pending() == false +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::follow_directory_symlink); + TEST_ASSERT(it != endIt); + while (it.depth() != 2) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 2); + return it; +} + +TEST_CASE(test_assignment_signature) { + using D = recursive_directory_iterator; + static_assert(std::is_copy_assignable<D>::value, ""); +} + +TEST_CASE(test_copy_to_end_iterator) +{ + const recursive_directory_iterator endIt; + + const recursive_directory_iterator from = createInterestingIterator(); + const path entry = *from; + + recursive_directory_iterator to; + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(*to == entry); + TEST_CHECK(to.options() == from.options()); + TEST_CHECK(to.depth() == from.depth()); + TEST_CHECK(to.recursion_pending() == from.recursion_pending()); +} + + +TEST_CASE(test_copy_from_end_iterator) +{ + const recursive_directory_iterator from; + recursive_directory_iterator to = createInterestingIterator(); + + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(to == recursive_directory_iterator{}); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const recursive_directory_iterator endIt; + + const recursive_directory_iterator it = createInterestingIterator(); + const path entry = *it; + + recursive_directory_iterator it2 = createDifferentInterestingIterator(); + TEST_REQUIRE(it2 != it); + TEST_CHECK(it2.options() != it.options()); + TEST_CHECK(it2.depth() != it.depth()); + TEST_CHECK(it2.recursion_pending() != it.recursion_pending()); + TEST_CHECK(*it2 != entry); + + it2 = it; + TEST_REQUIRE(it2 == it); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == entry); +} + +TEST_CASE(test_returns_reference_to_self) +{ + const recursive_directory_iterator it; + recursive_directory_iterator it2; + recursive_directory_iterator& ref = (it2 = it); + TEST_CHECK(&ref == &it2); +} + +TEST_CASE(test_self_copy) +{ + // Create two non-equal iterators that have exactly the same state. + recursive_directory_iterator it = createInterestingIterator(); + recursive_directory_iterator it2 = createInterestingIterator(); + TEST_CHECK(it != it2); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); + + // perform a self-copy and check that the state still matches the + // other unmodified iterator. + recursive_directory_iterator const& cit = it; + it = cit; + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp new file mode 100644 index 0000000000000..1cddccd0d7245 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp @@ -0,0 +1,240 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// +// explicit recursive_directory_iterator(const path& p); +// recursive_directory_iterator(const path& p, directory_options options); +// recursive_directory_iterator(const path& p, error_code& ec) noexcept; +// recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; + + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +using RDI = recursive_directory_iterator; + +TEST_SUITE(recursive_directory_iterator_constructor_tests) + +TEST_CASE(test_constructor_signatures) +{ + using D = recursive_directory_iterator; + + // explicit directory_iterator(path const&); + static_assert(!std::is_convertible<path, D>::value, ""); + static_assert(std::is_constructible<D, path>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path>::value, ""); + + // directory_iterator(path const&, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, ""); + + // directory_iterator(path const&, directory_options); + static_assert(std::is_constructible<D, path, directory_options>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, ""); + + // directory_iterator(path const&, directory_options, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, ""); +} + +TEST_CASE(test_construction_from_bad_path) +{ + std::error_code ec; + directory_options opts = directory_options::none; + const RDI endIt; + + const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink }; + for (path const& testPath : testPaths) + { + { + RDI it(testPath, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + RDI it(testPath, opts, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, RDI(testPath)); + TEST_CHECK_THROW(filesystem_error, RDI(testPath, opts)); + } + } +} + +TEST_CASE(access_denied_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testDir = env.make_env_path("dir1"); + path const testFile = testDir / "testFile"; + env.create_dir(testDir); + env.create_file(testFile, 42); + + // Test that we can iterator over the directory before changing the perms + RDI it(testDir); + TEST_REQUIRE(it != RDI{}); + + // Change the permissions so we can no longer iterate + permissions(testDir, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + RDI it(testDir, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == RDI{}); + } + // Check that construction does not report an error when + // 'skip_permissions_denied' is given. + { + std::error_code ec; + RDI it(testDir, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it == RDI{}); + } +} + + +TEST_CASE(access_denied_to_file_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testFile = env.make_env_path("file1"); + env.create_file(testFile, 42); + + // Change the permissions so we can no longer iterate + permissions(testFile, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + RDI it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == RDI{}); + } + // Check that construction still fails when 'skip_permissions_denied' is given + // because we tried to open a file and not a directory. + { + std::error_code ec; + RDI it(testFile, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == RDI{}); + } +} + +TEST_CASE(test_open_on_empty_directory_equals_end) +{ + scoped_test_env env; + const path testDir = env.make_env_path("dir1"); + env.create_dir(testDir); + + const RDI endIt; + { + std::error_code ec; + RDI it(testDir, ec); + TEST_CHECK(!ec); + TEST_CHECK(it == endIt); + } + { + RDI it(testDir); + TEST_CHECK(it == endIt); + } +} + +TEST_CASE(test_open_on_directory_succeeds) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const RDI endIt{}; + + { + std::error_code ec; + RDI it(testDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } + { + RDI it(testDir); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } +} + +TEST_CASE(test_open_on_file_fails) +{ + const path testFile = StaticEnv::File; + const RDI endIt{}; + { + std::error_code ec; + RDI it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, RDI(testFile)); + } +} + +TEST_CASE(test_options_post_conditions) +{ + const path goodDir = StaticEnv::Dir; + const path badDir = StaticEnv::DNE; + + { + std::error_code ec; + + RDI it1(goodDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it1.options() == directory_options::none); + + RDI it2(badDir, ec); + TEST_REQUIRE(ec); + TEST_REQUIRE(it2 == RDI{}); + } + { + std::error_code ec; + const directory_options opts = directory_options::skip_permission_denied; + + RDI it1(goodDir, opts, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it1.options() == opts); + + RDI it2(badDir, opts, ec); + TEST_REQUIRE(ec); + TEST_REQUIRE(it2 == RDI{}); + } + { + RDI it(goodDir); + TEST_CHECK(it.options() == directory_options::none); + } + { + const directory_options opts = directory_options::follow_directory_symlink; + RDI it(goodDir, opts); + TEST_CHECK(it.options() == opts); + } +} +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp new file mode 100644 index 0000000000000..676e6f27c886b --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// int depth() const + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_depth_tests) + +TEST_CASE(test_depth) +{ + const path testDir = StaticEnv::Dir; + const path DirDepth1 = StaticEnv::Dir2; + const path DirDepth2 = StaticEnv::Dir3; + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it.depth() == 0); + + bool seen_d1, seen_d2; + seen_d1 = seen_d2 = false; + + while (it != endIt) { + const path entry = *it; + const path parent = entry.parent_path(); + if (parent == testDir) { + TEST_CHECK(it.depth() == 0); + } else if (parent == DirDepth1) { + TEST_CHECK(it.depth() == 1); + seen_d1 = true; + } else if (parent == DirDepth2) { + TEST_CHECK(it.depth() == 2); + seen_d2 = true; + } else { + TEST_CHECK(!"Unexpected depth while iterating over static env"); + } + ++it; + } + TEST_REQUIRE(seen_d1 && seen_d2); + TEST_CHECK(it == endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp new file mode 100644 index 0000000000000..387c6145b6a50 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// void disable_recursion_pending(); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_disable_recursion_pending_tests) + +// NOTE: The main semantics of disable_recursion_pending are tested +// in the 'recursion_pending()' tests. +TEST_CASE(basic_test) +{ + recursive_directory_iterator it(StaticEnv::Dir); + TEST_REQUIRE(it.recursion_pending() == true); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp new file mode 100644 index 0000000000000..e67fc2f20f6ef --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp @@ -0,0 +1,240 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator& operator++(); +// recursive_directory_iterator& increment(error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_increment_tests) + +TEST_CASE(test_increment_signatures) +{ + using D = recursive_directory_iterator; + recursive_directory_iterator d; ((void)d); + std::error_code ec; ((void)ec); + + ASSERT_SAME_TYPE(decltype(++d), recursive_directory_iterator&); + ASSERT_NOT_NOEXCEPT(++d); + + ASSERT_SAME_TYPE(decltype(d.increment(ec)), recursive_directory_iterator&); + ASSERT_NOEXCEPT(d.increment(ec)); +} + +TEST_CASE(test_prefix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + recursive_directory_iterator& it_ref = ++it; + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_postfix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + const path entry2 = *it++; + TEST_CHECK(entry2 == entry); + } + TEST_CHECK(it == endIt); +} + + +TEST_CASE(test_increment_method) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + recursive_directory_iterator& it_ref = it.increment(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_follow_symlinks) +{ + const path testDir = StaticEnv::Dir; + auto const& IterList = StaticEnv::RecDirFollowSymlinksIterationList; + + const std::set<path> dir_contents(std::begin(IterList), std::end(IterList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, + directory_options::follow_directory_symlink, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + recursive_directory_iterator& it_ref = it.increment(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(&it_ref == &it); + } + TEST_CHECK(it == endIt); +} + +TEST_CASE(access_denied_on_recursion_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + const path testFiles[] = { + env.create_dir("dir1"), + env.create_dir("dir1/dir2"), + env.create_file("dir1/dir2/file1"), + env.create_file("dir1/file2") + }; + const path startDir = testFiles[0]; + const path permDeniedDir = testFiles[1]; + const path otherFile = testFiles[3]; + auto SkipEPerm = directory_options::skip_permission_denied; + + // Change the permissions so we can no longer iterate + permissions(permDeniedDir, perms::none); + + const recursive_directory_iterator endIt; + + // Test that recursion resulting in a "EACCESS" error is not ignored + // by default. + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(startDir, ec); + TEST_REQUIRE(ec != GetTestEC()); + TEST_REQUIRE(!ec); + while (it != endIt && it->path() != permDeniedDir) + ++it; + TEST_REQUIRE(it != endIt); + TEST_REQUIRE(*it == permDeniedDir); + + it.increment(ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + // Same as obove but test operator++(). + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(startDir, ec); + TEST_REQUIRE(!ec); + while (it != endIt && it->path() != permDeniedDir) + ++it; + TEST_REQUIRE(it != endIt); + TEST_REQUIRE(*it == permDeniedDir); + + TEST_REQUIRE_THROW(filesystem_error, ++it); + } + // Test that recursion resulting in a "EACCESS" error is ignored when the + // correct options are given to the constructor. + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(startDir, SkipEPerm, ec); + TEST_REQUIRE(!ec); + TEST_REQUIRE(it != endIt); + + bool seenOtherFile = false; + if (*it == otherFile) { + ++it; + seenOtherFile = true; + TEST_REQUIRE (it != endIt); + } + TEST_REQUIRE(*it == permDeniedDir); + + ec = GetTestEC(); + it.increment(ec); + TEST_REQUIRE(!ec); + + if (seenOtherFile) { + TEST_CHECK(it == endIt); + } else { + TEST_CHECK(it != endIt); + TEST_CHECK(*it == otherFile); + } + } + // Test that construction resulting in a "EACCESS" error is not ignored + // by default. + { + std::error_code ec; + recursive_directory_iterator it(permDeniedDir, ec); + TEST_REQUIRE(ec); + TEST_REQUIRE(it == endIt); + } + // Same as obove but testing the throwing constructors + { + TEST_REQUIRE_THROW(filesystem_error, + recursive_directory_iterator(permDeniedDir)); + } + // Test that construction resulting in a "EACCESS" error constructs the + // end iterator when the correct options are given. + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(permDeniedDir, SkipEPerm, ec); + TEST_REQUIRE(!ec); + TEST_REQUIRE(it == endIt); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp new file mode 100644 index 0000000000000..16dde66d216ea --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator(recursive_directory_iterator&&) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_move_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = recursive_directory_iterator; + static_assert(std::is_nothrow_move_constructible<D>::value, ""); +} + +TEST_CASE(test_move_end_iterator) +{ + const recursive_directory_iterator endIt; + recursive_directory_iterator endIt2{}; + + recursive_directory_iterator it(std::move(endIt2)); + TEST_CHECK(it == endIt); + TEST_CHECK(endIt2 == endIt); +} + +TEST_CASE(test_move_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt{}; + + // build 'it' up with "interesting" non-default state so we can test + // that it gets copied. We want to get 'it' into a state such that: + // it.options() != directory_options::none + // it.depth() != 0 + // it.recursion_pending() != true + const directory_options opts = directory_options::skip_permission_denied; + recursive_directory_iterator it(testDir, opts); + TEST_REQUIRE(it != endIt); + while (it.depth() == 0) { + ++it; + TEST_REQUIRE(it != endIt); + } + it.disable_recursion_pending(); + TEST_CHECK(it.options() == opts); + TEST_CHECK(it.depth() == 1); + TEST_CHECK(it.recursion_pending() == false); + const path entry = *it; + + // OPERATION UNDER TEST // + const recursive_directory_iterator it2(std::move(it)); + // ------------------- // + + TEST_REQUIRE(it2 != endIt); + TEST_CHECK(*it2 == entry); + TEST_CHECK(it2.depth() == 1); + TEST_CHECK(it2.recursion_pending() == false); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp new file mode 100644 index 0000000000000..915d00267a828 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp @@ -0,0 +1,169 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator& operator=(recursive_directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +// The filesystem specification explicitly allows for self-move on +// the directory iterators. Turn off this warning so we can test it. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wself-move" +#endif + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_move_assign_tests) + +recursive_directory_iterator createInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::skip_permission_denied + // it.depth() == 1 + // it.recursion_pending() == true +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::skip_permission_denied); + TEST_ASSERT(it != endIt); + while (it.depth() != 1) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 1); + it.disable_recursion_pending(); + return it; +} + +recursive_directory_iterator createDifferentInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::follow_directory_symlink + // it.depth() == 2 + // it.recursion_pending() == false +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::follow_directory_symlink); + TEST_ASSERT(it != endIt); + while (it.depth() != 2) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 2); + return it; +} + + +TEST_CASE(test_assignment_signature) +{ + using D = recursive_directory_iterator; + static_assert(std::is_nothrow_move_assignable<D>::value, ""); +} + + +TEST_CASE(test_move_to_end_iterator) +{ + const recursive_directory_iterator endIt; + + recursive_directory_iterator from = createInterestingIterator(); + const recursive_directory_iterator from_copy(from); + const path entry = *from; + + recursive_directory_iterator to; + to = std::move(from); + TEST_REQUIRE(to != endIt); + TEST_CHECK(*to == entry); + TEST_CHECK(to.options() == from_copy.options()); + TEST_CHECK(to.depth() == from_copy.depth()); + TEST_CHECK(to.recursion_pending() == from_copy.recursion_pending()); + TEST_CHECK(from == endIt || from == to); +} + + +TEST_CASE(test_move_from_end_iterator) +{ + recursive_directory_iterator from; + recursive_directory_iterator to = createInterestingIterator(); + + to = std::move(from); + TEST_REQUIRE(to == from); + TEST_CHECK(to == recursive_directory_iterator{}); +} + +TEST_CASE(test_move_valid_iterator) +{ + const recursive_directory_iterator endIt; + + recursive_directory_iterator it = createInterestingIterator(); + const recursive_directory_iterator it_copy(it); + const path entry = *it; + + recursive_directory_iterator it2 = createDifferentInterestingIterator(); + const recursive_directory_iterator it2_copy(it2); + TEST_REQUIRE(it2 != it); + TEST_CHECK(it2.options() != it.options()); + TEST_CHECK(it2.depth() != it.depth()); + TEST_CHECK(it2.recursion_pending() != it.recursion_pending()); + TEST_CHECK(*it2 != entry); + + it2 = std::move(it); + TEST_REQUIRE(it2 != it2_copy && it2 != endIt); + TEST_CHECK(it2.options() == it_copy.options()); + TEST_CHECK(it2.depth() == it_copy.depth()); + TEST_CHECK(it2.recursion_pending() == it_copy.recursion_pending()); + TEST_CHECK(*it2 == entry); + TEST_CHECK(it == endIt || it == it2); +} + +TEST_CASE(test_returns_reference_to_self) +{ + recursive_directory_iterator it; + recursive_directory_iterator it2; + recursive_directory_iterator& ref = (it2 = std::move(it)); + TEST_CHECK(&ref == &it2); +} + +TEST_CASE(test_self_move) +{ + // Create two non-equal iterators that have exactly the same state. + recursive_directory_iterator it = createInterestingIterator(); + recursive_directory_iterator it2 = createInterestingIterator(); + TEST_CHECK(it != it2); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); + + it = std::move(it); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp new file mode 100644 index 0000000000000..befa30484c0c3 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// void pop(); +// void pop(error_code& ec); + +#include <experimental/filesystem> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_pop_tests) + +TEST_CASE(signature_tests) +{ + recursive_directory_iterator it{}; ((void)it); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(it.pop()); + ASSERT_NOT_NOEXCEPT(it.pop(ec)); // may require allocation or other things +} + +// NOTE: Since the order of iteration is unspecified we use a list of +// seen files at each depth to determine the new depth after a 'pop()' operation. +TEST_CASE(test_depth) +{ + const recursive_directory_iterator endIt{}; + + auto& DE0 = StaticEnv::DirIterationList; + std::set<path> notSeenDepth0(std::begin(DE0), std::end(DE0)); + + auto& DE1 = StaticEnv::DirIterationListDepth1; + std::set<path> notSeenDepth1(std::begin(DE1), std::end(DE1)); + + std::error_code ec; + recursive_directory_iterator it(StaticEnv::Dir, ec); + TEST_REQUIRE(it != endIt); + TEST_CHECK(it.depth() == 0); + + while (it.depth() != 2) { + if (it.depth() == 0) + notSeenDepth0.erase(it->path()); + else + notSeenDepth1.erase(it->path()); + ++it; + TEST_REQUIRE(it != endIt); + } + + while (true) { + auto set_ec = std::make_error_code(std::errc::address_in_use); + it.pop(set_ec); + TEST_REQUIRE(!set_ec); + + if (it == endIt) { + // We must have seen every entry at depth 0 and 1. + TEST_REQUIRE(notSeenDepth0.empty() && notSeenDepth1.empty()); + break; + } + else if (it.depth() == 1) { + // If we popped to depth 1 then there must be unseen entries + // at this level. + TEST_REQUIRE(!notSeenDepth1.empty()); + TEST_CHECK(notSeenDepth1.count(it->path())); + notSeenDepth1.clear(); + } + else if (it.depth() == 0) { + // If we popped to depth 0 there must be unseen entries at this + // level. There should also be no unseen entries at depth 1. + TEST_REQUIRE(!notSeenDepth0.empty()); + TEST_REQUIRE(notSeenDepth1.empty()); + TEST_CHECK(notSeenDepth0.count(it->path())); + notSeenDepth0.clear(); + } + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp new file mode 100644 index 0000000000000..5a3bdd9d482bb --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp @@ -0,0 +1,162 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// bool recursion_pending() const; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_recursion_pending_tests) + +TEST_CASE(initial_value_test) +{ + recursive_directory_iterator it(StaticEnv::Dir); + TEST_REQUIRE(it.recursion_pending() == true); +} + +TEST_CASE(value_after_copy_construction_and_assignment_test) +{ + recursive_directory_iterator rec_pending_it(StaticEnv::Dir); + recursive_directory_iterator no_rec_pending_it(StaticEnv::Dir); + no_rec_pending_it.disable_recursion_pending(); + + { // copy construction + recursive_directory_iterator it(rec_pending_it); + TEST_CHECK(it.recursion_pending() == true); + it.disable_recursion_pending(); + TEST_REQUIRE(rec_pending_it.recursion_pending() == true); + + recursive_directory_iterator it2(no_rec_pending_it); + TEST_CHECK(it2.recursion_pending() == false); + } + { // copy assignment + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + it = rec_pending_it; + TEST_CHECK(it.recursion_pending() == true); + it.disable_recursion_pending(); + TEST_REQUIRE(rec_pending_it.recursion_pending() == true); + + recursive_directory_iterator it2(StaticEnv::Dir); + it2 = no_rec_pending_it; + TEST_CHECK(it2.recursion_pending() == false); + } + TEST_CHECK(rec_pending_it.recursion_pending() == true); + TEST_CHECK(no_rec_pending_it.recursion_pending() == false); +} + + +TEST_CASE(value_after_move_construction_and_assignment_test) +{ + recursive_directory_iterator rec_pending_it(StaticEnv::Dir); + recursive_directory_iterator no_rec_pending_it(StaticEnv::Dir); + no_rec_pending_it.disable_recursion_pending(); + + { // move construction + recursive_directory_iterator it_cp(rec_pending_it); + recursive_directory_iterator it(std::move(it_cp)); + TEST_CHECK(it.recursion_pending() == true); + + recursive_directory_iterator it_cp2(no_rec_pending_it); + recursive_directory_iterator it2(std::move(it_cp2)); + TEST_CHECK(it2.recursion_pending() == false); + } + { // copy assignment + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + recursive_directory_iterator it_cp(rec_pending_it); + it = std::move(it_cp); + TEST_CHECK(it.recursion_pending() == true); + + recursive_directory_iterator it2(StaticEnv::Dir); + recursive_directory_iterator it_cp2(no_rec_pending_it); + it2 = std::move(it_cp2); + TEST_CHECK(it2.recursion_pending() == false); + } + TEST_CHECK(rec_pending_it.recursion_pending() == true); + TEST_CHECK(no_rec_pending_it.recursion_pending() == false); +} + +TEST_CASE(increment_resets_value) +{ + const recursive_directory_iterator endIt; + { + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + ++it; + TEST_CHECK(it.recursion_pending() == true); + TEST_CHECK(it.depth() == 0); + } + { + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + it++; + TEST_CHECK(it.recursion_pending() == true); + TEST_CHECK(it.depth() == 0); + } + { + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + std::error_code ec; + it.increment(ec); + TEST_CHECK(it.recursion_pending() == true); + TEST_CHECK(it.depth() == 0); + } +} + +TEST_CASE(pop_does_not_reset_value) +{ + const recursive_directory_iterator endIt; + + auto& DE0 = StaticEnv::DirIterationList; + std::set<path> notSeenDepth0(std::begin(DE0), std::end(DE0)); + + recursive_directory_iterator it(StaticEnv::Dir); + TEST_REQUIRE(it != endIt); + + while (it.depth() == 0) { + notSeenDepth0.erase(it->path()); + ++it; + TEST_REQUIRE(it != endIt); + } + TEST_REQUIRE(it.depth() == 1); + it.disable_recursion_pending(); + it.pop(); + // Since the order of iteration is unspecified the pop() could result + // in the end iterator. When this is the case it is undefined behavior + // to call recursion_pending(). + if (it == endIt) { + TEST_CHECK(notSeenDepth0.empty()); +#if defined(_LIBCPP_VERSION) + TEST_CHECK(it.recursion_pending() == false); +#endif + } else { + TEST_CHECK(! notSeenDepth0.empty()); + TEST_CHECK(it.recursion_pending() == false); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp new file mode 100644 index 0000000000000..ca5117f0e32f3 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; +// recursive_directory_iterator end(recursive_directory_iterator iter) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_begin_end_tests) + +TEST_CASE(test_function_signatures) +{ + using D = recursive_directory_iterator; + recursive_directory_iterator d; ((void)d); + + ASSERT_SAME_TYPE(decltype(begin(d)), recursive_directory_iterator); + ASSERT_NOEXCEPT(begin(std::move(d))); + + ASSERT_SAME_TYPE(decltype(end(d)), recursive_directory_iterator); + ASSERT_NOEXCEPT(end(std::move(d))); +} + +TEST_CASE(test_ranged_for_loop) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + for (auto& elem : it) { + TEST_CHECK(dir_contents.erase(elem) == 1); + } + TEST_CHECK(dir_contents.empty()); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp b/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp new file mode 100644 index 0000000000000..77b136f3fcad9 --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp @@ -0,0 +1,75 @@ +#ifndef TEST_BITMASK_TYPE_HPP +#define TEST_BITMASK_TYPE_HPP + +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + + +template <class EnumType, EnumType Val1, EnumType Val2, + class UT = typename std::underlying_type<EnumType>::type, + UT UVal1 = static_cast<UT>(Val1), + UT UVal2 = static_cast<UT>(Val2), + UT UZero = static_cast<UT>(0), + EnumType Zero = static_cast<EnumType>(0) + > +struct check_bitmask_type { + + static constexpr UT dcast(EnumType e) { return static_cast<UT>(e); } + static constexpr UT unpromote(decltype((~UZero)) promoted) { return static_cast<UT>(promoted); } + // We need two values that are non-zero and share at least one bit. + static_assert(Val1 != Zero && Val2 != Zero, ""); + static_assert(Val1 != Val2, ""); + static_assert((UVal1 & UVal2) == 0, ""); + + + static bool check() + { + { + EnumType ValRef = Val1; + ASSERT_SAME_TYPE(EnumType, decltype(Val1 & Val2)); + ASSERT_SAME_TYPE(EnumType, decltype(Val1 | Val2)); + ASSERT_SAME_TYPE(EnumType, decltype(Val1 ^ Val2)); + ASSERT_SAME_TYPE(EnumType, decltype((~Val1))); + ASSERT_SAME_TYPE(EnumType&, decltype(ValRef &= Val2)); + ASSERT_SAME_TYPE(EnumType&, decltype(ValRef |= Val2)); + ASSERT_SAME_TYPE(EnumType&, decltype(ValRef ^= Val2)); + } + + static_assert((Val1 & Zero) == Zero, ""); + static_assert((Val1 & Val1) == Val1, ""); + static_assert(dcast(Val1 & Val2) == (UVal1 & UVal2), ""); + + static_assert((Val1 | Zero) == Val1, ""); + static_assert(dcast(Val1 | Val2) == (UVal1 | UVal2), ""); + + static_assert((Val1 ^ Zero) == Val1, ""); + static_assert(dcast(Val1 ^ Val2) == (UVal1 ^ UVal2), ""); + + static_assert(dcast(~Zero) == unpromote(~UZero), ""); + static_assert(dcast(~Val1) == unpromote(~UVal1), ""); + + { + EnumType e = Val1; + EnumType& eref = (e &= Val2); + assert(&eref == &e); + assert(dcast(eref) == (UVal1 & UVal2)); + } + { + EnumType e = Val1; + EnumType& eref = (e |= Val2); + assert(&eref == &e); + assert(dcast(eref) == (UVal1 | UVal2)); + } + { + EnumType e = Val1; + EnumType& eref = (e ^= Val2); + assert(&eref == &e); + assert(dcast(eref) == (UVal1 ^ UVal2)); + } + return true; + } +}; + +#endif // TEST_BITMASK_TYPE diff --git a/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp new file mode 100644 index 0000000000000..22f0cb845a72a --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// enum class copy_options; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "check_bitmask_types.hpp" +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +constexpr fs::copy_options ME(int val) { return static_cast<fs::copy_options>(val); } + +int main() { + typedef fs::copy_options E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + + static_assert(std::is_same<UT, unsigned short>::value, ""); // Implementation detail + + typedef check_bitmask_type<E, E::skip_existing, E::update_existing> BitmaskTester; + assert(BitmaskTester::check()); + + static_assert( + E::none == ME(0), + "Expected enumeration values do not match"); + // Option group for copy_file + static_assert( + E::skip_existing == ME(1) && + E::overwrite_existing == ME(2) && + E::update_existing == ME(4), + "Expected enumeration values do not match"); + // Option group for copy on directories + static_assert( + E::recursive == ME(8), + "Expected enumeration values do not match"); + // Option group for copy on symlinks + static_assert( + E::copy_symlinks == ME(16) && + E::skip_symlinks == ME(32), + "Expected enumeration values do not match"); + // Option group for changing form of copy + static_assert( + E::directories_only == ME(64) && + E::create_symlinks == ME(128) && + E::create_hard_links == ME(256), + "Expected enumeration values do not match"); +} diff --git a/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp new file mode 100644 index 0000000000000..7dbf7b2887e85 --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// enum class directory_options; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> +#include <sys/stat.h> + +#include "test_macros.h" +#include "check_bitmask_types.hpp" + +namespace fs = std::experimental::filesystem; + +constexpr fs::directory_options ME(int val) { return static_cast<fs::directory_options>(val); } + +int main() { + typedef fs::directory_options E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + static_assert(std::is_same<UT, unsigned char>::value, ""); + + typedef check_bitmask_type<E, E::follow_directory_symlink, E::skip_permission_denied> BitmaskTester; + assert(BitmaskTester::check()); + + static_assert( + E::none == ME(0) && + E::follow_directory_symlink == ME(1) && + E::skip_permission_denied == ME(2), + "Expected enumeration values do not match"); + +} diff --git a/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp new file mode 100644 index 0000000000000..ab94ad2877aac --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// enum class file_type; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +constexpr fs::file_type ME(int val) { return static_cast<fs::file_type>(val); } + +int main() { + typedef fs::file_type E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + + static_assert(std::is_same<UT, signed char>::value, ""); // Implementation detail + + static_assert( + E::none == ME(0) && + E::not_found == ME(-1) && + E::regular == ME(1) && + E::directory == ME(2) && + E::symlink == ME(3) && + E::block == ME(4) && + E::character == ME(5) && + E::fifo == ME(6) && + E::socket == ME(7) && + E::unknown == ME(8), + "Expected enumeration values do not match"); +} diff --git a/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp new file mode 100644 index 0000000000000..c0b14ba4b9b9a --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// enum class perms; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> +#include <sys/stat.h> + +#include "test_macros.h" +#include "check_bitmask_types.hpp" + +namespace fs = std::experimental::filesystem; + +constexpr fs::perms ME(int val) { return static_cast<fs::perms>(val); } + +int main() { + typedef fs::perms E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + + static_assert(std::is_same<UT, unsigned >::value, ""); // Implementation detail + + typedef check_bitmask_type<E, E::group_all, E::owner_all> BitmaskTester; + assert(BitmaskTester::check()); + + static_assert( + E::none == ME(0) && + + E::owner_read == ME(0400) && + E::owner_write == ME(0200) && + E::owner_exec == ME(0100) && + E::owner_all == ME(0700) && + + E::group_read == ME(040) && + E::group_write == ME(020) && + E::group_exec == ME(010) && + E::group_all == ME(070) && + + E::others_read == ME(04) && + E::others_write == ME(02) && + E::others_exec == ME(01) && + E::others_all == ME(07) && + E::all == ME(0777) && + E::set_uid == ME(04000) && + E::set_gid == ME(02000) && + E::sticky_bit == ME(01000) && + E::mask == ME(07777) && + E::unknown == ME(0xFFFF) && + E::add_perms == ME(0x10000) && + E::remove_perms == ME(0x20000) && + E::symlink_nofollow == ME(0x40000), + "Expected enumeration values do not match"); +} diff --git a/test/std/experimental/optional/version.pass.cpp b/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp index 585b7a24eea5a..b58f5c55b643a 100644 --- a/test/std/experimental/optional/version.pass.cpp +++ b/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp @@ -7,14 +7,6 @@ // //===----------------------------------------------------------------------===// -// <optional> - -#include <experimental/optional> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - int main() { } diff --git a/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp b/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp new file mode 100644 index 0000000000000..d8d92c5888ac6 --- /dev/null +++ b/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// typedef TrivialClock file_time_type; + +#include <experimental/filesystem> +#include <chrono> +#include <type_traits> + +// system_clock is used because it meets the requirements of TrivialClock, +// and it's resolution and range of system_clock should match the operating +// systems file time type. +typedef std::chrono::system_clock ExpectedClock; +typedef std::chrono::time_point<ExpectedClock> ExpectedTimePoint; + +int main() { + static_assert(std::is_same< + std::experimental::filesystem::file_time_type, + ExpectedTimePoint + >::value, ""); +} diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp new file mode 100644 index 0000000000000..4d59235c722b8 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// path absolute(const path& p, const path& base=current_path()); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_absolute_path_test_suite) + +TEST_CASE(absolute_signature_test) +{ + const path p; ((void)p); + ASSERT_NOT_NOEXCEPT(absolute(p)); + ASSERT_NOT_NOEXCEPT(absolute(p, p)); +} + +// There are 4 cases is the proposal for absolute path. +// Each scope tests one of the cases. +TEST_CASE(absolute_path_test) +{ + // has_root_name() && has_root_directory() + { + const path p("//net/foo"); + const path base("//net/bar/baz"); + TEST_REQUIRE(p.has_root_name()); + TEST_REQUIRE(p.has_root_directory()); + TEST_CHECK(p.is_absolute()); + path ret = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == p); + } + // !has_root_name() && has_root_directory() + { + const path p("/foo"); + const path base("//net/bar"); + TEST_REQUIRE(not p.has_root_name()); + TEST_REQUIRE(p.has_root_directory()); + TEST_CHECK(p.is_absolute()); + // ensure absolute(base) is not recursivly called + TEST_REQUIRE(base.has_root_name()); + TEST_REQUIRE(base.has_root_directory()); + + path ret = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret.has_root_name()); + TEST_CHECK(ret.root_name() == path("//net")); + TEST_CHECK(ret.has_root_directory()); + TEST_CHECK(ret.root_directory() == path("/")); + TEST_CHECK(ret == path("//net/foo")); + } + // has_root_name() && !has_root_directory() + { + const path p("//net"); + const path base("//net/foo/bar"); + TEST_REQUIRE(p.has_root_name()); + TEST_REQUIRE(not p.has_root_directory()); + TEST_CHECK(not p.is_absolute()); + // absolute is called recursivly on base. The following conditions + // must be true for it to return base unmodified + TEST_REQUIRE(base.has_root_name()); + TEST_REQUIRE(base.has_root_directory()); + path ret = absolute(p, base); + const path expect("//net/foo/bar"); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == path("//net/foo/bar")); + } + // !has_root_name() && !has_root_directory() + { + const path p("bar/baz"); + const path base("//net/foo"); + TEST_REQUIRE(not p.has_root_name()); + TEST_REQUIRE(not p.has_root_directory()); + TEST_REQUIRE(base.has_root_name()); + TEST_REQUIRE(base.has_root_directory()); + + path ret = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == path("//net/foo/bar/baz")); + } +} + +TEST_CASE(absolute_path_with_default_base) +{ + const path testCases[] = { + "//net/foo", // has_root_name() && has_root_directory() + "/foo", // !has_root_name() && has_root_directory() + "//net", // has_root_name() && !has_root_directory() + "bar/baz" // !has_root_name() && !has_root_directory() + }; + const path base = current_path(); + for (auto& p : testCases) { + const path ret = absolute(p); + const path expect = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == expect); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp new file mode 100644 index 0000000000000..407f5b111a836 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// path canonical(const path& p, const path& base = current_path()); +// path canonical(const path& p, error_code& ec); +// path canonical(const path& p, const path& base, error_code& ec); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_canonical_path_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(canonical(p)); + ASSERT_NOT_NOEXCEPT(canonical(p, p)); + ASSERT_NOT_NOEXCEPT(canonical(p, ec)); + ASSERT_NOT_NOEXCEPT(canonical(p, p, ec)); +} + +// There are 4 cases is the proposal for absolute path. +// Each scope tests one of the cases. +TEST_CASE(test_canonical) +{ + // has_root_name() && has_root_directory() + const path Root = StaticEnv::Root; + const path RootName = Root.filename(); + const path DirName = StaticEnv::Dir.filename(); + const path SymlinkName = StaticEnv::SymlinkToFile.filename(); + struct TestCase { + path p; + path expect; + path base; + TestCase(path p1, path e, path b = StaticEnv::Root) + : p(p1), expect(e), base(b) {} + }; + const TestCase testCases[] = { + { ".", Root, Root}, + { DirName / ".." / "." / DirName, StaticEnv::Dir, Root}, + { StaticEnv::Dir2 / "..", StaticEnv::Dir }, + { StaticEnv::Dir3 / "../..", StaticEnv::Dir }, + { StaticEnv::Dir / ".", StaticEnv::Dir }, + { Root / "." / DirName / ".." / DirName, StaticEnv::Dir}, + { path("..") / "." / RootName / DirName / ".." / DirName, StaticEnv::Dir, Root}, + { StaticEnv::SymlinkToFile, StaticEnv::File }, + { SymlinkName, StaticEnv::File, StaticEnv::Root} + }; + for (auto& TC : testCases) { + std::error_code ec; + const path ret = canonical(TC.p, TC.base, ec); + TEST_REQUIRE(!ec); + const path ret2 = canonical(TC.p, TC.base); + TEST_CHECK(ret == TC.expect); + TEST_CHECK(ret == ret2); + TEST_CHECK(ret.is_absolute()); + } +} + +TEST_CASE(test_dne_path) +{ + std::error_code ec; + { + const path ret = canonical(StaticEnv::DNE, ec); + TEST_REQUIRE(ec); + TEST_CHECK(ret == path{}); + } + ec.clear(); + { + const path ret = canonical(StaticEnv::DNE, StaticEnv::Root, ec); + TEST_REQUIRE(ec); + TEST_CHECK(ret == path{}); + } + { + TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE)); + TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE, StaticEnv::Root)); + } +} + +TEST_CASE(test_exception_contains_paths) +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + const path p = "blabla/dne"; + const path base = StaticEnv::Root; + try { + canonical(p, base); + TEST_REQUIRE(false); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == base); + } + try { + canonical(p); + TEST_REQUIRE(false); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == current_path()); + } +#endif +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp new file mode 100644 index 0000000000000..7d318719f740e --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp @@ -0,0 +1,251 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void copy(const path& from, const path& to); +// void copy(const path& from, const path& to, error_code& ec) noexcept; +// void copy(const path& from, const path& to, copy_options options); +// void copy(const path& from, const path& to, copy_options options, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +using CO = fs::copy_options; + +TEST_SUITE(filesystem_copy_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + const copy_options opts{}; ((void)opts); + ASSERT_NOT_NOEXCEPT(fs::copy(p, p)); + ASSERT_NOEXCEPT(fs::copy(p, p, ec)); + ASSERT_NOT_NOEXCEPT(copy(p, p, opts)); + ASSERT_NOEXCEPT(copy(p, p, opts, ec)); +} + +// There are 4 cases is the proposal for absolute path. +// Each scope tests one of the cases. +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::copy(f, t); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == t + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dir = env.create_dir("dir"); + const path fifo = env.create_fifo("fifo"); + TEST_REQUIRE(is_other(fifo)); + + // !exists(f) + { + std::error_code ec; + const path f = StaticEnv::DNE; + const path t = env.test_root; + fs::copy(f, t, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(f, t, ec)); + } + { // equivalent(f, t) == true + std::error_code ec; + fs::copy(file, file, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, file, ec)); + } + { // is_directory(from) && is_file(to) + std::error_code ec; + fs::copy(dir, file, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dir, file, ec)); + } + { // is_other(from) + std::error_code ec; + fs::copy(fifo, dir, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(fifo, dir, ec)); + } + { // is_other(to) + std::error_code ec; + fs::copy(file, fifo, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, fifo, ec)); + } +} + +TEST_CASE(from_is_symlink) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path symlink = env.create_symlink(file, "sym"); + const path dne = env.make_env_path("dne"); + + { // skip symlinks + std::error_code ec = GetTestEC(); + fs::copy(symlink, dne, copy_options::skip_symlinks, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(dne)); + } + { + const path dest = env.make_env_path("dest"); + std::error_code ec = GetTestEC(); + fs::copy(symlink, dest, copy_options::copy_symlinks, ec); + TEST_CHECK(!ec); + TEST_CHECK(exists(dest)); + TEST_CHECK(is_symlink(dest)); + } + { // copy symlink but target exists + std::error_code ec = GetTestEC(); + fs::copy(symlink, file, copy_options::copy_symlinks, ec); + TEST_CHECK(ec); + } + { // create symlinks but target exists + std::error_code ec = GetTestEC(); + fs::copy(symlink, file, copy_options::create_symlinks, ec); + TEST_CHECK(ec); + } +} + +TEST_CASE(from_is_regular_file) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + { // skip copy because of directory + const path dest = env.make_env_path("dest1"); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, CO::directories_only, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(dest)); + } + { // create symlink to file + const path dest = env.make_env_path("sym"); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, CO::create_symlinks, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(file, canonical(dest))); + } + { // create hard link to file + const path dest = env.make_env_path("hardlink"); + TEST_CHECK(hard_link_count(file) == 1); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, CO::create_hard_links, ec); + TEST_CHECK(!ec); + TEST_CHECK(exists(dest)); + TEST_CHECK(hard_link_count(file) == 2); + } + { // is_directory(t) + const path dest_dir = env.create_dir("dest_dir"); + const path expect_dest = dest_dir / file.filename(); + std::error_code ec = GetTestEC(); + fs::copy(file, dest_dir, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_regular_file(expect_dest)); + } + { // otherwise copy_file(from, to, ...) + const path dest = env.make_env_path("file_copy"); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_regular_file(dest)); + } +} + +TEST_CASE(from_is_directory) +{ + struct FileInfo { + path filename; + int size; + }; + const FileInfo files[] = { + {"file1", 0}, + {"file2", 42}, + {"file3", 300} + }; + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path nested_dir_name = "dir2"; + const path nested_dir = env.create_dir("dir/dir2"); + + for (auto& FI : files) { + env.create_file(dir / FI.filename, FI.size); + env.create_file(nested_dir / FI.filename, FI.size); + } + { // test for non-existent directory + const path dest = env.make_env_path("dest_dir1"); + std::error_code ec = GetTestEC(); + fs::copy(dir, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_directory(dest)); + for (auto& FI : files) { + path created = dest / FI.filename; + TEST_CHECK(is_regular_file(created)); + TEST_CHECK(file_size(created) == FI.size); + } + TEST_CHECK(!is_directory(dest / nested_dir_name)); + } + { // test for existing directory + const path dest = env.create_dir("dest_dir2"); + std::error_code ec = GetTestEC(); + fs::copy(dir, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_directory(dest)); + for (auto& FI : files) { + path created = dest / FI.filename; + TEST_CHECK(is_regular_file(created)); + TEST_CHECK(file_size(created) == FI.size); + } + TEST_CHECK(!is_directory(dest / nested_dir_name)); + } + { // test recursive copy + const path dest = env.make_env_path("dest_dir3"); + std::error_code ec = GetTestEC(); + fs::copy(dir, dest, CO::recursive, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_directory(dest)); + const path nested_dest = dest / nested_dir_name; + TEST_REQUIRE(is_directory(nested_dest)); + for (auto& FI : files) { + path created = dest / FI.filename; + path nested_created = nested_dest / FI.filename; + TEST_CHECK(is_regular_file(created)); + TEST_CHECK(file_size(created) == FI.size); + TEST_CHECK(is_regular_file(nested_created)); + TEST_CHECK(file_size(nested_created) == FI.size); + } + } + +} +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp new file mode 100644 index 0000000000000..ac9877bbd9ce7 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool copy_file(const path& from, const path& to); +// bool copy_file(const path& from, const path& to, error_code& ec) noexcept; +// bool copy_file(const path& from, const path& to, copy_options options); +// bool copy_file(const path& from, const path& to, copy_options options, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <chrono> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +using CO = fs::copy_options; + +TEST_SUITE(filesystem_copy_file_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + const copy_options opts{}; ((void)opts); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p)), bool); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts)), bool); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, ec)), bool); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p)); + ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts)); + ASSERT_NOEXCEPT(fs::copy_file(p, p, ec)); + ASSERT_NOEXCEPT(fs::copy_file(p, p, opts, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::copy_file(f, t); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == t + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path dne = env.make_env_path("dne"); + { // exists(to) && equivalent(to, from) + std::error_code ec; + TEST_CHECK(fs::copy_file(file, file, ec) == false); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, file, ec)); + } + { // exists(to) && !(skip_existing | overwrite_existing | update_existing) + std::error_code ec; + TEST_CHECK(fs::copy_file(file, file2, ec) == false); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, file2, ec)); + } +} + +TEST_CASE(copy_file) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + + { // !exists(to) + const path dest = env.make_env_path("dest1"); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(file_size(dest) == 42); + } + { // exists(to) && overwrite_existing + const path dest = env.create_file("dest2", 55); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, dest, + copy_options::overwrite_existing, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(file_size(dest) == 42); + } + { // exists(to) && update_existing + using Sec = std::chrono::seconds; + const path older = env.create_file("older_file", 1); + + SleepFor(Sec(2)); + const path from = env.create_file("update_from", 55); + + SleepFor(Sec(2)); + const path newer = env.create_file("newer_file", 2); + + std::error_code ec; + TEST_REQUIRE(fs::copy_file(from, older, copy_options::update_existing, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(file_size(older) == 55); + + TEST_REQUIRE(fs::copy_file(from, newer, copy_options::update_existing, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(file_size(newer) == 2); + } + { // skip_existing + const path file2 = env.create_file("file2", 55); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, file2, copy_options::skip_existing, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file2) == 55); + } +} + +TEST_CASE(test_attributes_get_copied) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dest = env.make_env_path("file2"); + auto st = status(file); + perms default_perms = st.permissions(); + perms new_perms = perms::owner_read; + permissions(file, new_perms); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); + TEST_CHECK(!ec); + auto new_st = status(dest); + TEST_CHECK(new_st.permissions() == new_perms); +} + +TEST_CASE(copy_dir_test) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dest = env.create_dir("dir1"); + std::error_code ec; + TEST_CHECK(fs::copy_file(file, dest, ec) == false); + TEST_CHECK(ec); + ec.clear(); + TEST_CHECK(fs::copy_file(dest, file, ec) == false); + TEST_CHECK(ec); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp new file mode 100644 index 0000000000000..6fae111952063 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void copy_symlink(const path& existing_symlink, const path& new_symlink); +// void copy_symlink(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_copy_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::copy_symlink(p, p)); + ASSERT_NOEXCEPT(fs::copy_symlink(p, p, ec)); +} + + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::copy_symlink(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + const path dir = env.create_dir("dir"); + const path dne = env.make_env_path("dne"); + { // from is a file, not a symlink + std::error_code ec; + fs::copy_symlink(file, dne, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, dne, ec)); + } + { // from is a file, not a symlink + std::error_code ec; + fs::copy_symlink(dir, dne, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dir, dne, ec)); + } + { // destination exists + std::error_code ec; + fs::copy_symlink(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(copy_symlink_basic) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir_sym = env.create_symlink(dir, "dir_sym"); + const path file = env.create_file("file", 42); + const path file_sym = env.create_symlink(file, "file_sym"); + { // test for directory symlinks + const path dest = env.make_env_path("dest1"); + std::error_code ec; + fs::copy_symlink(dir_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, dir)); + } + { // test for file symlinks + const path dest = env.make_env_path("dest2"); + std::error_code ec; + fs::copy_symlink(file_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, file)); + } +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp new file mode 100644 index 0000000000000..ba060254956fe --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool create_directories(const path& p); +// bool create_directories(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_directories_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::create_directories(p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directories(p, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::create_directories(p)); + ASSERT_NOEXCEPT(fs::create_directories(p, ec)); +} + +TEST_CASE(create_existing_directory) +{ + scoped_test_env env; + const path dir = env.create_dir("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directories(dir, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); +} + +TEST_CASE(create_directory_one_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directories(dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); +} + +TEST_CASE(create_directories_multi_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1/dir2/dir3"); + std::error_code ec; + TEST_CHECK(fs::create_directories(dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp new file mode 100644 index 0000000000000..5fce217bc49e2 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool create_directory(const path& p); +// bool create_directory(const path& p, error_code& ec) noexcept; +// bool create_directory(const path& p, const path& attr); +// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +#include <sys/types.h> +#include <sys/stat.h> + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +fs::perms read_umask() { + mode_t old_mask = umask(0); + umask(old_mask); // reset the mask to the old value. + return static_cast<fs::perms>(old_mask); +} + +TEST_SUITE(filesystem_create_directory_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, ec)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::create_directory(p)); + ASSERT_NOEXCEPT(fs::create_directory(p, ec)); + ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p)); + ASSERT_NOEXCEPT(fs::create_directory(p, p, ec)); +} + + +TEST_CASE(create_existing_directory) +{ + scoped_test_env env; + const path dir = env.create_dir("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); + // Test throwing version + TEST_CHECK(fs::create_directory(dir) == false); +} + +TEST_CASE(create_directory_one_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); + + auto st = status(dir); + const perms expect_perms = perms::all & ~(read_umask()); + TEST_CHECK((st.permissions() & perms::all) == expect_perms); +} + +TEST_CASE(create_directory_multi_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1/dir2"); + const path dir1 = env.make_env_path("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(!is_directory(dir)); + TEST_CHECK(!is_directory(dir1)); +} + +TEST_CASE(dest_is_file) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + std::error_code ec; + TEST_CHECK(fs::create_directory(file, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(is_regular_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp new file mode 100644 index 0000000000000..c32bdd2d1928e --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool create_directory(const path& p, const path& attr); +// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_directory_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p)); + ASSERT_NOEXCEPT(fs::create_directory(p, p, ec)); +} + +TEST_CASE(create_existing_directory) +{ + scoped_test_env env; + const path dir = env.create_dir("dir1"); + const path dir2 = env.create_dir("dir2"); + + const perms orig_p = status(dir).permissions(); + permissions(dir2, perms::none); + + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, dir2, ec) == false); + TEST_CHECK(!ec); + + // Check that the permissions were unchanged + TEST_CHECK(orig_p == status(dir).permissions()); + + // Test throwing version + TEST_CHECK(fs::create_directory(dir, dir2) == false); +} + +TEST_CASE(create_directory_one_level) +{ + scoped_test_env env; + // Remove setgid which mkdir would inherit + permissions(env.test_root, perms::remove_perms | perms::set_gid); + + const path dir = env.make_env_path("dir1"); + const path attr_dir = env.create_dir("dir2"); + permissions(attr_dir, perms::none); + + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); + + // Check that the new directory has the same permissions as attr_dir + auto st = status(dir); + TEST_CHECK(st.permissions() == perms::none); +} + +TEST_CASE(create_directory_multi_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1/dir2"); + const path dir1 = env.make_env_path("dir1"); + const path attr_dir = env.create_dir("attr_dir"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(!is_directory(dir)); + TEST_CHECK(!is_directory(dir1)); +} + +TEST_CASE(dest_is_file) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path attr_dir = env.create_dir("attr_dir"); + std::error_code ec; + TEST_CHECK(fs::create_directory(file, attr_dir, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(is_regular_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp new file mode 100644 index 0000000000000..e0473754cc886 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void create_directory_symlink(const path& existing_symlink, const path& new_symlink); +// void create_directory_symlink(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_directory_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::create_directory_symlink(p, p)); + ASSERT_NOEXCEPT(fs::create_directory_symlink(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::create_directory_symlink(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + { // destination exists + std::error_code ec; + fs::create_directory_symlink(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(create_directory_symlink_basic) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir_sym = env.create_symlink(dir, "dir_sym"); + + const path dest = env.make_env_path("dest1"); + std::error_code ec; + fs::create_directory_symlink(dir_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, dir)); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp new file mode 100644 index 0000000000000..4a865fdee7e8c --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void create_hard_link(const path& existing_symlink, const path& new_symlink); +// void create_hard_link(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_hard_link_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::create_hard_link(p, p)); + ASSERT_NOEXCEPT(fs::create_hard_link(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::create_hard_link(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + { // destination exists + std::error_code ec; + fs::create_hard_link(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(create_file_hard_link) +{ + scoped_test_env env; + const path file = env.create_file("file"); + const path dest = env.make_env_path("dest1"); + std::error_code ec; + TEST_CHECK(hard_link_count(file) == 1); + fs::create_hard_link(file, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(exists(dest)); + TEST_CHECK(equivalent(dest, file)); + TEST_CHECK(hard_link_count(file) == 2); +} + +TEST_CASE(create_directory_hard_link_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dest = env.make_env_path("dest2"); + std::error_code ec; + + fs::create_hard_link(dir, dest, ec); + TEST_REQUIRE(ec); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp new file mode 100644 index 0000000000000..35ba57f3ab46f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void create_symlink(const path& existing_symlink, const path& new_symlink); +// void create_symlink(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::create_symlink(p, p)); + ASSERT_NOEXCEPT(fs::create_symlink(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::create_symlink(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + { // destination exists + std::error_code ec; + fs::create_symlink(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(create_symlink_basic) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path file_sym = env.create_symlink(file, "file_sym"); + const path dir = env.create_dir("dir"); + const path dir_sym = env.create_symlink(dir, "dir_sym"); + { + const path dest = env.make_env_path("dest1"); + std::error_code ec; + fs::create_symlink(file_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, file)); + } + { + const path dest = env.make_env_path("dest2"); + std::error_code ec; + fs::create_symlink(dir_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, dir)); + } +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp new file mode 100644 index 0000000000000..9d004ab854c1d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// path current_path(); +// path current_path(error_code& ec); +// void current_path(path const&); +// void current_path(path const&, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_current_path_path_test_suite) + +TEST_CASE(current_path_signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(current_path()); + ASSERT_NOT_NOEXCEPT(current_path(ec)); + ASSERT_NOT_NOEXCEPT(current_path(p)); + ASSERT_NOEXCEPT(current_path(p, ec)); +} + +TEST_CASE(current_path_test) +{ + std::error_code ec; + const path p = current_path(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(p.is_absolute()); + TEST_CHECK(is_directory(p)); + + const path p2 = current_path(); + TEST_CHECK(p2 == p); +} + +TEST_CASE(current_path_after_change_test) +{ + const path new_path = StaticEnv::Dir; + current_path(new_path); + TEST_CHECK(current_path() == new_path); +} + +TEST_CASE(current_path_is_file_test) +{ + const path p = StaticEnv::File; + std::error_code ec; + const path old_p = current_path(); + current_path(p, ec); + TEST_CHECK(ec); + TEST_CHECK(old_p == current_path()); +} + +TEST_CASE(set_to_non_absolute_path) +{ + const path base = StaticEnv::Dir; + current_path(base); + const path p = StaticEnv::Dir2.filename(); + std::error_code ec; + current_path(p, ec); + TEST_CHECK(!ec); + const path new_cwd = current_path(); + TEST_CHECK(new_cwd == StaticEnv::Dir2); + TEST_CHECK(new_cwd.is_absolute()); +} + +TEST_CASE(set_to_empty) +{ + const path p = ""; + std::error_code ec; + const path old_p = current_path(); + current_path(p, ec); + TEST_CHECK(ec); + TEST_CHECK(old_p == current_path()); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp new file mode 100644 index 0000000000000..621ff8305fc3f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool equivalent(path const& lhs, path const& rhs); +// bool equivalent(path const& lhs, path const& rhs, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(equivalent_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(equivalent(p, p, ec)); + ASSERT_NOT_NOEXCEPT(equivalent(p, p)); +} + +TEST_CASE(equivalent_test) +{ + struct TestCase { + path lhs; + path rhs; + bool expect; + }; + const TestCase testCases[] = { + {StaticEnv::Dir, StaticEnv::Dir, true}, + {StaticEnv::File, StaticEnv::Dir, false}, + {StaticEnv::Dir, StaticEnv::SymlinkToDir, true}, + {StaticEnv::Dir, StaticEnv::SymlinkToFile, false}, + {StaticEnv::File, StaticEnv::File, true}, + {StaticEnv::File, StaticEnv::SymlinkToFile, true}, + }; + for (auto& TC : testCases) { + std::error_code ec; + TEST_CHECK(equivalent(TC.lhs, TC.rhs, ec) == TC.expect); + TEST_CHECK(!ec); + } +} + +TEST_CASE(equivalent_reports_double_dne) +{ + const path E = StaticEnv::File; + const path DNE = StaticEnv::DNE; + { // Test that no exception is thrown if one of the paths exists + TEST_CHECK(equivalent(E, DNE) == false); + TEST_CHECK(equivalent(DNE, E) == false); + } + { // Test that an exception is thrown if both paths do not exist. + TEST_CHECK_THROW(filesystem_error, equivalent(DNE, DNE)); + } + { + std::error_code ec; + TEST_CHECK(equivalent(DNE, DNE, ec) == false); + TEST_CHECK(ec); + } +} + +TEST_CASE(equivalent_is_other_succeeds) +{ + scoped_test_env env; + path const file = env.create_file("file", 42); + const path hl1 = env.create_hardlink(file, "hl1"); + const path hl2 = env.create_hardlink(file, "hl2"); + TEST_CHECK(equivalent(file, hl1)); + TEST_CHECK(equivalent(file, hl2)); + TEST_CHECK(equivalent(hl1, hl2)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp new file mode 100644 index 0000000000000..252ced6fd65fa --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool exists(file_status s) noexcept +// bool exists(path const& p); +// bool exists(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(exists_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(exists(s)); + ASSERT_NOEXCEPT(exists(p, ec)); + ASSERT_NOT_NOEXCEPT(exists(p)); +} + +TEST_CASE(exists_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, true}, + {file_type::directory, true}, + {file_type::symlink, true}, + {file_type::block, true}, + {file_type::character, true}, + {file_type::fifo, true}, + {file_type::socket, true}, + {file_type::unknown, true} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(exists(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(exists(p) == false); + + std::error_code ec = GetTestEC(); + TEST_CHECK(exists(p, ec) == false); + TEST_CHECK(!ec); +} + +TEST_CASE(test_exists_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(exists(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, exists(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp new file mode 100644 index 0000000000000..460e42dd1c3f3 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// uintmax_t file_size(const path& p); +// uintmax_t file_size(const path& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(file_size_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(file_size(p)), uintmax_t); + ASSERT_SAME_TYPE(decltype(file_size(p, ec)), uintmax_t); + ASSERT_NOT_NOEXCEPT(file_size(p)); + ASSERT_NOEXCEPT(file_size(p, ec)); +} + +TEST_CASE(file_size_empty_test) +{ + const path p = StaticEnv::EmptyFile; + TEST_CHECK(file_size(p) == 0); + std::error_code ec; + TEST_CHECK(file_size(p, ec) == 0); +} + +TEST_CASE(file_size_non_empty) +{ + scoped_test_env env; + const path p = env.create_file("file", 42); + TEST_CHECK(file_size(p) == 42); + std::error_code ec; + TEST_CHECK(file_size(p, ec) == 42); +} + +TEST_CASE(symlink_test_case) +{ + const path p = StaticEnv::File; + const path p2 = StaticEnv::SymlinkToFile; + TEST_CHECK(file_size(p) == file_size(p2)); +} + +TEST_CASE(file_size_error_cases) +{ + const path testCases[] = { + StaticEnv::Dir, + StaticEnv::SymlinkToDir, + StaticEnv::BadSymlink, + StaticEnv::DNE + }; + const uintmax_t expect = static_cast<uintmax_t>(-1); + for (auto& TC : testCases) { + std::error_code ec; + TEST_CHECK(file_size(TC, ec) == expect); + TEST_CHECK(ec); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp new file mode 100644 index 0000000000000..abc50e9c6a41d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// uintmax_t hard_link_count(const path& p); +// uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(hard_link_count_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(hard_link_count(p)), uintmax_t); + ASSERT_SAME_TYPE(decltype(hard_link_count(p, ec)), uintmax_t); + ASSERT_NOT_NOEXCEPT(hard_link_count(p)); + ASSERT_NOEXCEPT(hard_link_count(p, ec)); +} + +TEST_CASE(hard_link_count_for_file) +{ + TEST_CHECK(hard_link_count(StaticEnv::File) == 1); + std::error_code ec; + TEST_CHECK(hard_link_count(StaticEnv::File, ec) == 1); +} + +TEST_CASE(hard_link_count_for_directory) +{ + uintmax_t DirExpect = 3; + uintmax_t Dir3Expect = 2; +#if defined(__APPLE__) + DirExpect += 2; + Dir3Expect += 1; +#endif + TEST_CHECK(hard_link_count(StaticEnv::Dir) == DirExpect); + TEST_CHECK(hard_link_count(StaticEnv::Dir3) == Dir3Expect); + + std::error_code ec; + TEST_CHECK(hard_link_count(StaticEnv::Dir, ec) == DirExpect); + TEST_CHECK(hard_link_count(StaticEnv::Dir3, ec) == Dir3Expect); +} +TEST_CASE(hard_link_count_increments_test) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + TEST_CHECK(hard_link_count(file) == 1); + + env.create_hardlink(file, "file_hl"); + TEST_CHECK(hard_link_count(file) == 2); +} + + +TEST_CASE(hard_link_count_error_cases) +{ + const path testCases[] = { + StaticEnv::BadSymlink, + StaticEnv::DNE + }; + const uintmax_t expect = static_cast<uintmax_t>(-1); + for (auto& TC : testCases) { + std::error_code ec; + TEST_CHECK(hard_link_count(TC, ec) == expect); + TEST_CHECK(ec); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp new file mode 100644 index 0000000000000..dee28aa5be618 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_block_file(file_status s) noexcept +// bool is_block_file(path const& p); +// bool is_block_file(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_block_file_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_block_file(s)); + ASSERT_NOEXCEPT(is_block_file(p, ec)); + ASSERT_NOT_NOEXCEPT(is_block_file(p)); +} + +TEST_CASE(is_block_file_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, true}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_block_file(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_block_file(p) == false); +} + +TEST_CASE(test_is_block_file_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_block_file(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_block_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp new file mode 100644 index 0000000000000..2de42bf209758 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_character_file(file_status s) noexcept +// bool is_character_file(path const& p); +// bool is_character_file(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_character_file_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_character_file(s)); + ASSERT_NOEXCEPT(is_character_file(p, ec)); + ASSERT_NOT_NOEXCEPT(is_character_file(p)); +} + +TEST_CASE(is_character_file_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, true}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_character_file(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_character_file(p) == false); +} + +TEST_CASE(test_is_character_file_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_character_file(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_character_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp new file mode 100644 index 0000000000000..d6ecb1a1e684d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_directory(file_status s) noexcept +// bool is_directory(path const& p); +// bool is_directory(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_directory_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_directory(s)); + ASSERT_NOEXCEPT(is_directory(p, ec)); + ASSERT_NOT_NOEXCEPT(is_directory(p)); +} + +TEST_CASE(is_directory_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, true}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_directory(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_directory(p) == false); +} + +TEST_CASE(static_env_test) +{ + TEST_CHECK(is_directory(StaticEnv::Dir)); + TEST_CHECK(is_directory(StaticEnv::SymlinkToDir)); + TEST_CHECK(!is_directory(StaticEnv::File)); +} + +TEST_CASE(test_is_directory_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir2 = env.create_dir("dir/dir2"); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_directory(dir2, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_directory(dir2)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp new file mode 100644 index 0000000000000..ba07d09d10d92 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_empty(path const& p); +// bool is_empty(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_empty_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_empty(p, ec)); + ASSERT_NOT_NOEXCEPT(is_empty(p)); +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + std::error_code ec; + TEST_CHECK(is_empty(p, ec) == false); + TEST_CHECK(ec); + TEST_CHECK_THROW(filesystem_error, is_empty(p)); +} + +TEST_CASE(test_is_empty_directory) +{ + TEST_CHECK(!is_empty(StaticEnv::Dir)); + TEST_CHECK(!is_empty(StaticEnv::SymlinkToDir)); +} + +TEST_CASE(test_is_empty_directory_dynamic) +{ + scoped_test_env env; + TEST_CHECK(is_empty(env.test_root)); + env.create_file("foo", 42); + TEST_CHECK(!is_empty(env.test_root)); +} + +TEST_CASE(test_is_empty_file) +{ + TEST_CHECK(is_empty(StaticEnv::EmptyFile)); + TEST_CHECK(!is_empty(StaticEnv::NonEmptyFile)); +} + +TEST_CASE(test_is_empty_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir2 = env.create_dir("dir/dir2"); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_empty(dir2, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_empty(dir2)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp new file mode 100644 index 0000000000000..44892f65d86e9 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_fifo(file_status s) noexcept +// bool is_fifo(path const& p); +// bool is_fifo(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_fifo_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_fifo(s)); + ASSERT_NOEXCEPT(is_fifo(p, ec)); + ASSERT_NOT_NOEXCEPT(is_fifo(p)); +} + +TEST_CASE(is_fifo_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, true}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_fifo(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_fifo(p) == false); +} + +TEST_CASE(test_is_fifo_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_fifo(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_fifo(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp new file mode 100644 index 0000000000000..e86b66b4ea64f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_other(file_status s) noexcept +// bool is_other(path const& p); +// bool is_other(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_other_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_other(s)); + ASSERT_NOEXCEPT(is_other(p, ec)); + ASSERT_NOT_NOEXCEPT(is_other(p)); +} + +TEST_CASE(is_other_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, true}, + {file_type::character, true}, + {file_type::fifo, true}, + {file_type::socket, true}, + {file_type::unknown, true} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_other(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_other(p) == false); +} + +TEST_CASE(test_is_other_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_other(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_other(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp new file mode 100644 index 0000000000000..be68dcfc35de3 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_regular_file(file_status s) noexcept +// bool is_regular_file(path const& p); +// bool is_regular_file(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_regular_file_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_regular_file(s)); + ASSERT_NOEXCEPT(is_regular_file(p, ec)); + ASSERT_NOT_NOEXCEPT(is_regular_file(p)); +} + +TEST_CASE(is_regular_file_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, true}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_regular_file(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_regular_file(p) == false); + std::error_code ec; + TEST_CHECK(is_regular_file(p, ec) == false); + TEST_CHECK(ec); +} + +TEST_CASE(test_is_regular_file_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_regular_file(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_regular_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp new file mode 100644 index 0000000000000..49fd402eb546b --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_socket(file_status s) noexcept +// bool is_socket(path const& p); +// bool is_socket(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_socket_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_socket(s)); + ASSERT_NOEXCEPT(is_socket(p, ec)); + ASSERT_NOT_NOEXCEPT(is_socket(p)); +} + +TEST_CASE(is_socket_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, true}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_socket(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_socket(p) == false); +} + +TEST_CASE(test_is_socket_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_socket(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_socket(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp new file mode 100644 index 0000000000000..3de002978683a --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_symlink(file_status s) noexcept +// bool is_symlink(path const& p); +// bool is_symlink(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_symlink_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_symlink(s)); + ASSERT_NOEXCEPT(is_symlink(p, ec)); + ASSERT_NOT_NOEXCEPT(is_symlink(p)); +} + +TEST_CASE(is_symlink_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, true}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_symlink(s) == TC.expect); + } +} + +TEST_CASE(static_env_test) +{ + struct TestCase { + path p; + bool expect; + }; + const TestCase testCases[] = { + {StaticEnv::File, false}, + {StaticEnv::Dir, false}, + {StaticEnv::SymlinkToFile, true}, + {StaticEnv::SymlinkToDir, true}, + {StaticEnv::BadSymlink, true} + }; + for (auto& TC : testCases) { + TEST_CHECK(is_symlink(TC.p) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_symlink(p) == false); + std::error_code ec; + TEST_CHECK(is_symlink(p, ec) == false); + TEST_CHECK(ec); +} + +TEST_CASE(test_is_symlink_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_symlink(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_symlink(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp new file mode 100644 index 0000000000000..3c61b26d18e01 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp @@ -0,0 +1,361 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// file_time_type last_write_time(const path& p); +// file_time_type last_write_time(const path& p, std::error_code& ec) noexcept; +// void last_write_time(const path& p, file_time_type new_time); +// void last_write_time(const path& p, file_time_type new_type, +// std::error_code& ec) noexcept; + + +#include <experimental/filesystem> +#include <type_traits> +#include <chrono> +#include <fstream> +#include <cstdlib> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +#include <sys/stat.h> +#include <iostream> + +using namespace std::experimental::filesystem; + + +std::pair<std::time_t, std::time_t> GetTimes(path const& p) { + using Clock = file_time_type::clock; + struct ::stat st; + if (::stat(p.c_str(), &st) == -1) { + std::error_code ec(errno, std::generic_category()); +#ifndef TEST_HAS_NO_EXCEPTIONS + throw ec; +#else + std::cerr << ec.message() << std::endl; + std::exit(EXIT_FAILURE); +#endif + } + return {st.st_atime, st.st_mtime}; +} + +std::time_t LastAccessTime(path const& p) { + return GetTimes(p).first; +} + +std::time_t LastWriteTime(path const& p) { + return GetTimes(p).second; +} + +std::pair<std::time_t, std::time_t> GetSymlinkTimes(path const& p) { + using Clock = file_time_type::clock; + struct ::stat st; + if (::lstat(p.c_str(), &st) == -1) { + std::error_code ec(errno, std::generic_category()); +#ifndef TEST_HAS_NO_EXCEPTIONS + throw ec; +#else + std::cerr << ec.message() << std::endl; + std::exit(EXIT_FAILURE); +#endif + } + return {st.st_atime, st.st_mtime}; +} + +inline bool TimeIsRepresentableAsTimeT(file_time_type tp) { + using namespace std::chrono; + using Lim = std::numeric_limits<std::time_t>; + auto sec = duration_cast<seconds>(tp.time_since_epoch()).count(); + return (sec >= Lim::min() && sec <= Lim::max()); +} + + +TEST_SUITE(exists_test_suite) + +TEST_CASE(signature_test) +{ + const file_time_type t; + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(last_write_time(p)), file_time_type); + ASSERT_SAME_TYPE(decltype(last_write_time(p, ec)), file_time_type); + ASSERT_SAME_TYPE(decltype(last_write_time(p, t)), void); + ASSERT_SAME_TYPE(decltype(last_write_time(p, t, ec)), void); + ASSERT_NOT_NOEXCEPT(last_write_time(p)); + ASSERT_NOT_NOEXCEPT(last_write_time(p, t)); + ASSERT_NOEXCEPT(last_write_time(p, ec)); + ASSERT_NOEXCEPT(last_write_time(p, t, ec)); +} + +TEST_CASE(read_last_write_time_static_env_test) +{ + using C = file_time_type::clock; + file_time_type min = file_time_type::min(); + { + file_time_type ret = last_write_time(StaticEnv::File); + TEST_CHECK(ret != min); + TEST_CHECK(ret < C::now()); + TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::File)); + + file_time_type ret2 = last_write_time(StaticEnv::SymlinkToFile); + TEST_CHECK(ret == ret2); + TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToFile)); + } + { + file_time_type ret = last_write_time(StaticEnv::Dir); + TEST_CHECK(ret != min); + TEST_CHECK(ret < C::now()); + TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::Dir)); + + file_time_type ret2 = last_write_time(StaticEnv::SymlinkToDir); + TEST_CHECK(ret == ret2); + TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToDir)); + } +} + +TEST_CASE(get_last_write_time_dynamic_env_test) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + scoped_test_env env; + + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + + const auto file_times = GetTimes(file); + const std::time_t file_access_time = file_times.first; + const std::time_t file_write_time = file_times.second; + const auto dir_times = GetTimes(dir); + const std::time_t dir_access_time = dir_times.first; + const std::time_t dir_write_time = dir_times.second; + + file_time_type ftime = last_write_time(file); + TEST_CHECK(Clock::to_time_t(ftime) == file_write_time); + + file_time_type dtime = last_write_time(dir); + TEST_CHECK(Clock::to_time_t(dtime) == dir_write_time); + + SleepFor(Sec(2)); + + // update file and add a file to the directory. Make sure the times increase. + std::ofstream of(file, std::ofstream::app); + of << "hello"; + of.close(); + env.create_file("dir/file1", 1); + + file_time_type ftime2 = last_write_time(file); + file_time_type dtime2 = last_write_time(dir); + + TEST_CHECK(ftime2 > ftime); + TEST_CHECK(dtime2 > dtime); + TEST_CHECK(LastAccessTime(file) == file_access_time); + TEST_CHECK(LastAccessTime(dir) == dir_access_time); +} + + +TEST_CASE(set_last_write_time_dynamic_env_test) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using Hours = std::chrono::hours; + using Minutes = std::chrono::minutes; + using MicroSec = std::chrono::microseconds; + scoped_test_env env; + + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + const auto now = Clock::now(); + const file_time_type epoch_time = now - now.time_since_epoch(); + + const file_time_type future_time = now + Hours(3) + Sec(42) + MicroSec(17); + const file_time_type past_time = now - Minutes(3) - Sec(42) - MicroSec(17); + const file_time_type before_epoch_time = epoch_time - Minutes(3) - Sec(42) - MicroSec(17); + // FreeBSD has a bug in their utimes implementation where the time is not update + // when the number of seconds is '-1'. +#if defined(__FreeBSD__) + const file_time_type just_before_epoch_time = epoch_time - Sec(2) - MicroSec(17); +#else + const file_time_type just_before_epoch_time = epoch_time - MicroSec(17); +#endif + + struct TestCase { + path p; + file_time_type new_time; + } cases[] = { + {file, epoch_time}, + {dir, epoch_time}, + {file, future_time}, + {dir, future_time}, + {file, past_time}, + {dir, past_time}, + {file, before_epoch_time}, + {dir, before_epoch_time}, + {file, just_before_epoch_time}, + {dir, just_before_epoch_time} + }; + for (const auto& TC : cases) { + const auto old_times = GetTimes(TC.p); + file_time_type old_time(Sec(old_times.second)); + + std::error_code ec = GetTestEC(); + last_write_time(TC.p, TC.new_time, ec); + TEST_CHECK(!ec); + + file_time_type got_time = last_write_time(TC.p); + + TEST_CHECK(got_time != old_time); + if (TC.new_time < epoch_time) { + TEST_CHECK(got_time <= TC.new_time); + TEST_CHECK(got_time > TC.new_time - Sec(1)); + } else { + TEST_CHECK(got_time <= TC.new_time + Sec(1)); + TEST_CHECK(got_time >= TC.new_time - Sec(1)); + } + TEST_CHECK(LastAccessTime(TC.p) == old_times.first); + } +} + +TEST_CASE(last_write_time_symlink_test) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using Hours = std::chrono::hours; + using Minutes = std::chrono::minutes; + + scoped_test_env env; + + const path file = env.create_file("file", 42); + const path sym = env.create_symlink("file", "sym"); + + const file_time_type new_time = Clock::now() + Hours(3); + + const auto old_times = GetTimes(sym); + const auto old_sym_times = GetSymlinkTimes(sym); + + std::error_code ec = GetTestEC(); + last_write_time(sym, new_time, ec); + TEST_CHECK(!ec); + + const std::time_t new_time_t = Clock::to_time_t(new_time); + file_time_type got_time = last_write_time(sym); + std::time_t got_time_t = Clock::to_time_t(got_time); + + TEST_CHECK(got_time_t != old_times.second); + TEST_CHECK(got_time_t == new_time_t); + TEST_CHECK(LastWriteTime(file) == new_time_t); + TEST_CHECK(LastAccessTime(sym) == old_times.first); + TEST_CHECK(GetSymlinkTimes(sym) == old_sym_times); +} + + +TEST_CASE(test_write_min_time) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using MicroSec = std::chrono::microseconds; + using Lim = std::numeric_limits<std::time_t>; + scoped_test_env env; + const path p = env.create_file("file", 42); + + std::error_code ec = GetTestEC(); + file_time_type last_time = last_write_time(p); + file_time_type new_time = file_time_type::min(); + + last_write_time(p, new_time, ec); + file_time_type tt = last_write_time(p); + + if (!TimeIsRepresentableAsTimeT(new_time)) { + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + TEST_CHECK(tt == last_time); + } else { + TEST_CHECK(!ec); + TEST_CHECK(tt >= new_time); + TEST_CHECK(tt < new_time + Sec(1)); + } + + ec = GetTestEC(); + last_write_time(p, Clock::now()); + last_time = last_write_time(p); + + new_time = file_time_type::min() + MicroSec(1); + + last_write_time(p, new_time, ec); + tt = last_write_time(p); + + if (!TimeIsRepresentableAsTimeT(new_time)) { + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + TEST_CHECK(tt == last_time); + } else { + TEST_CHECK(!ec); + TEST_CHECK(tt >= new_time); + TEST_CHECK(tt < new_time + Sec(1)); + } +} + + + +TEST_CASE(test_write_min_max_time) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using Hours = std::chrono::hours; + using Lim = std::numeric_limits<std::time_t>; + scoped_test_env env; + const path p = env.create_file("file", 42); + + std::error_code ec = GetTestEC(); + file_time_type last_time = last_write_time(p); + file_time_type new_time = file_time_type::max(); + + ec = GetTestEC(); + last_write_time(p, new_time, ec); + file_time_type tt = last_write_time(p); + + if (!TimeIsRepresentableAsTimeT(new_time)) { + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + TEST_CHECK(tt == last_time); + } else { + TEST_CHECK(!ec); + TEST_CHECK(tt > new_time - Sec(1)); + TEST_CHECK(tt <= new_time); + } +} + +TEST_CASE(test_value_on_failure) +{ + const path p = StaticEnv::DNE; + std::error_code ec = GetTestEC(); + TEST_CHECK(last_write_time(p, ec) == file_time_type::min()); + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); +} + +TEST_CASE(test_exists_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec = GetTestEC(); + TEST_CHECK(last_write_time(file, ec) == file_time_type::min()); + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + + TEST_CHECK_THROW(filesystem_error, last_write_time(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp new file mode 100644 index 0000000000000..b177693c09bde --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void permissions(const path& p, perms prms); +// void permissions(const path& p, perms prms, std::error_code& ec) noexcept; + + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +using PR = fs::perms; + +TEST_SUITE(filesystem_permissions_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + const perms opts{}; ((void)opts); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts)); + // Not noexcept because of narrow contract + ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, fs::perms opts, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::permissions(f, opts); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path dne_sym = env.create_symlink(dne, "dne_sym"); + { // !exists + std::error_code ec; + fs::permissions(dne, fs::perms{}, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dne, fs::perms{}, ec)); + } + { + std::error_code ec; + fs::permissions(dne_sym, fs::perms{}, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dne_sym, fs::perms{}, ec)); + } +} + +TEST_CASE(basic_permissions_test) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dir = env.create_dir("dir1"); + const path file_for_sym = env.create_file("file2", 42); + const path sym = env.create_symlink(file_for_sym, "sym"); + const perms AP = perms::add_perms; + const perms RP = perms::remove_perms; + const perms NF = perms::symlink_nofollow; + struct TestCase { + path p; + perms set_perms; + perms expected; + } cases[] = { + // test file + {file, perms::none, perms::none}, + {file, perms::owner_all, perms::owner_all}, + {file, perms::group_all | AP, perms::owner_all | perms::group_all}, + {file, perms::group_all | RP, perms::owner_all}, + // test directory + {dir, perms::none, perms::none}, + {dir, perms::owner_all, perms::owner_all}, + {dir, perms::group_all | AP, perms::owner_all | perms::group_all}, + {dir, perms::group_all | RP, perms::owner_all}, + // test symlink without symlink_nofollow + {sym, perms::none, perms::none}, + {sym, perms::owner_all, perms::owner_all}, + {sym, perms::group_all | AP, perms::owner_all | perms::group_all}, + {sym, perms::group_all | RP , perms::owner_all}, + // test non-symlink with symlink_nofollow. The last test on file/dir + // will have set their permissions to perms::owner_all + {file, perms::group_all | AP | NF, perms::owner_all | perms::group_all}, + {dir, perms::group_all | AP | NF, perms::owner_all | perms::group_all} + }; + for (auto const& TC : cases) { + TEST_CHECK(status(TC.p).permissions() != TC.expected); + // Set the error code to ensure it's cleared. + std::error_code ec = std::make_error_code(std::errc::bad_address); + permissions(TC.p, TC.set_perms, ec); + TEST_CHECK(!ec); + auto pp = status(TC.p).permissions(); + TEST_CHECK(status(TC.p).permissions() == TC.expected); + } +} + +TEST_CASE(test_no_resolve_symlink_on_symlink) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path sym = env.create_symlink(file, "sym"); + const auto file_perms = status(file).permissions(); + + struct TestCase { + perms set_perms; + perms expected; // only expected on platform that support symlink perms. + } cases[] = { + {perms::owner_all, perms::owner_all}, + {perms::group_all | perms::add_perms, perms::owner_all | perms::group_all}, + {perms::owner_all | perms::remove_perms, perms::group_all}, + }; + for (auto const& TC : cases) { +#if defined(__APPLE__) || defined(__FreeBSD__) + // On OS X symlink permissions are supported. We should get an empty + // error code and the expected permissions. + const auto expected_link_perms = TC.expected; + std::error_code expected_ec; +#else + // On linux symlink permissions are not supported. The error code should + // be 'operation_not_supported' and the sylink permissions should be + // unchanged. + const auto expected_link_perms = symlink_status(sym).permissions(); + std::error_code expected_ec = std::make_error_code(std::errc::operation_not_supported); +#endif + std::error_code ec = std::make_error_code(std::errc::bad_address); + permissions(sym, TC.set_perms | perms::symlink_nofollow, ec); + TEST_CHECK(ec == expected_ec); + TEST_CHECK(status(file).permissions() == file_perms); + TEST_CHECK(symlink_status(sym).permissions() == expected_link_perms); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp new file mode 100644 index 0000000000000..00581cbe8bcc4 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// path read_symlink(const path& p); +// path read_symlink(const path& p, error_code& ec); + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_read_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::read_symlink(p)), fs::path); + ASSERT_SAME_TYPE(decltype(fs::read_symlink(p, ec)), fs::path); + + ASSERT_NOT_NOEXCEPT(fs::read_symlink(p)); + // Not noexcept because of narrow contract + ASSERT_NOT_NOEXCEPT(fs::read_symlink(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::read_symlink(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path cases[] = { + env.make_env_path("dne"), + env.create_file("file", 42), + env.create_dir("dir") + }; + for (path const& p : cases) { + std::error_code ec; + const path ret = fs::read_symlink(p, ec); + TEST_REQUIRE(ec); + TEST_CHECK(ret == path{}); + TEST_CHECK(checkThrow(p, ec)); + } + +} + +TEST_CASE(basic_symlink_test) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + const path link = env.create_symlink(dne, "link"); + const path nested_link = env.make_env_path("nested_link"); + create_symlink(link, nested_link); + struct TestCase { + path symlink; + path expected; + } testCases[] = { + {env.create_symlink(dne, "dne_link"), dne}, + {env.create_symlink(file, "file_link"), file}, + {env.create_symlink(dir, "dir_link"), dir}, + {nested_link, link} + }; + for (auto& TC : testCases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + const path ret = read_symlink(TC.symlink, ec); + TEST_CHECK(!ec); + TEST_CHECK(ret == TC.expected); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp new file mode 100644 index 0000000000000..edb0c4fc76c9f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool remove(const path& p); +// bool remove(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_remove_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::remove(p)), bool); + ASSERT_SAME_TYPE(decltype(fs::remove(p, ec)), bool); + + ASSERT_NOT_NOEXCEPT(fs::remove(p)); + ASSERT_NOEXCEPT(fs::remove(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::remove(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path non_empty_dir = env.create_dir("dir"); + env.create_file(non_empty_dir / "file1", 42); + const path bad_perms_dir = env.create_dir("bad_dir"); + const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42); + permissions(bad_perms_dir, perms::none); + const path testCases[] = { + "", + env.make_env_path("dne"), + non_empty_dir, + file_in_bad_dir, + }; + for (auto& p : testCases) { + std::error_code ec; + TEST_CHECK(!fs::remove(p, ec)); + TEST_CHECK(ec); + TEST_CHECK(checkThrow(p, ec)); + } +} + +TEST_CASE(basic_remove_test) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path link = env.create_symlink(dne, "link"); + const path nested_link = env.make_env_path("nested_link"); + create_symlink(link, nested_link); + const path testCases[] = { + env.create_file("file", 42), + env.create_dir("empty_dir"), + nested_link, + link + }; + for (auto& p : testCases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove(p, ec)); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(p))); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp new file mode 100644 index 0000000000000..aecfce7885e96 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// uintmax_t remove_all(const path& p); +// uintmax_t remove_all(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_remove_all_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::remove_all(p)), std::uintmax_t); + ASSERT_SAME_TYPE(decltype(fs::remove_all(p, ec)), std::uintmax_t); + + ASSERT_NOT_NOEXCEPT(fs::remove_all(p)); + ASSERT_NOEXCEPT(fs::remove_all(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::remove_all(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path non_empty_dir = env.create_dir("dir"); + env.create_file(non_empty_dir / "file1", 42); + const path bad_perms_dir = env.create_dir("bad_dir"); + const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42); + permissions(bad_perms_dir, perms::none); + const path bad_perms_file = env.create_file("file2", 42); + permissions(bad_perms_file, perms::none); + + const path testCases[] = { + env.make_env_path("dne"), + file_in_bad_dir + }; + const auto BadRet = static_cast<std::uintmax_t>(-1); + for (auto& p : testCases) { + std::error_code ec; + TEST_CHECK(fs::remove_all(p, ec) == BadRet); + TEST_CHECK(ec); + TEST_CHECK(checkThrow(p, ec)); + } +} + +TEST_CASE(basic_remove_all_test) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path link = env.create_symlink(dne, "link"); + const path nested_link = env.make_env_path("nested_link"); + create_symlink(link, nested_link); + const path testCases[] = { + env.create_file("file", 42), + env.create_dir("empty_dir"), + nested_link, + link + }; + for (auto& p : testCases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove(p, ec)); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(p))); + } +} + +TEST_CASE(symlink_to_dir) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file(dir / "file", 42); + const path link = env.create_symlink(dir, "sym"); + + { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove_all(link, ec) == 1); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(link))); + TEST_CHECK(exists(dir)); + TEST_CHECK(exists(file)); + } +} + + +TEST_CASE(nested_dir) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir1 = env.create_dir(dir / "dir1"); + const path out_of_dir_file = env.create_file("file1", 42); + const path all_files[] = { + dir, dir1, + env.create_file(dir / "file1", 42), + env.create_symlink(out_of_dir_file, dir / "sym1"), + env.create_file(dir1 / "file2", 42), + env.create_symlink(dir, dir1 / "sym2") + }; + const std::size_t expected_count = sizeof(all_files) / sizeof(all_files[0]); + + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove_all(dir, ec) == expected_count); + TEST_CHECK(!ec); + for (auto const& p : all_files) { + TEST_CHECK(!exists(symlink_status(p))); + } + TEST_CHECK(exists(out_of_dir_file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp new file mode 100644 index 0000000000000..c2ae854c0bf6d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void rename(const path& old_p, const path& new_p); +// void rename(const path& old_p, const path& new_p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_rename_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::rename(p, p)), void); + ASSERT_SAME_TYPE(decltype(fs::rename(p, p, ec)), void); + + ASSERT_NOT_NOEXCEPT(fs::rename(p, p)); + ASSERT_NOEXCEPT(fs::rename(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::rename(f, t); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == t + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path file = env.create_file("file1", 42); + const path dir = env.create_dir("dir1"); + struct TestCase { + path from; + path to; + } cases[] = { + {dne, dne}, + {file, dir}, + {dir, file} + }; + for (auto& TC : cases) { + auto from_before = status(TC.from); + auto to_before = status(TC.to); + std::error_code ec; + rename(TC.from, TC.to, ec); + TEST_REQUIRE(ec); + TEST_CHECK(from_before.type() == status(TC.from).type()); + TEST_CHECK(to_before.type() == status(TC.to).type()); + TEST_CHECK(checkThrow(TC.from, TC.to, ec)); + } +} + +TEST_CASE(basic_rename_test) +{ + scoped_test_env env; + + const std::error_code set_ec = std::make_error_code(std::errc::address_in_use); + const path file = env.create_file("file1", 42); + { // same file + std::error_code ec = set_ec; + rename(file, file, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_regular_file(file)); + TEST_CHECK(file_size(file) == 42); + } + const path sym = env.create_symlink(file, "sym"); + { // file -> symlink + std::error_code ec = set_ec; + rename(file, sym, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(file)); + TEST_CHECK(is_regular_file(symlink_status(sym))); + TEST_CHECK(file_size(sym) == 42); + } + const path file2 = env.create_file("file2", 42); + const path file3 = env.create_file("file3", 100); + { // file -> file + std::error_code ec = set_ec; + rename(file2, file3, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(file2)); + TEST_CHECK(is_regular_file(file3)); + TEST_CHECK(file_size(file3) == 42); + } + const path dne = env.make_env_path("dne"); + const path bad_sym = env.create_symlink(dne, "bad_sym"); + const path bad_sym_dest = env.make_env_path("bad_sym2"); + { // bad-symlink + std::error_code ec = set_ec; + rename(bad_sym, bad_sym_dest, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(bad_sym))); + TEST_CHECK(is_symlink(bad_sym_dest)); + TEST_CHECK(read_symlink(bad_sym_dest) == dne); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp new file mode 100644 index 0000000000000..8a6aa09b14c78 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// void resize_file(const path& p, uintmax_t new_size); +// void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_resize_file_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::uintmax_t i; ((void)i); + std::error_code ec; ((void)ec); + + ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i)), void); + ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i, ec)), void); + + ASSERT_NOT_NOEXCEPT(fs::resize_file(p, i)); + ASSERT_NOEXCEPT(fs::resize_file(p, i, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, std::uintmax_t s, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::resize_file(f, s); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path bad_sym = env.create_symlink(dne, "sym"); + const path dir = env.create_dir("dir1"); + const path cases[] = { + dne, bad_sym, dir + }; + for (auto& p : cases) { + std::error_code ec; + resize_file(p, 42, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(p, 42, ec)); + } +} + +TEST_CASE(basic_resize_file_test) +{ + scoped_test_env env; + const path file1 = env.create_file("file1", 42); + const auto set_ec = std::make_error_code(std::errc::address_in_use); + { // grow file + const std::uintmax_t new_s = 100; + std::error_code ec = set_ec; + resize_file(file1, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } + { // shrink file + const std::uintmax_t new_s = 1; + std::error_code ec = set_ec; + resize_file(file1, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } + { // shrink file to zero + const std::uintmax_t new_s = 0; + std::error_code ec = set_ec; + resize_file(file1, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } + const path sym = env.create_symlink(file1, "sym"); + { // grow file via symlink + const std::uintmax_t new_s = 1024; + std::error_code ec = set_ec; + resize_file(sym, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp new file mode 100644 index 0000000000000..865191520be3e --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp @@ -0,0 +1,127 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// space_info space(const path& p); +// space_info space(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <sys/statvfs.h> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +bool EqualDelta(std::uintmax_t x, std::uintmax_t y, std::uintmax_t delta) { + if (x >= y) { + return (x - y) <= delta; + } else { + return (y - x) <= delta; + } +} + +TEST_SUITE(filesystem_space_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(space(p)), space_info); + ASSERT_SAME_TYPE(decltype(space(p, ec)), space_info); + ASSERT_NOT_NOEXCEPT(space(p)); + ASSERT_NOEXCEPT(space(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + space(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + const path cases[] = { + "", + StaticEnv::DNE, + StaticEnv::BadSymlink + }; + for (auto& p : cases) { + const auto expect = static_cast<std::uintmax_t>(-1); + std::error_code ec; + space_info info = space(p, ec); + TEST_CHECK(ec); + TEST_CHECK(info.capacity == expect); + TEST_CHECK(info.free == expect); + TEST_CHECK(info.available == expect); + TEST_CHECK(checkThrow(p, ec)); + } +} + +TEST_CASE(basic_space_test) +{ + // All the test cases should reside on the same filesystem and therefore + // should have the same expected result. Compute this expected result + // one and check that it looks semi-sane. + struct statvfs expect; + TEST_REQUIRE(::statvfs(StaticEnv::Dir.c_str(), &expect) != -1); + TEST_CHECK(expect.f_bavail > 0); + TEST_CHECK(expect.f_bfree > 0); + TEST_CHECK(expect.f_bsize > 0); + TEST_CHECK(expect.f_blocks > 0); + TEST_REQUIRE(expect.f_frsize > 0); + auto do_mult = [&](std::uintmax_t val) { + std::uintmax_t fsize = expect.f_frsize; + std::uintmax_t new_val = val * fsize; + TEST_CHECK(new_val / fsize == val); // Test for overflow + return new_val; + }; + const std::uintmax_t bad_value = static_cast<std::uintmax_t>(-1); + const std::uintmax_t expect_capacity = do_mult(expect.f_blocks); + const std::uintmax_t expect_free = do_mult(expect.f_bfree); + const std::uintmax_t expect_avail = do_mult(expect.f_bavail); + + // Other processes running on the operating system may have changed + // the amount of space available. Check that these are within tolerances. + // Currently 5% of capacity + const std::uintmax_t delta = expect_capacity / 20; + const path cases[] = { + StaticEnv::File, + StaticEnv::Dir, + StaticEnv::Dir2, + StaticEnv::SymlinkToFile, + StaticEnv::SymlinkToDir + }; + for (auto& p : cases) { + std::error_code ec = GetTestEC(); + space_info info = space(p, ec); + TEST_CHECK(!ec); + TEST_CHECK(info.capacity != bad_value); + TEST_CHECK(expect_capacity == info.capacity); + TEST_CHECK(info.free != bad_value); + TEST_CHECK(EqualDelta(expect_free, info.free, delta)); + TEST_CHECK(info.available != bad_value); + TEST_CHECK(EqualDelta(expect_avail, info.available, delta)); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp new file mode 100644 index 0000000000000..2c76caf74c847 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// file_status status(const path& p); +// file_status status(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_status_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(status(p)); + ASSERT_NOEXCEPT(status(p, ec)); +} + +TEST_CASE(test_status_not_found) +{ + const std::error_code expect_ec = + std::make_error_code(std::errc::no_such_file_or_directory); + const path cases[] { + StaticEnv::DNE, + StaticEnv::BadSymlink + }; + for (auto& p : cases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + // test non-throwing overload. + file_status st = status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + // test throwing overload. It should not throw even though it reports + // that the file was not found. + TEST_CHECK_NO_THROW(st = status(p)); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + } +} + +TEST_CASE(test_status_cannot_resolve) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + const path sym = env.create_symlink("dir/file", "sym"); + permissions(dir, perms::none); + + const std::error_code set_ec = + std::make_error_code(std::errc::address_in_use); + const std::error_code expect_ec = + std::make_error_code(std::errc::permission_denied); + + const path cases[] = { + file, sym + }; + for (auto& p : cases) + { + { // test non-throwing case + std::error_code ec = set_ec; + file_status st = status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::none); + TEST_CHECK(st.permissions() == perms::unknown); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { // test throwing case + try { + status(p); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == ""); + TEST_CHECK(err.code() == expect_ec); + } + } +#endif + } +} + +TEST_CASE(status_file_types_test) +{ + scoped_test_env env; + struct TestCase { + path p; + file_type expect_type; + } cases[] = { + {StaticEnv::File, file_type::regular}, + {StaticEnv::SymlinkToFile, file_type::regular}, + {StaticEnv::Dir, file_type::directory}, + {StaticEnv::SymlinkToDir, file_type::directory}, + // Block files tested elsewhere + {StaticEnv::CharFile, file_type::character}, +#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets + {env.create_socket("socket"), file_type::socket}, +#endif + {env.create_fifo("fifo"), file_type::fifo} + }; + for (const auto& TC : cases) { + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = status(TC.p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = status(TC.p)); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + +TEST_CASE(test_block_file) +{ + const path possible_paths[] = { + "/dev/drive0", // Apple + "/dev/sda", + "/dev/loop0" + }; + path p; + for (const path& possible_p : possible_paths) { + std::error_code ec; + if (exists(possible_p, ec)) { + p = possible_p; + break; + } + } + if (p == path{}) { + TEST_UNSUPPORTED(); + } + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = status(p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = status(p)); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp new file mode 100644 index 0000000000000..169c5be9d9a86 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool status_known(file_status s) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(status_known_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + ASSERT_SAME_TYPE(decltype(status_known(s)), bool); + ASSERT_NOEXCEPT(status_known(s)); +} + +TEST_CASE(status_known_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, true}, + {file_type::regular, true}, + {file_type::directory, true}, + {file_type::symlink, true}, + {file_type::block, true}, + {file_type::character, true}, + {file_type::fifo, true}, + {file_type::socket, true}, + {file_type::unknown, true} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(status_known(s) == TC.expect); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp new file mode 100644 index 0000000000000..647504f6e1a44 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp @@ -0,0 +1,192 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// file_status symlink_status(const path& p); +// file_status symlink_status(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_symlink_status_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(symlink_status(p)); + ASSERT_NOEXCEPT(symlink_status(p, ec)); +} + +TEST_CASE(test_symlink_status_not_found) +{ + const std::error_code expect_ec = + std::make_error_code(std::errc::no_such_file_or_directory); + const path cases[] { + StaticEnv::DNE + }; + for (auto& p : cases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + // test non-throwing overload. + file_status st = symlink_status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + // test throwing overload. It should not throw even though it reports + // that the file was not found. + TEST_CHECK_NO_THROW(st = status(p)); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + } +} + +TEST_CASE(test_symlink_status_cannot_resolve) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file_in_dir = env.create_file("dir/file", 42); + const path sym_in_dir = env.create_symlink("dir/file", "dir/bad_sym"); + const path sym_points_in_dir = env.create_symlink("dir/file", "sym"); + permissions(dir, perms::none); + + const std::error_code set_ec = + std::make_error_code(std::errc::address_in_use); + const std::error_code expect_ec = + std::make_error_code(std::errc::permission_denied); + + const path fail_cases[] = { + file_in_dir, sym_in_dir + }; + for (auto& p : fail_cases) + { + { // test non-throwing case + std::error_code ec = set_ec; + file_status st = symlink_status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::none); + TEST_CHECK(st.permissions() == perms::unknown); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { // test throwing case + try { + symlink_status(p); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == ""); + TEST_CHECK(err.code() == expect_ec); + } + } +#endif + } + // Test that a symlink that points into a directory without read perms + // can be stat-ed using symlink_status + { + std::error_code ec = set_ec; + file_status st = symlink_status(sym_points_in_dir, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + // test non-throwing version + TEST_REQUIRE_NO_THROW(st = symlink_status(sym_points_in_dir)); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + + +TEST_CASE(symlink_status_file_types_test) +{ + scoped_test_env env; + struct TestCase { + path p; + file_type expect_type; + } cases[] = { + {StaticEnv::BadSymlink, file_type::symlink}, + {StaticEnv::File, file_type::regular}, + {StaticEnv::SymlinkToFile, file_type::symlink}, + {StaticEnv::Dir, file_type::directory}, + {StaticEnv::SymlinkToDir, file_type::symlink}, + // Block files tested elsewhere + {StaticEnv::CharFile, file_type::character}, +#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets + {env.create_socket("socket"), file_type::socket}, +#endif + {env.create_fifo("fifo"), file_type::fifo} + }; + for (const auto& TC : cases) { + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = symlink_status(TC.p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = symlink_status(TC.p)); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + +TEST_CASE(test_block_file) +{ + const path possible_paths[] = { + "/dev/drive0", // Apple + "/dev/sda", // Linux + "/dev/loop0" // Linux + // No FreeBSD files known + }; + path p; + for (const path& possible_p : possible_paths) { + std::error_code ec; + if (exists(possible_p, ec)) { + p = possible_p; + break; + } + } + if (p == path{}) { + TEST_UNSUPPORTED(); + } + scoped_test_env env; + { // test block file + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = symlink_status(p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = symlink_status(p)); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); + } + const path sym = env.make_env_path("sym"); + create_symlink(p, sym); + { // test symlink to block file + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = symlink_status(sym, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = symlink_status(sym)); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp new file mode 100644 index 0000000000000..634184e24e6d2 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// path system_complete(const path& p); +// path system_complete(const path& p, error_code& ec); + +// Note: For POSIX based operating systems, 'system_complete(p)' has the +// same semantics as 'absolute(p, current_path())'. + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_system_complete_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(system_complete(p)); + ASSERT_NOT_NOEXCEPT(system_complete(p, ec)); +} + + +TEST_CASE(basic_system_complete_tests) +{ + const path testCases[] = { + "//net/foo", // has_root_name() && has_root_directory() + "/foo", // !has_root_name() && has_root_directory() + "//net", // has_root_name() && !has_root_directory() + "bar/baz" // !has_root_name() && !has_root_directory() + }; + const path base = current_path(); + for (auto& p : testCases) { + const path ret = system_complete(p); + const path expect = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == expect); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp new file mode 100644 index 0000000000000..215c35a33f302 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// path temp_directory_path(); +// path temp_directory_path(error_code& ec); + +#include <experimental/filesystem> +#include <memory> +#include <cstdlib> +#include <cstring> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +void PutEnv(std::string var, std::string value) { + assert(::setenv(var.c_str(), value.c_str(), /* overwrite */ 1) == 0); +} + +void UnsetEnv(std::string var) { + assert(::unsetenv(var.c_str()) == 0); +} + +TEST_SUITE(filesystem_temp_directory_path_test_suite) + +TEST_CASE(signature_test) +{ + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(temp_directory_path()); + ASSERT_NOT_NOEXCEPT(temp_directory_path(ec)); +} + +TEST_CASE(basic_tests) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path file = env.create_file("file", 42); + const path dir_perms = env.create_dir("bad_perms_dir"); + const path nested_dir = env.create_dir("bad_perms_dir/nested"); + permissions(dir_perms, perms::none); + const std::error_code set_ec = std::make_error_code(std::errc::address_in_use); + const std::error_code expect_ec = std::make_error_code(std::errc::not_a_directory); + struct TestCase { + std::string name; + path p; + } cases[] = { + {"TMPDIR", env.create_dir("dir1")}, + {"TMP", env.create_dir("dir2")}, + {"TEMP", env.create_dir("dir3")}, + {"TEMPDIR", env.create_dir("dir4")} + }; + for (auto& TC : cases) { + PutEnv(TC.name, TC.p); + } + for (auto& TC : cases) { + std::error_code ec = set_ec; + path ret = temp_directory_path(ec); + TEST_CHECK(!ec); + TEST_CHECK(ret == TC.p); + TEST_CHECK(is_directory(ret)); + + // Set the env variable to a path that does not exist and check + // that it fails. + PutEnv(TC.name, dne); + ec = set_ec; + ret = temp_directory_path(ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(ret == ""); + + // Set the env variable to point to a file and check that it fails. + PutEnv(TC.name, file); + ec = set_ec; + ret = temp_directory_path(ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(ret == ""); + + // Set the env variable to point to a dir we can't access + PutEnv(TC.name, nested_dir); + ec = set_ec; + ret = temp_directory_path(ec); + TEST_CHECK(ec == std::make_error_code(std::errc::permission_denied)); + TEST_CHECK(ret == ""); + + // Finally erase this env variable + UnsetEnv(TC.name); + } + // No env variables are defined + { + std::error_code ec = set_ec; + path ret = temp_directory_path(ec); + TEST_CHECK(!ec); + TEST_CHECK(ret == "/tmp"); + TEST_CHECK(is_directory(ret)); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp b/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp new file mode 100644 index 0000000000000..d57dff4a7b789 --- /dev/null +++ b/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// #define __cpp_lib_experimental_filesystem 201406L + +#include <experimental/filesystem> + +#ifndef __cpp_lib_experimental_filesystem +#error Filesystem feature test macro is not defined (__cpp_lib_experimental_filesystem) +#elif __cpp_lib_experimental_filesystem != 201406L +#error Filesystem feature test macro has an incorrect value (__cpp_lib_experimental_filesystem) +#endif + +int main() { } diff --git a/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp b/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp new file mode 100644 index 0000000000000..77ae7b0989be8 --- /dev/null +++ b/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// namespace std::experimental::filesystem::v1 + +#include <experimental/filesystem> +#include <type_traits> + +int main() { + static_assert(std::is_same< + std::experimental::filesystem::path, + std::experimental::filesystem::v1::path + >::value, ""); +} diff --git a/test/std/experimental/filesystem/lit.local.cfg b/test/std/experimental/filesystem/lit.local.cfg new file mode 100644 index 0000000000000..3d9360431f486 --- /dev/null +++ b/test/std/experimental/filesystem/lit.local.cfg @@ -0,0 +1,3 @@ +# Disable all of the filesystem tests if the correct feature is not available. +if 'c++filesystem' not in config.available_features: + config.unsupported = True diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp index 7647b536aa95e..ae1b64222a29f 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp index 1323044c87041..bc44f1f6cbbfc 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -44,7 +44,7 @@ template <typename T> struct MyHash { template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_searcher<Iter2, + std::experimental::boyer_moore_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>> s{b2, e2}; assert(result == std::experimental::search(b1, e1, s)); diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp index 8fd5b8c9f784e..743ab92156be0 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -54,7 +54,7 @@ unsigned count_equal::count = 0; template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_searcher<Iter2, + std::experimental::boyer_moore_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp index d0655c82febb1..b27cabd76ab32 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -50,7 +50,7 @@ unsigned count_equal::count = 0; template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_searcher<Iter2, + std::experimental::boyer_moore_searcher<Iter2, typename std::hash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; count_equal::count = 0; assert(result == std::experimental::search(b1, e1, s)); diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp index af3bbbafb24e7..cbf9b41d590f8 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp index ff289f0edeb05..28a3f6d912f87 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -43,7 +43,7 @@ template <typename T> struct MyHash { template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_horspool_searcher<Iter2, + std::experimental::boyer_moore_horspool_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>> s{b2, e2}; assert(result == std::experimental::search(b1, e1, s)); diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp index 1150210a978ad..3a6647dbc7f56 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -53,7 +53,7 @@ unsigned count_equal::count = 0; template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_horspool_searcher<Iter2, + std::experimental::boyer_moore_horspool_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp index 55426874abe55..8c78b9de0b35c 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -49,7 +49,7 @@ unsigned count_equal::count = 0; template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_horspool_searcher<Iter2, + std::experimental::boyer_moore_horspool_searcher<Iter2, typename std::hash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; count_equal::count = 0; assert(result == std::experimental::search(b1, e1, s)); diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/default.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/default.pass.cpp index 446dcbde42be3..4eaf3a8703906 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.default/default.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.default/default.pass.cpp @@ -15,15 +15,16 @@ // template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> // class default_searcher { // public: -// default_searcher(_ForwardIterator __f, _ForwardIterator __l, +// default_searcher(_ForwardIterator __f, _ForwardIterator __l, // _BinaryPredicate __p = _BinaryPredicate()) // : __first_(__f), __last_(__l), __pred_(__p) {} -// +// // template <typename _ForwardIterator2> -// _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { +// pair<_ForwardIterator2, _ForwardIterator2> +// operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { // return std::search(__f, __l, __first_, __last_, __pred_); // } -// +// // private: // _ForwardIterator __first_; // _ForwardIterator __last_; diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/default.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/default.pred.pass.cpp index b65c500c31926..a2f690d7b7bfe 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.default/default.pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.default/default.pred.pass.cpp @@ -15,15 +15,16 @@ // template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> // class default_searcher { // public: -// default_searcher(_ForwardIterator __f, _ForwardIterator __l, +// default_searcher(_ForwardIterator __f, _ForwardIterator __l, // _BinaryPredicate __p = _BinaryPredicate()) // : __first_(__f), __last_(__l), __pred_(__p) {} -// +// // template <typename _ForwardIterator2> -// _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { +// pair<_ForwardIterator2, _ForwardIterator2> +// operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { // return std::search(__f, __l, __first_, __last_, __pred_); // } -// +// // private: // _ForwardIterator __first_; // _ForwardIterator __last_; diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pass.cpp index 9528002d5f2da..7798a6e73f5e7 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pass.cpp @@ -25,7 +25,7 @@ template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result) { - assert(result == std::experimental::search(b1, e1, + assert(result == std::experimental::search(b1, e1, std::experimental::make_default_searcher(b2, e2))); } diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pred.pass.cpp index 2770202131490..21f50a397e2ae 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pred.pass.cpp @@ -36,7 +36,7 @@ unsigned count_equal::count = 0; template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { count_equal::count = 0; - assert(result == std::experimental::search(b1, e1, + assert(result == std::experimental::search(b1, e1, std::experimental::make_default_searcher(b2, e2))); assert(count_equal::count <= max_count); } diff --git a/test/std/experimental/iterator/nothing_to_do.pass.cpp b/test/std/experimental/iterator/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..892d6895a326d --- /dev/null +++ b/test/std/experimental/iterator/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <experimental/iterator> + +int main () {} diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp new file mode 100644 index 0000000000000..5c84d210e53eb --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <experimental/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner(ostream_type& __os, _Delim&& __d); +// ostream_joiner(ostream_type& __os, const _Delim& __d); + +#include <experimental/iterator> +#include <iostream> +#include <string> + +#include "test_macros.h" + +namespace exp = std::experimental; + +int main () { + const char eight = '8'; + const std::string nine = "9"; + const std::wstring ten = L"10"; + const int eleven = 11; + +// Narrow streams w/rvalues + { exp::ostream_joiner<char> oj(std::cout, '8'); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); } + { exp::ostream_joiner<int> oj(std::cout, 11); } + +// Narrow streams w/lvalues + { exp::ostream_joiner<char> oj(std::cout, eight); } + { exp::ostream_joiner<std::string> oj(std::cout, nine); } + { exp::ostream_joiner<std::wstring> oj(std::cout, ten); } + { exp::ostream_joiner<int> oj(std::cout, eleven); } + +// Wide streams w/rvalues + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); } + +// Wide streams w/lvalues + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, eight); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, nine); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, ten); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, eleven); } + + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp new file mode 100644 index 0000000000000..a8c1b286f1de0 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <experimental/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// template <class _CharT, class _Traits, class _Delim> +// ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> +// make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d); +// + +#include <experimental/iterator> +#include <iostream> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +namespace exp = std::experimental; + +template <class Delim, class Iter, class CharT = char, class Traits = std::char_traits<CharT>> +void test (Delim &&d, Iter first, Iter last, const CharT *expected ) { + std::basic_stringstream<CharT, Traits> sstream; + auto joiner = exp::make_ostream_joiner(sstream, d); + typedef exp::ostream_joiner<typename std::decay<Delim>::type, CharT, Traits> Joiner; + static_assert((std::is_same<decltype(joiner), Joiner>::value), "" ); + while (first != last) + joiner = *first++; + assert(sstream.str() == expected); + } + +int main () { + const char chars[] = "0123456789"; + const int ints [] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + +// There are more of these tests in another file. +// This is just to make sure that the ostream_joiner is created correctly + test('X', chars, chars+10, "0X1X2X3X4X5X6X7X8X9"); + test('x', ints, ints+10, "10x11x12x13x14x15x16x17x18x19"); + test("Z", chars, chars+10, "0Z1Z2Z3Z4Z5Z6Z7Z8Z9"); + test("z", ints, ints+10, "10z11z12z13z14z15z16z17z18z19"); + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp new file mode 100644 index 0000000000000..b2c294fd034b4 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <experimental/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// template<typename T> +// ostream_joiner & operator=(const T&) +// + +#include <experimental/iterator> +#include <iostream> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +struct mutating_delimiter { + mutating_delimiter(char c = ' ') : c_(c) {} + char get () const { return c_++; } + mutable char c_; + }; + +template<class _CharT, class _Traits> +std::basic_ostream<_CharT, _Traits>& +operator<<(std::basic_ostream<_CharT, _Traits>& os, const mutating_delimiter &d) +{ return os << d.get(); } + + +struct mutating_delimiter2 { // same as above, w/o the const and the mutable + mutating_delimiter2(char c = ' ') : c_(c) {} + char get () { return c_++; } + char c_; + }; + +template<class _CharT, class _Traits> +std::basic_ostream<_CharT, _Traits>& +operator<<(std::basic_ostream<_CharT, _Traits>& os, mutating_delimiter2 &d) +{ return os << d.get(); } + + +namespace exp = std::experimental; + +template <class Delim, class Iter, class CharT = char, class Traits = std::char_traits<CharT>> +void test (Delim &&d, Iter first, Iter last, const CharT *expected ) { + typedef exp::ostream_joiner<typename std::decay<Delim>::type, CharT, Traits> Joiner; + + static_assert((std::is_copy_constructible<Joiner>::value == std::is_copy_constructible<typename std::decay<Delim>::type>::value), "" ); + static_assert((std::is_move_constructible<Joiner>::value == std::is_move_constructible<typename std::decay<Delim>::type>::value), "" ); + static_assert((std::is_copy_assignable<Joiner> ::value == std::is_copy_assignable<typename std::decay<Delim>::type> ::value), "" ); + static_assert((std::is_move_assignable<Joiner> ::value == std::is_move_assignable<typename std::decay<Delim>::type> ::value), "" ); + + std::basic_stringstream<CharT, Traits> sstream; + Joiner joiner(sstream, d); + while (first != last) + *joiner++ = *first++; + assert(sstream.str() == expected); + } + +int main () { +{ + const char chars[] = "0123456789"; + const int ints [] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + + test('X', chars, chars+10, "0X1X2X3X4X5X6X7X8X9"); + test('x', ints, ints+10, "10x11x12x13x14x15x16x17x18x19"); + test('X', input_iterator<const char*>(chars), input_iterator<const char*>(chars+10), "0X1X2X3X4X5X6X7X8X9"); + test('x', input_iterator<const int*>(ints), input_iterator<const int*>(ints+10), "10x11x12x13x14x15x16x17x18x19"); + test('X', forward_iterator<const char*>(chars), forward_iterator<const char*>(chars+10), "0X1X2X3X4X5X6X7X8X9"); + test('x', forward_iterator<const int*>(ints), forward_iterator<const int*>(ints+10), "10x11x12x13x14x15x16x17x18x19"); + test('X', random_access_iterator<const char*>(chars), random_access_iterator<const char*>(chars+10), "0X1X2X3X4X5X6X7X8X9"); + test('x', random_access_iterator<const int*>(ints), random_access_iterator<const int*>(ints+10), "10x11x12x13x14x15x16x17x18x19"); + + test("Z", chars, chars+10, "0Z1Z2Z3Z4Z5Z6Z7Z8Z9"); + test("z", ints, ints+10, "10z11z12z13z14z15z16z17z18z19"); + + test<char, const char *, wchar_t> ('X', chars, chars+10, L"0X1X2X3X4X5X6X7X8X9"); + test<char, const int *, wchar_t> ('x', ints, ints+10, L"10x11x12x13x14x15x16x17x18x19"); +// test<char, const char *, char16_t>('X', chars, chars+10, u"0X1X2X3X4X5X6X7X8X9"); +// test<char, const int *, char16_t>('x', ints, ints+10, u"10x11x12x13x14x15x16x17x18x19"); +// test<char, const char *, char32_t>('X', chars, chars+10, U"0X1X2X3X4X5X6X7X8X9"); +// test<char, const int *, char32_t>('x', ints, ints+10, U"10x11x12x13x14x15x16x17x18x19"); + + test(mutating_delimiter(), chars, chars+10, "0 1!2\"3#4$5%6&7'8(9"); + test(mutating_delimiter2(), chars, chars+10, "0 1!2\"3#4$5%6&7'8(9"); + } + + { + const wchar_t chars[] = L"0123456789"; + const int ints [] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + test(L'X', chars, chars+10, L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', ints, ints+10, L"10x11x12x13x14x15x16x17x18x19"); + test(L'X', input_iterator<const wchar_t*>(chars), input_iterator<const wchar_t*>(chars+10), L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', input_iterator<const int*>(ints), input_iterator<const int*>(ints+10), L"10x11x12x13x14x15x16x17x18x19"); + test(L'X', forward_iterator<const wchar_t*>(chars), forward_iterator<const wchar_t*>(chars+10), L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', forward_iterator<const int*>(ints), forward_iterator<const int*>(ints+10), L"10x11x12x13x14x15x16x17x18x19"); + test(L'X', random_access_iterator<const wchar_t*>(chars), random_access_iterator<const wchar_t*>(chars+10), L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', random_access_iterator<const int*>(ints), random_access_iterator<const int*>(ints+10), L"10x11x12x13x14x15x16x17x18x19"); + + test(L"Z", chars, chars+10, L"0Z1Z2Z3Z4Z5Z6Z7Z8Z9"); + test(L"z", ints, ints+10, L"10z11z12z13z14z15z16z17z18z19"); + + test<char, const wchar_t *, wchar_t> ('X', chars, chars+10, L"0X1X2X3X4X5X6X7X8X9"); + test<char, const int *, wchar_t> ('x', ints, ints+10, L"10x11x12x13x14x15x16x17x18x19"); + + test(mutating_delimiter(), chars, chars+10, L"0 1!2\"3#4$5%6&7'8(9"); + } + +} diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp new file mode 100644 index 0000000000000..e3872c3e030b0 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <experimental/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner & operator++(int) noexcept +// returns *this; + +#include <experimental/iterator> +#include <iostream> +#include <cassert> + +#include "test_macros.h" + +namespace exp = std::experimental; + +template <class Delim, class CharT, class Traits> +void test ( exp::ostream_joiner<Delim, CharT, Traits> &oj ) { + static_assert((noexcept(oj++)), "" ); + exp::ostream_joiner<Delim, CharT, Traits> &ret = oj++; + assert( &ret == &oj ); + } + +int main () { + + { exp::ostream_joiner<char> oj(std::cout, '8'); test(oj); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int> oj(std::cout, 11); test(oj); } + + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); test(oj); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); test(oj); } + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp new file mode 100644 index 0000000000000..87b493e6393a8 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <experimental/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner & operator++() noexcept +// returns *this; + +#include <experimental/iterator> +#include <iostream> +#include <cassert> + +#include "test_macros.h" + +namespace exp = std::experimental; + +template <class Delim, class CharT, class Traits> +void test ( exp::ostream_joiner<Delim, CharT, Traits> &oj ) { + static_assert((noexcept(++oj)), "" ); + exp::ostream_joiner<Delim, CharT, Traits> &ret = ++oj; + assert( &ret == &oj ); + } + +int main () { + + { exp::ostream_joiner<char> oj(std::cout, '8'); test(oj); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int> oj(std::cout, 11); test(oj); } + + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); test(oj); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); test(oj); } + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp new file mode 100644 index 0000000000000..794346d75e7fe --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <experimental/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner & operator*() noexcept +// returns *this; + +#include <experimental/iterator> +#include <iostream> +#include <cassert> + +#include "test_macros.h" + +namespace exp = std::experimental; + +template <class Delim, class CharT, class Traits> +void test ( exp::ostream_joiner<Delim, CharT, Traits> &oj ) { + static_assert((noexcept(*oj)), "" ); + exp::ostream_joiner<Delim, CharT, Traits> &ret = *oj; + assert( &ret == &oj ); + } + +int main () { + + { exp::ostream_joiner<char> oj(std::cout, '8'); test(oj); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int> oj(std::cout, 11); test(oj); } + + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); test(oj); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); test(oj); } + } diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp new file mode 100644 index 0000000000000..c4309d9097aab --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator operator=(polymorphic_allocator const &) = delete + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> T; + static_assert(!std::is_copy_assignable<T>::value, ""); + static_assert(!std::is_move_assignable<T>::value, ""); +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp new file mode 100644 index 0000000000000..ba3710d4de1ba --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator const &); + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + { + static_assert( + std::is_copy_constructible<A1>::value, "" + ); + static_assert( + std::is_move_constructible<A1>::value, "" + ); + } + // copy + { + A1 const a((ex::memory_resource*)42); + A1 const a2(a); + assert(a.resource() == a2.resource()); + } + // move + { + A1 a((ex::memory_resource*)42); + A1 a2(std::move(a)); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp new file mode 100644 index 0000000000000..b696d0c13fb31 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator() noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + static_assert( + std::is_nothrow_default_constructible<ex::polymorphic_allocator<void>>::value + , "Must me nothrow default constructible" + ); + } + { + // test that the allocator gets its resource from get_default_resource + TestResource R1(42); + ex::set_default_resource(&R1); + + typedef ex::polymorphic_allocator<void> A; + A const a; + assert(a.resource() == &R1); + + ex::set_default_resource(nullptr); + A const a2; + assert(a.resource() == &R1); + assert(a2.resource() == ex::new_delete_resource()); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp new file mode 100644 index 0000000000000..19d9646ad6162 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator(memory_resource *) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + typedef ex::polymorphic_allocator<void> A; + static_assert( + std::is_convertible<decltype(nullptr), A>::value + , "Must be convertible" + ); + static_assert( + std::is_convertible<ex::memory_resource *, A>::value + , "Must be convertible" + ); + } + { + typedef ex::polymorphic_allocator<void> A; + TestResource R; + A const a(&R); + assert(a.resource() == &R); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp new file mode 100644 index 0000000000000..aadfbcc322fce --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U> +// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator<U> const &); + + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<char> A2; + { // Test that the conversion is implicit and noexcept. + static_assert( + std::is_convertible<A1 const &, A2>::value, "" + ); + static_assert( + std::is_convertible<A2 const &, A1>::value, "" + ); + static_assert( + std::is_nothrow_constructible<A1, A2 const &>::value, "" + ); + static_assert( + std::is_nothrow_constructible<A2, A1 const &>::value, "" + ); + } + // copy other type + { + A1 const a((ex::memory_resource*)42); + A2 const a2(a); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } + { + A1 a((ex::memory_resource*)42); + A2 const a2(std::move(a)); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp new file mode 100644 index 0000000000000..d4aea1cf5f216 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp @@ -0,0 +1,134 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator; + +// template <class T, class U> +// bool operator==( +// polymorphic_allocator<T> const & +// , polymorphic_allocator<U> const &) noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<int> A2; + // check return types + { + A1 const a1; + A2 const a2; + static_assert(std::is_same<decltype(a1 == a2), bool>::value, ""); + static_assert(noexcept(a1 == a2), ""); + } + // equal same type (different resource) + { + TestResource d1(1); + TestResource d2(1); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } + // equal same type (same resource) + { + TestResource d1; + A1 const a1(&d1); + A1 const a2(&d1); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + } + // equal different type (different resource) + { + TestResource d1(42); + TestResource d2(42); + A1 const a1(&d1); + A2 const a2(&d2); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // equal different type (same resource) + { + TestResource d1(42); + A1 const a1(&d1); + A2 const a2(&d1); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + + } + // not equal same type + { + TestResource d1(1); + TestResource d2(2); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(!(a1 == a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 == a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // not equal different types + { + TestResource d1; + TestResource1 d2; + A1 const a1(&d1); + A2 const a2(&d2); + + assert(!(a1 == a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 == a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp new file mode 100644 index 0000000000000..7b9b1d3857b7c --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator; + +// template <class T> +// bool operator!=( +// polymorphic_allocator<T> const & +// , polymorphic_allocator<T> const &) noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<int> A2; + // check return types + { + A1 const a1; + A2 const a2; + static_assert(std::is_same<decltype(a1 != a2), bool>::value, ""); + static_assert(noexcept(a1 != a2), ""); + } + // not equal same type (different resource) + { + TestResource d1(1); + TestResource d2(2); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(a1 != a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 != a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } + // equal same type (same resource) + { + TestResource d1; + A1 const a1(&d1); + A1 const a2(&d1); + + assert(!(a1 != a2)); + assert(d1.checkIsEqualCalledEq(0)); + + assert(!(a2 != a1)); + assert(d1.checkIsEqualCalledEq(0)); + } + // equal same type + { + TestResource d1(1); + TestResource d2(1); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(!(a1 != a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 != a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // not equal different types + { + TestResource d1; + TestResource1 d2; + A1 const a1(&d1); + A2 const a2(&d2); + + assert(a1 != a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 != a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp new file mode 100644 index 0000000000000..a7efad1156dc0 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::allocate(size_t n) + +#include <experimental/memory_resource> +#include <limits> +#include <memory> +#include <exception> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <size_t S, size_t Align> +void testForSizeAndAlign() { + using T = typename std::aligned_storage<S, Align>::type; + TestResource R; + ex::polymorphic_allocator<T> a(&R); + + for (int N = 1; N <= 5; ++N) { + auto ret = a.allocate(N); + assert(R.checkAlloc(ret, N * sizeof(T), alignof(T))); + + a.deallocate(ret, N); + R.reset(); + } +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +template <size_t S> +void testAllocForSizeThrows() { + using T = typename std::aligned_storage<S>::type; + using Alloc = ex::polymorphic_allocator<T>; + using Traits = std::allocator_traits<Alloc>; + NullResource R; + Alloc a(&R); + + // Test that allocating exactly the max size does not throw. + size_t maxSize = Traits::max_size(a); + try { + a.allocate(maxSize); + } catch (...) { + assert(false); + } + + size_t sizeTypeMax = std::numeric_limits<std::size_t>::max(); + if (maxSize != sizeTypeMax) + { + // Test that allocating size_t(~0) throws bad alloc. + try { + a.allocate(sizeTypeMax); + assert(false); + } catch (std::exception const&) { + } + + // Test that allocating even one more than the max size does throw. + size_t overSize = maxSize + 1; + try { + a.allocate(overSize); + assert(false); + } catch (std::exception const&) { + } + } +} +#endif // TEST_HAS_NO_EXCEPTIONS + +int main() +{ + { + ex::polymorphic_allocator<int> a; + static_assert(std::is_same<decltype(a.allocate(0)), int*>::value, ""); + static_assert(!noexcept(a.allocate(0)), ""); + } + { + constexpr std::size_t MA = alignof(std::max_align_t); + testForSizeAndAlign<1, 1>(); + testForSizeAndAlign<1, 2>(); + testForSizeAndAlign<1, MA>(); + testForSizeAndAlign<2, 2>(); + testForSizeAndAlign<73, alignof(void*)>(); + testForSizeAndAlign<73, MA>(); + testForSizeAndAlign<13, MA>(); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + testAllocForSizeThrows<1>(); + testAllocForSizeThrows<2>(); + testAllocForSizeThrows<4>(); + testAllocForSizeThrows<8>(); + testAllocForSizeThrows<16>(); + testAllocForSizeThrows<73>(); + testAllocForSizeThrows<13>(); + } +#endif +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp new file mode 100644 index 0000000000000..2b43594756b70 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<U1, U2>*) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + +int constructed = 0; + +struct default_constructible +{ + default_constructible() : x(42) { ++constructed; } + int x{0}; +}; + +int main() +{ + // pair<default_constructible, default_constructible> as T() + { + typedef default_constructible T; + typedef std::pair<T, T> P; + typedef ex::polymorphic_allocator<void> A; + P * ptr = (P*)std::malloc(sizeof(P)); + A a; + a.construct(ptr); + assert(constructed == 2); + assert(ptr->first.x == 42); + assert(ptr->second.x == 42); + std::free(ptr); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp new file mode 100644 index 0000000000000..50a71eeca82b1 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> const&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::pair<TT, UU> const& p) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = (P*)std::malloc(sizeof(P)); + P * ptr2 = (P*)std::malloc(sizeof(P)); + + // UNDER TEST // + A.construct(ptr, p); + + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(p.first), + std::forward_as_tuple(p.second)); + // ------- // + + bool tres = checkConstruct<decltype((p.first))>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<decltype((p.second))>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + std::free(ptr); + A.destroy(ptr2); + std::free(ptr2); + return tres && ures; + +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(std::pair<TT, UU> const& p) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, p))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, p))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, p))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, p))); + } +} +template <class Tp> +struct Print; + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + const std::pair<int, int&> p(x, y); + test_pmr_uses_allocator<ERT>(p); + test_pmr_uses_allocator<PMR>(p); + test_pmr_uses_allocator<PMA>(p); + } + { + int x = 42; + int y = 42; + const std::pair<int&, int&&> p(x, std::move(y)); + test_pmr_uses_allocator<ERT>(p); + test_pmr_uses_allocator<PMR>(p); + test_pmr_uses_allocator<PMA>(p); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp new file mode 100644 index 0000000000000..b6adb558b1e47 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> &&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::pair<TT, UU>&& p) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = A.allocate(2); + P * ptr2 = ptr + 1; + + // UNDER TEST // + A.construct(ptr, std::move(p)); + + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(std::forward<TT>(p.first)), + std::forward_as_tuple(std::forward<UU>(p.second))); + // ------- // + + bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + A.destroy(ptr2); + A.deallocate(ptr, 2); + return tres && ures; +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(std::pair<TT, UU>&& p) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, std::move(p)))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::move(p)))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::move(p)))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, std::move(p)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + std::pair<int&, int&&> p(x, std::move(y)); + test_pmr_uses_allocator<ERT>(std::move(p)); + test_pmr_uses_allocator<PMR>(std::move(p)); + test_pmr_uses_allocator<PMA>(std::move(p)); + } + { + int x = 42; + int y = 42; + std::pair<int&&, int&> p(std::move(x), y); + test_pmr_uses_allocator<ERT>(std::move(p)); + test_pmr_uses_allocator<PMR>(std::move(p)); + test_pmr_uses_allocator<PMA>(std::move(p)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp new file mode 100644 index 0000000000000..a913742a854bd --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, U1&&, U2&&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + TT&& t, UU&& u) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = (P*)std::malloc(sizeof(P)); + P * ptr2 = (P*)std::malloc(sizeof(P)); + + // UNDER TEST // + A.construct(ptr, std::forward<TT>(t), std::forward<UU>(u)); + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(std::forward<TT>(t)), + std::forward_as_tuple(std::forward<UU>(u))); + // ------- // + + bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + A.destroy(ptr2); + std::free(ptr); + std::free(ptr2); + return tres && ures; +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(TT&& t, UU&& u) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, + std::forward<TT>(t), std::forward<UU>(u)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + test_pmr_uses_allocator<ERT>(x, std::move(y)); + test_pmr_uses_allocator<PMR>(x, std::move(y)); + test_pmr_uses_allocator<PMA>(x, std::move(y)); + } + { + int x = 42; + const int y = 42; + test_pmr_uses_allocator<ERT>(std::move(x), y); + test_pmr_uses_allocator<PMR>(std::move(x), y); + test_pmr_uses_allocator<PMA>(std::move(x), y); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp new file mode 100644 index 0000000000000..d0d76503da50d --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp @@ -0,0 +1,130 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U1, class U2, class ...Args1, class ...Args2> +// void polymorphic_allocator<T>::construct(pair<U1, U2>*, piecewise_construct_t +// tuple<Args1...>, tuple<Args2...>) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" +#include "test_allocator.h" + +namespace ex = std::experimental::pmr; + +template <class T, class U, class ...TTuple, class ...UTuple> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::tuple<TTuple...> ttuple, std::tuple<UTuple...> utuple) +{ + using P = std::pair<T, U>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = A.allocate(1); + + // UNDER TEST // + A.construct(ptr, std::piecewise_construct, std::move(ttuple), std::move(utuple)); + // ------- // + bool tres = checkConstruct<TTuple&&...>(ptr->first, TExpect, M); + bool ures = checkConstruct<UTuple&&...>(ptr->second, UExpect, M); + + A.destroy(ptr); + A.deallocate(ptr, 1); + return tres && ures; +} + +template <class Alloc, class ...TTypes, class ...UTypes> +void test_pmr_uses_allocator(std::tuple<TTypes...> ttuple, std::tuple<UTypes...> utuple) +{ + { + using T = NotUsesAllocator<Alloc, sizeof...(TTypes)>; + using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_None, UA_None, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV1<Alloc, sizeof...(TTypes)>; + using U = UsesAllocatorV2<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV2<Alloc, sizeof...(TTypes)>; + using U = UsesAllocatorV3<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV3<Alloc, sizeof...(TTypes)>; + using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocArg, UA_None, + std::move(ttuple), std::move(utuple)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + std::tuple<> t1; + test_pmr_uses_allocator<ERT>(t1, t1); + test_pmr_uses_allocator<PMR>(t1, t1); + test_pmr_uses_allocator<PMA>(t1, t1); + } + { + std::tuple<int> t1(42); + std::tuple<> t2; + test_pmr_uses_allocator<ERT>(t1, t2); + test_pmr_uses_allocator<ERT>(t2, t1); + test_pmr_uses_allocator<PMR>(t1, t2); + test_pmr_uses_allocator<PMR>(t2, t1); + test_pmr_uses_allocator<PMA>(t1, t2); + test_pmr_uses_allocator<PMA>(t2, t1); + } + { + std::tuple<int> t1(42); + int x = 55; + double dx = 42.42; + std::tuple<int&, double&&> t2(x, std::move(dx)); + test_pmr_uses_allocator<ERT>( t1, std::move(t2)); + test_pmr_uses_allocator<ERT>(std::move(t2), t1); + test_pmr_uses_allocator<PMR>( t1, std::move(t2)); + test_pmr_uses_allocator<PMR>(std::move(t2), t1); + test_pmr_uses_allocator<PMA>( t1, std::move(t2)); + test_pmr_uses_allocator<PMA>(std::move(t2), t1); + } + { + void* xptr = nullptr; + long y = 4242; + std::tuple<int, long const&, void*&> t1(42, y, xptr); + int x = 55; + double dx = 42.42; + const char* s = "hello World"; + std::tuple<int&, double&&, const char*> t2(x, std::move(dx), s); + test_pmr_uses_allocator<ERT>( t1, std::move(t2)); + test_pmr_uses_allocator<ERT>(std::move(t2), t1); + test_pmr_uses_allocator<PMR>( t1, std::move(t2)); + test_pmr_uses_allocator<PMR>(std::move(t2), t1); + test_pmr_uses_allocator<PMA>( t1, std::move(t2)); + test_pmr_uses_allocator<PMA>(std::move(t2), t1); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp new file mode 100644 index 0000000000000..73e4f0e101a8c --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp @@ -0,0 +1,190 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U, class ...Args> +// void polymorphic_allocator<T>::construct(U *, Args &&...) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" +#include "test_allocator.h" + +namespace ex = std::experimental::pmr; + +template <class T> +struct PMATest { + TestResource R; + ex::polymorphic_allocator<T> A; + T* ptr; + bool constructed; + + PMATest() : A(&R), ptr(A.allocate(1)), constructed(false) {} + + template <class ...Args> + void construct(Args&&... args) { + A.construct(ptr, std::forward<Args>(args)...); + constructed = true; + } + + ~PMATest() { + if (constructed) A.destroy(ptr); + A.deallocate(ptr, 1); + } +}; + +template <class T, class ...Args> +bool doTest(UsesAllocatorType UAExpect, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UAExpect, &TH.R); + // ------- // +} + + +template <class T, class ...Args> +bool doTestUsesAllocV0(Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UA_None); + // -------- // +} + + +template <class T, class EAlloc, class ...Args> +bool doTestUsesAllocV1(EAlloc const& ealloc, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::allocator_arg, ealloc, std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UA_AllocArg, ealloc); + // -------- // +} + +template <class T, class EAlloc, class ...Args> +bool doTestUsesAllocV2(EAlloc const& ealloc, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)..., ealloc); + return checkConstruct<Args&&...>(*TH.ptr, UA_AllocLast, ealloc); + // -------- // +} + +template <class Alloc, class ...Args> +void test_pmr_uses_alloc(Args&&... args) +{ + TestResource R(12435); + ex::memory_resource* M = &R; + { + // NotUsesAllocator provides valid signatures for each uses-allocator + // construction but does not supply the required allocator_type typedef. + // Test that we can call these constructors manually without + // polymorphic_allocator interfering. + using T = NotUsesAllocator<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(M, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(M, std::forward<Args>(args)...))); + } + { + // Test T(std::allocator_arg_t, Alloc const&, Args...) construction + using T = UsesAllocatorV1<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...))); + } + { + // Test T(Args..., Alloc const&) construction + using T = UsesAllocatorV2<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocLast, std::forward<Args>(args)...))); + } + { + // Test that T(std::allocator_arg_t, Alloc const&, Args...) construction + // is prefered when T(Args..., Alloc const&) is also available. + using T = UsesAllocatorV3<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...))); + } +} + +// Test that polymorphic_allocator does not prevent us from manually +// doing non-pmr uses-allocator construction. +template <class Alloc, class AllocObj, class ...Args> +void test_non_pmr_uses_alloc(AllocObj const& A, Args&&... args) +{ + { + using T = NotUsesAllocator<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV1<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV2<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV3<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } +} + +int main() +{ + using ET = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<void>; + using STDA = std::allocator<char>; + using TESTA = test_allocator<char>; + + int value = 42; + const int cvalue = 43; + { + test_pmr_uses_alloc<ET>(); + test_pmr_uses_alloc<PMR>(); + test_pmr_uses_alloc<PMA>(); + test_pmr_uses_alloc<ET>(value); + test_pmr_uses_alloc<PMR>(value); + test_pmr_uses_alloc<PMA>(value); + test_pmr_uses_alloc<ET>(cvalue); + test_pmr_uses_alloc<PMR>(cvalue); + test_pmr_uses_alloc<PMA>(cvalue); + test_pmr_uses_alloc<ET>(cvalue, std::move(value)); + test_pmr_uses_alloc<PMR>(cvalue, std::move(value)); + test_pmr_uses_alloc<PMA>(cvalue, std::move(value)); + } + { + STDA std_alloc; + TESTA test_alloc(42); + test_non_pmr_uses_alloc<STDA>(std_alloc); + test_non_pmr_uses_alloc<TESTA>(test_alloc); + test_non_pmr_uses_alloc<STDA>(std_alloc, value); + test_non_pmr_uses_alloc<TESTA>(test_alloc, value); + test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue); + test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue); + test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue, std::move(value)); + test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue, std::move(value)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp new file mode 100644 index 0000000000000..d60c2f2d90f6d --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::deallocate(T*, size_t size) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <size_t S, size_t Align> +void testForSizeAndAlign() { + using T = typename std::aligned_storage<S, Align>::type; + + TestResource R; + ex::polymorphic_allocator<T> a(&R); + + for (int N = 1; N <= 5; ++N) { + auto ret = a.allocate(N); + assert(R.checkAlloc(ret, N * sizeof(T), alignof(T))); + + a.deallocate(ret, N); + assert(R.checkDealloc(ret, N * sizeof(T), alignof(T))); + + R.reset(); + } +} + +int main() +{ + { + ex::polymorphic_allocator<int> a; + static_assert( + std::is_same<decltype(a.deallocate(nullptr, 0)), void>::value, ""); + } + { + constexpr std::size_t MA = alignof(std::max_align_t); + testForSizeAndAlign<1, 1>(); + testForSizeAndAlign<1, 2>(); + testForSizeAndAlign<1, MA>(); + testForSizeAndAlign<2, 2>(); + testForSizeAndAlign<73, alignof(void*)>(); + testForSizeAndAlign<73, MA>(); + testForSizeAndAlign<13, MA>(); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp new file mode 100644 index 0000000000000..5d907660dce27 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U> +// void polymorphic_allocator<T>::destroy(U * ptr); + +#include <experimental/memory_resource> +#include <type_traits> +#include <new> +#include <cassert> +#include <cstdlib> + +namespace ex = std::experimental::pmr; + +int count = 0; + +struct destroyable +{ + destroyable() { ++count; } + ~destroyable() { --count; } +}; + +int main() +{ + typedef ex::polymorphic_allocator<double> A; + { + A a; + static_assert( + std::is_same<decltype(a.destroy((destroyable*)nullptr)), void>::value, + ""); + } + { + destroyable * ptr = ::new (std::malloc(sizeof(destroyable))) destroyable(); + assert(count == 1); + A{}.destroy(ptr); + assert(count == 0); + std::free(ptr); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp new file mode 100644 index 0000000000000..b59606b9e80de --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// memory_resource * +// polymorphic_allocator<T>::resource() const + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A; + { + A const a; + static_assert( + std::is_same<decltype(a.resource()), ex::memory_resource*>::value + , "" + ); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + A const a(mptr); + assert(a.resource() == mptr); + } + { + A const a(nullptr); + assert(a.resource() == nullptr); + assert(a.resource() == nullptr); + } + { + A const a; + assert(a.resource() == ex::get_default_resource()); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + ex::set_default_resource(mptr); + A const a; + assert(a.resource() == mptr); + assert(a.resource() == ex::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp new file mode 100644 index 0000000000000..353fcafed740f --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator +// polymorphic_allocator<T>::select_on_container_copy_construction() const + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A; + { + A const a; + static_assert( + std::is_same<decltype(a.select_on_container_copy_construction()), A>::value, + ""); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + A const a(mptr); + assert(a.resource() == mptr); + A const other = a.select_on_container_copy_construction(); + assert(other.resource() == ex::get_default_resource()); + assert(a.resource() == mptr); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + ex::set_default_resource(mptr); + A const a(nullptr); + assert(a.resource() == nullptr); + A const other = a.select_on_container_copy_construction(); + assert(other.resource() == ex::get_default_resource()); + assert(other.resource() == mptr); + assert(a.resource() == nullptr); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..86bf8cc11bb95 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..86bf8cc11bb95 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp new file mode 100644 index 0000000000000..4de30bccb8169 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc const &) + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef CountingAllocator<char> AllocT; + typedef ex::resource_adaptor<AllocT> R; + { + AllocController P; + AllocT const a(P); + R const r(a); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } + { + AllocController P; + AllocT a(P); + R const r(a); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } + { + AllocController P; + AllocT const a(P); + R const r(std::move(a)); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp new file mode 100644 index 0000000000000..f3ecc98eeaa99 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc &&) + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef CountingAllocator<char> AllocT; + typedef ex::resource_adaptor<AllocT> R; + { + AllocController P; + AllocT a(P); + R const r(std::move(a)); + assert(P.copy_constructed == 0); + assert(P.move_constructed == 1); + assert(r.get_allocator() == a); + } + { + AllocController P; + R const r(AllocT{P}); + assert(P.copy_constructed == 0); + assert(P.move_constructed == 1); + assert(r.get_allocator() == AllocT{P}); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp new file mode 100644 index 0000000000000..4abc69f0b3d17 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp() = default; + +#include <experimental/memory_resource> +#include <memory> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + typedef CountingAllocator<char> AllocT; // Not default constructible + typedef ex::resource_adaptor<AllocT> R; + static_assert(!std::is_default_constructible<R>::value, ""); + } + { + typedef std::allocator<char> AllocT; // Is default constructible + typedef ex::resource_adaptor<AllocT> R; + static_assert(std::is_default_constructible<R>::value, ""); + R r; ((void)r); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp new file mode 100644 index 0000000000000..16b72697593da --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// void * do_allocate(size_t size, size_t align) +// void do_deallocate(void*, size_t, size_t) + + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <exception> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <class Alloc> +void check_allocate_deallocate() +{ + typedef ex::resource_adaptor<Alloc> R1; + const std::size_t max_align = alignof(std::max_align_t); + + for (std::size_t s = 1; s < 5012; ++s) + { + for(std::size_t align_req = 1; align_req <= (max_align * 2); align_req *= 2) + { + const std::size_t align_exp = align_req > max_align + ? max_align : align_req; + AllocController P; + R1 r{Alloc(P)}; + ex::memory_resource & m1 = r; + + void * const ret = m1.allocate(s, align_req); + assert(P.alive == 1); + assert(P.alloc_count == 1); + assert(P.checkAllocAtLeast(ret, s, align_exp)); + + assert(((std::size_t)ret % align_exp) == 0); + + m1.deallocate(ret, s, align_req); + assert(P.alive == 0); + assert(P.dealloc_count == 1); + assert(P.checkDeallocMatchesAlloc()); + } + } +} + +void check_alloc_max_size() { + using Alloc = NullAllocator<char>; + using R1 = ex::resource_adaptor<Alloc>; + const std::size_t max_align = alignof(std::max_align_t); + + auto check = [=](std::size_t s, std::size_t align_req) { + const std::size_t align_exp = align_req > max_align + ? max_align : align_req; + AllocController P; + R1 r{Alloc(P)}; + ex::memory_resource & m1 = r; + + void * const ret = m1.allocate(s, align_req); + assert(P.alive == 1); + assert(P.alloc_count == 1); + assert(P.checkAllocAtLeast(ret, s, align_exp)); + + m1.deallocate(ret, s, align_req); + assert(P.alive == 0); + assert(P.dealloc_count == 1); + assert(P.checkDeallocMatchesAlloc()); + }; + + const std::size_t sizeTypeMax = ~0; + const std::size_t testSizeStart = sizeTypeMax - (max_align * 3); + const std::size_t testSizeEnd = sizeTypeMax - max_align; + + for (std::size_t size = testSizeStart; size <= testSizeEnd; ++size) { + for (std::size_t align=1; align <= (max_align * 2); align *= 2) { + check(size, align); + } + } + +#ifndef TEST_HAS_NO_EXCEPTIONS + for (std::size_t size = sizeTypeMax; size > testSizeEnd; --size) { + AllocController P; + R1 r{Alloc(P)}; + ex::memory_resource & m1 = r; + + try { + m1.allocate(size); + assert(false); + } catch (std::exception const&) { + } + } +#endif +} + +int main() +{ + check_allocate_deallocate<CountingAllocator<char>>(); + check_allocate_deallocate<MinAlignedAllocator<char>>(); + check_alloc_max_size(); +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp new file mode 100644 index 0000000000000..ff4b3179a42ab --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// bool do_is_equal(memory_resource const &) const noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <cassert> +#include "test_memory_resource.hpp" + +using std::size_t; +namespace ex = std::experimental::pmr; + +int main() +{ + + typedef CountingAllocator<char> Alloc1; + typedef CountingAllocator<int> RAlloc1; + typedef ex::resource_adaptor<Alloc1> R1; + typedef ex::resource_adaptor<RAlloc1> RR1; + static_assert(std::is_same<R1, RR1>::value, ""); + + typedef std::allocator<char> Alloc2; + typedef ex::resource_adaptor<Alloc2> R2; + static_assert(!std::is_same<R1, R2>::value, ""); + + // equal same type + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + Alloc1 a2(C); + R1 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(m1.is_equal(m2)); + assert(m2.is_equal(m1)); + } + // not equal same type + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + AllocController C2; + Alloc1 a2(C2); + R1 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(!m1.is_equal(m2)); + assert(!m2.is_equal(m1)); + } + // different allocator types + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + Alloc2 a2; + R2 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(!m1.is_equal(m2)); + assert(!m2.is_equal(m1)); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp new file mode 100644 index 0000000000000..898543fbce4be --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::resource_adaptor<std::allocator<void>> R; + typedef ex::resource_adaptor<std::allocator<long>> R2; + static_assert(std::is_same<R, R2>::value, ""); + { + static_assert(std::is_base_of<ex::memory_resource, R>::value, ""); + static_assert(std::is_same<R::allocator_type, std::allocator<char>>::value, ""); + } + { + static_assert(std::is_default_constructible<R>::value, ""); + static_assert(std::is_copy_constructible<R>::value, ""); + static_assert(std::is_move_constructible<R>::value, ""); + static_assert(std::is_copy_assignable<R>::value, ""); + static_assert(std::is_move_assignable<R>::value, ""); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_deque_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_deque_synop.pass.cpp new file mode 100644 index 0000000000000..5654a785aebb7 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_deque_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/deque> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using deque = +// ::std::deque<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/deque> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdDeque = std::deque<int, pmr::polymorphic_allocator<int>>; + using PmrDeque = pmr::deque<int>; + static_assert(std::is_same<StdDeque, PmrDeque>::value, ""); + PmrDeque d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_forward_list_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_forward_list_synop.pass.cpp new file mode 100644 index 0000000000000..e834be3912f93 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_forward_list_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/forward_list> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using forward_list = +// ::std::forward_list<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/forward_list> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdForwardList = std::forward_list<int, pmr::polymorphic_allocator<int>>; + using PmrForwardList = pmr::forward_list<int>; + static_assert(std::is_same<StdForwardList, PmrForwardList>::value, ""); + PmrForwardList d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_list_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_list_synop.pass.cpp new file mode 100644 index 0000000000000..a53b528e877ed --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_list_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/list> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using list = +// ::std::list<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/list> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdList = std::list<int, pmr::polymorphic_allocator<int>>; + using PmrList = pmr::list<int>; + static_assert(std::is_same<StdList, PmrList>::value, ""); + PmrList d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_map_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_map_synop.pass.cpp new file mode 100644 index 0000000000000..4996d4e6dd252 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_map_synop.pass.cpp @@ -0,0 +1,69 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/map> + +// namespace std { namespace experimental { namespace pmr { +// template <class K, class V, class Compare = less<Key> > +// using map = +// ::std::map<K, V, Compare, polymorphic_allocator<pair<const K, V>>> +// +// template <class K, class V, class Compare = less<Key> > +// using multimap = +// ::std::multimap<K, V, Compare, polymorphic_allocator<pair<const K, V>>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/map> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using K = int; + using V = char; + using DC = std::less<int>; + using OC = std::greater<int>; + using P = std::pair<const K, V>; + { + using StdMap = std::map<K, V, DC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::map<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::map<K, V, OC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::map<K, V, OC>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::map<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdMap = std::multimap<K, V, DC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::multimap<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::multimap<K, V, OC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::multimap<K, V, OC>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::multimap<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp new file mode 100644 index 0000000000000..f371c8a52f1dc --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp @@ -0,0 +1,57 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/regex> + +// namespace std { namespace experimental { namespace pmr { +// +// template <class BidirectionalIterator> +// using match_results = +// std::match_results<BidirectionalIterator, +// polymorphic_allocator<sub_match<BidirectionalIterator>>>; +// +// typedef match_results<const char*> cmatch; +// typedef match_results<const wchar_t*> wcmatch; +// typedef match_results<string::const_iterator> smatch; +// typedef match_results<wstring::const_iterator> wsmatch; +// +// }}} // namespace std::experimental::pmr + +#include <experimental/regex> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +template <class Iter, class PmrTypedef> +void test_match_result_typedef() { + using StdMR = std::match_results<Iter, pmr::polymorphic_allocator<std::sub_match<Iter>>>; + using PmrMR = pmr::match_results<Iter>; + static_assert(std::is_same<StdMR, PmrMR>::value, ""); + static_assert(std::is_same<PmrMR, PmrTypedef>::value, ""); +} + +int main() +{ + { + test_match_result_typedef<const char*, pmr::cmatch>(); + test_match_result_typedef<const wchar_t*, pmr::wcmatch>(); + test_match_result_typedef<pmr::string::const_iterator, pmr::smatch>(); + test_match_result_typedef<pmr::wstring::const_iterator, pmr::wsmatch>(); + } + { + // Check that std::match_results has been included and is complete. + pmr::smatch s; + assert(s.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_set_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_set_synop.pass.cpp new file mode 100644 index 0000000000000..3af1d700504e6 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_set_synop.pass.cpp @@ -0,0 +1,67 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/set> + +// namespace std { namespace experimental { namespace pmr { +// template <class V, class Compare = less<V> > +// using set = +// ::std::set<V, Compare, polymorphic_allocator<V>> +// +// template <class V, class Compare = less<V> > +// using multiset = +// ::std::multiset<V, Compare, polymorphic_allocator<V>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/set> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using V = char; + using DC = std::less<V>; + using OC = std::greater<V>; + { + using StdSet = std::set<V, DC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::set<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::set<V, OC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::set<V, OC>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::set<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdSet = std::multiset<V, DC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::multiset<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::multiset<V, OC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::multiset<V, OC>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::multiset<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_string_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_string_synop.pass.cpp new file mode 100644 index 0000000000000..21889c2da3d2f --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_string_synop.pass.cpp @@ -0,0 +1,73 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/string> + +// namespace std { namespace experimental { namespace pmr { +// template <class Char, class Traits = ...> +// using basic_string = +// ::std::basic_string<Char, Traits, polymorphic_allocator<Char>> +// +// typedef ... string +// typedef ... u16string +// typedef ... u32string +// typedef ... wstring +// +// }}} // namespace std::experimental::pmr + +#include <experimental/string> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "constexpr_char_traits.hpp" + +namespace pmr = std::experimental::pmr; + +template <class Char, class PmrTypedef> +void test_string_typedef() { + using StdStr = std::basic_string<Char, std::char_traits<Char>, + pmr::polymorphic_allocator<Char>>; + using PmrStr = pmr::basic_string<Char>; + static_assert(std::is_same<StdStr, PmrStr>::value, ""); + static_assert(std::is_same<PmrStr, PmrTypedef>::value, ""); +} + +template <class Char, class Traits> +void test_basic_string_alias() { + using StdStr = std::basic_string<Char, Traits, + pmr::polymorphic_allocator<Char>>; + using PmrStr = pmr::basic_string<Char, Traits>; + static_assert(std::is_same<StdStr, PmrStr>::value, ""); +} + +int main() +{ + { + test_string_typedef<char, pmr::string>(); + test_string_typedef<wchar_t, pmr::wstring>(); + test_string_typedef<char16_t, pmr::u16string>(); + test_string_typedef<char32_t, pmr::u32string>(); + } + { + test_basic_string_alias<char, constexpr_char_traits<char>>(); + test_basic_string_alias<wchar_t, constexpr_char_traits<wchar_t>>(); + test_basic_string_alias<char16_t, constexpr_char_traits<char16_t>>(); + test_basic_string_alias<char32_t, constexpr_char_traits<char32_t>>(); + } + { + // Check that std::basic_string has been included and is complete. + pmr::string s; + assert(s.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_unordered_map_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_unordered_map_synop.pass.cpp new file mode 100644 index 0000000000000..99c928b7a9fde --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_unordered_map_synop.pass.cpp @@ -0,0 +1,87 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/unordered_map> + +// namespace std { namespace experimental { namespace pmr { +// template <class K, class V, class H = hash<K>, class P = equal_to<K> > +// using unordered_map = +// ::std::unordered_map<K, V, H, P, polymorphic_allocator<pair<const K, V>>> +// +// template <class K, class V, class H = hash<K>, class P = equal_to<K> > +// using unordered_multimap = +// ::std::unordered_multimap<K, V, H, P, polymorphic_allocator<pair<const K, V>>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/unordered_map> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +template <class T> +struct MyHash : std::hash<T> {}; + +template <class T> +struct MyPred : std::equal_to<T> {}; + +int main() +{ + using K = int; + using V = char; + using DH = std::hash<K>; + using MH = MyHash<K>; + using DP = std::equal_to<K>; + using MP = MyPred<K>; + using P = std::pair<const K, V>; + { + using StdMap = std::unordered_map<K, V, DH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_map<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_map<K, V, MH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_map<K, V, MH>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_map<K, V, MH, MP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_map<K, V, MH, MP>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::unordered_map<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdMap = std::unordered_multimap<K, V, DH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_multimap<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_multimap<K, V, MH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_multimap<K, V, MH>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_multimap<K, V, MH, MP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_multimap<K, V, MH, MP>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::unordered_multimap<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_unordered_set_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_unordered_set_synop.pass.cpp new file mode 100644 index 0000000000000..d427fe7c4ab01 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_unordered_set_synop.pass.cpp @@ -0,0 +1,85 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/unordered_set> + +// namespace std { namespace experimental { namespace pmr { +// template <class V, class H = hash<V>, class P = equal_to<V> > +// using unordered_set = +// ::std::unordered_set<V, H, P, polymorphic_allocator<V>> +// +// template <class V, class H = hash<V>, class P = equal_to<V> > +// using unordered_multiset = +// ::std::unordered_multiset<V, H, P, polymorphic_allocator<V>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/unordered_set> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +template <class T> +struct MyHash : std::hash<T> {}; + +template <class T> +struct MyPred : std::equal_to<T> {}; + +int main() +{ + using V = char; + using DH = std::hash<V>; + using MH = MyHash<V>; + using DP = std::equal_to<V>; + using MP = MyPred<V>; + { + using StdSet = std::unordered_set<V, DH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_set<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_set<V, MH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_set<V, MH>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_set<V, MH, MP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_set<V, MH, MP>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::unordered_set<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdSet = std::unordered_multiset<V, DH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_multiset<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_multiset<V, MH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_multiset<V, MH>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_multiset<V, MH, MP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_multiset<V, MH, MP>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::unordered_multiset<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_vector_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_vector_synop.pass.cpp new file mode 100644 index 0000000000000..7dfd3b820b364 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_vector_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/vector> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using vector = +// ::std::vector<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/vector> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdVector = std::vector<int, pmr::polymorphic_allocator<int>>; + using PmrVector = pmr::vector<int>; + static_assert(std::is_same<StdVector, PmrVector>::value, ""); + PmrVector d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp b/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp new file mode 100644 index 0000000000000..7aa16ab506fef --- /dev/null +++ b/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +//----------------------------------------------------------------------------- +// TESTING memory_resource * get_default_resource() noexcept; +// memory_resource * set_default_resource(memory_resource*) noexcept; +// +// Concerns: +// A) 'get_default_resource()' returns a non-null memory_resource pointer. +// B) 'get_default_resource()' returns the value set by the last call to +// 'set_default_resource(...)' and 'new_delete_resource()' if no call +// to 'set_default_resource(...)' has occurred. +// C) 'set_default_resource(...)' returns the previous value of the default +// resource. +// D) 'set_default_resource(T* p)' for a non-null 'p' sets the default resource +// to be 'p'. +// E) 'set_default_resource(null)' sets the default resource to +// 'new_delete_resource()'. +// F) 'get_default_resource' and 'set_default_resource' are noexcept. + + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +using namespace std::experimental::pmr; + +int main() { + TestResource R; + { // Test (A) and (B) + memory_resource* p = get_default_resource(); + assert(p != nullptr); + assert(p == new_delete_resource()); + assert(p == get_default_resource()); + } + { // Test (C) and (D) + memory_resource *expect = &R; + memory_resource *old = set_default_resource(expect); + assert(old != nullptr); + assert(old == new_delete_resource()); + + memory_resource *p = get_default_resource(); + assert(p != nullptr); + assert(p == expect); + assert(p == get_default_resource()); + } + { // Test (E) + memory_resource* old = set_default_resource(nullptr); + assert(old == &R); + memory_resource* p = get_default_resource(); + assert(p != nullptr); + assert(p == new_delete_resource()); + assert(p == get_default_resource()); + } + { // Test (F) + static_assert(noexcept(get_default_resource()), + "get_default_resource() must be noexcept"); + + static_assert(noexcept(set_default_resource(nullptr)), + "set_default_resource() must be noexcept"); + } +} diff --git a/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp b/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp new file mode 100644 index 0000000000000..412e3323d1bad --- /dev/null +++ b/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * new_delete_resource() + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "count_new.hpp" + +namespace ex = std::experimental::pmr; + +struct assert_on_compare : public ex::memory_resource +{ +protected: + virtual void * do_allocate(size_t, size_t) + { assert(false); } + + virtual void do_deallocate(void *, size_t, size_t) + { assert(false); } + + virtual bool do_is_equal(ex::memory_resource const &) const noexcept + { assert(false); } +}; + +void test_return() +{ + { + static_assert(std::is_same< + decltype(ex::new_delete_resource()), ex::memory_resource* + >::value, ""); + } + // assert not null + { + assert(ex::new_delete_resource()); + } + // assert same return value + { + assert(ex::new_delete_resource() == ex::new_delete_resource()); + } +} + +void test_equality() +{ + // Same object + { + ex::memory_resource & r1 = *ex::new_delete_resource(); + ex::memory_resource & r2 = *ex::new_delete_resource(); + // check both calls returned the same object + assert(&r1 == &r2); + // check for proper equality semantics + assert(r1 == r2); + assert(r2 == r1); + assert(!(r1 != r2)); + assert(!(r2 != r1)); + } + // Different types + { + ex::memory_resource & r1 = *ex::new_delete_resource(); + assert_on_compare c; + ex::memory_resource & r2 = c; + assert(r1 != r2); + assert(!(r1 == r2)); + } +} + +void test_allocate_deallocate() +{ + ex::memory_resource & r1 = *ex::new_delete_resource(); + + globalMemCounter.reset(); + + void *ret = r1.allocate(50); + assert(ret); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkLastNewSizeEq(50)); + + r1.deallocate(ret, 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + +} + +int main() +{ + static_assert(noexcept(ex::new_delete_resource()), "Must be noexcept"); + test_return(); + test_equality(); + test_allocate_deallocate(); +} diff --git a/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp b/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp new file mode 100644 index 0000000000000..f263df30ef4d9 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * null_memory_resource() + +#include <experimental/memory_resource> +#include <new> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" + +namespace ex = std::experimental::pmr; + +struct assert_on_compare : public ex::memory_resource +{ +protected: + virtual void * do_allocate(size_t, size_t) + { assert(false); } + + virtual void do_deallocate(void *, size_t, size_t) + { assert(false); } + + virtual bool do_is_equal(ex::memory_resource const &) const noexcept + { assert(false); } +}; + +void test_return() +{ + { + static_assert(std::is_same< + decltype(ex::null_memory_resource()), ex::memory_resource* + >::value, ""); + } + // Test that the returned value is not null + { + assert(ex::null_memory_resource()); + } + // Test the same value is returned by repeated calls. + { + assert(ex::null_memory_resource() == ex::null_memory_resource()); + } +} + +void test_equality() +{ + // Same object + { + ex::memory_resource & r1 = *ex::null_memory_resource(); + ex::memory_resource & r2 = *ex::null_memory_resource(); + // check both calls returned the same object + assert(&r1 == &r2); + // check for proper equality semantics + assert(r1 == r2); + assert(r2 == r1); + assert(!(r1 != r2)); + assert(!(r2 != r1)); + // check the is_equal method + assert(r1.is_equal(r2)); + assert(r2.is_equal(r1)); + } + // Different types + { + ex::memory_resource & r1 = *ex::null_memory_resource(); + assert_on_compare c; + ex::memory_resource & r2 = c; + assert(r1 != r2); + assert(!(r1 == r2)); + assert(!r1.is_equal(r2)); + } +} + +void test_allocate() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + DisableAllocationGuard g; // null_memory_resource shouldn't allocate. + try { + ex::null_memory_resource()->allocate(1); + assert(false); + } catch (std::bad_alloc const &) { + // do nothing + } catch (...) { + assert(false); + } +#endif +} + +void test_deallocate() +{ + globalMemCounter.reset(); + + int x = 42; + ex::null_memory_resource()->deallocate(nullptr, 0); + ex::null_memory_resource()->deallocate(&x, 0); + + assert(globalMemCounter.checkDeleteCalledEq(0)); + assert(globalMemCounter.checkDeleteArrayCalledEq(0)); +} + +int main() +{ + test_return(); + test_equality(); + test_allocate(); + test_deallocate(); +} diff --git a/test/std/experimental/utilities/utility/version.pass.cpp b/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp index 437712454ae5c..9a59227abdd98 100644 --- a/test/std/experimental/utilities/utility/version.pass.cpp +++ b/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp @@ -1,3 +1,4 @@ +// -*- C++ -*- //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure @@ -7,14 +8,6 @@ // //===----------------------------------------------------------------------===// -// <experimental/utility> - -#include <experimental/utility> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - int main() { } diff --git a/test/std/experimental/memory/memory.resource/construct.fail.cpp b/test/std/experimental/memory/memory.resource/construct.fail.cpp new file mode 100644 index 0000000000000..d990714acfd14 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/construct.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// Check that memory_resource is not constructible + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + ex::memory_resource m; // expected-error {{variable type 'ex::memory_resource' is an abstract class}} +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp new file mode 100644 index 0000000000000..0ccdeed3c54f7 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// bool operator==(memory_resource const &, memory_resource const &) noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + // check return types + { + ex::memory_resource const * mr1(nullptr); + ex::memory_resource const * mr2(nullptr); + static_assert(std::is_same<decltype(*mr1 == *mr2), bool>::value, ""); + static_assert(noexcept(*mr1 == *mr2), ""); + } + // equal + { + TestResource r1(1); + TestResource r2(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(mr1 == mr2); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(mr2 == mr1); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal same object + { + TestResource r1(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r1; + + assert(mr1 == mr2); + assert(r1.checkIsEqualCalledEq(0)); + + assert(mr2 == mr1); + assert(r1.checkIsEqualCalledEq(0)); + } + // not equal + { + TestResource r1(1); + TestResource r2(2); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(!(mr1 == mr2)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(!(mr2 == mr1)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp new file mode 100644 index 0000000000000..ede1bfdf9baca --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// bool operator!=(memory_resource const &, memory_resource const &) noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + // check return types + { + ex::memory_resource const * mr1(nullptr); + ex::memory_resource const * mr2(nullptr); + static_assert(std::is_same<decltype(*mr1 != *mr2), bool>::value, ""); + static_assert(noexcept(*mr1 != *mr2), ""); + } + // not equal + { + TestResource r1(1); + TestResource r2(2); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(mr1 != mr2); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(mr2 != mr1); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal + { + TestResource r1(1); + TestResource r2(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(!(mr1 != mr2)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(!(mr2 != mr1)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal same object + { + TestResource r1(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r1; + + assert(!(mr1 != mr2)); + assert(r1.checkIsEqualCalledEq(0)); + + assert(!(mr2 != mr1)); + assert(r1.checkIsEqualCalledEq(0)); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..86bf8cc11bb95 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp b/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp new file mode 100644 index 0000000000000..eddfede29630f --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource::do_allocate(size_t, size_t); /* protected */ +// memory_resource::do_deallocate(void*, size_t, size_t); /* protected */ +// memory_resource::do_is_equal(memory_resource const&); /* protected */ + +#include <experimental/memory_resource> + +namespace ex = std::experimental::pmr; + +int main() { + ex::memory_resource *m = ex::new_delete_resource(); + m->do_allocate(0, 0); // expected-error{{'do_allocate' is a protected member}} + m->do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a protected member}} + m->do_is_equal(*m); // expected-error{{'do_is_equal' is a protected member}} +}
\ No newline at end of file diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp new file mode 100644 index 0000000000000..26cf903fe0d8e --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <experimental/memory_resource> + +// UNSUPPORTED: c++98, c++03 + +//------------------------------------------------------------------------------ +// TESTING void * memory_resource::allocate(size_t, size_t = max_align) +// +// Concerns: +// A) 'memory_resource' contains a member 'allocate' with the required +// signature, including the default alignment parameter. +// B) The return type of 'allocate' is 'void*'. +// C) 'allocate' is not marked as 'noexcept'. +// D) Invoking 'allocate' invokes 'do_allocate' with the same arguments. +// E) If 'do_allocate' throws then 'allocate' propagates that exception. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cstddef> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + TestResource R(42); + auto& P = R.getController(); + memory_resource& M = R; + { + static_assert( + std::is_same<decltype(M.allocate(0, 0)), void*>::value + , "Must be void*" + ); + static_assert( + std::is_same<decltype(M.allocate(0)), void*>::value + , "Must be void*" + ); + } + { + static_assert( + ! noexcept(M.allocate(0, 0)) + , "Must not be noexcept." + ); + static_assert( + ! noexcept(M.allocate(0)) + , "Must not be noexcept." + ); + } + { + int s = 42; + int a = 64; + void* p = M.allocate(s, a); + assert(P.alloc_count == 1); + assert(P.checkAlloc(p, s, a)); + + s = 128; + a = MaxAlignV; + p = M.allocate(s); + assert(P.alloc_count == 2); + assert(P.checkAlloc(p, s, a)); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + TestResource R2; + auto& P = R2.getController(); + P.throw_on_alloc = true; + memory_resource& M2 = R2; + try { + M2.allocate(42); + assert(false); + } catch (TestException const&) { + // do nothing. + } catch (...) { + assert(false); + } + } +#endif +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp new file mode 100644 index 0000000000000..d1a4ab2b8196f --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <experimental/memory_resource> + +// UNSUPPORTED: c++98, c++03 + +//------------------------------------------------------------------------------ +// TESTING void * memory_resource::deallocate(void *, size_t, size_t = max_align) +// +// Concerns: +// A) 'memory_resource' contains a member 'deallocate' with the required +// signature, including the default alignment parameter. +// B) The return type of 'deallocate' is 'void'. +// C) 'deallocate' is not marked as 'noexcept'. +// D) Invoking 'deallocate' invokes 'do_deallocate' with the same arguments. + + +#include <experimental/memory_resource> +#include <type_traits> +#include <cstddef> +#include <cassert> + +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + NullResource R(42); + auto& P = R.getController(); + memory_resource& M = R; + { + static_assert( + std::is_same<decltype(M.deallocate(nullptr, 0, 0)), void>::value + , "Must be void" + ); + static_assert( + std::is_same<decltype(M.deallocate(nullptr, 0)), void>::value + , "Must be void" + ); + } + { + static_assert( + ! noexcept(M.deallocate(nullptr, 0, 0)) + , "Must not be noexcept." + ); + static_assert( + ! noexcept(M.deallocate(nullptr, 0)) + , "Must not be noexcept." + ); + } + { + int s = 100; + int a = 64; + void* p = reinterpret_cast<void*>(640); + M.deallocate(p, s, a); + assert(P.dealloc_count == 1); + assert(P.checkDealloc(p, s, a)); + + s = 128; + a = alignof(std::max_align_t); + p = reinterpret_cast<void*>(12800); + M.deallocate(p, s); + assert(P.dealloc_count == 2); + assert(P.checkDealloc(p, s, a)); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp new file mode 100644 index 0000000000000..9e1d28618f92d --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +//------------------------------------------------------------------------------ +// TESTING virtual ~memory_resource() +// +// Concerns: +// A) 'memory_resource' is destructible. +// B) The destructor is implicitly marked noexcept. +// C) The destructor is marked virtual. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + static_assert( + std::has_virtual_destructor<memory_resource>::value + , "Must have virtual destructor" + ); + static_assert( + std::is_nothrow_destructible<memory_resource>::value, + "Must be nothrow destructible" + ); + static_assert( + std::is_abstract<memory_resource>::value + , "Must be abstract" + ); + // Check that the destructor of `TestResource` is called when + // it is deleted as a pointer to `memory_resource` + { + using TR = TestResource; + memory_resource* M = new TR(42); + assert(TR::resource_alive == 1); + assert(TR::resource_constructed == 1); + assert(TR::resource_destructed == 0); + + delete M; + + assert(TR::resource_alive == 0); + assert(TR::resource_constructed == 1); + assert(TR::resource_destructed == 1); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp new file mode 100644 index 0000000000000..32792cf867a61 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +//------------------------------------------------------------------------------ +// TESTING virtual bool is_equal(memory_resource const &) const noexcept +// +// Concerns: +// A) 'memory_resource' provides a function 'is_equal' with the required +// signature. +// B) 'is_equal' is noexcept. +// C) 'do_is_equal' is called using the same arguments passed to 'is_equal' +// and the resulting value is returned. +// D) 'do_is_equal' is called on the LHS object and not the RHS object. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + { + memory_resource const* r1 = nullptr; + memory_resource const* r2 = nullptr; + static_assert( + noexcept(r1->is_equal(*r2)) + , "is_equal must be noexcept" + ); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource2 R2(1); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == false); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == false); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource1 R2(2); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == false); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == false); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource1 R2(1); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == true); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == true); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/utilities/meta/version.pass.cpp b/test/std/experimental/memory/nothing_to_do.pass.cpp index 593fb52a4c3b2..9a59227abdd98 100644 --- a/test/std/experimental/utilities/meta/version.pass.cpp +++ b/test/std/experimental/memory/nothing_to_do.pass.cpp @@ -1,3 +1,4 @@ +// -*- C++ -*- //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure @@ -7,14 +8,6 @@ // //===----------------------------------------------------------------------===// -// <experimental/type_traits> - -#include <experimental/type_traits> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - int main() { } diff --git a/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp b/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp index cecf98a3518b3..c166bb72a8379 100644 --- a/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp +++ b/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 + // <optional> // class bad_optional_access is default constructible @@ -16,8 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::bad_optional_access; bad_optional_access ex; -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp b/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp index c13d6603990a1..4630165f07080 100644 --- a/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp +++ b/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp @@ -7,19 +7,19 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 + // <optional> -// class bad_optional_access : public logic_error +// class bad_optional_access : public logic_error #include <experimental/optional> #include <type_traits> int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::bad_optional_access; static_assert(std::is_base_of<std::logic_error, bad_optional_access>::value, ""); static_assert(std::is_convertible<bad_optional_access*, std::logic_error*>::value, ""); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp index e796723cc097c..749fa7dcf0a1e 100644 --- a/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator==(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,16 +26,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr T val(2); constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -47,12 +43,11 @@ int main() static_assert ( !(o3 == T(1)), "" ); static_assert ( (o3 == T(2)), "" ); static_assert ( (o3 == val), "" ); - + static_assert ( !(T(1) == o1), "" ); static_assert ( (T(1) == o2), "" ); static_assert ( !(T(1) == o3), "" ); static_assert ( (T(2) == o3), "" ); static_assert ( (val == o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp index cf3923bb4fb0b..c4d95a1c878ff 100644 --- a/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( !(val > o3), "" ); // equal static_assert ( (T(3) > o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp index 85fea1377b3cd..ce1cd9f984812 100644 --- a/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>=(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( (val >= o3), "" ); // equal static_assert ( (T(3) >= o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp index 333f7cdea2197..c519bde1e9f29 100644 --- a/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<=(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( (val <= o3), "" ); // equal static_assert ( !(T(3) <= o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp index e35df21bbabb2..ee1e98f2b8c9d 100644 --- a/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( !(val < o3), "" ); // equal static_assert ( !(T(3) < o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp index 0dad68d386354..a3daa02d5dbb2 100644 --- a/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator!=(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,16 +26,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr T val(2); constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -47,12 +43,11 @@ int main() static_assert ( (o3 != T(1)), "" ); static_assert ( !(o3 != T(2)), "" ); static_assert ( !(o3 != val), "" ); - + static_assert ( (T(1) != o1), "" ); static_assert ( !(T(1) != o2), "" ); static_assert ( (T(1) != o3), "" ); static_assert ( !(T(2) != o3), "" ); static_assert ( !(val != o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.hash/hash.pass.cpp b/test/std/experimental/optional/optional.hash/hash.pass.cpp index 9e5fb55c833fa..21126740bf860 100644 --- a/test/std/experimental/optional/optional.hash/hash.pass.cpp +++ b/test/std/experimental/optional/optional.hash/hash.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> struct hash<optional<T>>; @@ -19,7 +20,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; { @@ -43,5 +43,4 @@ int main() opt = std::unique_ptr<int>(new int(3)); assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt)); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp b/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp index 360b9d91671e0..b63977bb69ff2 100644 --- a/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp +++ b/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // struct in_place_t{}; @@ -15,8 +16,6 @@ #include <experimental/optional> #include <type_traits> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -28,15 +27,10 @@ test(const in_place_t&) return 3; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 - static_assert((std::is_class<in_place_t>::value), ""); static_assert((std::is_empty<in_place_t>::value), ""); - + static_assert(test(in_place) == 3, ""); -#endif } diff --git a/test/std/experimental/optional/optional.nullops/equal.pass.cpp b/test/std/experimental/optional/optional.nullops/equal.pass.cpp index 931db61442563..79a5a7e06fa46 100644 --- a/test/std/experimental/optional/optional.nullops/equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/equal.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept; @@ -17,15 +17,14 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; - + { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt == o1), ""); static_assert (noexcept(o1 == nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/greater.pass.cpp b/test/std/experimental/optional/optional.nullops/greater.pass.cpp index b72a4d3f1a6a4..15b22005b830a 100644 --- a/test/std/experimental/optional/optional.nullops/greater.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/greater.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept; @@ -17,7 +17,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -25,7 +24,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt > o1), ""); static_assert (noexcept(o1 > nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp b/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp index 86c8743b55589..313770ff408e2 100644 --- a/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept; @@ -17,7 +17,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -25,7 +24,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt >= o1), ""); static_assert (noexcept(o1 >= nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp b/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp index 3e8444bc73f0b..cddb27e93a6a4 100644 --- a/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp @@ -25,7 +25,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged diff --git a/test/std/experimental/optional/optional.nullops/less_than.pass.cpp b/test/std/experimental/optional/optional.nullops/less_than.pass.cpp index 149c809b04035..fdb400700d832 100644 --- a/test/std/experimental/optional/optional.nullops/less_than.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/less_than.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept; @@ -17,7 +17,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -25,7 +24,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt < o1), ""); static_assert (noexcept(o1 < nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp b/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp index 6f28edf6d266e..70ae0f1d885ca 100644 --- a/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept; @@ -17,15 +17,14 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; - + { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt != o1), ""); static_assert (noexcept(o1 != nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp b/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp index de1e83b653ce1..8ad49c7485d0e 100644 --- a/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp +++ b/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // struct nullopt_t{see below}; @@ -15,8 +16,6 @@ #include <experimental/optional> #include <type_traits> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -28,16 +27,12 @@ test(const nullopt_t&) return 3; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 static_assert((std::is_class<nullopt_t>::value), ""); static_assert((std::is_empty<nullopt_t>::value), ""); static_assert((std::is_literal_type<nullopt_t>::value), ""); static_assert((!std::is_default_constructible<nullopt_t>::value), ""); - + static_assert(test(nullopt) == 3, ""); -#endif } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp index e256a098f1ac7..3d0d2e03158b0 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class U> optional<T>& operator=(U&& v); @@ -16,19 +17,14 @@ #include <cassert> #include <memory> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X { }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 static_assert(std::is_assignable<optional<int>, int>::value, ""); static_assert(std::is_assignable<optional<int>, int&>::value, ""); static_assert(std::is_assignable<optional<int>&, int>::value, ""); @@ -68,5 +64,4 @@ int main() assert(static_cast<bool>(opt) == true); assert(**opt == 3); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp index 999d03d3a8855..89ea345029c2f 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -34,11 +33,8 @@ struct X bool X::throw_now = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt; constexpr optional<int> opt2; @@ -87,5 +83,4 @@ int main() assert(static_cast<bool>(opt) == false); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp index ec98ef4491538..94f2bb21a4759 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -17,8 +18,6 @@ #include <cassert> #include <memory> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -55,11 +54,8 @@ public: bool Z::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt; opt.emplace(); @@ -145,5 +141,4 @@ int main() assert(Z::dtor_called == true); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp index aada0f4ec535e..fec37408e43b5 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -18,8 +19,6 @@ #include <cassert> #include <vector> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -60,7 +59,7 @@ public: static bool dtor_called; constexpr Z() : i_(0) {} constexpr Z(int i) : i_(i) {} - constexpr Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) + Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {throw 6;} ~Z() {dtor_called = true;} @@ -70,11 +69,8 @@ public: bool Z::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { X x; { @@ -113,5 +109,4 @@ int main() assert(Z::dtor_called == true); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp index 3e084e5b7dc24..fa00f5602c7fd 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -18,8 +19,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -42,11 +41,8 @@ struct Y {}; bool X::throw_now = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { static_assert(std::is_nothrow_move_assignable<optional<int>>::value, ""); optional<int> opt; @@ -100,5 +96,4 @@ int main() { static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, ""); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp index 7f39744f0557d..b1d851b32f4cd 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // optional<T>& operator=(nullopt_t) noexcept; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -29,11 +28,8 @@ struct X bool X::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt; static_assert(noexcept(opt = nullopt) == true, ""); @@ -63,5 +59,4 @@ int main() assert(static_cast<bool>(opt) == false); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp index 7d401de1d9789..144af2e3a7dc7 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class T> @@ -76,11 +75,8 @@ public: }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { typedef int T; optional<T> rhs; @@ -121,5 +117,4 @@ int main() optional<T> rhs(Z(3)); test(rhs, true); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp index 6a1763de22bd6..d24a1ac69b866 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr optional() noexcept; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class Opt> @@ -55,13 +54,9 @@ struct X X(); }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 test_constexpr<optional<int>>(); test_constexpr<optional<int*>>(); test<optional<X>>(); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp index 014ee859e8a97..dc1666b103625 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp @@ -69,7 +69,7 @@ int main() struct test_constexpr_ctor : public optional<int> { - constexpr test_constexpr_ctor(in_place_t, int i) + constexpr test_constexpr_ctor(in_place_t, int i) : optional<int>(in_place, i) {} }; @@ -97,7 +97,7 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t) + constexpr test_constexpr_ctor(in_place_t) : optional<Y>(in_place) {} }; @@ -110,7 +110,7 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t, int i) + constexpr test_constexpr_ctor(in_place_t, int i) : optional<Y>(in_place, i) {} }; @@ -123,7 +123,7 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t, int i, int j) + constexpr test_constexpr_ctor(in_place_t, int i, int j) : optional<Y>(in_place, i, j) {} }; diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp index 7a98e0bf31f3e..9bd6b18989fc9 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -19,8 +20,6 @@ #include <vector> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -60,19 +59,15 @@ class Z public: constexpr Z() : i_(0) {} constexpr Z(int i) : i_(i) {} - constexpr Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) + Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {throw 6;} friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_ && x.j_ == y.j_;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, ""); static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, ""); @@ -98,10 +93,12 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) + constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) : optional<Y>(in_place, i) {} }; + constexpr test_constexpr_ctor dopt(in_place, {42, 101, -1}); + static_assert(*dopt == Y{42, 101, -1}, ""); } { static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, ""); @@ -114,14 +111,5 @@ int main() { assert(i == 6); } - - struct test_constexpr_ctor - : public optional<Z> - { - constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) - : optional<Z>(in_place, i) {} - }; - } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp index 40d55f9189933..851157f960f91 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class T> @@ -75,12 +74,8 @@ public: friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { typedef int T; optional<T> rhs; @@ -121,5 +116,4 @@ int main() optional<T> rhs(Z(3)); test(rhs, true); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp index c307a2e1e258b..40c96581ed847 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr optional(nullopt_t) noexcept; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -56,13 +55,9 @@ struct X X(); }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 test_constexpr<optional<int>>(); test_constexpr<optional<int*>>(); test<optional<X>>(); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp index 2697799f0e5ee..2bec19e6b4f43 100644 --- a/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // ~optional(); @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -29,11 +28,8 @@ public: bool X::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { typedef int T; static_assert(std::is_trivially_destructible<T>::value, ""); @@ -55,5 +51,4 @@ int main() } assert(X::dtor_called == true); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp index a3724375cf4d0..a5bfae240073c 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr explicit optional<T>::operator bool() const noexcept; @@ -17,7 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; { @@ -28,5 +28,4 @@ int main() constexpr optional<int> opt(0); static_assert(opt, ""); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp index 98e5dac9719ed..faba8d256067c 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T& optional<T>::operator*(); @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -29,11 +28,8 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<X> opt(X{}); assert((*opt).test() == 4); @@ -45,5 +41,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp index c72a57852a327..f1bdc36424daf 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr const T& optional<T>::operator*() const; @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -33,11 +32,8 @@ struct Y int test() const {return 2;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(X{}); static_assert((*opt).test() == 3, ""); @@ -53,5 +49,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp index b17fcf8d30506..954ccd71ff538 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr T* optional<T>::operator->(); @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -28,11 +27,8 @@ struct X constexpr int test() const {return 3;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(X{}); static_assert(opt->test() == 3, ""); @@ -44,5 +40,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp index e813dd992a5b2..cf900d7029e1d 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr const T* optional<T>::operator->() const; @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -39,11 +38,8 @@ struct Z constexpr int test() const {return 1;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(X{}); static_assert(opt->test() == 3, ""); @@ -63,5 +59,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp index 85f9be6998a01..b998f3067f4fb 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::bad_optional_access; @@ -29,11 +28,8 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<X> opt; opt.emplace(); @@ -50,5 +46,4 @@ int main() { } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp index f0f8af6da45df..baad3b47f3ec7 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr const T& optional<T>::value() const; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -25,16 +24,10 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt; static_assert(opt.value().test() == 3, ""); } -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp index c99baab8b6e42..a38b1f930c72f 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -31,11 +30,8 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(in_place); static_assert(opt.value().test() == 3, ""); @@ -55,5 +51,4 @@ int main() { } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp index 6118c44bb5baa..6fca8c82cebdc 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class U> T optional<T>::value_or(U&& v) &&; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -40,11 +39,8 @@ struct X {return x.i_ == y.i_;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<X> opt(in_place, 2); Y y(3); @@ -67,5 +63,4 @@ int main() assert(std::move(opt).value_or(Y(3)) == 4); assert(!opt); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp index d51f18abbd28b..4a008dce23863 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class U> constexpr T optional<T>::value_or(U&& v) const&; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct Y @@ -37,11 +36,8 @@ struct X {return x.i_ == y.i_;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(2); constexpr Y y(3); @@ -78,5 +74,4 @@ int main() const optional<X> opt; assert(opt.value_or(Y(3)) == 4); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp index d24a2d06b9d5b..620dda19e3ff1 100644 --- a/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -18,8 +19,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -63,12 +62,8 @@ public: friend void swap(Z& x, Z& y) {throw 6;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt1; optional<int> opt2; @@ -303,5 +298,4 @@ int main() assert(static_cast<bool>(opt2) == true); assert(*opt2 == 2); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp b/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp index 6999cf2451f1e..02c0a3a63a5e6 100644 --- a/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible @@ -15,11 +16,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<const void> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp b/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp index 61470af01195a..da8bd05f2c9be 100644 --- a/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -23,13 +22,7 @@ private: ~X() {} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 optional<X> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp b/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp index eaee02014c2ff..7aa179afeaf6a 100644 --- a/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -22,13 +21,7 @@ struct X ~X() noexcept(false) {} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 optional<X> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_void.fail.cpp b/test/std/experimental/optional/optional.object/optional_void.fail.cpp index f911e9a2d6d48..73f689c56720e 100644 --- a/test/std/experimental/optional/optional.object/optional_void.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_void.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible @@ -15,11 +16,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<void> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/types.pass.cpp b/test/std/experimental/optional/optional.object/types.pass.cpp index 8b9ad2e195707..af8da2df8fd51 100644 --- a/test/std/experimental/optional/optional.object/types.pass.cpp +++ b/test/std/experimental/optional/optional.object/types.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> @@ -19,8 +20,6 @@ #include <experimental/optional> #include <type_traits> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class Opt, class T> @@ -30,14 +29,10 @@ test() static_assert(std::is_same<typename Opt::value_type, T>::value, ""); } -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 test<optional<int>, int>(); test<optional<const int>, const int>(); test<optional<double>, double>(); test<optional<const double>, const double>(); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.relops/equal.pass.cpp b/test/std/experimental/optional/optional.relops/equal.pass.cpp index 03b9d3fda5cff..413e7c8b3780b 100644 --- a/test/std/experimental/optional/optional.relops/equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y); @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -28,16 +27,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged @@ -75,5 +71,4 @@ int main() static_assert ( o5 == o5 , "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp b/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp index 98d6855f93131..c0739dda6b832 100644 --- a/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>= (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( (o1 >= o1), "" ); static_assert ( (o1 >= o2), "" ); static_assert ( !(o1 >= o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( !(o5 >= o4), "" ); static_assert ( (o5 >= o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/greater_than.pass.cpp b/test/std/experimental/optional/optional.relops/greater_than.pass.cpp index d51bd4f2ac466..df7dbb64717fb 100644 --- a/test/std/experimental/optional/optional.relops/greater_than.pass.cpp +++ b/test/std/experimental/optional/optional.relops/greater_than.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator> (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( !(o1 > o1), "" ); static_assert ( !(o1 > o2), "" ); static_assert ( !(o1 > o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( !(o5 > o4), "" ); static_assert ( !(o5 > o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/less_equal.pass.cpp b/test/std/experimental/optional/optional.relops/less_equal.pass.cpp index 326f3a8964939..d4874d17b2405 100644 --- a/test/std/experimental/optional/optional.relops/less_equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/less_equal.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<= (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( (o1 <= o1), "" ); static_assert ( (o1 <= o2), "" ); static_assert ( (o1 <= o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( (o5 <= o4), "" ); static_assert ( (o5 <= o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/less_than.pass.cpp b/test/std/experimental/optional/optional.relops/less_than.pass.cpp index 37f7e1942982c..4113408268e8f 100644 --- a/test/std/experimental/optional/optional.relops/less_than.pass.cpp +++ b/test/std/experimental/optional/optional.relops/less_than.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator< (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( !(o1 < o1), "" ); static_assert ( !(o1 < o2), "" ); static_assert ( (o1 < o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( (o5 < o4), "" ); static_assert ( !(o5 < o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/not_equal.pass.cpp b/test/std/experimental/optional/optional.relops/not_equal.pass.cpp index f386c7e361ecd..19a196317d4f8 100644 --- a/test/std/experimental/optional/optional.relops/not_equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/not_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y); @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -28,16 +27,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged @@ -75,5 +71,4 @@ int main() static_assert ( !(o5 != o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp b/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp index cc95e6110e8d7..9abd87bd40513 100644 --- a/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp +++ b/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> @@ -19,9 +20,10 @@ #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::make_optional; @@ -38,7 +40,7 @@ int main() std::string s("123"); optional<std::string> opt = make_optional(std::move(s)); assert(*opt == "123"); - assert(s.empty()); + LIBCPP_ASSERT(s.empty()); } { std::unique_ptr<int> s(new int(3)); @@ -46,5 +48,4 @@ int main() assert(**opt == 3); assert(s == nullptr); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.specalg/swap.pass.cpp b/test/std/experimental/optional/optional.specalg/swap.pass.cpp index 6c5f7b0e860c1..d339c53c1f771 100644 --- a/test/std/experimental/optional/optional.specalg/swap.pass.cpp +++ b/test/std/experimental/optional/optional.specalg/swap.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -17,8 +18,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -62,12 +61,8 @@ public: friend void swap(Z& x, Z& y) {throw 6;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt1; optional<int> opt2; @@ -302,5 +297,4 @@ int main() assert(static_cast<bool>(opt2) == true); assert(*opt2 == 2); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp index 60836ae2396ea..bdf01eba406f7 100644 --- a/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for @@ -16,13 +17,9 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; optional<const in_place_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp b/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp index 9a4ba1a027a10..61393c105e959 100644 --- a/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for a @@ -16,11 +17,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<const int&> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp index f6220bda69c4e..89c207306aba8 100644 --- a/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp @@ -7,22 +7,19 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for -// (possibly cv-qualified) null_opt_t is ill-formed. +// (possibly cv-qualified) nullopt_t is ill-formed. #include <experimental/optional> int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; optional<const nullopt_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp index 12f291fcd228f..47c2be7da0d0a 100644 --- a/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for @@ -16,13 +17,9 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; optional<in_place_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp b/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp index 7e6697ff6e508..8cf11b553e745 100644 --- a/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp +++ b/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // #include <initializer_list> @@ -15,9 +16,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; std::initializer_list<int> list; -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp b/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp index 850df342aef04..de2f18991b246 100644 --- a/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for a @@ -16,11 +17,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<int&> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp index 20955ace834ae..3d276d6420226 100644 --- a/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp @@ -7,22 +7,19 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for -// (possibly cv-qualified) null_opt_t is ill-formed. +// (possibly cv-qualified) nullopt_t is ill-formed. #include <experimental/optional> int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; optional<nullopt_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp b/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp index d773e993df227..fd6da18e8c161 100644 --- a/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for a @@ -16,11 +17,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<int&&> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/string.view/string.view.access/at.pass.cpp b/test/std/experimental/string.view/string.view.access/at.pass.cpp index 46804d4df3af8..7ceaf5ab3d9f3 100644 --- a/test/std/experimental/string.view/string.view.access/at.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/at.pass.cpp @@ -10,7 +10,7 @@ // NOTE: Older versions of clang have a bug where they fail to evalute // string_view::at as a constant expression. // XFAIL: clang-3.4, clang-3.3 -// XFAIL: libcpp-no-exceptions + // <string_view> @@ -20,6 +20,8 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" + template <typename CharT> void test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -27,12 +29,14 @@ void test ( const CharT *s, size_t len ) { for ( size_t i = 0; i < len; ++i ) { assert ( sv.at(i) == s[i] ); assert ( &sv.at(i) == s + i ); - } + } +#ifndef TEST_HAS_NO_EXCEPTIONS try { sv.at(len); } catch ( const std::out_of_range & ) { return ; } assert ( false ); - } - +#endif +} + int main () { test ( "ABCDE", 5 ); test ( "a", 1 ); @@ -40,7 +44,7 @@ int main () { test ( L"ABCDE", 5 ); test ( L"a", 1 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); @@ -48,7 +52,7 @@ int main () { test ( U"a", 1 ); #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 ); static_assert ( sv.length() == 2, "" ); diff --git a/test/std/experimental/string.view/string.view.access/back.pass.cpp b/test/std/experimental/string.view/string.view.access/back.pass.cpp index 093a858a48055..09f7950341a8d 100644 --- a/test/std/experimental/string.view/string.view.access/back.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/back.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> bool test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -22,7 +24,7 @@ bool test ( const CharT *s, size_t len ) { assert ( sv.back() == s[len-1] ); return &sv.back() == s + len - 1; } - + int main () { assert ( test ( "ABCDE", 5 )); assert ( test ( "a", 1 )); @@ -30,7 +32,7 @@ int main () { assert ( test ( L"ABCDE", 5 )); assert ( test ( L"a", 1 )); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert ( test ( u"ABCDE", 5 )); assert ( test ( u"a", 1 )); @@ -38,7 +40,7 @@ int main () { assert ( test ( U"a", 1 )); #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 ); static_assert ( sv.length() == 2, "" ); diff --git a/test/std/experimental/string.view/string.view.access/data.pass.cpp b/test/std/experimental/string.view/string.view.access/data.pass.cpp index 562a765f50ceb..53e95ddaea31a 100644 --- a/test/std/experimental/string.view/string.view.access/data.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/data.pass.cpp @@ -15,13 +15,15 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> void test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); assert ( sv.length() == len ); assert ( sv.data() == s ); } - + int main () { test ( "ABCDE", 5 ); test ( "a", 1 ); @@ -29,7 +31,7 @@ int main () { test ( L"ABCDE", 5 ); test ( L"a", 1 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); diff --git a/test/std/experimental/string.view/string.view.access/front.pass.cpp b/test/std/experimental/string.view/string.view.access/front.pass.cpp index e9df44b19b1af..acb00a46a2e54 100644 --- a/test/std/experimental/string.view/string.view.access/front.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/front.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> bool test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -22,7 +24,7 @@ bool test ( const CharT *s, size_t len ) { assert ( sv.front() == s[0] ); return &sv.front() == s; } - + int main () { assert ( test ( "ABCDE", 5 )); assert ( test ( "a", 1 )); @@ -30,7 +32,7 @@ int main () { assert ( test ( L"ABCDE", 5 )); assert ( test ( L"a", 1 )); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert ( test ( u"ABCDE", 5 )); assert ( test ( u"a", 1 )); @@ -38,7 +40,7 @@ int main () { assert ( test ( U"a", 1 )); #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 ); static_assert ( sv.length() == 2, "" ); diff --git a/test/std/experimental/string.view/string.view.access/index.pass.cpp b/test/std/experimental/string.view/string.view.access/index.pass.cpp index 4491207cbb85e..2c1bd1dc91cb5 100644 --- a/test/std/experimental/string.view/string.view.access/index.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/index.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> void test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -24,7 +26,7 @@ void test ( const CharT *s, size_t len ) { assert ( &sv[i] == s + i ); } } - + int main () { test ( "ABCDE", 5 ); test ( "a", 1 ); @@ -32,7 +34,7 @@ int main () { test ( L"ABCDE", 5 ); test ( L"a", 1 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); diff --git a/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp b/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp index eb802165930d1..9f5d86f2f82b2 100644 --- a/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp +++ b/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp @@ -19,6 +19,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename SV> void test1 () { #if _LIBCPP_STD_VER > 11 @@ -30,7 +32,7 @@ void test1 () { static_assert ( sv1.max_size() > sv1.size(), ""); } #endif - + { SV sv1; assert ( sv1.size() == 0 ); @@ -73,7 +75,7 @@ int main () { test2 ( L"a", 1 ); test2 ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test2 ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 ); test2 ( u"ABCDE", 5 ); test2 ( u"a", 1 ); diff --git a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp index 148dc18d7ec81..0df37a6ffd9f8 100644 --- a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp @@ -58,7 +58,7 @@ int main() static_assert ( "" == sv1, "" ); static_assert (!(sv1 == "abcde"), "" ); static_assert (!("abcde" == sv1), "" ); - + static_assert ( sv2 == "abcde", "" ); static_assert ( "abcde" == sv2, "" ); static_assert (!(sv2 == "abcde0"), "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp index 23a2aef242d7f..1fd72d7964b6c 100644 --- a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp @@ -17,8 +17,6 @@ #include <experimental/string_view> #include <cassert> -#if _LIBCPP_STD_VER > 11 - template <class S> void test(const std::string &lhs, S rhs, bool x) @@ -49,6 +47,4 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true); } } -#else -int main () {} -#endif + diff --git a/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp index f02459b01c49b..f5bcb7e97b73b 100644 --- a/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert ( "" >= sv1, "" ); static_assert (!(sv1 >= "abcde"), "" ); static_assert ( "abcde" >= sv1, "" ); - + static_assert ( sv2 >= "", "" ); static_assert (!("" >= sv2), "" ); static_assert ( sv2 >= "abcde", "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp index 48703cac612f2..63002a5c415c7 100644 --- a/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert (!("" > sv1), "" ); static_assert (!(sv1 > "abcde"), "" ); static_assert ( "abcde" > sv1, "" ); - + static_assert ( sv2 > "", "" ); static_assert (!("" > sv2), "" ); static_assert (!(sv2 > "abcde"), "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp index 539f5fa5402e4..c542efea99a7e 100644 --- a/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert ( "" <= sv1, "" ); static_assert ( sv1 <= "abcde", "" ); static_assert (!("abcde" <= sv1), "" ); - + static_assert (!(sv2 <= ""), "" ); static_assert ( "" <= sv2, "" ); static_assert ( sv2 <= "abcde", "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp index a1013e4d81523..2c0461481e783 100644 --- a/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert (!("" < sv1), "" ); static_assert ( sv1 < "abcde", "" ); static_assert (!("abcde" < sv1), "" ); - + static_assert (!(sv2 < ""), "" ); static_assert ( "" < sv2, "" ); static_assert (!(sv2 < "abcde"), "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp index 299be934a8119..1deee9ac7fc6b 100644 --- a/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert (!("" != sv1), "" ); static_assert ( sv1 != "abcde", "" ); static_assert ( "abcde" != sv1, "" ); - + static_assert (!(sv2 != "abcde"), "" ); static_assert (!("abcde" != sv2), "" ); static_assert ( sv2 != "abcde0", "" ); diff --git a/test/std/experimental/string.view/string.view.cons/default.pass.cpp b/test/std/experimental/string.view/string.view.cons/default.pass.cpp index e1d69f4a3dfe2..e817bfffb89da 100644 --- a/test/std/experimental/string.view/string.view.cons/default.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/default.pass.cpp @@ -24,7 +24,7 @@ void test () { static_assert ( sv1.empty(), ""); } #endif - + { T sv1; assert ( sv1.size() == 0 ); diff --git a/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp b/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp index 82d0d79541490..9de3a30395234 100644 --- a/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp @@ -40,12 +40,12 @@ int main () { test ( "QBCDE" ); test ( "A" ); test ( "" ); - + test ( L"QBCDE" ); test ( L"A" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"QBCDE" ); test ( u"A" ); test ( u"" ); diff --git a/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp b/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp index 1038d0484f8cb..663d25e954f93 100644 --- a/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp @@ -18,6 +18,8 @@ #include <string> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t sz ) { { @@ -53,7 +55,7 @@ int main () { } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"QBCDE", 5 ); test ( u"QBCDE", 2 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp b/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp index 670c033a653fe..4ecd2cdff9ba9 100644 --- a/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp @@ -18,6 +18,8 @@ #include <string> #include <cassert> +#include "test_macros.h" + struct dummy_char_traits : public std::char_traits<char> {}; template<typename CharT, typename Traits> @@ -32,12 +34,12 @@ int main () { test ( std::string("QBCDE") ); test ( std::string("") ); test ( std::string() ); - + test ( std::wstring(L"QBCDE") ); test ( std::wstring(L"") ); test ( std::wstring() ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( std::u16string{u"QBCDE"} ); test ( std::u16string{u""} ); test ( std::u16string{} ); @@ -46,7 +48,7 @@ int main () { test ( std::u32string{U""} ); test ( std::u32string{} ); #endif - + test ( std::basic_string<char, dummy_char_traits>("QBCDE") ); test ( std::basic_string<char, dummy_char_traits>("") ); test ( std::basic_string<char, dummy_char_traits>() ); diff --git a/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp b/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp index 6ef4b9669bf45..b2ffa61c29d99 100644 --- a/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp @@ -22,7 +22,7 @@ struct dummy_char_traits : public std::char_traits<char> {}; int main () { using string_view = std::experimental::basic_string_view<char>; using string = std:: basic_string <char, dummy_char_traits>; - + { string s{"QBCDE"}; string_view sv1 ( s ); diff --git a/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp b/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp index 6c77a3f99a2b1..a14e131c85aaf 100644 --- a/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp @@ -22,7 +22,7 @@ struct dummy_char_traits : public std::char_traits<char> {}; int main () { using string_view = std::experimental::basic_string_view<char, dummy_char_traits>; using string = std:: basic_string <char>; - + { string s{"QBCDE"}; string_view sv1 ( s ); diff --git a/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp b/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp index 07f3b36e1d2b0..8040b81d4efe5 100644 --- a/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -30,7 +32,7 @@ test(S s) assert(&*cb1 == &s[0]); assert( *cb2 == s[0]); assert(&*cb2 == &s[0]); - + } assert( b == cb1); assert( b == cb2); @@ -51,7 +53,7 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif @@ -62,7 +64,7 @@ int main() constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; - + static_assert ( *sv.begin() == sv[0], "" ); static_assert ( *u16sv.begin() == u16sv[0], "" ); static_assert ( *u32sv.begin() == u32sv[0], "" ); diff --git a/test/std/experimental/string.view/string.view.iterators/end.pass.cpp b/test/std/experimental/string.view/string.view.iterators/end.pass.cpp index 2ed52b8de947d..3a1091e9983c2 100644 --- a/test/std/experimental/string.view/string.view.iterators/end.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/end.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -35,7 +37,7 @@ test(S s) assert(ce1 != cs.begin()); assert(ce2 != s.begin()); } - + assert( e - s.begin() == s.size()); assert(ce1 - cs.begin() == cs.size()); assert(ce2 - s.cbegin() == s.size()); @@ -59,7 +61,7 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif @@ -70,7 +72,7 @@ int main() constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; - + static_assert ( sv.begin() != sv.end(), "" ); static_assert ( u16sv.begin() != u16sv.end(), "" ); static_assert ( u32sv.begin() != u32sv.end(), "" ); diff --git a/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp b/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp index 7d1c7003eaf49..068557e398635 100644 --- a/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -31,7 +33,7 @@ test(S s) assert(&*cb1 == &s[last]); assert( *cb2 == s[last]); assert(&*cb2 == &s[last]); - + } assert( b == cb1); assert( b == cb2); @@ -52,7 +54,7 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif diff --git a/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp b/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp index 57002f30518f3..55e28a2669486 100644 --- a/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -35,7 +37,7 @@ test(S s) assert(ce1 != cs.rbegin()); assert(ce2 != s.rbegin()); } - + assert( e - s.rbegin() == s.size()); assert(ce1 - cs.rbegin() == cs.size()); assert(ce2 - s.crbegin() == s.size()); @@ -52,14 +54,14 @@ int main() typedef std::experimental::u16string_view u16string_view; typedef std::experimental::u32string_view u32string_view; typedef std::experimental::wstring_view wstring_view; - + test(string_view ()); test(u16string_view()); test(u32string_view()); test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif diff --git a/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp index 6a9982e0d3a56..9a4891c8f2599 100644 --- a/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; @@ -48,7 +50,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp index 0a2dd6d9329cc..4a31486afaa0b 100644 --- a/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp @@ -16,6 +16,8 @@ #include <cassert> #include <iostream> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; @@ -30,10 +32,10 @@ void test ( const CharT *s, size_t len ) { assert ( sv1.data() == (s + 1)); sv1.remove_prefix ( len - 1 ); } - + assert ( sv1.size() == 0 ); sv1.remove_prefix ( 0 ); - assert ( sv1.size() == 0 ); + assert ( sv1.size() == 0 ); } } @@ -55,7 +57,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp index 9dd59882cce6e..9ddc6de84bf32 100644 --- a/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; @@ -29,10 +31,10 @@ void test ( const CharT *s, size_t len ) { assert ( sv1.data() == s); sv1.remove_suffix ( len - 1 ); } - + assert ( sv1.size() == 0 ); sv1.remove_suffix ( 0 ); - assert ( sv1.size() == 0 ); + assert ( sv1.size() == 0 ); } } @@ -55,7 +57,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp index cacb8ed40b885..d747def8549e1 100644 --- a/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp @@ -15,13 +15,15 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; { SV sv1(s); SV sv2; - + assert ( sv1.size() == len ); assert ( sv1.data() == s ); assert ( sv2.size() == 0 ); @@ -54,7 +56,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp b/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp index c86e9619f1930..6ba03212d42b6 100644 --- a/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp +++ b/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp @@ -103,7 +103,7 @@ void round_trip ( const wchar_t *p ) { assert ( s == sv ); assert ( skippingws == is_skipws ( &ss )); } - + void round_trip_ws ( const wchar_t *p ) { std::wstringstream ss; @@ -165,31 +165,31 @@ int main() round_trip_ws ( "" ); round_trip_d ( "", 'q' ); round_trip_e ( "", 'q' ); - + round_trip ( L"" ); round_trip_ws ( L"" ); round_trip_d ( L"", 'q' ); round_trip_e ( L"", 'q' ); - + round_trip ( "Hi" ); round_trip_ws ( "Hi" ); round_trip_d ( "Hi", '!' ); round_trip_e ( "Hi", '!' ); assert ( quote ( "Hi", '!' ) == "!Hi!" ); assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" ); - + round_trip ( L"Hi" ); round_trip_ws ( L"Hi" ); round_trip_d ( L"Hi", '!' ); round_trip_e ( L"Hi", '!' ); assert ( quote ( L"Hi", '!' ) == L"!Hi!" ); assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" ); - + round_trip ( "Hi Mom" ); round_trip_ws ( "Hi Mom" ); round_trip ( L"Hi Mom" ); round_trip_ws ( L"Hi Mom" ); - + assert ( quote ( "" ) == "\"\"" ); assert ( quote ( L"" ) == L"\"\"" ); assert ( quote ( "a" ) == "\"a\"" ); @@ -198,7 +198,7 @@ int main() // missing end quote - must not hang assert ( unquote ( "\"abc" ) == "abc" ); assert ( unquote ( L"\"abc" ) == L"abc" ); - + assert ( unquote ( "abc" ) == "abc" ); // no delimiter assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter assert ( unquote ( "abc def" ) == "abc" ); // no delimiter diff --git a/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp b/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp index 29f5064d81dca..a29bb15f5ac9c 100644 --- a/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp @@ -16,11 +16,13 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s ) { typedef std::experimental::basic_string_view<CharT> string_view_t; typedef std::basic_string<CharT> string_t; - + { string_view_t sv1 ( s ); string_t str = (string_t) sv1; @@ -49,7 +51,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); diff --git a/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp index 6ccec9b3729ad..583395451fd49 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp @@ -72,7 +72,7 @@ int main() test(L"abcdefghijklmnopqrst", L"abcdefghijklmnopqrst", 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(U"", U"", 0); test(U"", U"abcde", -5); diff --git a/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp index 7ccbd528c7fc8..cfe35fcb47193 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, const charT* s) const; @@ -15,18 +14,27 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } template<typename CharT> -void test1 ( std::experimental::basic_string_view<CharT> sv1, +void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1, const CharT *s, int expected ) { - try { + if (pos1 > sv1.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, s); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { assert(sign(sv1.compare(pos1, n1, s)) == sign(expected)); - assert(pos1 <= sv1.size()); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size()); } } template<typename CharT> @@ -391,7 +399,7 @@ int main() test(L"abcdefghijklmnopqrst", 0, -1, L"abcdefghijklmnopqrst", 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(U"", 0, 0, U"", 0); test(U"", 0, 0, U"abcde", -5); @@ -410,7 +418,7 @@ int main() test(U"abcdefghijklmnopqrst", 0, 12, U"abcdefghij", 10); test(U"abcdefghijklmnopqrst", 0, -1, U"abcdefghijklmnopqrst", 0); } - + { test(u"", 0, 0, u"", 0); test(u"", 0, 0, u"abcde", -5); @@ -431,7 +439,7 @@ int main() } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1; diff --git a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp index 244de9eb5104a..2684d903405e3 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, basic_string_view str) const; @@ -16,6 +14,7 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } @@ -24,19 +23,25 @@ template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1, std::experimental::basic_string_view<CharT> sv2, int expected ) { - try - { + if (pos1 > sv1.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, sv2); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { assert ( sign( sv1.compare(pos1, n1, sv2)) == sign(expected)); - assert(pos1 <= sv1.size()); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size()); } } template<typename CharT> void test ( const CharT *s1, size_t pos1, size_t n1, const CharT *s2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - string_view_t sv1 ( s1 ); string_view_t sv2 ( s2 ); test1(sv1, pos1, n1, sv2, expected); @@ -355,7 +360,7 @@ int main () { test0(); test1(); test2(); - + { test("abcde", 5, 1, "", 0); test("abcde", 2, 4, "", 3); @@ -370,7 +375,7 @@ int main () { test(L"ABCde", 2, 4, L"abcde", -1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(u"abcde", 5, 1, u"", 0); test(u"abcde", 2, 4, u"", 3); @@ -386,7 +391,7 @@ int main () { } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1 { "abcde", 5 }; diff --git a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp index 1c3bc089a656f..69de6335fb5ca 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, @@ -17,6 +15,7 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } @@ -25,22 +24,29 @@ template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1, const CharT *s2, size_t n2, int expected ) { - - try - { - assert ( sign( sv1.compare(pos1, n1, s2, n2)) == sign(expected)); - assert(pos1 <= sv1.size()); + if (pos1 > sv1.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, s2, n2); + assert(false); + } catch (const std::out_of_range&) { + return; + } catch (...) { + assert(false); + } +#endif + } else { + assert(sign(sv1.compare(pos1, n1, s2, n2)) == sign(expected)); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size()); } + } template<typename CharT> -void test ( const CharT *s1, size_t pos1, size_t n1, - const CharT *s2, size_t n2, +void test ( const CharT *s1, size_t pos1, size_t n1, + const CharT *s2, size_t n2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - string_view_t sv1 ( s1 ); test1 (sv1, pos1, n1, s2, n2, expected); } @@ -1302,7 +1308,7 @@ int main () { test9(); test10(); test11(); - + { test("", 0, 0, "abcde", 0, 0); test("", 0, 0, "abcde", 1, -1); @@ -1319,7 +1325,7 @@ int main () { test(L"abcdefghijklmnopqrst", 10, 0, L"abcdefghij", 10, -10); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(U"", 0, 0, U"abcde", 0, 0); test(U"", 0, 0, U"abcde", 1, -1); @@ -1337,7 +1343,7 @@ int main () { } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1; diff --git a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp index c7a6f1e1eb66d..5d5ccc5b5d59f 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, basic_string_view str, @@ -17,6 +15,7 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } @@ -26,22 +25,28 @@ void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_ std::experimental::basic_string_view<CharT> sv2, size_t pos2, size_t n2, int expected ) { - try - { - assert ( sign( sv1.compare(pos1, n1, sv2, pos2, n2)) == sign(expected)); - assert(pos1 <= sv1.size()); - assert(pos2 <= sv2.size()); + if (pos1 > sv1.size() || pos2 > sv2.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, sv2, pos2, n2); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { + assert (sign( sv1.compare(pos1, n1, sv2, pos2, n2)) == sign(expected)); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size() || pos2 > sv2.size()); } } template<typename CharT> -void test ( const CharT *s1, size_t pos1, size_t n1, - const CharT *s2, size_t pos2, size_t n2, +void test ( const CharT *s1, size_t pos1, size_t n1, + const CharT *s2, size_t pos2, size_t n2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s1 ); string_view_t sv2 ( s2 ); test1(sv1, pos1, n1, sv2, pos2, n2, expected); @@ -5801,7 +5806,7 @@ int main () { test53(); test54(); - + { test("abcde", 5, 1, "", 0, 0, 0); test("abcde", 2, 4, "", 0, 0, 3); @@ -5816,7 +5821,7 @@ int main () { test(L"ABCde", 2, 4, L"abcde", 2, 4, -1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(u"abcde", 5, 1, u"", 0, 0, 0); test(u"abcde", 2, 4, u"", 0, 0, 3); @@ -5832,7 +5837,7 @@ int main () { } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1 { "abcde", 5 }; diff --git a/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp index 3f686697ba400..4364ab0635430 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp @@ -19,7 +19,7 @@ int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } template<typename CharT> -void test1 ( std::experimental::basic_string_view<CharT> sv1, +void test1 ( std::experimental::basic_string_view<CharT> sv1, std::experimental::basic_string_view<CharT> sv2, int expected ) { assert ( sign( sv1.compare(sv2)) == sign(expected)); } @@ -28,7 +28,7 @@ void test1 ( std::experimental::basic_string_view<CharT> sv1, template<typename CharT> void test ( const CharT *s1, const CharT *s2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s1 ); string_view_t sv2 ( s2 ); test1(sv1, sv2, expected); @@ -70,7 +70,7 @@ int main () { test(L"abcdefghijklmnopqrst", L"abcdefghij", 10); test(L"abcdefghijklmnopqrst", L"abcdefghijklmnopqrst", 0); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u"", u"", 0); test(u"", u"abcde", -5); test(u"", u"abcdefghij", -10); @@ -105,7 +105,7 @@ int main () { test(U"abcdefghijklmnopqrst", U"abcdefghij", 10); test(U"abcdefghijklmnopqrst", U"abcdefghijklmnopqrst", 0); #endif - + #if _LIBCPP_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; @@ -117,5 +117,5 @@ int main () { static_assert ( sv3.compare(sv2) > 0, "" ); static_assert ( sv2.compare(sv3) < 0, "" ); } -#endif +#endif } diff --git a/test/std/experimental/string.view/string.view.ops/copy.pass.cpp b/test/std/experimental/string.view/string.view.ops/copy.pass.cpp index 0e4eb9e50bb0a..0acd5bda40112 100644 --- a/test/std/experimental/string.view/string.view.ops/copy.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/copy.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // size_type copy(charT* s, size_type n, size_type pos = 0) const; @@ -23,30 +21,40 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv, size_t n, size_t pos ) { const size_t rlen = std::min ( n, sv.size() - pos ); CharT *dest1 = new CharT [rlen + 1]; dest1[rlen] = 0; CharT *dest2 = new CharT [rlen + 1]; dest2[rlen] = 0; - - try { + + if (pos > sv.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv.copy(dest1, n, pos); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { sv.copy(dest1, n, pos); std::copy_n(sv.begin() + pos, rlen, dest2); - for ( size_t i = 0; i <= rlen; ++i ) assert ( dest1[i] == dest2[i] ); - } - catch ( const std::out_of_range & ) { assert ( pos > sv.size()); } + } delete [] dest1; - delete [] dest2; + delete [] dest2; } template<typename CharT> void test ( const CharT *s ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s ); test1(sv1, 0, 0); @@ -54,7 +62,7 @@ void test ( const CharT *s ) { test1(sv1, 20, 0); test1(sv1, sv1.size(), 0); test1(sv1, 20, string_view_t::npos); - + test1(sv1, 0, 3); test1(sv1, 2, 3); test1(sv1, 100, 3); @@ -79,7 +87,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); diff --git a/test/std/experimental/string.view/string.view.ops/substr.pass.cpp b/test/std/experimental/string.view/string.view.ops/substr.pass.cpp index c80e90a04788f..a651010d4b278 100644 --- a/test/std/experimental/string.view/string.view.ops/substr.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/substr.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; @@ -20,30 +18,42 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv, size_t n, size_t pos ) { - try { + if (pos > sv.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + std::experimental::basic_string_view<CharT> sv1 = sv.substr(pos, n); + assert(false); + } catch (const std::out_of_range&) { + return; + } catch (...) { + assert(false); + } +#endif + } else { std::experimental::basic_string_view<CharT> sv1 = sv.substr(pos, n); const size_t rlen = std::min ( n, sv.size() - pos ); assert ( sv1.size() == rlen ); for ( size_t i = 0; i <= rlen; ++i ) assert ( sv[pos+i] == sv1[i] ); - } - catch ( const std::out_of_range & ) { assert ( pos > sv.size()); } + } } template<typename CharT> void test ( const CharT *s ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s ); test1(sv1, 0, 0); test1(sv1, 1, 0); test1(sv1, 20, 0); test1(sv1, sv1.size(), 0); - + test1(sv1, 0, 3); test1(sv1, 2, 3); test1(sv1, 100, 3); @@ -68,7 +78,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); @@ -79,8 +89,8 @@ int main () { test ( U"a" ); test ( U"" ); #endif - -#if _LIBCPP_STD_VER > 11 + +#if TEST_STD_VER > 11 { constexpr std::experimental::string_view sv1 { "ABCDE", 5 }; @@ -91,7 +101,7 @@ int main () { static_assert ( sv2[1] == 'B', "" ); static_assert ( sv2[2] == 'C', "" ); } - + { constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 0 ); static_assert ( sv2.size() == 0, "" ); diff --git a/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp b/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp index a180ab257bf5f..a32a2684c5485 100644 --- a/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp @@ -26,11 +26,11 @@ void test ( const CharT *s ) { { const std::experimental::basic_string_view<CharT> sv1 ( s ); String str1 = (String) sv1; - + assert ( sv1.size() == str1.size ()); assert ( std::char_traits<CharT>::compare ( sv1.data(), str1.data(), sv1.size()) == 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 auto str2 = sv1.to_string(min_allocator<CharT>()); assert ( sv1.size() == str2.size ()); assert ( std::char_traits<CharT>::compare ( sv1.data(), str2.data(), sv1.size()) == 0 ); @@ -44,7 +44,7 @@ void test ( const CharT *s ) { assert ( sv1.size() == 0); assert ( sv1.size() == str1.size ()); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 auto str2 = sv1.to_string(min_allocator<CharT>()); assert ( sv1.size() == str2.size ()); #endif @@ -62,7 +62,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); diff --git a/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp index 2c90dd6418136..ddc82cb5482f0 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 -# ifndef _LIBCPP_TYPE_TRAITS -# error "<experimental/type_traits> must include <type_traits>" -# endif +#ifndef _LIBCPP_TYPE_TRAITS +# error "<experimental/type_traits> must include <type_traits>" #endif int main() diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp index 96af4b676181e..8edc917303acf 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct base_type {}; @@ -60,6 +59,4 @@ int main() static_assert(ex::is_convertible_v<T, U> == std::is_convertible<T, U>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp index 2d1e706f67d22..a4a91c1369278 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct class_type {}; @@ -176,6 +175,4 @@ int main() static_assert(ex::is_function_v<T> == std::is_function<T>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp index 814f450f4e07a..b3927b120951e 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct class_type {}; @@ -97,6 +96,4 @@ int main() static_assert(ex::is_member_pointer_v<T> == std::is_member_pointer<T>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp index 41cb27fced37b..e267c6833ab99 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct non_literal_type { non_literal_type() {} }; @@ -484,6 +483,4 @@ int main() static_assert(ex::has_virtual_destructor_v<T> == std::has_virtual_destructor<T>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp index aedd369e5ac8e..f91667da523c0 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; int main() @@ -61,6 +60,3 @@ int main() static_assert(ex::extent_v<T, 0> == std::extent<T, 0>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp new file mode 100644 index 0000000000000..33826383d1277 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(const propagate_const<U>&)=delete; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { static_assert(!std::is_assignable<P, const P &>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp new file mode 100644 index 0000000000000..6de6c63d6104e --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<CopyConstructibleFromX> PY; + + X x1(1); + PY p(2); + + assert(*p==2); + + p = x1; + + assert(*p==1); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp new file mode 100644 index 0000000000000..ae6ef08d3cf08 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator=(U&& u); // won't bind to propagate_const + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> PX; +typedef propagate_const<CopyConstructibleFromX> PY; + +int main() { static_assert(!std::is_assignable<PY, const PX &>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp new file mode 100644 index 0000000000000..e4051325f1c1b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + X x1(1); + P p(2); + + assert(*p==2); + + p = x1; + + assert(*p==1); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp new file mode 100644 index 0000000000000..b112b078d821b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(propagate_const<U>&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + P p1(1); + P p2(2); + + p2=std::move(p1); + + assert(*p2==1); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp new file mode 100644 index 0000000000000..282f0aee61531 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(propagate_const<U>&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> PX; + typedef propagate_const<MoveConstructibleFromX> PY; + + PX px2(2); + PY py1(1); + + py1=std::move(px2); + + assert(*py1==2); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp new file mode 100644 index 0000000000000..743fc8eacbfa4 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> PX; + typedef propagate_const<MoveConstructibleFromX> PY; + + PX px2(2); + PY py1(1); + + py1=std::move(px2); + + assert(*py1==2); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp new file mode 100644 index 0000000000000..10b0dd896280d --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<ExplicitCopyConstructibleFromX> P; + +int main() { + static_assert(!std::is_convertible<P, X>::value, ""); + static_assert(std::is_constructible<P, X>::value, ""); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp new file mode 100644 index 0000000000000..8ba5261de5e30 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<CopyConstructibleFromX> P; + +void f(const P& p) +{ + assert(*p==2); +} + +int main() { + f(X(2)); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp new file mode 100644 index 0000000000000..ca65f3c47fff8 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> PX; +typedef propagate_const<CopyConstructibleFromX> PY; + +int main() { static_assert(!std::is_constructible<PX, PY>::value, ""); } + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp new file mode 100644 index 0000000000000..b021cbd5e5e1a --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> PX; +typedef propagate_const<ExplicitMoveConstructibleFromX> PY; + +int main() { + static_assert(!std::is_convertible<PY, PX &&>::value, ""); + static_assert(std::is_constructible<PY, PX &&>::value, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp new file mode 100644 index 0000000000000..ee104a5250ea8 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<MoveConstructibleFromX> PY; +typedef propagate_const<X> PX; + +int main() { + PX px(1); + PY py(std::move(px)); + + assert(*py==1); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp new file mode 100644 index 0000000000000..daefdf320e3af --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// propagate_const(const propagate_const&)=delete; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { static_assert(!std::is_constructible<P, const P &>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp new file mode 100644 index 0000000000000..6a7289b2f1a6c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<ExplicitX> P; + +int main() { + static_assert(!std::is_convertible<P, int>::value, ""); + static_assert(std::is_constructible<P, int>::value, ""); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp new file mode 100644 index 0000000000000..9c6ed89f6757b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +void f(const P&) +{ +} + +int main() { f(2); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp new file mode 100644 index 0000000000000..a5adf2d1f7f0b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// propagate_const(propagate_const&&)=default; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + P p1(2); + P p2(std::move(p1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp new file mode 100644 index 0000000000000..5e9e0434fed7b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// element_type& propagate_const::operator*(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +constexpr P f() +{ + P p(1); + *p = 2; + return p; +} + +int main() { + constexpr P p = f(); + static_assert(*p==2,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..808eda0e3cc3c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// propagate_const::operator element_type*(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { static_assert(!std::is_convertible<P, int *>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp new file mode 100644 index 0000000000000..298389b7b59dc --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// element_type* propagate_const::get(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +constexpr P f() +{ + P p(1); + *p.get() = 2; + return p; +} + +int main() { + constexpr P p = f(); + static_assert(*(p.get())==2,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp new file mode 100644 index 0000000000000..810e86eea172e --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// element_type* propagate_const::operator->(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +constexpr P f() +{ + P p(1); + *(p.operator->()) = 2; + return p; +} + +int main() { + constexpr P p = f(); + static_assert(*(p.operator->())==2,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..6bdf76c92e995 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// propagate_const::operator element_type*(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<XWithImplicitIntStarConversion> P; + + P p(1); + + int* ptr_1 = p; + + assert(*ptr_1==1); + + *ptr_1 = 2; + + assert(*ptr_1==2); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp new file mode 100644 index 0000000000000..292335449649c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// const element_type& propagate_const::operator*() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + constexpr P p(1); + + static_assert(*p==1,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..b9b6b3f90f230 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// propagate_const::operator const element_type*() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { + static_assert(!std::is_convertible<const P, const int *>::value, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp new file mode 100644 index 0000000000000..8029ff47475ef --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// const element_type* propagate_const::get() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + constexpr P p(1); + + static_assert(*(p.get())==1, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp new file mode 100644 index 0000000000000..4ceea8a1d7819 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// const element_type* propagate_const::operator->() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + constexpr P p(1); + + static_assert(*(p.operator->())==1,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..1ac6d254a3429 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// propagate_const::operator const element_type*() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<XWithImplicitConstIntStarConversion> P; + +constexpr P p(1); + +constexpr const int *ptr_1 = p; + +int main() { assert(*ptr_1 == 1); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp new file mode 100644 index 0000000000000..c5c832bbe0c2c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr void propagate_const::swap(propagate_const<T>& x); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +bool swap_called = false; +void swap(X &, X &) { swap_called = true; } + +int main() { + typedef propagate_const<X> P; + P p1(1); + P p2(2); + p1.swap(p2); + assert(swap_called); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp new file mode 100644 index 0000000000000..8cf670a25402c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +namespace std { +template <> struct hash<X> +{ + typedef X first_argument_type; + + size_t operator()(const first_argument_type& x1) const + { + return 99; + } + +}; +} // namespace std + +int main() { + + typedef propagate_const<X> P; + + P p(1); + + auto h = std::hash<P>(); + + assert(h(p)==99); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp new file mode 100644 index 0000000000000..d54222a97a1c6 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator==(const X &x1, const X &x2) { return x1.i_ == x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::equal_to<P>(); + + assert(c(p1_1,p2_1)); + assert(!c(p1_1,p3_2)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp new file mode 100644 index 0000000000000..fb8e1282f214e --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>(const X &x1, const X &x2) { return x1.i_ > x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::greater<P>(); + + assert(!c(p1_1,p2_1)); + assert(!c(p2_1,p1_1)); + assert(!c(p1_1,p3_2)); + assert(c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp new file mode 100644 index 0000000000000..29a1868d64716 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>=(const X &x1, const X &x2) { return x1.i_ >= x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::greater_equal<P>(); + + assert(c(p1_1,p2_1)); + assert(c(p2_1,p1_1)); + assert(!c(p1_1,p3_2)); + assert(c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp new file mode 100644 index 0000000000000..074a3914a51c0 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<(const X &x1, const X &x2) { return x1.i_ < x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::less<P>(); + + assert(!c(p1_1,p2_1)); + assert(!c(p2_1,p1_1)); + assert(c(p1_1,p3_2)); + assert(!c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp new file mode 100644 index 0000000000000..a2082ec5cb317 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<=(const X &x1, const X &x2) { return x1.i_ <= x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::less_equal<P>(); + + assert(c(p1_1,p2_1)); + assert(c(p2_1,p1_1)); + assert(c(p1_1,p3_2)); + assert(!c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp new file mode 100644 index 0000000000000..20756d984e94d --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator!=(const X &x1, const X &x2) { return x1.i_ != x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::not_equal_to<P>(); + + assert(!c(p1_1,p2_1)); + assert(c(p1_1,p3_2)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp new file mode 100644 index 0000000000000..a4a28b48a545b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator==(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator==(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator==(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; +using std::nullptr_t; + +constexpr bool operator==(const X &lhs, const X &rhs) { + return lhs.i_ == rhs.i_; +} + +constexpr bool operator==(const X &, const nullptr_t &) { + return false; +} + +constexpr bool operator==(const nullptr_t &, const X &) { + return false; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(x1_1 == x1_1, ""); + static_assert(x1_1 == x2_1, ""); + static_assert(!(x1_1 == x3_2), ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(p1_1 == p1_1, ""); + static_assert(p1_1 == p2_1, ""); + static_assert(!(p1_1 == p3_2), ""); + + static_assert(x1_1 == p1_1, ""); + static_assert(!(x1_1 == p3_2), ""); + + static_assert(p1_1 == x1_1, ""); + static_assert(!(p1_1 == x3_2), ""); + + static_assert(!(p1_1==nullptr),""); + static_assert(!(nullptr==p1_1),""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp new file mode 100644 index 0000000000000..4b5b42467c092 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp @@ -0,0 +1,54 @@ +//>==---------------------------------------------------------------------->==// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//>==---------------------------------------------------------------------->==// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator>=(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>=(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>=(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>=(const X &lhs, const X &rhs) { + return lhs.i_ >= rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(x1_1 >= x2_1, ""); + static_assert(!(x1_1 >= x3_2), ""); + static_assert(x3_2 >= x1_1, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(p1_1 >= p2_1, ""); + static_assert(!(p1_1 >= p3_2), ""); + static_assert(p3_2 >= p1_1, ""); + + static_assert(p1_1 >= x2_1, ""); + static_assert(!(p1_1 >= x3_2), ""); + static_assert(p3_2 >= x1_1, ""); + + static_assert(x1_1 >= p2_1, ""); + static_assert(!(x1_1 >= p3_2), ""); + static_assert(x3_2 >= p1_1, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp new file mode 100644 index 0000000000000..3865b9370727f --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp @@ -0,0 +1,50 @@ +//>=---------------------------------------------------------------------->=// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//>=---------------------------------------------------------------------->=// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator>(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>(const X &lhs, const X &rhs) { + return lhs.i_ > rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(!(x1_1 > x2_1), ""); + static_assert(x3_2 > x1_1, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(!(p1_1 > p2_1), ""); + static_assert(p3_2 > p1_1, ""); + + static_assert(!(p1_1 > x2_1), ""); + static_assert(p3_2 > x1_1, ""); + + static_assert(!(x1_1 > p2_1), ""); + static_assert(x3_2 > p1_1, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp new file mode 100644 index 0000000000000..3ac12c27f8bbc --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp @@ -0,0 +1,55 @@ +//<==----------------------------------------------------------------------<==// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//<==----------------------------------------------------------------------<==// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator<=(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<=(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<=(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<=(const X &lhs, const X &rhs) { + return lhs.i_ <= rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(x1_1 <= x2_1, ""); + static_assert(x1_1 <= x3_2, ""); + static_assert(!(x3_2 <= x1_1), ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(p1_1 <= p2_1, ""); + static_assert(p1_1 <= p3_2, ""); + static_assert(!(p3_2 <= p1_1), ""); + + static_assert(p1_1 <= x2_1, ""); + static_assert(p1_1 <= x3_2, ""); + static_assert(!(p3_2 <= x1_1), ""); + + static_assert(x1_1 <= p2_1, ""); + static_assert(x1_1 <= p3_2, ""); + static_assert(!(x3_2 <= p1_1), ""); + +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp new file mode 100644 index 0000000000000..42b2730c58cc5 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp @@ -0,0 +1,50 @@ +//<=----------------------------------------------------------------------<=// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//<=----------------------------------------------------------------------<=// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator<(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<(const X &lhs, const X &rhs) { + return lhs.i_ < rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(!(x1_1 < x2_1), ""); + static_assert(x1_1 < x3_2, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(!(p1_1 < p2_1), ""); + static_assert(p1_1 < p3_2, ""); + + static_assert(!(x1_1 < p1_1), ""); + static_assert(x1_1 < p3_2, ""); + + static_assert(!(p1_1 < x1_1), ""); + static_assert(p1_1 < x3_2, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp new file mode 100644 index 0000000000000..1104abdecb6d5 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator!=(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator!=(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator!=(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; +using std::nullptr_t; + +constexpr bool operator!=(const X &lhs, const X &rhs) { + return lhs.i_ != rhs.i_; +} + +constexpr bool operator!=(const X &, const nullptr_t &) { + return true; +} + +constexpr bool operator!=(const nullptr_t &, const X &) { + return true; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(!(x1_1 != x2_1), ""); + static_assert(x1_1 != x3_2, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(!(p1_1 != p2_1), ""); + static_assert(p1_1 != p3_2, ""); + + static_assert(!(x1_1 != p1_1), ""); + static_assert(x1_1 != p3_2, ""); + + static_assert(!(p1_1 != x1_1), ""); + static_assert(p1_1 != x3_2, ""); + + static_assert(p1_1!=nullptr,""); + static_assert(nullptr!=p1_1,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp new file mode 100644 index 0000000000000..6c3b609489658 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr void swap(propagate_const<T>& x, propagate_const<T>& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +bool swap_called = false; +void swap(X &, X &) { swap_called = true; } + +int main() { + typedef propagate_const<X> P; + P p1(1); + P p2(2); + swap(p1, p2); + assert(swap_called); +} diff --git a/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp index 2d700486f26bd..5b8a8f09d1eee 100644 --- a/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp +++ b/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp @@ -9,11 +9,6 @@ // UNSUPPORTED: c++98, c++03, c++11 -// TODO(ericwf) -// constexpr support temporarily reverted due to bug: -// https://llvm.org/bugs/show_bug.cgi?id=23141 -// XFAIL: * - // <experimental/tuple> // template <class F, class T> constexpr decltype(auto) apply(F &&, T &&) diff --git a/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp index 1ec38da5c043e..314d2783f7ec3 100644 --- a/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp +++ b/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp @@ -25,30 +25,27 @@ template <int N> struct index {}; void f(index<0>) {} int f(index<1>) { return 0; } -int const f(index<2>) { return 0; } -int volatile f(index<3>) { return 0; } -int const volatile f(index<4>) { return 0; } -int & f(index<5>) { return static_cast<int &>(my_int); } -int const & f(index<6>) { return static_cast<int const &>(my_int); } -int volatile & f(index<7>) { return static_cast<int volatile &>(my_int); } -int const volatile & f(index<8>) { return static_cast<int const volatile &>(my_int); } +int & f(index<2>) { return static_cast<int &>(my_int); } +int const & f(index<3>) { return static_cast<int const &>(my_int); } +int volatile & f(index<4>) { return static_cast<int volatile &>(my_int); } +int const volatile & f(index<5>) { return static_cast<int const volatile &>(my_int); } -int && f(index<9>) { return static_cast<int &&>(my_int); } -int const && f(index<10>) { return static_cast<int const &&>(my_int); } -int volatile && f(index<11>) { return static_cast<int volatile &&>(my_int); } -int const volatile && f(index<12>) { return static_cast<int const volatile &&>(my_int); } +int && f(index<6>) { return static_cast<int &&>(my_int); } +int const && f(index<7>) { return static_cast<int const &&>(my_int); } +int volatile && f(index<8>) { return static_cast<int volatile &&>(my_int); } +int const volatile && f(index<9>) { return static_cast<int const volatile &&>(my_int); } -int * f(index<13>) { return static_cast<int *>(&my_int); } -int const * f(index<14>) { return static_cast<int const *>(&my_int); } -int volatile * f(index<15>) { return static_cast<int volatile *>(&my_int); } -int const volatile * f(index<16>) { return static_cast<int const volatile *>(&my_int); } +int * f(index<10>) { return static_cast<int *>(&my_int); } +int const * f(index<11>) { return static_cast<int const *>(&my_int); } +int volatile * f(index<12>) { return static_cast<int volatile *>(&my_int); } +int const volatile * f(index<13>) { return static_cast<int const volatile *>(&my_int); } template <int Func, class Expect> void test() { - using F = decltype((f(index<Func>{}))); + using F = decltype(f(index<Func>{})); static_assert(std::is_same<F, Expect>::value, ""); } @@ -58,19 +55,16 @@ int main() { test<0, void>(); test<1, int>(); - //test<2, int const>(); - //test<3, int volatile>(); - //test<4, int const volatile>(); - test<5, int &>(); - test<6, int const &>(); - test<7, int volatile &>(); - test<8, int const volatile &>(); - test<9, int &&>(); - test<10, int const &&>(); - test<11, int volatile &&>(); - test<12, int const volatile &&>(); - test<13, int *>(); - test<14, int const *>(); - test<15, int volatile *>(); - test<16, int const volatile *>(); + test<2, int &>(); + test<3, int const &>(); + test<4, int volatile &>(); + test<5, int const volatile &>(); + test<6, int &&>(); + test<7, int const &&>(); + test<8, int volatile &&>(); + test<9, int const volatile &&>(); + test<10, int *>(); + test<11, int const *>(); + test<12, int volatile *>(); + test<13, int const volatile *>(); } |