diff --git a/doc/release_history.html b/doc/release_history.html
index 74f0d06..1e72994 100644
--- a/doc/release_history.html
+++ b/doc/release_history.html
@@ -39,6 +39,11 @@
+
1.82.0
+
+ - Fixed compilation errors that could have been caused by
path
conversion constructors being too permissive on the accepted arguments. (#273)
+
+
1.81.0
- Deprecated:
path
construction, assignment and appending from containers of characters, such as std::vector<char>
or std::list<wchar_t>
, is deprecated in v3 and removed in v4. Please use string types or iterators instead.
diff --git a/include/boost/filesystem/detail/path_traits.hpp b/include/boost/filesystem/detail/path_traits.hpp
index 0840c1e..5cbdf2c 100644
--- a/include/boost/filesystem/detail/path_traits.hpp
+++ b/include/boost/filesystem/detail/path_traits.hpp
@@ -398,37 +398,37 @@ void convert(const wchar_t* from, const wchar_t* from_end, std::string& to, cons
// Source dispatch -----------------------------------------------------------------//
template< typename Source, typename Callback >
-inline void dispatch(Source const& source, Callback cb, const codecvt_type* cvt = NULL);
+typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt = NULL);
template< typename Callback >
-BOOST_FORCEINLINE void dispatch(const char* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(const char* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag)
{
- cb(source, source + std::strlen(source), cvt);
+ return cb(source, source + std::strlen(source), cvt);
}
template< typename Callback >
-BOOST_FORCEINLINE void dispatch(const wchar_t* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(const wchar_t* source, Callback cb, const codecvt_type* cvt, ntcts_type_tag)
{
- cb(source, source + std::wcslen(source), cvt);
+ return cb(source, source + std::wcslen(source), cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch(Source const& source, Callback cb, const codecvt_type* cvt, string_class_tag)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt, string_class_tag)
{
- cb(source.data(), source.data() + source.size(), cvt);
+ return cb(source.data(), source.data() + source.size(), cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch(Source const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
{
std::basic_string< typename Source::value_type > src(source.begin(), source.end());
- cb(src.data(), src.data() + src.size(), cvt);
+ return cb(src.data(), src.data() + src.size(), cvt);
}
#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
template< typename Callback >
-BOOST_FORCEINLINE void dispatch(std::vector< char > const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(std::vector< char > const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
{
const char* data = NULL, *data_end = NULL;
if (!source.empty())
@@ -436,11 +436,11 @@ BOOST_FORCEINLINE void dispatch(std::vector< char > const& source, Callback cb,
data = &source[0];
data_end = data + source.size();
}
- cb(data, data_end, cvt);
+ return cb(data, data_end, cvt);
}
template< typename Callback >
-BOOST_FORCEINLINE void dispatch(std::vector< wchar_t > const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(std::vector< wchar_t > const& source, Callback cb, const codecvt_type* cvt, range_type_tag)
{
const wchar_t* data = NULL, *data_end = NULL;
if (!source.empty())
@@ -448,19 +448,19 @@ BOOST_FORCEINLINE void dispatch(std::vector< wchar_t > const& source, Callback c
data = &source[0];
data_end = data + source.size();
}
- cb(data, data_end, cvt);
+ return cb(data, data_end, cvt);
}
#endif // !defined(BOOST_FILESYSTEM_NO_DEPRECATED) && BOOST_FILESYSTEM_VERSION < 4
// Defined in directory.hpp to avoid circular header dependencies
template< typename Callback >
-void dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag);
+typename Callback::result_type dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag);
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch(Source const& source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(Source const& source, Callback cb, const codecvt_type* cvt)
{
- path_traits::dispatch(source, cb, cvt,
+ return path_traits::dispatch(source, cb, cvt,
typename path_traits::path_source_traits< typename boost::remove_cv< Source >::type >::tag_type());
}
@@ -552,35 +552,35 @@ struct make_dependent
};
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl(const char* source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const char* source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< const char*, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl(const wchar_t* source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(const wchar_t* source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< const wchar_t*, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl(std::string const& source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string const& source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< std::string, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl(std::wstring const& source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring const& source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< std::wstring, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
(
boost::container::basic_string< char, std::char_traits< char >, void > const& source,
Callback cb,
@@ -588,11 +588,11 @@ BOOST_FORCEINLINE void dispatch_convertible_impl
)
{
typedef typename path_traits::make_dependent< boost::container::basic_string< char, std::char_traits< char >, void >, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
(
boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void > const& source,
Callback cb,
@@ -600,11 +600,11 @@ BOOST_FORCEINLINE void dispatch_convertible_impl
)
{
typedef typename path_traits::make_dependent< boost::container::basic_string< wchar_t, std::char_traits< wchar_t >, void >, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
(
boost::basic_string_view< char, std::char_traits< char > > const& source,
Callback cb,
@@ -612,11 +612,11 @@ BOOST_FORCEINLINE void dispatch_convertible_impl
)
{
typedef typename path_traits::make_dependent< boost::basic_string_view< char, std::char_traits< char > >, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl
(
boost::basic_string_view< wchar_t, std::char_traits< wchar_t > > const& source,
Callback cb,
@@ -624,7 +624,7 @@ BOOST_FORCEINLINE void dispatch_convertible_impl
)
{
typedef typename path_traits::make_dependent< boost::basic_string_view< wchar_t, std::char_traits< wchar_t > >, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
#if !defined(BOOST_FILESYSTEM_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
@@ -632,60 +632,62 @@ BOOST_FORCEINLINE void dispatch_convertible_impl
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
#endif // !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL)
{
typedef typename boost::remove_cv< Source >::type source_t;
- path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
+ return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
}
#else // !defined(BOOST_FILESYSTEM_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_sv_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::string_view const& source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< std::string_view, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
-BOOST_FORCEINLINE void dispatch_convertible_sv_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
+BOOST_FORCEINLINE typename Callback::result_type dispatch_convertible_sv_impl(std::wstring_view const& source, Callback cb, const codecvt_type* cvt)
{
typedef typename path_traits::make_dependent< std::wstring_view, Source >::type source_t;
- path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
+ return path_traits::dispatch(static_cast< source_t const& >(source), cb, cvt);
}
template< typename Source, typename Callback >
BOOST_FORCEINLINE typename boost::disable_if_c<
- is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value
+ is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value,
+ typename Callback::result_type
>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL)
{
typedef typename boost::remove_cv< Source >::type source_t;
- path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
+ return path_traits::dispatch_convertible_impl< source_t >(source, cb, cvt);
}
template< typename Source, typename Callback >
BOOST_FORCEINLINE typename boost::enable_if_c<
- is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value
+ is_convertible_to_std_string_view< typename boost::remove_cv< Source >::type >::value,
+ typename Callback::result_type
>::type dispatch_convertible(Source const& source, Callback cb, const codecvt_type* cvt = NULL)
{
typedef typename boost::remove_cv< Source >::type source_t;
- path_traits::dispatch_convertible_sv_impl< source_t >(source, cb, cvt);
+ return path_traits::dispatch_convertible_sv_impl< source_t >(source, cb, cvt);
}
#endif // !defined(BOOST_FILESYSTEM_CXX23_STRING_VIEW_HAS_IMPLICIT_RANGE_CTOR)
diff --git a/include/boost/filesystem/directory.hpp b/include/boost/filesystem/directory.hpp
index c499006..8990f2a 100644
--- a/include/boost/filesystem/directory.hpp
+++ b/include/boost/filesystem/directory.hpp
@@ -174,10 +174,10 @@ namespace path_traits {
// Dispatch function for integration with path class
template< typename Callback >
-BOOST_FORCEINLINE void dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag)
+BOOST_FORCEINLINE typename Callback::result_type dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag)
{
boost::filesystem::path::string_type const& source = de.path().native();
- cb(source.data(), source.data() + source.size(), cvt);
+ return cb(source.data(), source.data() + source.size(), cvt);
}
} // namespace path_traits
diff --git a/include/boost/filesystem/path.hpp b/include/boost/filesystem/path.hpp
index fe29a9b..07f05da 100644
--- a/include/boost/filesystem/path.hpp
+++ b/include/boost/filesystem/path.hpp
@@ -227,6 +227,35 @@ private:
}
};
+ //! Path comparison operation
+ class compare_op;
+ friend class compare_op;
+ class compare_op
+ {
+ private:
+ path const& m_self;
+
+ public:
+ typedef int result_type;
+
+ explicit compare_op(path const& self) BOOST_NOEXCEPT : m_self(self) {}
+
+ BOOST_FORCEINLINE result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = NULL) const
+ {
+ return m_self.compare(path(source, source_end));
+ }
+
+ template< typename OtherChar >
+ BOOST_FORCEINLINE result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = NULL) const
+ {
+ path src;
+ detail::path_traits::convert(source, source_end, src.m_pathname, cvt);
+ return m_self.compare(src);
+ }
+ };
+
+ struct sfinae_helper;
+
public:
class iterator;
friend class iterator;
@@ -255,10 +284,7 @@ public:
typename Source,
typename = typename boost::enable_if_c<
boost::conjunction<
- boost::disjunction<
- detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
- detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >
- >,
+ detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > >
>::value
>::type
@@ -268,10 +294,7 @@ public:
template< typename Source >
path(Source const& source, typename boost::enable_if_c<
boost::conjunction<
- boost::disjunction<
- detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
- detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >
- >,
+ detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > >
>::value
>::type* = NULL)
@@ -285,23 +308,17 @@ public:
typename Source,
typename = typename boost::enable_if_c<
boost::conjunction<
- boost::disjunction<
- detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
- detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >
- >,
+ detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > >
>::value
>::type
>
- path(Source const& source, codecvt_type const& cvt)
+ explicit path(Source const& source, codecvt_type const& cvt)
#else
template< typename Source >
- path(Source const& source, codecvt_type const& cvt, typename boost::enable_if_c<
+ explicit path(Source const& source, codecvt_type const& cvt, typename boost::enable_if_c<
boost::conjunction<
- boost::disjunction<
- detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
- detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >
- >,
+ detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
boost::negation< detail::path_traits::is_native_path_source< typename boost::remove_cv< Source >::type > >
>::value
>::type* = NULL)
@@ -568,10 +585,7 @@ public:
template< typename Source >
typename boost::enable_if_c<
- boost::disjunction<
- detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
- detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >
- >::value,
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
path&
>::type operator+=(Source const& source)
{
@@ -710,10 +724,7 @@ public:
template< typename Source >
BOOST_FORCEINLINE typename boost::enable_if_c<
- boost::disjunction<
- detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
- detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >
- >::value,
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
path&
>::type operator/=(Source const& source)
{
@@ -947,6 +958,48 @@ public:
return BOOST_FILESYSTEM_VERSIONED_SYM(compare)(p);
}
+ template< typename Source >
+ BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value,
+ int
+ >::type compare(Source const& source) const
+ {
+ return detail::path_traits::dispatch(source, compare_op(*this));
+ }
+
+ template< typename Source >
+ BOOST_FORCEINLINE typename boost::enable_if_c<
+ boost::conjunction<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >,
+ boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > >
+ >::value,
+ int
+ >::type compare(Source const& source) const
+ {
+ return detail::path_traits::dispatch_convertible(source, compare_op(*this));
+ }
+
+ template< typename Source >
+ BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >::value,
+ int
+ >::type compare(Source const& source, codecvt_type const& cvt) const
+ {
+ return detail::path_traits::dispatch(source, compare_op(*this), &cvt);
+ }
+
+ template< typename Source >
+ BOOST_FORCEINLINE typename boost::enable_if_c<
+ boost::conjunction<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >,
+ boost::negation< detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type > >
+ >::value,
+ int
+ >::type compare(Source const& source, codecvt_type const& cvt) const
+ {
+ return detail::path_traits::dispatch_convertible(source, compare_op(*this), &cvt);
+ }
+
// ----- decomposition -----
path root_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + find_root_path_size()); }
@@ -1239,31 +1292,140 @@ BOOST_FORCEINLINE bool operator==(path const& lhs, path const& rhs)
return lhs.compare(rhs) == 0;
}
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator==(path const& lhs, Source const& rhs)
+{
+ return lhs.compare(rhs) == 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator==(Source const& lhs, path const& rhs)
+{
+ return rhs.compare(lhs) == 0;
+}
+
BOOST_FORCEINLINE bool operator!=(path const& lhs, path const& rhs)
{
return lhs.compare(rhs) != 0;
}
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator!=(path const& lhs, Source const& rhs)
+{
+ return lhs.compare(rhs) != 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator!=(Source const& lhs, path const& rhs)
+{
+ return rhs.compare(lhs) != 0;
+}
+
BOOST_FORCEINLINE bool operator<(path const& lhs, path const& rhs)
{
return lhs.compare(rhs) < 0;
}
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator<(path const& lhs, Source const& rhs)
+{
+ return lhs.compare(rhs) < 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator<(Source const& lhs, path const& rhs)
+{
+ return rhs.compare(lhs) > 0;
+}
+
BOOST_FORCEINLINE bool operator<=(path const& lhs, path const& rhs)
{
- return !(rhs < lhs);
+ return lhs.compare(rhs) <= 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator<=(path const& lhs, Source const& rhs)
+{
+ return lhs.compare(rhs) <= 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator<=(Source const& lhs, path const& rhs)
+{
+ return rhs.compare(lhs) >= 0;
}
BOOST_FORCEINLINE bool operator>(path const& lhs, path const& rhs)
{
- return rhs < lhs;
+ return lhs.compare(rhs) > 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator>(path const& lhs, Source const& rhs)
+{
+ return lhs.compare(rhs) > 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator>(Source const& lhs, path const& rhs)
+{
+ return rhs.compare(lhs) < 0;
}
BOOST_FORCEINLINE bool operator>=(path const& lhs, path const& rhs)
{
- return !(lhs < rhs);
+ return lhs.compare(rhs) >= 0;
}
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator>=(path const& lhs, Source const& rhs)
+{
+ return lhs.compare(rhs) >= 0;
+}
+
+template< typename Source >
+BOOST_FORCEINLINE typename boost::enable_if_c<
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
+ bool
+>::type operator>=(Source const& lhs, path const& rhs)
+{
+ return rhs.compare(lhs) <= 0;
+}
+
+
// Note: Declared as a template to delay binding to Boost.ContainerHash functions and make the dependency optional
template< typename T >
inline typename boost::enable_if_c<
@@ -1294,10 +1456,7 @@ BOOST_FORCEINLINE path operator/(path lhs, path const& rhs)
template< typename Source >
BOOST_FORCEINLINE typename boost::enable_if_c<
- boost::disjunction<
- detail::path_traits::is_path_source< typename boost::remove_cv< Source >::type >,
- detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >
- >::value,
+ detail::path_traits::is_convertible_to_path_source< typename boost::remove_cv< Source >::type >::value,
path
>::type operator/(path lhs, Source const& rhs)
{
diff --git a/test/path_test.cpp b/test/path_test.cpp
index ce1a36a..f6be318 100644
--- a/test/path_test.cpp
+++ b/test/path_test.cpp
@@ -187,6 +187,15 @@ typedef basic_custom_string< char > custom_string;
typedef basic_custom_string< wchar_t > wcustom_string;
typedef basic_custom_string< fs::path::value_type > pcustom_string;
+inline std::string const& to_string(std::string const& s)
+{
+ return s;
+}
+
+inline std::string to_string(fs::path const& p)
+{
+ return p.string();
+}
std::string platform(BOOST_PLATFORM);
@@ -2102,6 +2111,11 @@ void construction_tests()
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
PATH_TEST_EQ(std::string_view("foo"), "foo");
#endif
+
+ // Check that path constructors don't cause ambiguity for to_string calls
+ // https://github.com/boostorg/filesystem/issues/273
+ custom_string c("test");
+ BOOST_TEST_EQ(to_string(c), std::string("test"));
}
// append_tests --------------------------------------------------------------------//