/*!
 * \file    sfinae.h
 * \brief   Template meta-programming SFINAE helpers
 *
 * Copyright (C) 2018-2019 Christos Choutouridis
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *
 * This program 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __utl_meta_sfinae_h__
#define __utl_meta_sfinae_h__

#include <utl/core/impl.h>
#include <type_traits>

/*!
 * \ingroup meta
 * \defgroup sfinae
 * conditional use support header.
 */
//! @{
namespace utl {
namespace meta {

   //! Tool to enable a partial specialization only if a boolean condition is true.
   //! @{
   namespace detail {
//      template <typename... T>
//      struct dev_null { using type = dev_null; };  //< Same as typelist

      template <bool If>  struct when_ { };
      template <>         struct when_<true> { using type = void; };
   }
   //! Well formed only if \p If is true
   template <bool If>
   using when = eval< detail::when_<If> >;

//   //! Well formed only if all of \p Ifs are \c true
//   template <bool ...Ifs>
//   using when_all = detail::dev_null<
//         when<Ifs>...
//   >;

   //! @}

   //! enable_if
   //! @{

   //! enable_if, imported from stl
   template <bool If, typename _Tp = void>   using enable_if = std::enable_if<If, _Tp>;

   //! alias template for enable_if
   template<bool If, typename _Tp = void>    using enable_if_t = eval< enable_if<If, _Tp> >;

   //! @}

}}

//! @}

#endif /* __utl_meta_sfinae_h__ */
