Commit a1e7d33b by Tom Honermann Committed by Jonathan Wakely

libstdc++: P1423R3 char8_t remediation (1/4)

Decouple constraints for u8path from path constructors

This patch moves helper classes and functions for std::filesystem::path out of
the class definition to a detail namespace so that they are available to the
implementations of std::filesystem::u8path.  Prior to this patch, the SFINAE
constraints for those implementations were specified via delegation to the
overloads of path constructors with a std::locale parameter; it just so
happened that those overloads had the same constraints.  As of P1423R3, u8path
and those overloads no longer have the same constraints, so this dependency
must be broken.

This patch also updates the experimental implementation of the filesystem TS
to add SFINAE constraints to its implementations of u8path.  These functions
were previously unconstrained and marked with a TODO comment.

This patch does not provide any intentional behavioral changes other than the
added constraints to the experimental filesystem TS implementation of u8path.

Alternatives to this refactoring would have been to make the u8path overloads
friends of class path, or to make the helpers public members. Both of those
approaches struck me as less desirable than this approach, though this
approach does require more code changes and will affect implementation detail
portions of mangled names for path constructors and inline member functions
(mostly function template specializations).

2019-11-29  Tom Honermann  <tom@honermann.net>

	Decouple constraints for u8path from path constructors
	* include/bits/fs_path.h: Moved helper utilities out of
	std::filesystem::path into a detail namespace to make them
	available for use by u8path.
	* include/experimental/bits/fs_path.h: Moved helper utilities out
	of std::experimental::filesystem::v1::path into a detail
	namespace to make them available for use by u8path.

