public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/103448] New: unexpected tuple collapse
@ 2021-11-27  2:45 janezz55 at gmail dot com
  2021-11-27  2:49 ` [Bug libstdc++/103448] " pinskia at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: janezz55 at gmail dot com @ 2021-11-27  2:45 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

            Bug ID: 103448
           Summary: unexpected tuple collapse
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: janezz55 at gmail dot com
  Target Milestone: ---

Here you have a fully working program, that instead of creating a

std::tuple<std::tuple<int&, int&>>

creates a

std::tuple<int&, int&>

something collapses the tuple of tuples into a single tuple. The workaround is
to replace the std::tuple() constructor call with a std::make_tuple() call.

https://wandbox.org/permlink/Q5P8iaUjThDKxJL9

#include <iostream>
#include <tuple>
#include <string_view>

template <typename T>
constexpr auto type_name() {
  std::string_view name, prefix, suffix;
#ifdef __clang__
  name = __PRETTY_FUNCTION__;
  prefix = "auto type_name() [T = ";
  suffix = "]";
#elif defined(__GNUC__)
  name = __PRETTY_FUNCTION__;
  prefix = "constexpr auto type_name() [with T = ";
  suffix = "]";
#elif defined(_MSC_VER)
  name = __FUNCSIG__;
  prefix = "auto __cdecl type_name<";
  suffix = ">(void)";
#endif
  name.remove_prefix(prefix.size());
  name.remove_suffix(suffix.size());
  return name;
}

template <std::size_t N>
constexpr auto split(auto&& t) noexcept requires(bool(N))
{
  constexpr auto n(std::tuple_size_v<std::remove_cvref_t<decltype(t)>>);
  static_assert(n && !(n % N));
  return [&]<auto ...I>(std::index_sequence<I...>) noexcept
  {
    return std::tuple(
      [&]<auto ...J>(std::index_sequence<J...>) noexcept
      {
        constexpr auto K(N * I);
        return std::forward_as_tuple(std::get<K + J>(t)...);
      }(std::make_index_sequence<N + I - I>())...
    );
  }(std::make_index_sequence<n / N>());
}

int main()
{
  auto t(split<2>(std::tuple(1, 2)));
  std::cout << type_name<decltype(t)>() << std::endl;

  return 0;
}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
@ 2021-11-27  2:49 ` pinskia at gcc dot gnu.org
  2021-11-27  2:53 ` janezz55 at gmail dot com
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-27  2:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Hmm, even clang with libc++ produces the same ....

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
  2021-11-27  2:49 ` [Bug libstdc++/103448] " pinskia at gcc dot gnu.org
@ 2021-11-27  2:53 ` janezz55 at gmail dot com
  2021-11-27  2:55 ` pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: janezz55 at gmail dot com @ 2021-11-27  2:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #2 from Janez Zemva <janezz55 at gmail dot com> ---
I have no idea, but it seems wrong me. Is there an explanation for the lvalue
references? I expected rvalue references, but that's unrelated to the bug.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
  2021-11-27  2:49 ` [Bug libstdc++/103448] " pinskia at gcc dot gnu.org
  2021-11-27  2:53 ` janezz55 at gmail dot com
@ 2021-11-27  2:55 ` pinskia at gcc dot gnu.org
  2021-11-27  2:59 ` janezz55 at gmail dot com
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-27  2:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>something collapses the tuple of tuples into a single tuple. The workaround is to replace the std::tuple() constructor 

Yes it is called the copy (or move) constructor :).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
                   ` (2 preceding siblings ...)
  2021-11-27  2:55 ` pinskia at gcc dot gnu.org
@ 2021-11-27  2:59 ` janezz55 at gmail dot com
  2021-11-27  3:01 ` pinskia at gcc dot gnu.org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: janezz55 at gmail dot com @ 2021-11-27  2:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #4 from Janez Zemva <janezz55 at gmail dot com> ---
Ok, thank you :)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
                   ` (3 preceding siblings ...)
  2021-11-27  2:59 ` janezz55 at gmail dot com
