xref: /llvm-project/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp (revision ac8c9f1e39e1a773fd81ce23dbf1c80ea186f226)
1f7b43230SLouis Dionne //===----------------------------------------------------------------------===//
2f7b43230SLouis Dionne //
3f7b43230SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f7b43230SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5f7b43230SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f7b43230SLouis Dionne //
7f7b43230SLouis Dionne //===----------------------------------------------------------------------===//
8f7b43230SLouis Dionne 
9*ac8c9f1eSLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
10a7f9895cSLouis Dionne // UNSUPPORTED: no-localization
11c352fa74SLouis Dionne // UNSUPPORTED: availability-filesystem-missing
12f7b43230SLouis Dionne 
13f7b43230SLouis Dionne // <filesystem>
14f7b43230SLouis Dionne 
15f7b43230SLouis Dionne // class path
16f7b43230SLouis Dionne 
17f7b43230SLouis Dionne // template <class charT, class traits>
18f7b43230SLouis Dionne // basic_ostream<charT, traits>&
19f7b43230SLouis Dionne // operator<<(basic_ostream<charT, traits>& os, const path& p);
20f7b43230SLouis Dionne //
21f7b43230SLouis Dionne // template <class charT, class traits>
22f7b43230SLouis Dionne // basic_istream<charT, traits>&
23f7b43230SLouis Dionne // operator>>(basic_istream<charT, traits>& is, path& p)
24f7b43230SLouis Dionne //
25f7b43230SLouis Dionne 
26*ac8c9f1eSLouis Dionne #include <filesystem>
27f7b43230SLouis Dionne #include <type_traits>
28f7b43230SLouis Dionne #include <sstream>
29f7b43230SLouis Dionne #include <cassert>
30f7b43230SLouis Dionne #include <iostream>
31f7b43230SLouis Dionne 
32cc89063bSNico Weber #include "count_new.h"
33c352fa74SLouis Dionne #include "make_string.h"
34c352fa74SLouis Dionne #include "test_iterators.h"
35c352fa74SLouis Dionne #include "test_macros.h"
36*ac8c9f1eSLouis Dionne namespace fs = std::filesystem;
37f7b43230SLouis Dionne 
38f7b43230SLouis Dionne MultiStringType InStr =  MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789");
39f7b43230SLouis Dionne MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\"");
40f7b43230SLouis Dionne 
41f7b43230SLouis Dionne template <class CharT>
doIOTest()42f7b43230SLouis Dionne void doIOTest() {
43f7b43230SLouis Dionne   using namespace fs;
44f7b43230SLouis Dionne   using Ptr = const CharT*;
45f7b43230SLouis Dionne   using StrStream = std::basic_stringstream<CharT>;
46f7b43230SLouis Dionne   const Ptr E = OutStr;
47f7b43230SLouis Dionne   const path p((const char*)InStr);
48f7b43230SLouis Dionne   StrStream ss;
49f7b43230SLouis Dionne   { // test output
50f7b43230SLouis Dionne     auto& ret = (ss << p);
51f7b43230SLouis Dionne     assert(ss.str() == E);
52f7b43230SLouis Dionne     assert(&ret == &ss);
53f7b43230SLouis Dionne   }
54f7b43230SLouis Dionne   { // test input
55f7b43230SLouis Dionne     path p_in;
56f7b43230SLouis Dionne     auto& ret = ss >> p_in;
573784bdf2SMartin Storsjö     assert(p_in.native() == (const path::value_type*)InStr);
58f7b43230SLouis Dionne     assert(&ret == &ss);
59f7b43230SLouis Dionne   }
60f7b43230SLouis Dionne }
61f7b43230SLouis Dionne 
62f7b43230SLouis Dionne namespace impl {
63f7b43230SLouis Dionne using namespace fs;
64f7b43230SLouis Dionne 
65f7b43230SLouis Dionne template <class Stream, class Tp, class = decltype(std::declval<Stream&>() << std::declval<Tp&>())>
66f7b43230SLouis Dionne std::true_type is_ostreamable_imp(int);
67f7b43230SLouis Dionne 
68f7b43230SLouis Dionne template <class Stream, class Tp>
69f7b43230SLouis Dionne std::false_type is_ostreamable_imp(long);
70f7b43230SLouis Dionne 
71f7b43230SLouis Dionne template <class Stream, class Tp, class = decltype(std::declval<Stream&>() >> std::declval<Tp&>())>
72f7b43230SLouis Dionne std::true_type is_istreamable_imp(int);
73f7b43230SLouis Dionne 
74f7b43230SLouis Dionne template <class Stream, class Tp>
75f7b43230SLouis Dionne std::false_type is_istreamable_imp(long);
76f7b43230SLouis Dionne 
77f7b43230SLouis Dionne 
78f7b43230SLouis Dionne } // namespace impl
79f7b43230SLouis Dionne 
80f7b43230SLouis Dionne template <class Stream, class Tp>
81f7b43230SLouis Dionne struct is_ostreamable : decltype(impl::is_ostreamable_imp<Stream, Tp>(0)) {};
82f7b43230SLouis Dionne template <class Stream, class Tp>
83f7b43230SLouis Dionne struct is_istreamable : decltype(impl::is_istreamable_imp<Stream, Tp>(0)) {};
84f7b43230SLouis Dionne 
test_LWG2989()85f7b43230SLouis Dionne void test_LWG2989() {
86f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
87f7b43230SLouis Dionne   static_assert(!is_ostreamable<decltype(std::cout), std::wstring>::value, "");
88f7b43230SLouis Dionne   static_assert(!is_ostreamable<decltype(std::wcout), std::string>::value, "");
89f7b43230SLouis Dionne   static_assert(!is_istreamable<decltype(std::cin), std::wstring>::value, "");
90f7b43230SLouis Dionne   static_assert(!is_istreamable<decltype(std::wcin), std::string>::value, "");
91f4c1258dSLouis Dionne #endif
92f7b43230SLouis Dionne }
93f7b43230SLouis Dionne 
main(int,char **)94f7b43230SLouis Dionne int main(int, char**) {
95f7b43230SLouis Dionne   doIOTest<char>();
96f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
97f7b43230SLouis Dionne   doIOTest<wchar_t>();
98f4c1258dSLouis Dionne #endif
99b6d87773SKonstantin Varlamov   // TODO(var-const): uncomment when it becomes possible to instantiate a `basic_ostream` object with a sized character
100b6d87773SKonstantin Varlamov   // type (see https://llvm.org/PR53119).
101f7b43230SLouis Dionne   //doIOTest<char16_t>();
102f7b43230SLouis Dionne   //doIOTest<char32_t>();
103f7b43230SLouis Dionne   test_LWG2989();
104f7b43230SLouis Dionne 
105f7b43230SLouis Dionne   return 0;
106f7b43230SLouis Dionne }
107