libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

source.pass.cpp (6583B)


      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03
     11 
     12 // <filesystem>
     13 
     14 // class path
     15 
     16 // template <class Source>
     17 //      path& operator=(Source const&);
     18 //  path& operator=(string_type&&);
     19 // template <class Source>
     20 //      path& assign(Source const&);
     21 // template <class InputIterator>
     22 //      path& assign(InputIterator first, InputIterator last);
     23 
     24 
     25 #include "filesystem_include.hpp"
     26 #include <type_traits>
     27 #include <string_view>
     28 #include <cassert>
     29 
     30 #include "test_macros.h"
     31 #include "test_iterators.h"
     32 #include "count_new.hpp"
     33 #include "filesystem_test_helper.hpp"
     34 #include <iostream>
     35 
     36 
     37 template <class CharT>
     38 void RunTestCase(MultiStringType const& MS) {
     39   using namespace fs;
     40   const char* Expect = MS;
     41   const CharT* TestPath = MS;
     42   const CharT* TestPathEnd = StrEnd(TestPath);
     43   const std::size_t Size = TestPathEnd - TestPath;
     44   const std::size_t SSize = StrEnd(Expect) - Expect;
     45   assert(Size == SSize);
     46   //////////////////////////////////////////////////////////////////////////////
     47   // basic_string<Char, Traits, Alloc>
     48   {
     49     const std::basic_string<CharT> S(TestPath);
     50     path p; PathReserve(p, S.length() + 1);
     51     {
     52       // string provides a contiguous iterator. No allocation needed.
     53       DisableAllocationGuard g;
     54       path& pref = (p = S);
     55       assert(&pref == &p);
     56     }
     57     assert(p.native() == Expect);
     58     assert(p.string<CharT>() == TestPath);
     59     assert(p.string<CharT>() == S);
     60   }
     61   {
     62     const std::basic_string<CharT> S(TestPath);
     63     path p; PathReserve(p, S.length() + 1);
     64     {
     65       DisableAllocationGuard g;
     66       path& pref = p.assign(S);
     67       assert(&pref == &p);
     68     }
     69     assert(p.native() == Expect);
     70     assert(p.string<CharT>() == TestPath);
     71     assert(p.string<CharT>() == S);
     72   }
     73   // basic_string<Char, Traits, Alloc>
     74   {
     75     const std::basic_string_view<CharT> S(TestPath);
     76     path p; PathReserve(p, S.length() + 1);
     77     {
     78       // string provides a contiguous iterator. No allocation needed.
     79       DisableAllocationGuard g;
     80       path& pref = (p = S);
     81       assert(&pref == &p);
     82     }
     83     assert(p.native() == Expect);
     84     assert(p.string<CharT>() == TestPath);
     85     assert(p.string<CharT>() == S);
     86   }
     87   {
     88     const std::basic_string_view<CharT> S(TestPath);
     89     path p; PathReserve(p, S.length() + 1);
     90     {
     91       DisableAllocationGuard g;
     92       path& pref = p.assign(S);
     93       assert(&pref == &p);
     94     }
     95     assert(p.native() == Expect);
     96     assert(p.string<CharT>() == TestPath);
     97     assert(p.string<CharT>() == S);
     98   }
     99   //////////////////////////////////////////////////////////////////////////////
    100   // Char* pointers
    101   {
    102     path p; PathReserve(p, Size + 1);
    103     {
    104       // char* pointers are contiguous and can be used with code_cvt directly.
    105       // no allocations needed.
    106       DisableAllocationGuard g;
    107       path& pref = (p = TestPath);
    108       assert(&pref == &p);
    109     }
    110     assert(p.native() == Expect);
    111     assert(p.string<CharT>() == TestPath);
    112   }
    113   {
    114     path p; PathReserve(p, Size + 1);
    115     {
    116       DisableAllocationGuard g;
    117       path& pref = p.assign(TestPath);
    118       assert(&pref == &p);
    119     }
    120     assert(p.native() == Expect);
    121     assert(p.string<CharT>() == TestPath);
    122   }
    123   {
    124     path p; PathReserve(p, Size + 1);
    125     {
    126       DisableAllocationGuard g;
    127       path& pref = p.assign(TestPath, TestPathEnd);
    128       assert(&pref == &p);
    129     }
    130     assert(p.native() == Expect);
    131     assert(p.string<CharT>() == TestPath);
    132   }
    133   //////////////////////////////////////////////////////////////////////////////
    134   // Iterators
    135   {
    136     using It = input_iterator<const CharT*>;
    137     path p; PathReserve(p, Size + 1);
    138     It it(TestPath);
    139     {
    140       // Iterators cannot be used with code_cvt directly. This assignment
    141       // may allocate if it's larger than a "short-string".
    142       path& pref = (p = it);
    143       assert(&pref == &p);
    144     }
    145     assert(p.native() == Expect);
    146     assert(p.string<CharT>() == TestPath);
    147   }
    148   {
    149     using It = input_iterator<const CharT*>;
    150     path p; PathReserve(p, Size + 1);
    151     It it(TestPath);
    152     {
    153       path& pref = p.assign(it);
    154       assert(&pref == &p);
    155     }
    156     assert(p.native() == Expect);
    157     assert(p.string<CharT>() == TestPath);
    158   }
    159   {
    160     using It = input_iterator<const CharT*>;
    161     path p; PathReserve(p, Size + 1);
    162     It it(TestPath);
    163     It e(TestPathEnd);
    164     {
    165       path& pref = p.assign(it, e);
    166       assert(&pref == &p);
    167     }
    168     assert(p.native() == Expect);
    169     assert(p.string<CharT>() == TestPath);
    170   }
    171 }
    172 
    173 template <class It, class = decltype(fs::path{}.assign(std::declval<It>()))>
    174 constexpr bool has_assign(int) { return true; }
    175 template <class It>
    176 constexpr bool has_assign(long) { return false; }
    177 template <class It>
    178 constexpr bool has_assign() { return has_assign<It>(0); }
    179 
    180 void test_sfinae() {
    181   using namespace fs;
    182   {
    183     using It = const char* const;
    184     static_assert(std::is_assignable<path, It>::value, "");
    185     static_assert(has_assign<It>(), "");
    186   }
    187   {
    188     using It = input_iterator<const char*>;
    189     static_assert(std::is_assignable<path, It>::value, "");
    190     static_assert(has_assign<It>(), "");
    191   }
    192   {
    193     struct Traits {
    194       using iterator_category = std::input_iterator_tag;
    195       using value_type = const char;
    196       using pointer = const char*;
    197       using reference = const char&;
    198       using difference_type = std::ptrdiff_t;
    199     };
    200     using It = input_iterator<const char*, Traits>;
    201     static_assert(std::is_assignable<path, It>::value, "");
    202     static_assert(has_assign<It>(), "");
    203   }
    204   {
    205     using It = output_iterator<const char*>;
    206     static_assert(!std::is_assignable<path, It>::value, "");
    207     static_assert(!has_assign<It>(), "");
    208 
    209   }
    210   {
    211     static_assert(!std::is_assignable<path, int*>::value, "");
    212     static_assert(!has_assign<int*>(), "");
    213   }
    214 }
    215 
    216 void RunStringMoveTest(const char* Expect) {
    217   using namespace fs;
    218   std::string ss(Expect);
    219   path p;
    220   {
    221     DisableAllocationGuard g; ((void)g);
    222     path& pr = (p = std::move(ss));
    223     assert(&pr == &p);
    224   }
    225   assert(p == Expect);
    226   {
    227     // Signature test
    228     ASSERT_NOEXCEPT(p = std::move(ss));
    229   }
    230 }
    231 
    232 int main() {
    233   for (auto const& MS : PathList) {
    234     RunTestCase<char>(MS);
    235     RunTestCase<wchar_t>(MS);
    236     RunTestCase<char16_t>(MS);
    237     RunTestCase<char32_t>(MS);
    238     RunStringMoveTest(MS);
    239   }
    240   test_sfinae();
    241 }