Skip to content

Commit 95a1816

Browse files
committed
Fix up spaceship operators on path_view to match P1030R7.
1 parent e7b0ca8 commit 95a1816

File tree

2 files changed

+188
-44
lines changed

2 files changed

+188
-44
lines changed

include/llfio/revision.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
2-
#define LLFIO_PREVIOUS_COMMIT_REF dc08ec4b231900c4236a0a6a493b6a30d91ae81a
3-
#define LLFIO_PREVIOUS_COMMIT_DATE "2024-08-22 13:23:33 +00:00"
4-
#define LLFIO_PREVIOUS_COMMIT_UNIQUE dc08ec4b
2+
#define LLFIO_PREVIOUS_COMMIT_REF e7b0ca825515759b49176417c4ae1aa0d5b8a890
3+
#define LLFIO_PREVIOUS_COMMIT_DATE "2024-08-23 11:19:37 +00:00"
4+
#define LLFIO_PREVIOUS_COMMIT_UNIQUE e7b0ca82

include/llfio/v2.0/path_view.hpp

Lines changed: 185 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* A view of a path to something
2-
(C) 2017-2022 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
2+
(C) 2017-2024 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
33
File Created: Jul 2017
44
55
@@ -219,15 +219,20 @@ namespace detail
219219
class path_view;
220220
class path_view_component;
221221
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator==(path_view_component x, path_view_component y) noexcept;
222+
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator==(path_view x, path_view y) noexcept;
223+
#if __cplusplus >= 202000L || _HAS_CXX20
224+
inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view_component x, path_view_component y) noexcept;
225+
inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view x, path_view y) noexcept;
226+
#else
222227
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator!=(path_view_component x, path_view_component y) noexcept;
223228
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator<(path_view_component x, path_view_component y) noexcept;
229+
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator!=(path_view x, path_view y) noexcept;
230+
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator<(path_view x, path_view y) noexcept;
231+
#endif
224232
inline LLFIO_PATH_VIEW_CONSTEXPR size_t hash_value(path_view_component x) noexcept;
225233
template <class F> inline LLFIO_PATH_VIEW_CONSTEXPR auto visit(path_view_component view, F &&f);
226234
template <class F> inline LLFIO_PATH_VIEW_CONSTEXPR auto visit(F &&f, path_view_component view);
227235
inline std::ostream &operator<<(std::ostream &s, const path_view_component &v);
228-
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator==(path_view x, path_view y) noexcept;
229-
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator!=(path_view x, path_view y) noexcept;
230-
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator<(path_view x, path_view y) noexcept;
231236
inline LLFIO_PATH_VIEW_CONSTEXPR size_t hash_value(path_view x) noexcept;
232237

