1. Introduction
In integer numerics and bit-manipulation code, it is common to implement functionality in terms of the corresponding signed/unsigned type. The most concise form is a function-style cast with a very short type name.
template < class T > T arithmetic_shift_right ( T x , int s ) { return T ( std :: make_signed_t < T > ( x ) >> s ); } template < class T > T wrapping_add ( T x , T y ) { constexpr unsigned to_int_promotion_defense = 0 ; return T ( to_int_promotion_defense + std :: make_unsigned_t < T > ( x ) + std :: make_unsigned_t < T > ( y )); } 
However, this is problematic for two reasons:
- 
     The use of C-style/function-style casts may conflict with the project’s style. When static_cast 
- 
     Repeating the type T x T std :: make_signed_t < T > ( x ) std :: make_signed_t < decltype ( x ) > ( x ) x 
The greater the distance between 
To solve these issues, this proposal adds the function templates 
A GitHub code search for
  / [ ^ a - zA - Z_ ]( to_signed | to_unsigned ) | static_cast < ( typename ) ?  ? (( :: ) ? std :: ) ? ( make_signed | make_unsigned ) /  - is : fork  language : c ++ 
   ... shows that roughly 12.9K C++ files already use a non-standard 
By comparison,
  / [ ^ a - zA - Z_ ]( to_underlying ) | static_cast < ( typename ) ?  ? (( :: ) ? std :: ) ? ( underlying_type ) /  - is : fork  language : c ++ 
   ... yields 30.8K C++ files which use 
The proposal [P1682R3] for 
2. Impact on the standard
This proposal is a pure library extension.
Note: [ranges.syn] already defines an exposition-only function 
3. Possible implementation
template < class T > constexpr std :: make_signed_t < T > to_signed ( T x ) noexcept { return static_cast < std :: make_signed_t < T >> ( x ); } template < class T > constexpr std :: make_unsigned_t < T > to_unsigned ( T x ) noexcept { return static_cast < std :: make_unsigned_t < T >> ( x ); } 
4. Design decisions
This proposal follows precedent:
Similar to 
5. Proposed wording
The proposed wording is relative to [N5001].
In subclause [version.syn], add the following feature-testing macro:
#define __cpp_lib_to_signed 20XXXXL // also in <utility> 
In subclause [utility.syn], update the synopsis as follows:
namespace std { [...] // [utility.sign.conv], sign conversion template < class T > constexpr make_signed_t < T > to_signed ( T value ) noexcept ; template < class T > constexpr make_unsigned_t < T > to_unsigned ( T value ) noexcept ; // [utility.underlying], to_underlying template < class T > constexpr underlying_type_t < T > to_underlying ( T value ) noexcept ; [...] } 
In subclause [utility], add a subclause immediately prior to [utility.underlying]:
Sign conversion [utility.sign.conv]template < class T > constexpr make_signed_t < T > to_signed ( T value ) noexcept ; Constraints:
is an integral or enumeration type other than cvT .bool Returns:
.static_cast < make_signed_t < T >> ( x ) template < class T > constexpr make_unsigned_t < T > to_unsigned ( T value ) noexcept ; Constraints:
is an integral or enumeration type other than cvT .bool Returns:
.static_cast < make_unsigned_t < T >> ( x ) 
Note: Because 
Note: The name of the subclause is based on [meta.trans.sign], sign modifications.