From-SVN: r278855
parent 6851de8b
2019-11-29 Tom Honermann <tom@honermann.net>
Decouple constraints for u8path from path constructors
* include/bits/fs_path.h: Moved helper utilities out of
std::filesystem::path into a detail namespace to make them
available for use by u8path.
* include/experimental/bits/fs_path.h: Moved helper utilities out
of std::experimental::filesystem::v1::path into a detail
namespace to make them available for use by u8path.
2019-11-29 Jonathan Wakely <jwakely@redhat.com> 2019-11-29 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/91997 PR libstdc++/91997
......
...@@ -63,9 +63,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -63,9 +63,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @{ * @{
*/ */
/// A filesystem path. class path;
class path
{ /// @cond undocumented
namespace __detail
{
template<typename _CharT> template<typename _CharT>
using __is_encoded_char = __is_one_of<remove_const_t<_CharT>, using __is_encoded_char = __is_one_of<remove_const_t<_CharT>,
char, char,
...@@ -156,6 +158,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -156,6 +158,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
using __value_type_is_char using __value_type_is_char
= std::enable_if_t<std::is_same_v<std::remove_const_t<_Val>, char>>; = std::enable_if_t<std::is_same_v<std::remove_const_t<_Val>, char>>;
} // namespace __detail
/// @endcond
/// A filesystem path.
class path
{
public: public:
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
using value_type = wchar_t; using value_type = wchar_t;
...@@ -193,29 +201,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -193,29 +201,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _Source, template<typename _Source,
typename _Require = _Path<_Source>> typename _Require = __detail::_Path<_Source>>
path(_Source const& __source, format = auto_format) path(_Source const& __source, format = auto_format)
: _M_pathname(_S_convert(_S_range_begin(__source), : _M_pathname(_S_convert(__detail::_S_range_begin(__source),
_S_range_end(__source))) __detail::_S_range_end(__source)))
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _InputIterator, template<typename _InputIterator,
typename _Require = _Path<_InputIterator, _InputIterator>> typename _Require = __detail::_Path<_InputIterator, _InputIterator>>
path(_InputIterator __first, _InputIterator __last, format = auto_format) path(_InputIterator __first, _InputIterator __last, format = auto_format)
: _M_pathname(_S_convert(__first, __last)) : _M_pathname(_S_convert(__first, __last))
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _Source, template<typename _Source,
typename _Require = _Path<_Source>, typename _Require = __detail::_Path<_Source>,
typename _Require2 = __value_type_is_char<_Source>> typename _Require2 = __detail::__value_type_is_char<_Source>>
path(_Source const& __source, const locale& __loc, format = auto_format) path(_Source const& __source, const locale& __loc, format = auto_format)
: _M_pathname(_S_convert_loc(_S_range_begin(__source), : _M_pathname(_S_convert_loc(__detail::_S_range_begin(__source),
_S_range_end(__source), __loc)) __detail::_S_range_end(__source), __loc))
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _InputIterator, template<typename _InputIterator,
typename _Require = _Path<_InputIterator, _InputIterator>, typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
typename _Require2 = __value_type_is_char<_InputIterator>> typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
path(_InputIterator __first, _InputIterator __last, const locale& __loc, path(_InputIterator __first, _InputIterator __last, const locale& __loc,
format = auto_format) format = auto_format)
: _M_pathname(_S_convert_loc(__first, __last, __loc)) : _M_pathname(_S_convert_loc(__first, __last, __loc))
...@@ -231,17 +239,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -231,17 +239,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
path& assign(string_type&& __source); path& assign(string_type&& __source);
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
operator=(_Source const& __source) operator=(_Source const& __source)
{ return *this = path(__source); } { return *this = path(__source); }
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
assign(_Source const& __source) assign(_Source const& __source)
{ return *this = path(__source); } { return *this = path(__source); }
template<typename _InputIterator> template<typename _InputIterator>
_Path<_InputIterator, _InputIterator>& __detail::_Path<_InputIterator, _InputIterator>&
assign(_InputIterator __first, _InputIterator __last) assign(_InputIterator __first, _InputIterator __last)
{ return *this = path(__first, __last); } { return *this = path(__first, __last); }
...@@ -250,23 +258,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -250,23 +258,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
path& operator/=(const path& __p); path& operator/=(const path& __p);
template <class _Source> template <class _Source>
_Path<_Source>& __detail::_Path<_Source>&
operator/=(_Source const& __source) operator/=(_Source const& __source)
{ {
_M_append(_S_convert(_S_range_begin(__source), _S_range_end(__source))); _M_append(_S_convert(__detail::_S_range_begin(__source),
__detail::_S_range_end(__source)));
return *this; return *this;
} }
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
append(_Source const& __source) append(_Source const& __source)
{ {
_M_append(_S_convert(_S_range_begin(__source), _S_range_end(__source))); _M_append(_S_convert(__detail::_S_range_begin(__source),
__detail::_S_range_end(__source)));
return *this; return *this;
} }
template<typename _InputIterator> template<typename _InputIterator>
_Path<_InputIterator, _InputIterator>& __detail::_Path<_InputIterator, _InputIterator>&
append(_InputIterator __first, _InputIterator __last) append(_InputIterator __first, _InputIterator __last)
{ {
_M_append(_S_convert(__first, __last)); _M_append(_S_convert(__first, __last));
...@@ -282,23 +292,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -282,23 +292,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
path& operator+=(basic_string_view<value_type> __x); path& operator+=(basic_string_view<value_type> __x);
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
operator+=(_Source const& __x) { return concat(__x); } operator+=(_Source const& __x) { return concat(__x); }
template<typename _CharT> template<typename _CharT>
_Path<_CharT*, _CharT*>& __detail::_Path<_CharT*, _CharT*>&
operator+=(_CharT __x); operator+=(_CharT __x);
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
concat(_Source const& __x) concat(_Source const& __x)
{ {
_M_concat(_S_convert(_S_range_begin(__x), _S_range_end(__x))); _M_concat(_S_convert(__detail::_S_range_begin(__x),
__detail::_S_range_end(__x)));
return *this; return *this;
} }
template<typename _InputIterator> template<typename _InputIterator>
_Path<_InputIterator, _InputIterator>& __detail::_Path<_InputIterator, _InputIterator>&
concat(_InputIterator __first, _InputIterator __last) concat(_InputIterator __first, _InputIterator __last)
{ {
_M_concat(_S_convert(__first, __last)); _M_concat(_S_convert(__first, __last));
...@@ -496,11 +507,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -496,11 +507,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
struct _Cvt; struct _Cvt;
static basic_string_view<value_type> static basic_string_view<value_type>
_S_convert(value_type* __src, __null_terminated) _S_convert(value_type* __src, __detail::__null_terminated)
{ return __src; } { return __src; }
static basic_string_view<value_type> static basic_string_view<value_type>
_S_convert(const value_type* __src, __null_terminated) _S_convert(const value_type* __src, __detail::__null_terminated)
{ return __src; } { return __src; }
static basic_string_view<value_type> static basic_string_view<value_type>
...@@ -522,7 +533,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -522,7 +533,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
template<typename _InputIterator> template<typename _InputIterator>
static string_type static string_type
_S_convert(_InputIterator __src, __null_terminated) _S_convert(_InputIterator __src, __detail::__null_terminated)
{ {
// Read from iterator into basic_string until a null value is seen: // Read from iterator into basic_string until a null value is seen:
auto __s = _S_string_from_iter(__src); auto __s = _S_string_from_iter(__src);
...@@ -544,7 +555,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -544,7 +555,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
template<typename _InputIterator> template<typename _InputIterator>
static string_type static string_type
_S_convert_loc(_InputIterator __src, __null_terminated, _S_convert_loc(_InputIterator __src, __detail::__null_terminated,
const std::locale& __loc) const std::locale& __loc)
{ {
const std::string __s = _S_string_from_iter(__src); const std::string __s = _S_string_from_iter(__src);
...@@ -657,10 +668,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -657,10 +668,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* *
* @relates std::filesystem::path * @relates std::filesystem::path
*/ */
template<typename _InputIterator> template<typename _InputIterator,
inline auto typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
inline path
u8path(_InputIterator __first, _InputIterator __last) u8path(_InputIterator __first, _InputIterator __last)
-> decltype(filesystem::path(__first, __last, std::locale::classic()))
{ {
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
// XXX This assumes native wide encoding is UTF-16. // XXX This assumes native wide encoding is UTF-16.
...@@ -691,10 +703,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -691,10 +703,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* *
* @relates std::filesystem::path * @relates std::filesystem::path
*/ */
template<typename _Source> template<typename _Source,
inline auto typename _Require = __detail::_Path<_Source>,
typename _Require2 = __detail::__value_type_is_char<_Source>>
inline path
u8path(const _Source& __source) u8path(const _Source& __source)
-> decltype(filesystem::path(__source, std::locale::classic()))
{ {
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
if constexpr (is_convertible_v<const _Source&, std::string_view>) if constexpr (is_convertible_v<const _Source&, std::string_view>)
...@@ -950,7 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -950,7 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
} }
template<typename _CharT> template<typename _CharT>
inline path::_Path<_CharT*, _CharT*>& inline __detail::_Path<_CharT*, _CharT*>&
path::operator+=(_CharT __x) path::operator+=(_CharT __x)
{ {
auto* __addr = std::__addressof(__x); auto* __addr = std::__addressof(__x);
......
...@@ -71,14 +71,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -71,14 +71,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
using std::basic_string_view; using std::basic_string_view;
#endif #endif
/** /** @addtogroup filesystem-ts
* @addtogroup filesystem-ts
* @{ * @{
*/ */
/// A filesystem path. /// @cond undocumented
class path namespace __detail
{ {
template<typename _CharT, template<typename _CharT,
typename _Ch = typename remove_const<_CharT>::type> typename _Ch = typename remove_const<_CharT>::type>
using __is_encoded_char using __is_encoded_char
...@@ -176,6 +175,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -176,6 +175,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
std::is_same<typename std::remove_const<_Val>::type, char>::value std::is_same<typename std::remove_const<_Val>::type, char>::value
>::type; >::type;
} // namespace __detail
/// @endcond
/// A filesystem path.
class path
{
public: public:
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
typedef wchar_t value_type; typedef wchar_t value_type;
...@@ -205,29 +210,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -205,29 +210,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _Source, template<typename _Source,
typename _Require = _Path<_Source>> typename _Require = __detail::_Path<_Source>>
path(_Source const& __source) path(_Source const& __source)
: _M_pathname(_S_convert(_S_range_begin(__source), : _M_pathname(_S_convert(__detail::_S_range_begin(__source),
_S_range_end(__source))) __detail::_S_range_end(__source)))
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _InputIterator, template<typename _InputIterator,
typename _Require = _Path<_InputIterator, _InputIterator>> typename _Require = __detail::_Path<_InputIterator, _InputIterator>>
path(_InputIterator __first, _InputIterator __last) path(_InputIterator __first, _InputIterator __last)
: _M_pathname(_S_convert(__first, __last)) : _M_pathname(_S_convert(__first, __last))
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _Source, template<typename _Source,
typename _Require = _Path<_Source>, typename _Require = __detail::_Path<_Source>,
typename _Require2 = __value_type_is_char<_Source>> typename _Require2 = __detail::__value_type_is_char<_Source>>
path(_Source const& __source, const locale& __loc) path(_Source const& __source, const locale& __loc)
: _M_pathname(_S_convert_loc(_S_range_begin(__source), : _M_pathname(_S_convert_loc(__detail::_S_range_begin(__source),
_S_range_end(__source), __loc)) __detail::_S_range_end(__source), __loc))
{ _M_split_cmpts(); } { _M_split_cmpts(); }
template<typename _InputIterator, template<typename _InputIterator,
typename _Require = _Path<_InputIterator, _InputIterator>, typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
typename _Require2 = __value_type_is_char<_InputIterator>> typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
path(_InputIterator __first, _InputIterator __last, const locale& __loc) path(_InputIterator __first, _InputIterator __last, const locale& __loc)
: _M_pathname(_S_convert_loc(__first, __last, __loc)) : _M_pathname(_S_convert_loc(__first, __last, __loc))
{ _M_split_cmpts(); } { _M_split_cmpts(); }
...@@ -242,17 +247,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -242,17 +247,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
path& assign(string_type&& __source); path& assign(string_type&& __source);
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
operator=(_Source const& __source) operator=(_Source const& __source)
{ return *this = path(__source); } { return *this = path(__source); }
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
assign(_Source const& __source) assign(_Source const& __source)
{ return *this = path(__source); } { return *this = path(__source); }
template<typename _InputIterator> template<typename _InputIterator>
_Path<_InputIterator, _InputIterator>& __detail::_Path<_InputIterator, _InputIterator>&
assign(_InputIterator __first, _InputIterator __last) assign(_InputIterator __first, _InputIterator __last)
{ return *this = path(__first, __last); } { return *this = path(__first, __last); }
...@@ -261,20 +266,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -261,20 +266,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
path& operator/=(const path& __p) { return _M_append(__p._M_pathname); } path& operator/=(const path& __p) { return _M_append(__p._M_pathname); }
template <class _Source> template <class _Source>
_Path<_Source>& __detail::_Path<_Source>&
operator/=(_Source const& __source) operator/=(_Source const& __source)
{ return append(__source); } { return append(__source); }
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
append(_Source const& __source) append(_Source const& __source)
{ {
return _M_append(_S_convert(_S_range_begin(__source), return _M_append(_S_convert(__detail::_S_range_begin(__source),
_S_range_end(__source))); __detail::_S_range_end(__source)));
} }
template<typename _InputIterator> template<typename _InputIterator>
_Path<_InputIterator, _InputIterator>& __detail::_Path<_InputIterator, _InputIterator>&
append(_InputIterator __first, _InputIterator __last) append(_InputIterator __first, _InputIterator __last)
{ return _M_append(_S_convert(__first, __last)); } { return _M_append(_S_convert(__first, __last)); }
...@@ -289,20 +294,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -289,20 +294,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
#endif #endif
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
operator+=(_Source const& __x) { return concat(__x); } operator+=(_Source const& __x) { return concat(__x); }
template<typename _CharT> template<typename _CharT>
_Path<_CharT*, _CharT*>& __detail::_Path<_CharT*, _CharT*>&
operator+=(_CharT __x); operator+=(_CharT __x);
template<typename _Source> template<typename _Source>
_Path<_Source>& __detail::_Path<_Source>&
concat(_Source const& __x) concat(_Source const& __x)
{ return *this += _S_convert(_S_range_begin(__x), _S_range_end(__x)); } {
return *this += _S_convert(__detail::_S_range_begin(__x),
__detail::_S_range_end(__x));
}
template<typename _InputIterator> template<typename _InputIterator>
_Path<_InputIterator, _InputIterator>& __detail::_Path<_InputIterator, _InputIterator>&
concat(_InputIterator __first, _InputIterator __last) concat(_InputIterator __first, _InputIterator __last)
{ return *this += _S_convert(__first, __last); } { return *this += _S_convert(__first, __last); }
...@@ -446,11 +454,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -446,11 +454,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
struct _Cvt; struct _Cvt;
static string_type static string_type
_S_convert(value_type* __src, __null_terminated) _S_convert(value_type* __src, __detail::__null_terminated)
{ return string_type(__src); } { return string_type(__src); }
static string_type static string_type
_S_convert(const value_type* __src, __null_terminated) _S_convert(const value_type* __src, __detail::__null_terminated)
{ return string_type(__src); } { return string_type(__src); }
template<typename _Iter> template<typename _Iter>
...@@ -464,7 +472,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -464,7 +472,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
template<typename _InputIterator> template<typename _InputIterator>
static string_type static string_type
_S_convert(_InputIterator __src, __null_terminated) _S_convert(_InputIterator __src, __detail::__null_terminated)
{ {
auto __s = _S_string_from_iter(__src); auto __s = _S_string_from_iter(__src);
return _S_convert(__s.c_str(), __s.c_str() + __s.size()); return _S_convert(__s.c_str(), __s.c_str() + __s.size());
...@@ -484,7 +492,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -484,7 +492,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
template<typename _InputIterator> template<typename _InputIterator>
static string_type static string_type
_S_convert_loc(_InputIterator __src, __null_terminated, _S_convert_loc(_InputIterator __src, __detail::__null_terminated,
const std::locale& __loc) const std::locale& __loc)
{ {
const std::string __s = _S_string_from_iter(__src); const std::string __s = _S_string_from_iter(__src);
...@@ -580,8 +588,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -580,8 +588,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
} }
/// Create a path from a UTF-8-encoded sequence of char /// Create a path from a UTF-8-encoded sequence of char
// TODO constrain with _Path<InputIterator, InputIterator> and __value_type_is_char template<typename _InputIterator,
template<typename _InputIterator> typename _Require = __detail::_Path<_InputIterator, _InputIterator>,
typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
inline path inline path
u8path(_InputIterator __first, _InputIterator __last) u8path(_InputIterator __first, _InputIterator __last)
{ {
...@@ -602,8 +611,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -602,8 +611,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
} }
/// Create a path from a UTF-8-encoded sequence of char /// Create a path from a UTF-8-encoded sequence of char
// TODO constrain with _Path<Source> and __value_type_is_char template<typename _Source,
template<typename _Source> typename _Require = __detail::_Path<_Source>,
typename _Require2 = __detail::__value_type_is_char<_Source>>
inline path inline path
u8path(const _Source& __source) u8path(const _Source& __source)
{ {
...@@ -872,7 +882,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -872,7 +882,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
#endif #endif
template<typename _CharT> template<typename _CharT>
inline path::_Path<_CharT*, _CharT*>& inline __detail::_Path<_CharT*, _CharT*>&
path::operator+=(_CharT __x) path::operator+=(_CharT __x)
{ {
auto* __addr = std::__addressof(__x); auto* __addr = std::__addressof(__x);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment