Implement LWG2989: path's streaming operators allow everything under the sun.

Because path can be constructed from a ton of different types, including string
and wide strings, this caused it's streaming operators to suck up all sorts
of silly types via silly conversions. For example:

using namespace std::experimental::filesystem::v1;
std::wstring w(L"wide");
std::cout << w; // converts to path.

This patch tentatively adopts the resolution to LWG2989 and fixes the issue
by making the streaming operators friends of path.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@324189 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2018-02-04 03:10:53 +00:00
parent cc7688a719
commit 0b47a655ac
3 changed files with 72 additions and 37 deletions

View File

@@ -26,6 +26,7 @@
#include <type_traits>
#include <sstream>
#include <cassert>
#include <iostream>
#include "test_macros.h"
#include "test_iterators.h"
@@ -35,6 +36,8 @@
MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789");
MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\"");
template <class CharT>
void doIOTest() {
using namespace fs;
@@ -56,10 +59,40 @@ void doIOTest() {
}
}
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);
} // namespace impl
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() {
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, "");
}
int main() {
doIOTest<char>();
doIOTest<wchar_t>();
//doIOTest<char16_t>();
//doIOTest<char32_t>();
test_LWG2989();
}