Copy less tie_from_structure
- Dominant language
- C++
- Stars
- 1.5k
- Forks
- 176
- Avg merge
- 5d 21h
- Merged PRs (30d)
- 1
Description
Hi all, thanks for great work.
The problem I have with tie_from_structure is that it calls copy assignments instead of move assignments.
I think I understand why it happens: you convert the structure on the rhs of operator= into tuple of refs, and then assign it to the tuple of refs on the lhs.
Have you ever been thinking about a way to convert the structure on the rhs into a tuple of values, not refs?
To be more specific, I want to create a tuple, somehow call std::move on each member of the structure , and then assign that tuple (which now will be a rval) to the tuple of refs on the lhs of the operator?
This way it should work same as for std::tie.
I'm not familiar enough with your library to implement like that, so for now I'm using a workaround where I put both lhs args and rhs structure as a single function parameters:
https://godbolt.org/z/ajrGMPMez
Edit:
Ok, so here is a working example of how I would like the tie_from_structure to behave:
```
template
void tie_from_structure_assign_next(T &&)
{
static_assert(N == boost::pfr::tuple_size_v, "Wrong number of elements in tie_from_structure.");
}
template
void tie_from_structure_assign_next(T &&t, A &a, Args &... args)
{
a = std::move(boost::pfr::get(t));
tie_from_structure_assign_next - sizeof...(Args), T>(std::forward(t), args...);
}
template
void tie_from_structure_assign_all(T &&t, A &a, Args &... args)
{
static_assert(boost::pfr::tuple_size_v == sizeof...(Args) + 1, "Wrong number of elements in tie_from_structure.");
a = std::move(boost::pfr::get<0>(t));
tie_from_structure_assign_next<1, T>(std::forward(t), args...);
}
template
void tie_from_structure_assign(T &&t, Tuple &tuple, std::index_sequence) {
tie_from_structure_assign_all(std::forward(t), std::get(tuple)...);
}
template
struct tie_from_structure_tuple : std::tuple
{
using base = std::tuple;
using base::base;
template
constexpr tie_from_structure_tuple &operator=(T &&t)
{
tie_from_structure_assign(std::forward(t), dynamic_cast(*this), std::make_index_sequence::value>());
return *this;
}
};
template
constexpr tie_from_structure_tuple tie_from_structure(Elements &... args) noexcept
{
return tie_from_structure_tuple(args...);
}
```
Same example on godbolt: https://godbolt.org/z/Yq9nqdYnW
With this implementation you call move assignment for all members of the structure.
What do you think about it? Would it be possible to add sth like this to your library?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the existing tie_from_structure implementation and the two linked Compiler Explorer examples. Compare its current copy-assignment behavior with the requested move-assignment behavior, then check how the proposed tuple type fits the library's API. Done means structure members are move-assigned through tie_from_structure while existing tuple-like behavior remains valid.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100