#include <filesystem>
#include <type_traits>
#include <sstream>
#include <cassert>
#include <iostream>
#include "count_new.h"
#include "make_string.h"
#include "test_iterators.h"
#include "test_macros.h"
namespace fs = std::filesystem;
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 Ptr E = OutStr;
const path p((const char*)InStr);
StrStream ss;
{
auto& ret = (ss << p);
assert(ss.str() == E);
assert(&ret == &ss);
}
{
path p_in;
auto& ret = ss >> p_in;
assert(p_in.native() == (const path::value_type*)InStr);
assert(&ret == &ss);
}
}
namespace impl {
using namespace fs;
template <class Stream, class Tp, class = decltype(std::declval<Stream&>() << std::declval<Tp&>())>
std::true_type is_ostreamable_imp(int);
template <class Stream, class Tp>
std::false_type is_ostreamable_imp(long);
template <class Stream, class Tp, class = decltype(std::declval<Stream&>() >> std::declval<Tp&>())>
std::true_type is_istreamable_imp(int);
template <class Stream, class Tp>
std::false_type is_istreamable_imp(long);
}
template <class Stream, class Tp>
struct is_ostreamable : decltype(impl::is_ostreamable_imp<Stream, Tp>(0)) {};
template <class Stream, class Tp>
struct is_istreamable : decltype(impl::is_istreamable_imp<Stream, Tp>(0)) {};
void test_LWG2989() {
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
static_assert(!is_ostreamable<decltype(std::cout), std::wstring>::value, "");
static_assert(!is_ostreamable<decltype(std::wcout), std::string>::value, "");
static_assert(!is_istreamable<decltype(std::cin), std::wstring>::value, "");
static_assert(!is_istreamable<decltype(std::wcin), std::string>::value, "");
#endif
}
int main(int, char**) {
doIOTest<char>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
doIOTest<wchar_t>();
#endif
test_LWG2989();
return 0;
}