|
13 | 13 | #include <boost/nowide/convert.hpp> |
14 | 14 | #include <boost/nowide/cstdio.hpp> |
15 | 15 | #include <boost/nowide/fstream.hpp> |
| 16 | +#include <boost/nowide/quoted.hpp> |
| 17 | +#include <boost/nowide/utf/convert.hpp> |
16 | 18 | #include "test.hpp" |
| 19 | +#include <iomanip> |
| 20 | +#include <sstream> |
| 21 | +#include <type_traits> |
17 | 22 | #if defined(_MSC_VER) |
18 | 23 | #pragma warning(disable : 4714) // function marked as __forceinline not inlined |
19 | 24 | #endif |
20 | | -#include <boost/filesystem/operations.hpp> |
| 25 | +#include <boost/filesystem.hpp> |
| 26 | + |
| 27 | +// Exclude apple as support there is target level specific -.- |
| 28 | +#if defined(__cpp_lib_filesystem) && !defined(__APPLE__) |
| 29 | +#include <filesystem> |
| 30 | +#define BOOST_NOWIDE_TEST_STD_PATH |
| 31 | +#endif |
| 32 | +#if defined(__cpp_lib_experimental_filesystem) |
| 33 | +#ifndef _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING |
| 34 | +#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING |
| 35 | +#endif |
| 36 | +#include <experimental/filesystem> |
| 37 | +#define BOOST_NOWIDE_TEST_STD_EXPERIMENTAL_PATH |
| 38 | +#endif |
| 39 | + |
| 40 | +template<typename T, typename = void> |
| 41 | +struct is_istreamable : std::false_type |
| 42 | +{}; |
| 43 | +using boost::nowide::detail::void_t; |
| 44 | +template<typename T> |
| 45 | +struct is_istreamable<T, void_t<decltype(std::declval<std::istream&>() >> std::declval<T>())>> : std::true_type |
| 46 | +{}; |
| 47 | + |
| 48 | +template<typename T_Char> |
| 49 | +std::string maybe_narrow(const std::basic_string<T_Char>& s) |
| 50 | +{ |
| 51 | + return boost::nowide::narrow(s); |
| 52 | +} |
| 53 | + |
| 54 | +const std::string& maybe_narrow(const std::string& s) |
| 55 | +{ |
| 56 | + return s; |
| 57 | +} |
| 58 | + |
| 59 | +template<class Path> |
| 60 | +void test_fs_path_io(std::string utf8_name) |
| 61 | +{ |
| 62 | +#if defined(__cpp_lib_quoted_string_io) && __cpp_lib_quoted_string_io >= 201304 |
| 63 | + Path path(boost::nowide::utf::convert_string<typename Path::value_type>(utf8_name)); |
| 64 | + // Get native and UTF-8/narrow name here as the Path ctor may change the string (e.g. slash substitution) |
| 65 | + const auto nativeName = path.native(); |
| 66 | + utf8_name = maybe_narrow(nativeName); |
| 67 | + // Output |
| 68 | + std::ostringstream s, sRef; |
| 69 | + sRef << std::quoted(utf8_name); |
| 70 | + s << boost::nowide::quoted(path); |
| 71 | + TEST_EQ(s.str(), sRef.str()); |
| 72 | + // const |
| 73 | + const Path constPath(path); |
| 74 | + s.str(""); |
| 75 | + s << boost::nowide::quoted(constPath); |
| 76 | + TEST_EQ(s.str(), sRef.str()); |
| 77 | + // Rvalue |
| 78 | + s.str(""); |
| 79 | + s << boost::nowide::quoted(Path(path)); |
| 80 | + TEST_EQ(s.str(), sRef.str()); |
| 81 | + |
| 82 | + // Input |
| 83 | + std::istringstream sIn(sRef.str()); |
| 84 | + Path pathOut; |
| 85 | + static_assert(is_istreamable<decltype(boost::nowide::quoted(pathOut))>::value, "!"); |
| 86 | + sIn >> boost::nowide::quoted(pathOut); |
| 87 | + TEST_EQ(pathOut.native(), nativeName); |
| 88 | + // Can't read into a const path |
| 89 | + static_assert(!is_istreamable<decltype(boost::nowide::quoted(constPath))>::value, "!"); |
| 90 | + // or an Rvalue |
| 91 | + static_assert(!is_istreamable<decltype(boost::nowide::quoted(Path(path)))>::value, "!"); |
| 92 | + |
| 93 | + // Wide stream |
| 94 | + std::wostringstream ws, wsRef; |
| 95 | + wsRef << std::quoted(boost::nowide::widen(utf8_name)); |
| 96 | + ws << boost::nowide::quoted(path); |
| 97 | + TEST_EQ(ws.str(), wsRef.str()); |
| 98 | + std::wistringstream wsIn(wsRef.str()); |
| 99 | + pathOut.clear(); |
| 100 | + wsIn >> boost::nowide::quoted(pathOut); |
| 101 | + TEST_EQ(maybe_narrow(pathOut.native()), utf8_name); |
| 102 | +#else |
| 103 | + (void)utf8_name; // Suppress unused warning |
| 104 | + std::cout << "Skipping tests for boost::nowide::quoted" << std::endl; |
| 105 | +#endif |
| 106 | +} |
21 | 107 |
|
22 | 108 | // coverity[root_function] |
23 | 109 | void test_main(int, char** argv, char**) |
@@ -63,4 +149,15 @@ void test_main(int, char** argv, char**) |
63 | 149 | TEST(test == "Test"); |
64 | 150 | } |
65 | 151 | boost::filesystem::remove(path); |
| 152 | + |
| 153 | + std::cout << "Testing boost::filesystem::path" << std::endl; |
| 154 | + test_fs_path_io<boost::filesystem::path>(utf8_name); |
| 155 | +#ifdef BOOST_NOWIDE_TEST_STD_EXPERIMENTAL_PATH |
| 156 | + std::cout << "Testing std::experimental::filesystem::path" << std::endl; |
| 157 | + test_fs_path_io<std::experimental::filesystem::path>(utf8_name); |
| 158 | +#endif |
| 159 | +#ifdef BOOST_NOWIDE_TEST_STD_PATH |
| 160 | + std::cout << "Testing std::filesystem::path" << std::endl; |
| 161 | + test_fs_path_io<std::filesystem::path>(utf8_name); |
| 162 | +#endif |
66 | 163 | } |
0 commit comments