Boost.Nowide
quoted.hpp
1//
2// Copyright (c) 2023 Alexander Grund
3//
4// Distributed under the Boost Software License, Version 1.0.
5// https://www.boost.org/LICENSE_1_0.txt
6
7#ifndef BOOST_NOWIDE_QUOTED_HPP_INCLUDED
8#define BOOST_NOWIDE_QUOTED_HPP_INCLUDED
9
11#include <boost/nowide/detail/is_path.hpp>
12#include <boost/nowide/utf/convert.hpp>
13#include <iomanip>
14#include <istream>
15#include <ostream>
16#include <type_traits>
17
18#if defined(__cpp_lib_quoted_string_io) && __cpp_lib_quoted_string_io >= 201304
19
20namespace boost {
21namespace nowide {
23 namespace detail {
24 template<class Path>
25 struct quoted;
26 template<typename T>
27 using remove_cvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
28
29 } // namespace detail
31
42 template<class Path>
43#ifdef BOOST_NOWIDE_DOXYGEN
44 unspecified_type
45#else
46 detail::enable_if_path_t<detail::remove_cvref_t<Path>, detail::quoted<Path&>>
47#endif
48 quoted(Path& path)
49 {
50 return {path};
51 }
52
54 // Same but for const-refs and r-values
55 template<class Path>
56 detail::enable_if_path_t<detail::remove_cvref_t<Path>, detail::quoted<const Path&>> quoted(const Path& path)
57 {
58 return {path};
59 }
60
61 namespace detail {
62 template<typename CharOut,
63 typename CharIn,
64 typename = typename std::enable_if<!std::is_same<CharOut, CharIn>::value>::type>
65 std::basic_string<CharOut> maybe_convert_string(const std::basic_string<CharIn>& s)
66 {
67 return utf::convert_string<CharOut>(s);
68 }
69 template<typename Char>
70 const std::basic_string<Char>& maybe_convert_string(const std::basic_string<Char>& s)
71 {
72 return s;
73 }
74
75 template<typename T>
76 using requires_non_const =
77 typename std::enable_if<!std::is_const<typename std::remove_reference<T>::type>::value>::type;
78
79 template<class Path>
80 struct quoted
81 {
82 Path value;
83 template<typename CharType>
84 friend std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const quoted& path)
85 {
86 return out << std::quoted(maybe_convert_string<CharType>(path.value.native()));
87 }
88
89 template<typename CharType, class Path2 = Path, typename = requires_non_const<Path2>>
90 friend std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const quoted& path)
91 {
92 std::basic_string<CharType> value;
93 using PlainPath = remove_cvref_t<Path>;
94 if(in >> std::quoted(value))
95 path.value = PlainPath(maybe_convert_string<typename PlainPath::value_type>(value));
96 return in;
97 }
98 };
99
100 } // namespace detail
102} // namespace nowide
103} // namespace boost
104
105#elif defined(BOOST_PRAGMA_MESSAGE)
106BOOST_PRAGMA_MESSAGE("To use boost::nowide::quoted at least C++14 is required.")
107#endif
108
109#endif