meta: SFINAE functions added. Small name changes
This commit is contained in:
parent
eea6f7b231
commit
22583ae55e
0
include/utl/meta/bool.h
Executable file → Normal file
0
include/utl/meta/bool.h
Executable file → Normal file
27
include/utl/meta/if.h
Executable file → Normal file
27
include/utl/meta/if.h
Executable file → Normal file
@ -31,32 +31,35 @@
|
||||
//! @{
|
||||
namespace utl {
|
||||
|
||||
//! if_
|
||||
//! select _T1 or _T2 based on _C
|
||||
//! @{
|
||||
template <bool _C, typename _T1, typename _T2>
|
||||
struct if_ {
|
||||
struct select_ {
|
||||
typedef _T1 type;
|
||||
};
|
||||
|
||||
template <typename _T1, typename _T2>
|
||||
struct if_ <false, _T1, _T2> {
|
||||
struct select_ <false, _T1, _T2> {
|
||||
typedef _T2 type;
|
||||
};
|
||||
//! @}
|
||||
|
||||
//! enable_if
|
||||
//! select _Tp if _C is true, else SFINAE
|
||||
//! @{
|
||||
template <bool, typename _Tp = void>
|
||||
struct enable_if { };
|
||||
|
||||
// Partial specialization for true.
|
||||
template<typename _Tp>
|
||||
struct enable_if <true, _Tp> {
|
||||
template <bool _C, typename _Tp = void>
|
||||
struct if_ {
|
||||
typedef _Tp type;
|
||||
};
|
||||
//! Alias template for enable_if
|
||||
template<typename _Tp> // Partial specialization for false.
|
||||
struct if_ <false, _Tp> { };
|
||||
|
||||
//! Alias template for if_
|
||||
template<bool _C, typename _Tp = void>
|
||||
using enable_if_t = typename enable_if<_C, _Tp>::type;
|
||||
using if_t = typename if_<_C, _Tp>::type;
|
||||
|
||||
//! Publicly recognized alias template for if_
|
||||
template<bool _C, typename _Tp = void>
|
||||
using enable_if_t = typename if_<_C, _Tp>::type;
|
||||
//! @}
|
||||
}
|
||||
|
||||
|
0
include/utl/meta/integral.h
Executable file → Normal file
0
include/utl/meta/integral.h
Executable file → Normal file
8
include/utl/meta/logical.h
Executable file → Normal file
8
include/utl/meta/logical.h
Executable file → Normal file
@ -50,11 +50,11 @@ namespace utl {
|
||||
|
||||
template<typename _T1, typename _T2>
|
||||
struct or_ <_T1, _T2>
|
||||
: if_<_T1::value, _T1, _T2>::type { };
|
||||
: select_<_T1::value, _T1, _T2> { };
|
||||
|
||||
template<typename _T1, typename _T2, typename _T3, typename... _Tn>
|
||||
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<typename _T1, typename _T2>
|
||||
struct and_<_T1, _T2>
|
||||
: if_<_T1::value, _T2, _T1>::type { };
|
||||
: select_<_T1::value, _T2, _T1> { };
|
||||
|
||||
template<typename _T1, typename _T2, typename _T3, typename... _Tn>
|
||||
struct and_<_T1, _T2, _T3, _Tn...>
|
||||
: if_<_T1::value, and_<_T2, _T3, _Tn...>, _T1>::type { };
|
||||
: select_<_T1::value, and_<_T2, _T3, _Tn...>, _T1> { };
|
||||
//! @}
|
||||
|
||||
//! same
|
||||
|
77
include/utl/meta/sfinae.h
Executable file → Normal file
77
include/utl/meta/sfinae.h
Executable file → Normal file
@ -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 <typename ...>
|
||||
* 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 <typename _Tp1, typename _Tp2, typename _Ret>
|
||||
template<typename... _Ts>
|
||||
struct void_t_impl {
|
||||
typedef void type;
|
||||
};
|
||||
//! The actual void_t type alias
|
||||
template<typename... _Ts>
|
||||
using void_t = typename void_t_impl<_Ts...>::type;
|
||||
//! @}
|
||||
|
||||
|
||||
//! If same type resolves to _Ret, else SFINAE
|
||||
//! @{
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
struct use_if_same_ {
|
||||
using type = enable_if_t <
|
||||
same_<_Tp1, _Tp2>::value,
|
||||
using type = if_t <
|
||||
same_<_T1, _T2>::value,
|
||||
_Ret
|
||||
>;
|
||||
};
|
||||
template <typename _Tp1, typename _Tp2, typename _Ret>
|
||||
using use_if_same_t = typename use_if_same_<_Tp1, _Tp2, _Ret>::type;
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
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 <typename _Tp1, typename _Tp2, typename _Ret>
|
||||
struct discard_if_same_ {
|
||||
using type = enable_if_t <
|
||||
!same_<_Tp1, _Tp2>::value,
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
struct use_if_not_same_ {
|
||||
using type = if_t <
|
||||
!same_<_T1, _T2>::value,
|
||||
_Ret
|
||||
>;
|
||||
};
|
||||
template <typename _Tp1, typename _Tp2, typename _Ret>
|
||||
using discard_if_same_t = typename discard_if_same_<_Tp1, _Tp2, _Ret>::type;
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
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 <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
struct use_if_any_ {
|
||||
using type = if_t <
|
||||
or_<_T1, _T2>::value,
|
||||
_Ret
|
||||
>;
|
||||
};
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
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 <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
struct use_if_both_ {
|
||||
using type = if_t <
|
||||
and_<_T1, _T2>::value,
|
||||
_Ret
|
||||
>;
|
||||
};
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
using use_if_both_t = typename use_if_both_<_T1, _T2, _Ret>::type;
|
||||
//! @}
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
0
include/utl/meta/void.h
Executable file → Normal file
0
include/utl/meta/void.h
Executable file → Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __utl_meta_void_t_h__
|
||||
#define __utl_meta_void_t_h__
|
||||
|
||||
#include <utl/impl/version.h>
|
||||
|
||||
//! \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 <typename ...>
|
||||
* 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<typename... _Ts>
|
||||
struct void_impl {
|
||||
typedef void type;
|
||||
};
|
||||
//! The actual void_t type alias
|
||||
template<typename... _Ts>
|
||||
using void_t = typename void_impl<_Ts...>::type;
|
||||
}
|
||||
//! @}
|
||||
|
||||
#endif /* __utl_meta_void_t_h__ */
|
Loading…
x
Reference in New Issue
Block a user