Bug 71187 - declval() can be implemented without requiring a template instantiation
Summary: declval() can be implemented without requiring a template instantiation
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 5.3.0
: P3 enhancement
Target Milestone: 8.0
Assignee: Jonathan Wakely
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-18 22:22 UTC by Eric Niebler
Modified: 2021-08-04 19:27 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-05-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Niebler 2016-05-18 22:22:59 UTC
declval gets used *everywhere*. It doesn't need to instantiate a template. Rather than:

  template<typename _Tp>
    inline typename add_rvalue_reference<_Tp>::type
    declval() noexcept
    {
      static_assert(__declval_protector<_Tp>::__stop,
                    "declval() must not be used!");
      return __declval_protector<_Tp>::__delegate();
    }

declval can be defined as:

  template<typename _Tp, typename _Up = _Tp&&>
    _Up
    __declval(int);

  template<typename _Tp>
    _Tp
    __declval(long);

  template<typename _Tp>
    auto declval() noexcept -> decltype(__declval<_Tp>(0))
    {
      static_assert(__declval_protector<_Tp>::__stop,
                    "declval() must not be used!");
      return __declval_protector<_Tp>::__delegate();
    }


In a large code base that makes heavy use of templates, this small change is a measured 4% compile-time win (g++ (GCC) 5.x 20160302).

I think the as-if rule gives implementers enough latitude to make this change.
Comment 1 Jonathan Wakely 2016-05-18 22:57:24 UTC
Thanks, Eric. Ville pointed me to your LLVM bug report earlier, and I think it's great.
Comment 2 Jonathan Wakely 2017-09-14 16:14:58 UTC
I wonder if it would make sense to use the same __declval helper for add_rvalue_reference too. That would allow us to lose the __add_rvalue_reference_helper class template.
Comment 3 Eric Niebler 2017-09-14 16:52:06 UTC
I suppose, but I doubt it would matter much. add_rvalue_reference is not used nearly as frequently as declval (except in the current implementation of declval).
Comment 4 Jonathan Wakely 2017-09-18 11:40:42 UTC
Author: redi
Date: Mon Sep 18 11:40:10 2017
New Revision: 252922

URL: https://gcc.gnu.org/viewcvs?rev=252922&root=gcc&view=rev
Log:
PR libstdc++/71187 reimplement declval without add_rvalue_reference

	PR libstdc++/71187
	* include/std/type_traits (__declval): New function to deduce return
	type of declval.
	(__declval_protector::_delegate): Remove.
	(declval): Use __declval instead of add_rvalue_reference and
	__declval_protector::__delegate.
	* testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
	lineno.
	* testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
	Likewise.
	* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
	Likewise.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/type_traits
    trunk/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
    trunk/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
    trunk/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
Comment 5 Jonathan Wakely 2017-09-18 11:49:09 UTC
I've committed this change on trunk. Thanks for the suggestion.