From 22583ae55eb8aa35680bf14a92784d36258d5dc8 Mon Sep 17 00:00:00 2001 From: Christos Houtouridis Date: Tue, 23 Oct 2018 09:58:46 +0300 Subject: [PATCH] meta: SFINAE functions added. Small name changes --- include/utl/meta/bool.h | 0 include/utl/meta/if.h | 27 +++++++------ include/utl/meta/integral.h | 0 include/utl/meta/logical.h | 8 ++-- include/utl/meta/sfinae.h | 77 ++++++++++++++++++++++++++++++------- include/utl/meta/void.h | 0 include/utl/meta/void_t.h | 52 ------------------------- 7 files changed, 83 insertions(+), 81 deletions(-) mode change 100755 => 100644 include/utl/meta/bool.h mode change 100755 => 100644 include/utl/meta/if.h mode change 100755 => 100644 include/utl/meta/integral.h mode change 100755 => 100644 include/utl/meta/logical.h mode change 100755 => 100644 include/utl/meta/sfinae.h mode change 100755 => 100644 include/utl/meta/void.h delete mode 100755 include/utl/meta/void_t.h diff --git a/include/utl/meta/bool.h b/include/utl/meta/bool.h old mode 100755 new mode 100644 diff --git a/include/utl/meta/if.h b/include/utl/meta/if.h old mode 100755 new mode 100644 index db753d5..11c0b89 --- a/include/utl/meta/if.h +++ b/include/utl/meta/if.h @@ -31,32 +31,35 @@ //! @{ namespace utl { - //! if_ + //! select _T1 or _T2 based on _C //! @{ template - struct if_ { + struct select_ { typedef _T1 type; }; template - struct if_ { + struct select_ { typedef _T2 type; }; //! @} - //! enable_if + //! select _Tp if _C is true, else SFINAE //! @{ - template - struct enable_if { }; - - // Partial specialization for true. - template - struct enable_if { + template + struct if_ { typedef _Tp type; }; - //! Alias template for enable_if + template // Partial specialization for false. + struct if_ { }; + + //! Alias template for if_ + template + using if_t = typename if_<_C, _Tp>::type; + + //! Publicly recognized alias template for if_ template - using enable_if_t = typename enable_if<_C, _Tp>::type; + using enable_if_t = typename if_<_C, _Tp>::type; //! @} } diff --git a/include/utl/meta/integral.h b/include/utl/meta/integral.h old mode 100755 new mode 100644 diff --git a/include/utl/meta/logical.h b/include/utl/meta/logical.h old mode 100755 new mode 100644 index a5f3d0d..9960c39 --- a/include/utl/meta/logical.h +++ b/include/utl/meta/logical.h @@ -50,11 +50,11 @@ namespace utl { template struct or_ <_T1, _T2> - : if_<_T1::value, _T1, _T2>::type { }; + : select_<_T1::value, _T1, _T2> { }; template struct or_<_T1, _T2, _T3, _Tn...> - : if_<_T1::value, _T1, or_<_T2, _T3, _Tn...>>::type { }; + : select_<_T1::value, _T1, or_<_T2, _T3, _Tn...>> { }; //! @} //! AND implementation @@ -71,11 +71,11 @@ namespace utl { template struct and_<_T1, _T2> - : if_<_T1::value, _T2, _T1>::type { }; + : select_<_T1::value, _T2, _T1> { }; template struct and_<_T1, _T2, _T3, _Tn...> - : if_<_T1::value, and_<_T2, _T3, _Tn...>, _T1>::type { }; + : select_<_T1::value, and_<_T2, _T3, _Tn...>, _T1> { }; //! @} //! same diff --git a/include/utl/meta/sfinae.h b/include/utl/meta/sfinae.h old mode 100755 new mode 100644 index d611685..9dc127e --- a/include/utl/meta/sfinae.h +++ b/include/utl/meta/sfinae.h @@ -32,32 +32,83 @@ //! @{ namespace utl { - //! If same type resolves to _Ret, else to SFINAE + /*! + * void_t + * Utility meta-function that maps a sequence of any types to the type void + * \note The idea is: + * template + * using void_t = void; + * + * Until CWG 1558 (a C++14 defect), unused parameters in alias templates were not + * guaranteed to ensure SFINAE and could be ignored, so earlier compilers require + * a more complex definition of void_t, such as the following implementation + * https://en.cppreference.com + */ //! @{ - template + template + struct void_t_impl { + typedef void type; + }; + //! The actual void_t type alias + template + using void_t = typename void_t_impl<_Ts...>::type; + //! @} + + + //! If same type resolves to _Ret, else SFINAE + //! @{ + template struct use_if_same_ { - using type = enable_if_t < - same_<_Tp1, _Tp2>::value, + using type = if_t < + same_<_T1, _T2>::value, _Ret >; }; - template - using use_if_same_t = typename use_if_same_<_Tp1, _Tp2, _Ret>::type; + template + using use_if_same_t = typename use_if_same_<_T1, _T2, _Ret>::type; //! @} - //! If same type resolves to SFINAE, else to _Ret + + //! If not same type resolves to _Ret, else SFINAE //! @{ - template - struct discard_if_same_ { - using type = enable_if_t < - !same_<_Tp1, _Tp2>::value, + template + struct use_if_not_same_ { + using type = if_t < + !same_<_T1, _T2>::value, _Ret >; }; - template - using discard_if_same_t = typename discard_if_same_<_Tp1, _Tp2, _Ret>::type; + template + using use_if_not_same_t = typename use_if_not_same_<_T1, _T2, _Ret>::type; //! @} + + //! If any type (_T1 or _T2) type resolves to _Ret, else to SFINAE + //! @{ + template + struct use_if_any_ { + using type = if_t < + or_<_T1, _T2>::value, + _Ret + >; + }; + template + using use_if_any_t = typename use_if_any_<_T1, _T2, _Ret>::type; + //! @} + + + //! If both type (_T1 and _T2) type resolves to _Ret, else to SFINAE + //! @{ + template + struct use_if_both_ { + using type = if_t < + and_<_T1, _T2>::value, + _Ret + >; + }; + template + using use_if_both_t = typename use_if_both_<_T1, _T2, _Ret>::type; + //! @} } //! @} diff --git a/include/utl/meta/void.h b/include/utl/meta/void.h old mode 100755 new mode 100644 diff --git a/include/utl/meta/void_t.h b/include/utl/meta/void_t.h deleted file mode 100755 index 523fd1c..0000000 --- a/include/utl/meta/void_t.h +++ /dev/null @@ -1,52 +0,0 @@ -/*! - * \file void_t.h - * \brief Template meta-programming helpers - * - * Copyright (C) 2018 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 . - */ -#ifndef __utl_meta_void_t_h__ -#define __utl_meta_void_t_h__ - -#include - -//! \ingroup meta -//! \defgroup void_t -//! A void_t implementation for utl -//! @{ -namespace utl { - - /*! - * Utility meta-function that maps a sequence of any types to the type void - * \note The idea is: - * template - * using void_t = void; - * - * Until CWG 1558 (a C++14 defect), unused parameters in alias templates were not - * guaranteed to ensure SFINAE and could be ignored, so earlier compilers require - * a more complex definition of void_t, such as the following implementation - * https://en.cppreference.com - */ - template - struct void_impl { - typedef void type; - }; - //! The actual void_t type alias - template - using void_t = typename void_impl<_Ts...>::type; -} -//! @} - -#endif /* __utl_meta_void_t_h__ */