/*
 * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_METAPROGRAMMING_ENABLEIF_HPP
#define SHARE_METAPROGRAMMING_ENABLEIF_HPP

#include <type_traits>

// Retained temporarily for backward compatibility.
// For function template SFINAE, use the ENABLE_IF macro below.
// For class template SFINAE, use std::enable_if_t directly.
template<bool cond, typename T = void>
using EnableIf = std::enable_if<cond, T>;

// ENABLE_IF(Condition...)
// ENABLE_IF_SDEFN(Condition...)
//
// The ENABLE_IF macro can be used in a function template parameter list to
// control the presence of that overload via SFINAE.
//
// When the declaration and definition of a function template are separate,
// only the declaration can use ENABLE_IF in the template parameter list.
// The definition should instead use ENABLE_IF_SDEFN with an _equivalent_
// (C++14 14.4 and 14.5.6.1) Condition for the corresponding template
// parameter.  ("SDEFN" is short for "SEPARATE_DEFINITION".)
//
// Condition must be a constant expression whose value is convertible to
// bool.  The Condition is captured as a variadic macro parameter so that it
// may contain unparenthesized commas.
//
// An example of the usage of the ENABLE_IF macro is
//
// template<typename T,
//          ENABLE_IF(std::is_integral<T>::value),
//          ENABLE_IF(std::is_signed<T>::value)>
// void foo(T x) { ... }
//
// That definition will not be considered in a call to foo unless T is a
// signed integral type.
//
// An alternative to two ENABLE_IF parameters would be single parameter
// that is a conjunction of the expressions.  The benefit of multiple
// ENABLE_IF parameters is the compiler may provide more information in
// certain error contexts.
//
// Details:
//
// With C++98/03 there are 2 ways to use enable_if with function templates:
//
// (1) As the return type
// (2) As an extra parameter
//
// C++11 adds another way, using an extra anonymous non-type template
// parameter with a default value, i.e.
//
//   std::enable_if_t<CONDITION, int> = 0
//
// (The left-hand side is the 'int' type of the anonymous parameter.  The
// right-hand side is the default value.  The use of 'int' and '0' are
// conventional; the specific type and value don't matter, so long as they
// are compatible.)
//
// Compared to (1) this has the benefit of less cluttered syntax for the
// function signature.  Compared to (2) it avoids polluting the signature
// with dummy extra parameters.  And there are cases where this new approach
// can be used while neither of the others is even possible.
//
// Using an extra template parameter is somewhat syntactically complex, with
// a number of details to get right.  However, that complexity can be
// largely hidden using a macro, resulting in more readable uses of SFINAE
// for function templates.
//
// One of those details is that a function template definition that is
// separate from its declaration cannot have a default value.  Thus,
// ENABLE_IF can't be used in such a definition.  But the type expression in
// the separate definition must be equivalent (C++14 14.4 and 14.5.6.1) to
// that in the declaration.  The ENABLE_IF_SDEFN macro provides the common
// code for the separate definition that must match the corresponding
// declaration code at the token level.
//
// The Condition must be wrapped in parenthesis in the expansion. Otherwise,
// a '>' operator in the expression may be misinterpreted as the end of the
// template parameter list.  But rather than simply wrapping in parenthesis,
// Condition is wrapped in an explicit conversion to bool, so the value need
// not be *implicitly* convertible.
//
// There is a problem when Condition is not dependent on any template
// parameter.  Such a Condition will be evaluated at template definition
// time, as part of template type checking.  If Condition is false, that
// will result in a compile-time error rather than the desired SFINAE
// exclusion.  This situation is sufficiently rare that no additional
// macro support is provided for it.  (One solution is to add a new
// type parameter defaulted to the type being checked in Condition, and
// use that new parameter instead in Condition.  There is an automatic
// macro-based solution, but it involves the __COUNTER__ extension.)
//
// Some references suggest a different approach to using a template
// parameter for SFINAE. An anonymous type parameter with a default type
// that uses std::enable_if can also be used in some cases, i.e.
//
//   typename = std::enable_if_t<CONDITION>
//
// However, this doesn't work when there are overloads that need to be
// selected amongst via SFINAE. Two signatures that differ only in a
// template parameter default are not distinct overloads, they are multiple
// definitions of the same function.
//
// Some versions of gcc permit ENABLE_IF to be used in some separate
// definitions.  Other toolchains reject such usage.
//
// The expansion of ENABLE_IF doesn't use ENABLE_IF_SDEFN (or both use a
// common helper) because of issues with the Visual Studio preprocessor's
// handling of variadic macros.

#define ENABLE_IF(...) \
  std::enable_if_t<bool(__VA_ARGS__), int> = 0

#define ENABLE_IF_SDEFN(...) \
  std::enable_if_t<bool(__VA_ARGS__), int>

#endif // SHARE_METAPROGRAMMING_ENABLEIF_HPP
