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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03 10 // UNSUPPORTED: no-localization 11 12 // <filesystem> 13 14 // class path 15 16 // template <class charT, class traits> 17 // basic_ostream<charT, traits>& 18 // operator<<(basic_ostream<charT, traits>& os, const path& p); 19 // 20 // template <class charT, class traits> 21 // basic_istream<charT, traits>& 22 // operator>>(basic_istream<charT, traits>& is, path& p) 23 // 24 25 #include "filesystem_include.h" 26 #include <type_traits> 27 #include <sstream> 28 #include <cassert> 29 #include <iostream> 30 31 #include "test_macros.h" 32 #include "test_iterators.h" 33 #include "count_new.h" 34 #include "filesystem_test_helper.h" 35 36 MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789"); 37 MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\""); 38 39 template <class CharT> 40 void doIOTest() { 41 using namespace fs; 42 using Ptr = const CharT*; 43 using StrStream = std::basic_stringstream<CharT>; 44 const Ptr E = OutStr; 45 const path p((const char*)InStr); 46 StrStream ss; 47 { // test output 48 auto& ret = (ss << p); 49 assert(ss.str() == E); 50 assert(&ret == &ss); 51 } 52 { // test input 53 path p_in; 54 auto& ret = ss >> p_in; 55 assert(p_in.native() == (const path::value_type*)InStr); 56 assert(&ret == &ss); 57 } 58 } 59 60 namespace impl { 61 using namespace fs; 62 63 template <class Stream, class Tp, class = decltype(std::declval<Stream&>() << std::declval<Tp&>())> 64 std::true_type is_ostreamable_imp(int); 65 66 template <class Stream, class Tp> 67 std::false_type is_ostreamable_imp(long); 68 69 template <class Stream, class Tp, class = decltype(std::declval<Stream&>() >> std::declval<Tp&>())> 70 std::true_type is_istreamable_imp(int); 71 72 template <class Stream, class Tp> 73 std::false_type is_istreamable_imp(long); 74 75 76 } // namespace impl 77 78 template <class Stream, class Tp> 79 struct is_ostreamable : decltype(impl::is_ostreamable_imp<Stream, Tp>(0)) {}; 80 template <class Stream, class Tp> 81 struct is_istreamable : decltype(impl::is_istreamable_imp<Stream, Tp>(0)) {}; 82 83 void test_LWG2989() { 84 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 85 static_assert(!is_ostreamable<decltype(std::cout), std::wstring>::value, ""); 86 static_assert(!is_ostreamable<decltype(std::wcout), std::string>::value, ""); 87 static_assert(!is_istreamable<decltype(std::cin), std::wstring>::value, ""); 88 static_assert(!is_istreamable<decltype(std::wcin), std::string>::value, ""); 89 #endif 90 } 91 92 int main(int, char**) { 93 doIOTest<char>(); 94 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 95 doIOTest<wchar_t>(); 96 #endif 97 // TODO(var-const): uncomment when it becomes possible to instantiate a `basic_ostream` object with a sized character 98 // type (see https://llvm.org/PR53119). 99 //doIOTest<char16_t>(); 100 //doIOTest<char32_t>(); 101 test_LWG2989(); 102 103 return 0; 104 } 105