@ 2021-11-27  3:01 ` pinskia at gcc dot gnu.org
  2021-11-27  3:03 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-27  3:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #3)
> Yes it is called the copy (or move) constructor :).

That is:
  auto t = std::tuple(std::tuple(1,2));
  std::cout << type_name<decltype(t)>() << std::endl;

Will produce the same result.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
                   ` (4 preceding siblings ...)
  2021-11-27  3:01 ` pinskia at gcc dot gnu.org
@ 2021-11-27  3:03 ` pinskia at gcc dot gnu.org
  2021-11-27  3:11 ` janezz55 at gmail dot com
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-27  3:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #5)
> (In reply to Andrew Pinski from comment #3)
> > Yes it is called the copy (or move) constructor :).
> 
> That is:
>   auto t = std::tuple(std::tuple(1,2));
>   std::cout << type_name<decltype(t)>() << std::endl;
> 
> Will produce the same result.

Or:

  auto t1 = std::tuple(1,2);
  auto t = std::tuple(t1);
  std::cout << type_name<decltype(t)>() << std::endl;

There is no magic going on here, just a copy constructor happening which it
looks like you forgot about.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
                   ` (5 preceding siblings ...)
  2021-11-27  3:03 ` pinskia at gcc dot gnu.org
@ 2021-11-27  3:11 ` janezz55 at gmail dot com
  2021-11-27  3:18 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: janezz55 at gmail dot com @ 2021-11-27  3:11 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #7 from Janez Zemva <janezz55 at gmail dot com> ---
The c++17 type deduction rules are also going on. This makes me wonder how
std::make_tuple() circumvents the problem.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
                   ` (6 preceding siblings ...)
  2021-11-27  3:11 ` janezz55 at gmail dot com
@ 2021-11-27  3:18 ` pinskia at gcc dot gnu.org
  2021-11-27 11:52 ` redi at gcc dot gnu.org
  2021-11-28 11:18 ` janezz55 at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-27  3:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Janez Zemva from comment #7)
> The c++17 type deduction rules are also going on. This makes me wonder how
> std::make_tuple() circumvents the problem.

Easy, it does not use the C++17 deduction rules at all, it is explict.

That is:
std::make_tuple is defined as:

template<typename ...T>
auto make_tuple(const T &...a)
{
  return std::tuple<T...>(a...);
}

And there is no C++17 class deduction rules going on, it is pure normal C++11
template function deduction rules.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
                   ` (7 preceding siblings ...)
  2021-11-27  3:18 ` pinskia at gcc dot gnu.org
@ 2021-11-27 11:52 ` redi at gcc dot gnu.org
  2021-11-28 11:18 ` janezz55 at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2021-11-27 11:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
With class template argument deduction, T(T<args...>{}) will always make a copy
of the same type, and not wrap it in a different specialization of the
template.

There is no bug here, as Andrew said.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/103448] unexpected tuple collapse
  2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
                   ` (8 preceding siblings ...)
  2021-11-27 11:52 ` redi at gcc dot gnu.org
@ 2021-11-28 11:18 ` janezz55 at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: janezz55 at gmail dot com @ 2021-11-28 11:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103448

--- Comment #10 from Janez Zemva <janezz55 at gmail dot com> ---
The code worked for ((...), (...), ...), but not for ((...)), I did not
understand how a tuple not containing another tuple could possibly be
constructed. On the other hand, I already found a workaround and I already
asked a question on SO and it was the folks there who advised incorrectly, that
I should construct the top tuple using std::tuple() and not std::make_tuple().
The only place remaining to write anything in was therefore here.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-11-28 11:18 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-27  2:45 [Bug libstdc++/103448] New: unexpected tuple collapse janezz55 at gmail dot com
2021-11-27  2:49 ` [Bug libstdc++/103448] " pinskia at gcc dot gnu.org
2021-11-27  2:53 ` janezz55 at gmail dot com
2021-11-27  2:55 ` pinskia at gcc dot gnu.org
2021-11-27  2:59 ` janezz55 at gmail dot com
2021-11-27  3:01 ` pinskia at gcc dot gnu.org
2021-11-27  3:03 ` pinskia at gcc dot gnu.org
2021-11-27  3:11 ` janezz55 at gmail dot com
2021-11-27  3:18 ` pinskia at gcc dot gnu.org
2021-11-27 11:52 ` redi at gcc dot gnu.org
2021-11-28 11:18 ` janezz55 at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).