brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · b43517d Raw
250 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// These tests require locale for non-char paths12// UNSUPPORTED: no-localization13 14// <filesystem>15 16// class path17 18// template <class Source>19//      path& operator=(Source const&);20//  path& operator=(string_type&&);21// template <class Source>22//      path& assign(Source const&);23// template <class InputIterator>24//      path& assign(InputIterator first, InputIterator last);25 26#include <filesystem>27#include <type_traits>28#include <string_view>29#include <cassert>30 31// On Windows, charset conversions cause allocations in the path class in32// cases where no allocations are done on other platforms.33 34#include "../../path_helper.h"35#include "count_new.h"36#include "make_string.h"37#include "test_iterators.h"38#include "test_macros.h"39namespace fs = std::filesystem;40 41template <class CharT>42void RunTestCase(MultiStringType const& MS) {43  using namespace fs;44  const fs::path::value_type* Expect = MS;45  const CharT* TestPath = MS;46  const CharT* TestPathEnd = StrEnd(TestPath);47  const std::size_t Size = TestPathEnd - TestPath;48  const std::size_t SSize = StrEnd(Expect) - Expect;49  assert(Size == SSize);50  //////////////////////////////////////////////////////////////////////////////51  // basic_string<Char, Traits, Alloc>52  {53    const std::basic_string<CharT> S(TestPath);54    path p; PathReserve(p, S.length() + 1);55    {56      // string provides a contiguous iterator. No allocation needed.57      TEST_NOT_WIN32(DisableAllocationGuard g);58      path& pref = (p = S);59      assert(&pref == &p);60    }61    assert(p.native() == Expect);62    assert(p.string<CharT>() == TestPath);63    assert(p.string<CharT>() == S);64  }65  {66    const std::basic_string<CharT> S(TestPath);67    path p; PathReserve(p, S.length() + 1);68    {69      TEST_NOT_WIN32(DisableAllocationGuard g);70      path& pref = p.assign(S);71      assert(&pref == &p);72    }73    assert(p.native() == Expect);74    assert(p.string<CharT>() == TestPath);75    assert(p.string<CharT>() == S);76  }77  // basic_string<Char, Traits, Alloc>78  {79    const std::basic_string_view<CharT> S(TestPath);80    path p; PathReserve(p, S.length() + 1);81    {82      // string provides a contiguous iterator. No allocation needed.83      TEST_NOT_WIN32(DisableAllocationGuard g);84      path& pref = (p = S);85      assert(&pref == &p);86    }87    assert(p.native() == Expect);88    assert(p.string<CharT>() == TestPath);89    assert(p.string<CharT>() == S);90  }91  {92    const std::basic_string_view<CharT> S(TestPath);93    path p; PathReserve(p, S.length() + 1);94    {95      TEST_NOT_WIN32(DisableAllocationGuard g);96      path& pref = p.assign(S);97      assert(&pref == &p);98    }99    assert(p.native() == Expect);100    assert(p.string<CharT>() == TestPath);101    assert(p.string<CharT>() == S);102  }103  //////////////////////////////////////////////////////////////////////////////104  // Char* pointers105  {106    path p; PathReserve(p, Size + 1);107    {108      // char* pointers are contiguous and can be used with code_cvt directly.109      // no allocations needed.110      TEST_NOT_WIN32(DisableAllocationGuard g);111      path& pref = (p = TestPath);112      assert(&pref == &p);113    }114    assert(p.native() == Expect);115    assert(p.string<CharT>() == TestPath);116  }117  {118    path p; PathReserve(p, Size + 1);119    {120      TEST_NOT_WIN32(DisableAllocationGuard g);121      path& pref = p.assign(TestPath);122      assert(&pref == &p);123    }124    assert(p.native() == Expect);125    assert(p.string<CharT>() == TestPath);126  }127  {128    path p; PathReserve(p, Size + 1);129    {130      TEST_NOT_WIN32(DisableAllocationGuard g);131      path& pref = p.assign(TestPath, TestPathEnd);132      assert(&pref == &p);133    }134    assert(p.native() == Expect);135    assert(p.string<CharT>() == TestPath);136  }137  //////////////////////////////////////////////////////////////////////////////138  // Iterators139  {140    using It = cpp17_input_iterator<const CharT*>;141    path p; PathReserve(p, Size + 1);142    It it(TestPath);143    {144      // Iterators cannot be used with code_cvt directly. This assignment145      // may allocate if it's larger than a "short-string".146      path& pref = (p = it);147      assert(&pref == &p);148    }149    assert(p.native() == Expect);150    assert(p.string<CharT>() == TestPath);151  }152  {153    using It = cpp17_input_iterator<const CharT*>;154    path p; PathReserve(p, Size + 1);155    It it(TestPath);156    {157      path& pref = p.assign(it);158      assert(&pref == &p);159    }160    assert(p.native() == Expect);161    assert(p.string<CharT>() == TestPath);162  }163  {164    using It = cpp17_input_iterator<const CharT*>;165    path p; PathReserve(p, Size + 1);166    It it(TestPath);167    It e(TestPathEnd);168    {169      path& pref = p.assign(it, e);170      assert(&pref == &p);171    }172    assert(p.native() == Expect);173    assert(p.string<CharT>() == TestPath);174  }175}176 177template <class It, class = decltype(fs::path{}.assign(std::declval<It>()))>178constexpr bool has_assign(int) { return true; }179template <class It>180constexpr bool has_assign(long) { return false; }181template <class It>182constexpr bool has_assign() { return has_assign<It>(0); }183 184void test_sfinae() {185  using namespace fs;186  {187    using It = const char* const;188    static_assert(std::is_assignable<path, It>::value, "");189    static_assert(has_assign<It>(), "");190  }191  {192    using It = cpp17_input_iterator<const char*>;193    static_assert(std::is_assignable<path, It>::value, "");194    static_assert(has_assign<It>(), "");195  }196  {197    struct Traits {198      using iterator_category = std::input_iterator_tag;199      using value_type = const char;200      using pointer = const char*;201      using reference = const char&;202      using difference_type = std::ptrdiff_t;203    };204    using It = cpp17_input_iterator<const char*, Traits>;205    static_assert(std::is_assignable<path, It>::value, "");206    static_assert(has_assign<It>(), "");207  }208  {209    using It = cpp17_output_iterator<const char*>;210    static_assert(!std::is_assignable<path, It>::value, "");211    static_assert(!has_assign<It>(), "");212 213  }214  {215    static_assert(!std::is_assignable<path, int*>::value, "");216    static_assert(!has_assign<int*>(), "");217  }218}219 220void RunStringMoveTest(const fs::path::value_type* Expect) {221  using namespace fs;222  fs::path::string_type ss(Expect);223  path p;224  {225    DisableAllocationGuard g; ((void)g);226    path& pr = (p = std::move(ss));227    assert(&pr == &p);228  }229  assert(p == Expect);230  {231    // Signature test232    LIBCPP_ASSERT_NOEXCEPT(p = std::move(ss));233  }234}235 236int main(int, char**) {237  for (auto const& MS : PathList) {238    RunTestCase<char>(MS);239#ifndef TEST_HAS_NO_WIDE_CHARACTERS240    RunTestCase<wchar_t>(MS);241#endif242    RunTestCase<char16_t>(MS);243    RunTestCase<char32_t>(MS);244    RunStringMoveTest(MS);245  }246  test_sfinae();247 248  return 0;249}250