233238
/*! \class path_view_component
@@ -238,21 +243,11 @@ class LLFIO_DECL path_view_component
238243
friend class path_view;
239244
friend class detail::path_view_iterator;
240245
friend inline LLFIO_PATH_VIEW_CONSTEXPR bool LLFIO_V2_NAMESPACE::operator==(path_view_component x, path_view_component y) noexcept;
246+
#if __cplusplus >= 202000L || _HAS_CXX20
247+
friend inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view_component x, path_view_component y) noexcept;
248+
#else
241249
friend inline LLFIO_PATH_VIEW_CONSTEXPR bool LLFIO_V2_NAMESPACE::operator!=(path_view_component x, path_view_component y) noexcept;
242250
friend inline LLFIO_PATH_VIEW_CONSTEXPR bool LLFIO_V2_NAMESPACE::operator<(path_view_component x, path_view_component y) noexcept;
243-
#if __cplusplus >= 202000L || _HAS_CXX20
244-
friend inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view_component x, path_view_component y) noexcept
245-
{
246-
if(x == y)
247-
{
248-
return std::strong_ordering::equal;
249-
}
250-
if(x < y)
251-
{
252-
return std::strong_ordering::less;
253-
}
254-
return std::strong_ordering::greater;
255-
}
256251
#endif
257252
friend inline LLFIO_PATH_VIEW_CONSTEXPR size_t hash_value(path_view_component x) noexcept;
258253
template <class F> friend inline LLFIO_PATH_VIEW_CONSTEXPR auto LLFIO_V2_NAMESPACE::visit(path_view_component view, F &&f);
@@ -1598,6 +1593,7 @@ class LLFIO_DECL path_view_component
15981593
};
15991594
static_assert(std::is_trivially_copyable<path_view_component>::value, "path_view_component is not trivially copyable!");
16001595
static_assert(sizeof(path_view_component) == 3 * sizeof(void *), "path_view_component is not three pointers in size!");
1596+
16011597
//! \brief Compares **identity** equality not equivalence i.e. backing storage type must be identical, and backing bytes must be identical. Use `compare()` if
16021598
//! you want something stronger.
16031599
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator==(path_view_component x, path_view_component y) noexcept
@@ -1635,6 +1631,106 @@ inline LLFIO_PATH_VIEW_CONSTEXPR bool operator==(path_view_component x, path_vie
16351631
const auto bytes = (x._wchar || x._utf16) ? (x._length * 2) : x._length;
16361632
return 0 == memcmp(x._bytestr, y._bytestr, bytes);
16371633
}
1634+
LLFIO_TEMPLATE(class CharT)
1635+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1636+
inline constexpr bool operator==(path_view_component /*unused*/, const CharT * /*unused*/) noexcept
1637+
{
1638+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator== with path_view_component and a string literal, use .compare<>()");
1639+
return false;
1640+
}
1641+
LLFIO_TEMPLATE(class CharT)
1642+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1643+
inline constexpr bool operator==(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
1644+
{
1645+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator== with path_view_component and a string literal, use .compare<>()");
1646+
return false;
1647+
}
1648+
#if __cplusplus >= 202000L || _HAS_CXX20
1649+
inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view_component x, path_view_component y) noexcept
1650+
{
1651+
if(x.native_size() < y.native_size())
1652+
{
1653+
return std::strong_ordering::less;
1654+
}
1655+
if(x.native_size() > y.native_size())
1656+
{
1657+
return std::strong_ordering::greater;
1658+
}
1659+
if(x._passthrough < y._passthrough)
1660+
{
1661+
return std::strong_ordering::less;
1662+
}
1663+
if(x._passthrough > y._passthrough)
1664+
{
1665+
return std::strong_ordering::greater;
1666+
}
1667+
if(x._char < y._char)
1668+
{
1669+
return std::strong_ordering::less;
1670+
}
1671+
if(x._char > y._char)
1672+
{
1673+
return std::strong_ordering::greater;
1674+
}
1675+
if(x._wchar < y._wchar)
1676+
{
1677+
return std::strong_ordering::less;
1678+
}
1679+
if(x._wchar > y._wchar)
1680+
{
1681+
return std::strong_ordering::greater;
1682+
}
1683+
if(x._utf8 < y._utf8)
1684+
{
1685+
return std::strong_ordering::less;
1686+
}
1687+
if(x._utf8 > y._utf8)
1688+
{
1689+
return std::strong_ordering::greater;
1690+
}
1691+
if(x._utf16 < y._utf16)
1692+
{
1693+
return std::strong_ordering::less;
1694+
}
1695+
if(x._utf16 > y._utf16)
1696+
{
1697+
return std::strong_ordering::greater;
1698+
}
1699+
if(x.native_size() == 0)
1700+
{
1701+
return std::strong_ordering::equal;
1702+
}
1703+
assert(x._bytestr != nullptr);
1704+
assert(y._bytestr != nullptr);
1705+
const auto bytes = (x._wchar || x._utf16) ? (x._length * 2) : x._length;
1706+
int comp = memcmp(x._bytestr, y._bytestr, bytes);
1707+
if(comp == 0)
1708+
{
1709+
return std::strong_ordering::equal;
1710+
}
1711+
else if(comp < 0)
1712+
{
1713+
return std::strong_ordering::less;
1714+
}
1715+
return std::strong_ordering::greater;
1716+
}
1717+
1718+
LLFIO_TEMPLATE(class CharT)
1719+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1720+
inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view_component /*unused*/, const CharT * /*unused*/) noexcept
1721+
{
1722+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator<=> with path_view_component and a string literal, use .compare<>()");
1723+
return std::strong_ordering::equal;
1724+
}
1725+
LLFIO_TEMPLATE(class CharT)
1726+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1727+
inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
1728+
{
1729+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator<=> with path_view_component and a string literal, use .compare<>()");
1730+
return std::strong_ordering::equal;
1731+
}
1732+
1733+
#else
16381734
//! \brief Compares **identity** inequality not disequivalence i.e. backing storage type must be different, or backing bytes must be different. Use `compare()`
16391735
//! if you want something stronger.
16401736
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator!=(path_view_component x, path_view_component y) noexcept
@@ -1736,32 +1832,34 @@ inline LLFIO_PATH_VIEW_CONSTEXPR bool operator<(path_view_component x, path_view
17361832

17371833
LLFIO_TEMPLATE(class CharT)
17381834
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1739-
inline constexpr bool operator==(path_view_component /*unused*/, const CharT * /*unused*/) noexcept
1835+
inline constexpr bool operator!=(path_view_component /*unused*/, const CharT * /*unused*/) noexcept
17401836
{
1741-
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator== with path_view_component and a string literal, use .compare<>()");
1837+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator!= with path_view_component and a string literal, use .compare<>()");
17421838
return false;
17431839
}
17441840
LLFIO_TEMPLATE(class CharT)
17451841
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1746-
inline constexpr bool operator==(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
1842+
inline constexpr bool operator!=(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
17471843
{
1748-
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator== with path_view_component and a string literal, use .compare<>()");
1844+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator!= with path_view_component and a string literal, use .compare<>()");
17491845
return false;
17501846
}
17511847
LLFIO_TEMPLATE(class CharT)
17521848
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1753-
inline constexpr bool operator!=(path_view_component /*unused*/, const CharT * /*unused*/) noexcept
1849+
inline constexpr bool operator<(path_view_component /*unused*/, const CharT * /*unused*/) noexcept
17541850
{
1755-
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator!= with path_view_component and a string literal, use .compare<>()");
1851+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator< with path_view_component and a string literal, use .compare<>()");
17561852
return false;
17571853
}
17581854
LLFIO_TEMPLATE(class CharT)
17591855
LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
1760-
inline constexpr bool operator!=(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
1856+
inline constexpr bool operator<(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
17611857
{
1762-
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator!= with path_view_component and a string literal, use .compare<>()");
1858+
static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator< with path_view_component and a string literal, use .compare<>()");
17631859
return false;
17641860
}
1861+
#endif
1862+
17651863
//! \brief Hashes a `path_view_component`.
17661864
inline LLFIO_PATH_VIEW_CONSTEXPR size_t hash_value(path_view_component view) noexcept
17671865
{
@@ -1915,10 +2013,11 @@ class path_view : public path_view_component
19152013
{
19162014
friend class detail::path_view_iterator;
19172015
friend inline LLFIO_PATH_VIEW_CONSTEXPR bool LLFIO_V2_NAMESPACE::operator==(path_view x, path_view y) noexcept;
2016+
#if __cplusplus >= 202000L || _HAS_CXX20
2017+
friend inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view x, path_view y) noexcept;
2018+
#else
19182019
friend inline LLFIO_PATH_VIEW_CONSTEXPR bool LLFIO_V2_NAMESPACE::operator!=(path_view x, path_view y) noexcept;
19192020
friend inline LLFIO_PATH_VIEW_CONSTEXPR bool LLFIO_V2_NAMESPACE::operator<(path_view x, path_view y) noexcept;
1920-
#if __cplusplus >= 202000L || _HAS_CXX20
1921-
friend inline LLFIO_PATH_VIEW_CONSTEXPR auto operator<=>(path_view x, path_view y) = default;
19222021
#endif
19232022
friend inline LLFIO_PATH_VIEW_CONSTEXPR size_t hash_value(path_view x) noexcept;
19242023

@@ -2861,6 +2960,60 @@ inline LLFIO_PATH_VIEW_CONSTEXPR bool operator==(path_view x, path_view y) noexc
28612960
}
28622961
return true;
28632962
}
2963+
LLFIO_TEMPLATE(class CharT)
2964+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
2965+
inline constexpr bool operator==(path_view /*unused*/, const CharT * /*unused*/) noexcept
2966+
{
2967+
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator== with path_view and a string literal, use .compare<>()");
2968+
return false;
2969+
}
2970+
LLFIO_TEMPLATE(class CharT)
2971+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
2972+
inline constexpr bool operator==(const CharT * /*unused*/, path_view /*unused*/) noexcept
2973+
{
2974+
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator== with path_view and a string literal, use .compare<>()");
2975+
return false;
2976+
}
2977+
#if __cplusplus >= 202000L || _HAS_CXX20
2978+
inline LLFIO_PATH_VIEW_CONSTEXPR std::strong_ordering operator<=>(path_view x, path_view y) noexcept
2979+
{
2980+
auto it1 = x.begin(), it2 = y.begin();
2981+
for(; it1 != x.end() && it2 != y.end(); ++it1, ++it2)
2982+
{
2983+
if(*it1 < *it2)
2984+
{
2985+
return std::strong_ordering::less;
2986+
}
2987+
if(*it1 > *it2)
2988+
{
2989+
return std::strong_ordering::greater;
2990+
}
2991+
}
2992+
if(it1 == x.end() && it2 != y.end())
2993+
{
2994+
return std::strong_ordering::less;
2995+
}
2996+
if(it2 == x.end() && it1 != y.end())
2997+
{
2998+
return std::strong_ordering::greater;
2999+
}
3000+
return std::strong_ordering::equal;
3001+
}
3002+
LLFIO_TEMPLATE(class CharT)
3003+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
3004+
inline constexpr std::strong_ordering operator<=>(path_view /*unused*/, const CharT * /*unused*/) noexcept
3005+
{
3006+
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator<=> with path_view and a string literal, use .compare<>()");
3007+
return std::strong_ordering::equal;
3008+
}
3009+
LLFIO_TEMPLATE(class CharT)
3010+
LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
3011+
inline constexpr std::strong_ordering operator<=>(const CharT * /*unused*/, path_view /*unused*/) noexcept
3012+
{
3013+
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator<=> with path_view and a string literal, use .compare<>()");
3014+
return std::strong_ordering::equal;
3015+
}
3016+
#else
28643017
//! \brief Compares individual path view components for non-**identity** not disequivalence. Use `compare()` if you want something stronger.
28653018
inline LLFIO_PATH_VIEW_CONSTEXPR bool operator!=(path_view x, path_view y) noexcept
28663019
{
@@ -2892,6 +3045,10 @@ inline LLFIO_PATH_VIEW_CONSTEXPR bool operator<(path_view x, path_view y) noexce
28923045
{
28933046
return true;
28943047
}
3048+
if(*it2 < *it1)
3049+
{
3050+
return false;
3051+
}
28953052
}
28963053
if(it1 == x.end() && it2 != y.end())
28973054
{
@@ -2901,20 +3058,6 @@ inline LLFIO_PATH_VIEW_CONSTEXPR bool operator<(path_view x, path_view y) noexce
29013058
}
29023059
LLFIO_TEMPLATE(class CharT)
29033060
LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
2904-
inline constexpr bool operator==(path_view /*unused*/, const CharT * /*unused*/) noexcept
2905-
{
2906-
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator== with path_view and a string literal, use .compare<>()");
2907-
return false;
2908-
}
2909-
LLFIO_TEMPLATE(class CharT)
2910-
LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
2911-
inline constexpr bool operator==(const CharT * /*unused*/, path_view /*unused*/) noexcept
2912-
{
2913-
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator== with path_view and a string literal, use .compare<>()");
2914-
return false;
2915-
}
2916-
LLFIO_TEMPLATE(class CharT)
2917-
LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
29183061
inline constexpr bool operator!=(path_view /*unused*/, const CharT * /*unused*/) noexcept
29193062
{
29203063
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator!= with path_view and a string literal, use .compare<>()");
@@ -2927,6 +3070,7 @@ inline constexpr bool operator!=(const CharT * /*unused*/, path_view /*unused*/)
29273070
static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator!= with path_view and a string literal, use .compare<>()");
29283071
return false;
29293072
}
3073+
#endif
29303074
//! \brief Return the combined hash of individual path components
29313075
inline LLFIO_PATH_VIEW_CONSTEXPR size_t hash_value(path_view x) noexcept
29323076
{

0 commit comments

Comments
 (0)