[libc++] Member types `argument_type`, `first_argument_type`, and `second_argument_type` of `reference_wrapper` are not correctly provided
Nobody has claimed this yet.
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
It seems that libc++ hasn't implemented the rules in N4659 [depr.func.adaptor.typedefs]/4.3 and N4659 [depr.func.adaptor.typedefs]/5.3 at all.
Sometimes argument_type, first_argument_type, or second_argument_type are incorrectly provided due to inheritance form some base classes (unary_function and its friends) even if these names are shadowed in the derived class.
For some "normal" cases, these member types are basically missing when they were required to be provided.
Example (link)
#include <functional>
#include <type_traits>
struct S1 {
using argument_type = void;
using first_argument_type = int() const;
using second_argument_type = char&&;
};
static_assert(std::is_same_v<std::reference_wrapper<S1>::argument_type, void>);
static_assert(std::is_same_v<std::reference_wrapper<S1>::first_argument_type, int() const>);
static_assert(std::is_same_v<std::reference_wrapper<S1>::second_argument_type, char&&>);
struct S2 : std::reference_wrapper<int(long)> {
static constexpr int argument_type = 1729;
};
template <class T, class = void>
constexpr bool has_no_argument_type = true;
template <class T>
constexpr bool has_no_argument_type<T, std::void_t<typename T::argument_type>> = false;
static_assert(has_no_argument_type<std::reference_wrapper<S2>>);
struct S3 : std::reference_wrapper<void(int&, int&&)> {
static constexpr int first_argument_type = 421;
static constexpr int second_argument_type = 729;
};
template <class T, class = void>
constexpr bool has_no_first_argument_type = true;
template <class T>
constexpr bool has_no_first_argument_type<T, std::void_t<typename T::first_argument_type>> = false;
template <class T, class = void>
constexpr bool has_no_second_argument_type = true;
template <class T>
constexpr bool has_no_second_argument_type<T, std::void_t<typename T::second_argument_type>> = false;
static_assert(has_no_first_argument_type<std::reference_wrapper<S3>>);
static_assert(has_no_second_argument_type<std::reference_wrapper<S3>>);
I'm not sure whether this is worth fixing because these member types were deprecated in C++17 and removed in C++20.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the std::reference_wrapper cases from the issue against libc++, then compare the observed member types with N4659 [depr.func.adaptor.typedefs]/4.3 and /5.3. Done means the static assertions pass, including suppression of inherited names when the wrapped type shadows them and provision of the required types in normal cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100