Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce _Is_transparent helper trait #3736

Merged
merged 3 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions stl/inc/xhash
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,15 @@ struct _Uhash_choose_transparency {
#if _HAS_CXX20
template <class _Kty, class _Hasher, class _Keyeq>
struct _Uhash_choose_transparency<_Kty, _Hasher, _Keyeq,
void_t<typename _Hasher::is_transparent, typename _Keyeq::is_transparent>> {
enable_if_t<conjunction_v<_Is_transparent<_Hasher>, _Is_transparent<_Keyeq>>>> {
// transparency selector for transparent hashed containers
template <class _Keyty>
using _Deduce_key = const _Keyty&;

using _Transparent = void;
template <class _Container, class _Kx>
static constexpr bool _Supports_transparency =
!disjunction_v<is_convertible<_Kx, typename _Container::const_iterator>,
is_convertible<_Kx, typename _Container::iterator>>;
};
#endif // _HAS_CXX20

Expand Down Expand Up @@ -1140,8 +1143,8 @@ public:
}

#if _HAS_CXX23
template <class _Kx, class _Mytraits = _Traits, class = typename _Mytraits::_Transparent,
enable_if_t<!disjunction_v<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>, int> = 0>
template <class _Kx, class _Mytraits = _Traits,
enable_if_t<_Mytraits::template _Supports_transparency<_Hash, _Kx>, int> = 0>
size_type erase(_Kx&& _Keyval) noexcept(noexcept(_Erase(_Keyval))) /* strengthened */ {
return _Erase(_Keyval);
}
Expand Down Expand Up @@ -1380,8 +1383,8 @@ public:
}

#if _HAS_CXX23
template <class _Kx, class _Mytraits = _Traits, class = typename _Mytraits::_Transparent,
enable_if_t<!disjunction_v<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>, int> = 0>
template <class _Kx, class _Mytraits = _Traits,
enable_if_t<_Mytraits::template _Supports_transparency<_Hash, _Kx>, int> = 0>
node_type extract(_Kx&& _Keyval) {
const auto _Ptr = _Extract(_Keyval);
if (!_Ptr) {
Expand Down
14 changes: 14 additions & 0 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2567,6 +2567,20 @@ _EXPORT_STD inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t&
_Space -= _Off;
return _Ptr;
}

template <class _Ty, class = void>
_INLINE_VAR constexpr bool _Is_transparent_v = false;

template <class _Ty>
_INLINE_VAR constexpr bool _Is_transparent_v<_Ty, void_t<typename _Ty::is_transparent>> = true;

template <class _Ty>
struct _Is_transparent : bool_constant<_Is_transparent_v<_Ty>> {};

#ifdef __cpp_lib_concepts // TRANSITION, GH-395
template <class _Ty>
concept _Transparent = _Is_transparent_v<_Ty>;
#endif // __cpp_lib_concepts
_STD_END

#pragma pop_macro("new")
Expand Down
32 changes: 18 additions & 14 deletions stl/inc/xtree
Original file line number Diff line number Diff line change
Expand Up @@ -1344,8 +1344,10 @@ public:
}

#if _HAS_CXX23
template <class _Kx, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent,
enable_if_t<!disjunction_v<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>, int> = 0>
template <class _Kx, class _Mycomp = key_compare,
enable_if_t<conjunction_v<_Is_transparent<_Mycomp>,
negation<disjunction<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>>>,
int> = 0>
size_type erase(_Kx&& _Keyval) noexcept(noexcept(_Eqrange(_Keyval))) /* strengthened */ {
return _Erase(_Eqrange(_Keyval));
}
Expand Down Expand Up @@ -1382,12 +1384,12 @@ public:
return const_iterator(_Find(_Keyval), _Get_scary());
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD iterator find(const _Other& _Keyval) {
return iterator(_Find(_Keyval), _Get_scary());
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD const_iterator find(const _Other& _Keyval) const {
return const_iterator(_Find(_Keyval), _Get_scary());
}
Expand All @@ -1397,7 +1399,7 @@ public:
return _Lower_bound_duplicate(_Find_lower_bound(_Keyval)._Bound, _Keyval);
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD bool contains(const _Other& _Keyval) const {
return _Lower_bound_duplicate(_Find_lower_bound(_Keyval)._Bound, _Keyval);
}
Expand All @@ -1413,7 +1415,7 @@ public:
}
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD size_type count(const _Other& _Keyval) const {
const auto _Ans = _Eqrange(_Keyval);
return static_cast<size_type>(_STD distance(
Expand All @@ -1428,12 +1430,12 @@ public:
return const_iterator(_Find_lower_bound(_Keyval)._Bound, _Get_scary());
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD iterator lower_bound(const _Other& _Keyval) {
return iterator(_Find_lower_bound(_Keyval)._Bound, _Get_scary());
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD const_iterator lower_bound(const _Other& _Keyval) const {
return const_iterator(_Find_lower_bound(_Keyval)._Bound, _Get_scary());
}
Expand All @@ -1446,12 +1448,12 @@ public:
return const_iterator(_Find_upper_bound(_Keyval)._Bound, _Get_scary());
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD iterator upper_bound(const _Other& _Keyval) {
return iterator(_Find_upper_bound(_Keyval)._Bound, _Get_scary());
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD const_iterator upper_bound(const _Other& _Keyval) const {
return const_iterator(_Find_upper_bound(_Keyval)._Bound, _Get_scary());
}
Expand All @@ -1468,14 +1470,14 @@ public:
return {const_iterator(_Result.first, _Scary), const_iterator(_Result.second, _Scary)};
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD pair<iterator, iterator> equal_range(const _Other& _Keyval) {
const auto _Result = _Eqrange(_Keyval);
const auto _Scary = _Get_scary();
return {iterator(_Result.first, _Scary), iterator(_Result.second, _Scary)};
}

template <class _Other, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent>
template <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
_NODISCARD pair<const_iterator, const_iterator> equal_range(const _Other& _Keyval) const {
const auto _Result = _Eqrange(_Keyval);
const auto _Scary = _Get_scary();
Expand Down Expand Up @@ -1750,8 +1752,10 @@ public:
}

#if _HAS_CXX23
template <class _Kx, class _Mycomp = key_compare, class = typename _Mycomp::is_transparent,
enable_if_t<!disjunction_v<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>, int> = 0>
template <class _Kx, class _Mycomp = key_compare,
enable_if_t<conjunction_v<_Is_transparent<_Mycomp>,
negation<disjunction<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>>>,
int> = 0>
node_type extract(_Kx&& _Keyval) {
const const_iterator _Where = find(_Keyval);
if (_Where == end()) {
Expand Down