Skip to content

Commit

Permalink
Improved string_view support
Browse files Browse the repository at this point in the history
  • Loading branch information
phprus committed Feb 16, 2021
1 parent daf0e7d commit f6a972f
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 21 deletions.
74 changes: 61 additions & 13 deletions include/ghc/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,23 @@
#endif
#endif // GHC_EXPAND_IMPL

// After standard library includes.
// Standard library support for std::string_view.
#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 4000) && (__cplusplus >= 201402)
#define GHC_HAS_STD_STRING_VIEW
#elif defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE >= 7) && (__cplusplus >= 201703)
#define GHC_HAS_STD_STRING_VIEW
#elif defined(_MSC_VER) && (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
#define GHC_HAS_STD_STRING_VIEW
#endif

// Standard library support for std::experimental::string_view.
#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 3700 && _LIBCPP_VERSION < 7000) && (__cplusplus >= 201402)
#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW
#elif defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)) && (__cplusplus >= 201402)
#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW
#endif

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Behaviour Switches (see README.md, should match the config in test/filesystem_test.cpp):
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down Expand Up @@ -277,6 +294,16 @@
namespace ghc {
namespace filesystem {

#if defined(GHC_HAS_USER_STRING_VIEW)
#define GHC_WITH_STRING_VIEW
#elif defined(GHC_HAS_STD_STRING_VIEW)
#define GHC_WITH_STRING_VIEW
using std::basic_string_view;
#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
#define GHC_WITH_STRING_VIEW
using std::experimental::basic_string_view;
#endif

// temporary existing exception type for yet unimplemented parts
class GHC_FS_API_CLASS not_implemented_exception : public std::logic_error
{
Expand Down Expand Up @@ -354,9 +381,13 @@ class GHC_FS_API_CLASS path
struct _is_basic_string<std::basic_string<CharT, std::char_traits<CharT>, std::allocator<CharT>>> : std::true_type
{
};
#ifdef __cpp_lib_string_view
#ifdef GHC_WITH_STRING_VIEW
template <class CharT, class Traits>
struct _is_basic_string<basic_string_view<CharT, Traits>> : std::true_type
{
};
template <class CharT>
struct _is_basic_string<std::basic_string_view<CharT>> : std::true_type
struct _is_basic_string<basic_string_view<CharT, std::char_traits<CharT>>> : std::true_type
{
};
#endif
Expand Down Expand Up @@ -417,8 +448,8 @@ class GHC_FS_API_CLASS path
// 30.10.8.4.4 concatenation
path& operator+=(const path& x);
path& operator+=(const string_type& x);
#ifdef __cpp_lib_string_view
path& operator+=(std::basic_string_view<value_type> x);
#ifdef GHC_WITH_STRING_VIEW
path& operator+=(basic_string_view<value_type> x);
#endif
path& operator+=(const value_type* x);
path& operator+=(value_type x);
Expand Down Expand Up @@ -471,8 +502,8 @@ class GHC_FS_API_CLASS path
// 30.10.8.4.8 compare
int compare(const path& p) const noexcept;
int compare(const string_type& s) const;
#ifdef __cpp_lib_string_view
int compare(std::basic_string_view<value_type> s) const;
#ifdef GHC_WITH_STRING_VIEW
int compare(basic_string_view<value_type> s) const;
#endif
int compare(const value_type* s) const;

Expand Down Expand Up @@ -1521,8 +1552,8 @@ inline StringType fromUtf8(const Utf8String& utf8String, const typename StringTy
template <class StringType, typename charT, std::size_t N>
inline StringType fromUtf8(const charT (&utf8String)[N])
{
#ifdef __cpp_lib_string_view
return fromUtf8<StringType>(std::basic_string_view<charT>(utf8String, N - 1));
#ifdef GHC_WITH_STRING_VIEW
return fromUtf8<StringType>(basic_string_view<charT>(utf8String, N - 1));
#else
return fromUtf8<StringType>(std::basic_string<charT>(utf8String, N - 1));
#endif
Expand Down Expand Up @@ -1576,7 +1607,11 @@ inline std::string toUtf8(const strT& unicodeString)
template <typename charT>
inline std::string toUtf8(const charT* unicodeString)
{
#ifdef GHC_WITH_STRING_VIEW
return toUtf8(basic_string_view<charT, std::char_traits<charT>>(unicodeString));
#else
return toUtf8(std::basic_string<charT, std::char_traits<charT>>(unicodeString));
#endif
}

#ifdef GHC_USE_WCHAR_T
Expand Down Expand Up @@ -1622,7 +1657,11 @@ inline std::wstring toWChar(const strT& unicodeString)
template <typename charT>
inline std::wstring toWChar(const charT* unicodeString)
{
#ifdef GHC_WITH_STRING_VIEW
return toWChar(basic_string_view<charT, std::char_traits<charT>>(unicodeString));
#else
return toWChar(std::basic_string<charT, std::char_traits<charT>>(unicodeString));
#endif
}
#endif // GHC_USE_WCHAR_T

Expand Down Expand Up @@ -2464,16 +2503,21 @@ GHC_INLINE path& path::operator+=(const string_type& x)
return concat(x);
}

#ifdef __cpp_lib_string_view
GHC_INLINE path& path::operator+=(std::basic_string_view<value_type> x)
#ifdef GHC_WITH_STRING_VIEW
GHC_INLINE path& path::operator+=(basic_string_view<value_type> x)
{
return concat(x);
}
#endif

GHC_INLINE path& path::operator+=(const value_type* x)
{
return concat(string_type(x));
#ifdef GHC_WITH_STRING_VIEW
basic_string_view<value_type> part(x);
#else
string_type part(x);
#endif
return concat(part);
}

GHC_INLINE path& path::operator+=(value_type x)
Expand Down Expand Up @@ -2501,7 +2545,11 @@ inline path::path_from_string<Source>& path::operator+=(const Source& x)
template <class EcharT>
inline path::path_type_EcharT<EcharT>& path::operator+=(EcharT x)
{
#ifdef GHC_WITH_STRING_VIEW
basic_string_view<EcharT> part(&x, 1);
#else
std::basic_string<EcharT> part(1, x);
#endif
concat(part);
return *this;
}
Expand Down Expand Up @@ -2799,8 +2847,8 @@ GHC_INLINE int path::compare(const string_type& s) const
return compare(path(s));
}

#ifdef __cpp_lib_string_view
GHC_INLINE int path::compare(std::basic_string_view<value_type> s) const
#ifdef GHC_WITH_STRING_VIEW
GHC_INLINE int path::compare(basic_string_view<value_type> s) const
{
return compare(path(s));
}
Expand Down
35 changes: 27 additions & 8 deletions test/filesystem_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ using fstream = ghc::filesystem::fstream;
} // namespace fs
#endif

#if defined(GHC_HAS_STD_STRING_VIEW)
#include <string_view>
#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
#include <experimental/string_view>
#endif

#if defined(WIN32) || defined(_WIN32)
#include <windows.h>
#else
Expand Down Expand Up @@ -2740,31 +2746,44 @@ TEST_CASE("30.10.15.39 weakly_canonical", "[filesystem][operations][fs.op.weakly

TEST_CASE("std::string_view support", "[filesystem][fs.string_view]")
{
#if __cpp_lib_string_view
#if defined(GHC_HAS_STD_STRING_VIEW) || defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)

#if defined(GHC_HAS_STD_STRING_VIEW)
using namespace std::literals;
using string_view = std::string_view;
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
using wstring_view = std::wstring_view;
#endif
#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
using string_view = std::experimental::string_view;
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
using wstring_view = std::experimental::wstring_view;
#endif
#endif

{
std::string p("foo/bar");
std::string_view sv(p);
string_view sv(p);
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
fs::path p2("fo");
p2 += std::string_view("o");
p2 += string_view("o");
CHECK(p2 == "foo");
CHECK(p2.compare(std::string_view("foo")) == 0);
CHECK(p2.compare(string_view("foo")) == 0);
}
{
auto p = fs::path{"XYZ"};
p /= std::string_view("Appendix");
p /= string_view("Appendix");
CHECK(p == "XYZ/Appendix");
}
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
{
std::wstring p(L"foo/bar");
std::wstring_view sv(p);
wstring_view sv(p);
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
fs::path p2(L"fo");
p2 += std::wstring_view(L"o");
p2 += wstring_view(L"o");
CHECK(p2 == "foo");
CHECK(p2.compare(std::wstring_view(L"foo")) == 0);
CHECK(p2.compare(wstring_view(L"foo")) == 0);
}
#endif

Expand Down

0 comments on commit f6a972f

Please sign in to comment.