RFR: 8258853: Support separate function declaration and definition with ENABLE_IF-based SFINAE

Kim Barrett kbarrett at openjdk.java.net
Wed Dec 23 01:14:04 UTC 2020


Please review this change which adds the ENABLE_IF_PARAM macro.  This is
used in the definition of a function template when that definition is
separate from the declaration and the declaration uses ENABLE_IF.

For the separate definition to match the declaration, the non-type template
parameter for SFINAE in the two places must be "equivalent", where that's
defined in terms of tokens.  Rather than requiring a separate definition
match the ENABLE_IF expansion directly, the new macro is provided; it is
maintained in parallel with ENABLE_IF to ensure the needed consistency.

Alternative names for the new macro are possible.

(1) This gives the following usage:

template<typename T, ENABLE_IF(std::is_integral<T>::value)>
void foo(T x) { ... }

and this for separate declaration and definition.  

template<typename T, ENABLE_IF(std::is_integral<T>::value)>
void foo(T x);

// later separate definition
template<typename T, ENABLE_IF_PARAM(std::is_integral<T>::value)>
void foo(T x) { ... }

(2) An alternative that isn't being proposed here, but which could be done
instead, would be to drop the ENABLE_IF macro and use a type alias, with
associated change of syntax. Suppose the name is EnableIfX (should probably
be EnableIf, but need to deal with name conflict). It would be defined as

template<bool cond> using EnableIfX = std::enable_if_t<cond, int>;

and used as

template<typename T, EnableIfX<std::is_integral<T>::value> = 0>
void foo(T x) { ... }

and this for separate declaration and definition. 

template<typename T, EnableIfX<std::is_integral<T>::value> = 0>
void foo(T x);

// later separate definition
template<typename T, EnableIfX<std::is_integral<T>::value>>
void foo(T x) { ... }

(3) Or we could not provide any syntactic help, and just write it all out everywhere:

template<typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
void foo(T x) { ... }

and this for separate declaration and definition.  

template<typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
void foo(T x);

// later separate definition
template<typename T, std::enable_if_t<std::is_integral<T>::value, int>> 
void foo(T x) { ... }

Testing:
mach5 tier1
This includes some new gtests for the macros.
There aren't any current non-test uses of ENABLE_IF_PARAM yet.

-------------

Commit messages:
 - Add ENABLE_IF_PARAM, unit tests

Changes: https://git.openjdk.java.net/jdk/pull/1873/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1873&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8258853
  Stats: 36 lines in 2 files changed: 31 ins; 0 del; 5 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1873.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1873/head:pull/1873

PR: https://git.openjdk.java.net/jdk/pull/1873


More information about the hotspot-dev mailing list