-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[libc++] Simplify the implementation of std::get for pairs #114984
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
base: main
Are you sure you want to change the base?
Conversation
libcxx/include/__utility/pair.h
Outdated
} | ||
|
||
template <class _T1, class _T2> | ||
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { | ||
return __get_pair<0>::get(std::move(__p)); | ||
return std::forward<_T1&&>(std::move(__p).first); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to just use static_cast
(ditto below)?
return std::forward<_T1&&>(std::move(__p).first); | |
return static_cast<_T1&&>(__p.first); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you think that a static_cast would be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO given it's necessary spell out the resulted reference type anyway, it would be clearer to just use a cast.
5d09660
to
4333081
Compare
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThis makes it clearer what the functions actually do. As a nice side-effect it also avoids a function call. If the C++03 header split is successful we could drop Full diff: https://github.com/llvm/llvm-project/pull/114984.diff 2 Files Affected:
diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h
index f9d0f4e4723113..17631277691108 100644
--- a/libcxx/include/__utility/pair.h
+++ b/libcxx/include/__utility/pair.h
@@ -633,42 +633,42 @@ get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
#if _LIBCPP_STD_VER >= 14
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
- return __get_pair<0>::get(__p);
+ return __p.first;
}
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
- return __get_pair<0>::get(__p);
+ return __p.first;
}
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
- return __get_pair<0>::get(std::move(__p));
+ return std::forward<_T1&&>(__p.first);
}
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
- return __get_pair<0>::get(std::move(__p));
+ return std::forward<_T1 const&&>(__p.first);
}
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT {
- return __get_pair<1>::get(__p);
+ return __p.second;
}
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT {
- return __get_pair<1>::get(__p);
+ return __p.second;
}
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT {
- return __get_pair<1>::get(std::move(__p));
+ return std::forward<_T1&&>(__p.second);
}
template <class _T1, class _T2>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) _NOEXCEPT {
- return __get_pair<1>::get(std::move(__p));
+ return std::forward<_T1 const&&>(__p.second);
}
#endif // _LIBCPP_STD_VER >= 14
diff --git a/libcxx/test/std/utilities/utility/pairs/pair.astuple/get_ref.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pair.astuple/get_ref.pass.cpp
new file mode 100644
index 00000000000000..4343361930959c
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/pairs/pair.astuple/get_ref.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template<size_t I, class T1, class T2>
+// typename tuple_element<I, std::pair<T1, T2> >::type&&
+// get(pair<T1, T2>&&);
+
+#include <cassert>
+#include <utility>
+
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX14 bool test() {
+ int i = 1;
+ int j = 2;
+
+ {
+ std::pair<int&, int&&> p(i, std::move(j));
+ assert(&std::get<int&>(p) == &i);
+ assert(&std::get<int&&>(p) == &j);
+
+ assert(&std::get<int&>(std::move(p)) == &i);
+ assert(std::get<int&&>(std::move(p)) == 2);
+
+ const std::pair<int&, int&&> cp(i, std::move(j));
+ assert(&std::get<int&>(cp) == &i);
+ assert(&std::get<int&&>(cp) == &j);
+
+ assert(&std::get<int&>(std::move(cp)) == &i);
+ assert(std::get<int&&>(std::move(cp)) == 2);
+ }
+
+ {
+ std::pair<int&&, int&> p(std::move(i), j);
+ assert(&std::get<int&>(p) == &j);
+ assert(&std::get<int&&>(p) == &i);
+
+ assert(&std::get<int&>(std::move(p)) == &j);
+ assert(std::get<int&&>(std::move(p)) == 1);
+
+ const std::pair<int&&, int&> cp(std::move(i), j);
+ assert(&std::get<int&>(cp) == &j);
+ assert(&std::get<int&&>(cp) == &i);
+
+ assert(&std::get<int&>(std::move(cp)) == &j);
+ assert(std::get<int&&>(std::move(cp)) == 1);
+ }
+
+ return true;
+}
+
+int main() {
+ test();
+#if TEST_STD_VER >= 14
+ static_assert(test(), "");
+#endif
+}
|
libcxx/test/std/utilities/utility/pairs/pair.astuple/get_ref.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/utilities/utility/pairs/pair.astuple/get_ref.pass.cpp
Outdated
Show resolved
Hide resolved
4333081
to
331ac8c
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
331ac8c
to
1a53b6f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for the simplification.
1a53b6f
to
b2cd819
Compare
54b6c87
to
b2cd819
Compare
This makes it clearer what the functions actually do. As a nice side-effect it also avoids a function call. If the C++03 header split is successful we could drop
__get_pair
entirely.