meta: Renaming
This commit is contained in:
@@ -709,8 +709,8 @@ namespace _1wire_i_det {
|
||||
* \param _Tp Type to check
|
||||
* \return True if _Tp is a 1-wire interface
|
||||
*/
|
||||
template <typename _Tp>
|
||||
constexpr bool _1Wire_i = _1wire_i_det::is_1wire_<_Tp>::value;
|
||||
// template <typename _Tp>
|
||||
// constexpr bool _1Wire_i = _1wire_i_det::is_1wire_<_Tp>::value;
|
||||
#endif
|
||||
|
||||
//!@}
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace utl {
|
||||
* \arg 1 dev_id rhs is smaller than dev_id lhs
|
||||
*/
|
||||
static int compare (const _1wire_id_t& lhs, const _1wire_id_t& rhs) noexcept {
|
||||
auto p = std::mismatch (lhs.rbegin(), lhs.rend(), rhs.rbegin(), rhs.rend());
|
||||
auto p = std::mismatch (lhs.rbegin(), lhs.rend(), rhs.rbegin());
|
||||
if (p.first == lhs.rend()) return 0;
|
||||
else if (*p.first < *p.second) return -1;
|
||||
else return 1;
|
||||
|
||||
@@ -275,8 +275,8 @@ namespace utl {
|
||||
* \param _Tp Type to check
|
||||
* \return True if _Tp is a i2c interface
|
||||
*/
|
||||
template <typename _Tp>
|
||||
constexpr bool I2c_i = i2c_i_details::is_i2c_<_Tp>::value;
|
||||
// template <typename _Tp>
|
||||
// constexpr bool I2c_i = i2c_i_details::is_i2c_<_Tp>::value;
|
||||
#endif
|
||||
|
||||
//!@}
|
||||
|
||||
@@ -321,8 +321,8 @@ namespace utl {
|
||||
* \param _Tp Type to check
|
||||
* \return True if _Tp is a spi interface
|
||||
*/
|
||||
template <typename _Tp>
|
||||
constexpr bool Spi_i = spi_i_details::is_spi_<_Tp>::value;
|
||||
// template <typename _Tp>
|
||||
// constexpr bool Spi_i = spi_i_details::is_spi_<_Tp>::value;
|
||||
#endif
|
||||
//! @}
|
||||
|
||||
|
||||
@@ -157,9 +157,8 @@ namespace utl {
|
||||
* \param bit The bit location we want to read
|
||||
*/
|
||||
constexpr bool bit (uint8_t bit) const noexcept {
|
||||
value_type one = 1;
|
||||
uint8_t den = 8*sizeof(_Tp)/sizeof(uint8_t);
|
||||
return traits_t::Ref (_data, bit/den) & (one << ((bit % den)-1));
|
||||
return traits_t::Ref (_data, bit/(8*sizeof(_Tp))) &
|
||||
(static_cast<value_type>(0x01) << ((bit % (8*sizeof(_Tp)))-1));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*!
|
||||
* \file /utl/impl/concepts.h
|
||||
* \brief Concept support header
|
||||
*
|
||||
* 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_impl_concepts_h__
|
||||
#define __utl_impl_concepts_h__
|
||||
|
||||
/*!
|
||||
* utl inner concept preprocessor flag
|
||||
* \defgroup crtp
|
||||
* \ingroup impl
|
||||
*/
|
||||
//!@{
|
||||
#if defined __cpp_concepts
|
||||
#define _utl_have_concepts (1)
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* requires keyword wrapper
|
||||
*/
|
||||
#if defined _utl_have_concepts
|
||||
#define _requires(_r_) requires (_r_)
|
||||
#else
|
||||
#define _requires(_r_)
|
||||
#endif
|
||||
|
||||
//!@}
|
||||
#endif /* __utl_impl_concepts_h__ */
|
||||
@@ -43,6 +43,7 @@ namespace utl {
|
||||
#define _CRTP_IMPL(T) \
|
||||
constexpr T& impl() { return *static_cast<T*>(this); } \
|
||||
constexpr const T& impl() const { return *static_cast<const T*>(this); }
|
||||
|
||||
}
|
||||
//!@}
|
||||
#endif /* __utl_impl_crtp_h__ */
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
//#include <type_traits>
|
||||
|
||||
namespace utl {
|
||||
//! @{ \name byte and word types
|
||||
using byte_t = uint8_t; //!< 8 bits wide
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* \file /utl/core/version.h
|
||||
* \brief version and cpp version checks
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -26,10 +26,10 @@
|
||||
//!@{
|
||||
|
||||
//! utl version
|
||||
#define UTL_VERSION "0.0.1"
|
||||
#define UTL_VERSION "0.1.0"
|
||||
#define UTL_VERSION_MAJOR 0
|
||||
#define UTL_VERSION_MINOR 0
|
||||
#define UTL_VERSION_PATCH 1
|
||||
#define UTL_VERSION_MINOR 1
|
||||
#define UTL_VERSION_PATCH 0
|
||||
#define UTL_VERSION_VALUE ( (UTL_VERSION_MAJOR * 10000) \
|
||||
+ (UTL_VERSION_MINOR * 100) \
|
||||
+ UTL_VERSION_PATCH)
|
||||
@@ -40,8 +40,6 @@
|
||||
#define CXX_VER_STD_14 201402L
|
||||
#define CXX_VER_STD_17 201703L
|
||||
|
||||
//#include <type_traits>
|
||||
|
||||
//! Check for variable templates
|
||||
#ifndef CXX_VARIABLE_TEMPLATES
|
||||
#ifdef __cpp_variable_templates
|
||||
@@ -51,15 +49,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//! Check integer sequence
|
||||
#ifndef CXX_INTEGER_SEQUENCE
|
||||
#ifdef __cpp_lib_integer_sequence
|
||||
#define CXX_INTEGER_SEQUENCE __cpp_lib_integer_sequence
|
||||
#else
|
||||
#define CXX_INTEGER_SEQUENCE (CXX_VER >= CXX_VER_STD_14)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//! Check concepts
|
||||
#ifndef CXX_CONCEPTS
|
||||
#ifdef __cpp_concepts
|
||||
@@ -86,9 +75,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Workaround inspection
|
||||
* Workaround inspections
|
||||
*/
|
||||
#if defined(__GNUC__) && (__GNUC__ < 5)
|
||||
// https://wg21.link/cwg1558
|
||||
@@ -97,8 +85,8 @@
|
||||
|
||||
|
||||
//! Base library requirement
|
||||
#if __cplusplus < CXX_VER_STD_11
|
||||
#error "uTL requires C++11"
|
||||
#if CXX_VER < CXX_VER_STD_14
|
||||
#error "uTL requires C++14"
|
||||
#endif
|
||||
|
||||
//!@}
|
||||
|
||||
@@ -437,8 +437,8 @@ namespace utl {
|
||||
* \param _Tp Type to check
|
||||
* \return True if _Tp is a spi interface
|
||||
*/
|
||||
template <typename _Tp>
|
||||
constexpr bool Outdev_it = outdev_it_details::is_outdev_it_<_Tp>::value;
|
||||
// template <typename _Tp>
|
||||
// constexpr bool Outdev_it = outdev_it_details::is_outdev_it_<_Tp>::value;
|
||||
#endif
|
||||
//! @}
|
||||
|
||||
@@ -714,8 +714,8 @@ namespace utl {
|
||||
* \param _Tp Type to check
|
||||
* \return True if _Tp is a spi interface
|
||||
*/
|
||||
template <typename _Tp>
|
||||
constexpr bool Indev_it = indev_it_details::is_indev_it_<_Tp>::value;
|
||||
// template <typename _Tp>
|
||||
// constexpr bool Indev_it = indev_it_details::is_indev_it_<_Tp>::value;
|
||||
#endif
|
||||
//! @}
|
||||
|
||||
@@ -998,8 +998,8 @@ namespace utl {
|
||||
* \param _Tp Type to check
|
||||
* \return True if _Tp is a spi interface
|
||||
*/
|
||||
template <typename _Tp>
|
||||
constexpr bool Idxdev_it = idxdev_it_details::is_idxdev_it_<_Tp>::value;
|
||||
// template <typename _Tp>
|
||||
// constexpr bool Idxdev_it = idxdev_it_details::is_idxdev_it_<_Tp>::value;
|
||||
#endif
|
||||
//! @}
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/*!
|
||||
* \file void.h
|
||||
* \brief void_t meta-function
|
||||
* \file detection.h
|
||||
* \brief Detection idiom based on WG21's N4502[1] from Walter E. Brown
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* [1]: www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf
|
||||
*
|
||||
* 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
|
||||
@@ -17,14 +19,17 @@
|
||||
* 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_h__
|
||||
#define __utl_meta_void_h__
|
||||
#ifndef __utl_meta_detection_h__
|
||||
#define __utl_meta_detection_h__
|
||||
|
||||
#include <utl/core/impl.h>
|
||||
#include <utl/meta/logical.h>
|
||||
#include <type_traits>
|
||||
|
||||
/*!
|
||||
* \ingroup meta
|
||||
* \defgroup void
|
||||
* \defgroup detection
|
||||
* Detection idiom support header.
|
||||
*/
|
||||
//! @{
|
||||
|
||||
@@ -42,7 +47,7 @@ namespace meta {
|
||||
};
|
||||
//! void_t type alias
|
||||
template<typename... _Ts>
|
||||
using void_t = type_of<void_<_Ts...>>;
|
||||
using void_t = eval<void_<_Ts...>>;
|
||||
#else
|
||||
//! void_ type alias
|
||||
template <typename...> using void_ = void;
|
||||
@@ -2,7 +2,7 @@
|
||||
* \file pack.h
|
||||
* \brief Template meta-programming parameter pack container
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -65,8 +65,8 @@ namespace meta {
|
||||
// Builds an index_tuple<0, 1, 2, ..., _Num-1>.
|
||||
template<size_t _Num>
|
||||
struct make_index_tuple_
|
||||
: it_cat_<type_<make_index_tuple_<_Num / 2>>,
|
||||
type_<make_index_tuple_<_Num - _Num / 2>>>
|
||||
: it_cat_<eval<make_index_tuple_<_Num / 2>>,
|
||||
eval<make_index_tuple_<_Num - _Num / 2>>>
|
||||
{ };
|
||||
// termination specialization for 1
|
||||
template<>
|
||||
@@ -81,7 +81,7 @@ namespace meta {
|
||||
|
||||
// factory type
|
||||
template<typename _Tp, _Tp _Num,
|
||||
typename _ISeq = type_<make_index_tuple_<_Num>>>
|
||||
typename _ISeq = eval<make_index_tuple_<_Num>>>
|
||||
struct make_integer_sequence_;
|
||||
|
||||
template<typename _Tp, _Tp _Num, size_t... _Idx>
|
||||
@@ -94,7 +94,7 @@ namespace meta {
|
||||
//! Alias template make_integer_sequence
|
||||
//! Complexity \f$ O(log N) \f$
|
||||
template<typename _Tp, _Tp N>
|
||||
using make_integer_sequence = type_<detail::make_integer_sequence_<_Tp, N>>;
|
||||
using make_integer_sequence = eval<detail::make_integer_sequence_<_Tp, N>>;
|
||||
|
||||
//! Alias template make_index_sequence
|
||||
//! Complexity \f$ O(log N) \f$
|
||||
|
||||
+25
-29
@@ -2,7 +2,7 @@
|
||||
* \file integralconstant.h
|
||||
* \brief Template meta-programming integral constant
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -43,20 +43,20 @@ namespace meta {
|
||||
using type = nil_;
|
||||
};
|
||||
|
||||
//! Type alias for \p _Tp::type. Used to extract return type of metafunctions
|
||||
//! Type alias for \p _Tp::type. Used to evaluate/extract return type of metafunctions
|
||||
template <typename _Tp>
|
||||
using type_ = typename _Tp::type;
|
||||
using eval = typename _Tp::type;
|
||||
|
||||
//! integral_constant
|
||||
//! An Integral Constant is a holder class for a compile-time value of an integral type.
|
||||
//! integral_
|
||||
//! Integral Constant is a holder class for a compile-time value of an integral type.
|
||||
//! Every Integral Constant is also a null-ary Metafunction, returning itself.
|
||||
//! An integral constant object is implicitly convertible to the corresponding
|
||||
//! run-time value of the wrapped integral type
|
||||
//! @{
|
||||
template <typename _Tp, _Tp _v>
|
||||
struct integral_constant {
|
||||
struct integral_ {
|
||||
using value_type = _Tp;
|
||||
using type = integral_constant<_Tp, _v>;
|
||||
using type = integral_<_Tp, _v>;
|
||||
|
||||
constexpr operator value_type() const noexcept {
|
||||
return value;
|
||||
@@ -68,77 +68,73 @@ namespace meta {
|
||||
};
|
||||
|
||||
template<typename _Tp, _Tp _v>
|
||||
constexpr _Tp integral_constant<_Tp, _v>::value;
|
||||
constexpr _Tp integral_<_Tp, _v>::value;
|
||||
//! @}
|
||||
|
||||
//! Wrappers for basic types
|
||||
//! @{
|
||||
|
||||
//! integral constant
|
||||
template <typename _Tp, _Tp _v>
|
||||
using integral_c = integral_constant<_Tp, _v>;
|
||||
|
||||
//! bool_ type: integral constant wrapper for bool
|
||||
template<bool _v>
|
||||
using bool_ = integral_c<bool, _v>;
|
||||
using bool_ = integral_<bool, _v>;
|
||||
|
||||
using true_ = bool_<true>; //!< The type used as a compile-time boolean with true value.
|
||||
using false_ = bool_<false>; //!< The type used as a compile-time boolean with false value.
|
||||
|
||||
//! int8_ type: integral constant wrapper for \c int8_t
|
||||
template<int8_t _v>
|
||||
using int8_ = integral_c<int8_t, _v>;
|
||||
using int8_ = integral_<int8_t, _v>;
|
||||
//! uint8_ type: integral constant wrapper for \c uint8_t
|
||||
template<uint8_t _v>
|
||||
using uint8_ = integral_c<uint8_t, _v>;
|
||||
using uint8_ = integral_<uint8_t, _v>;
|
||||
|
||||
//! int16_ type: integral constant wrapper for \c int16_t
|
||||
template<int16_t _v>
|
||||
using int16_ = integral_c<int16_t, _v>;
|
||||
using int16_ = integral_<int16_t, _v>;
|
||||
//! uint16_ type: integral constant wrapper for \c uint16_t
|
||||
template<uint16_t _v>
|
||||
using uint16_ = integral_c<uint16_t, _v>;
|
||||
using uint16_ = integral_<uint16_t, _v>;
|
||||
|
||||
//! int32_ type: integral constant wrapper for \c int32_t
|
||||
template<int32_t _v>
|
||||
using int32_ = integral_c<int32_t, _v>;
|
||||
using int32_ = integral_<int32_t, _v>;
|
||||
//! uint32_ type: integral constant wrapper for \c uint32_t
|
||||
template<uint32_t _v>
|
||||
using uint32_ = integral_c<uint32_t, _v>;
|
||||
using uint32_ = integral_<uint32_t, _v>;
|
||||
|
||||
//! char_ type: integral constant wrapper for \c char
|
||||
template<char _v>
|
||||
using char_ = integral_c<char, _v>;
|
||||
using char_ = integral_<char, _v>;
|
||||
|
||||
//! int_ type: integral constant wrapper for \c int
|
||||
template<int _v>
|
||||
using int_ = integral_c<int, _v>;
|
||||
using int_ = integral_<int, _v>;
|
||||
|
||||
//! long_ type: integral constant wrapper for \c long
|
||||
template<long _v>
|
||||
using long_ = integral_c<long, _v>;
|
||||
using long_ = integral_<long, _v>;
|
||||
|
||||
//! index_t_ type: integral constant wrapper for \c index_t a.k.a std::size_t
|
||||
//! index_ type: integral constant wrapper for \c index_t a.k.a std::size_t
|
||||
template<index_t _v>
|
||||
using index_t_ = integral_c<index_t, _v>;
|
||||
using index_ = integral_<index_t, _v>;
|
||||
|
||||
//! size_t_ type: integral constant wrapper for \c size_t a.k.a std::size_t
|
||||
//! size_ type: integral constant wrapper for \c size_t a.k.a std::size_t
|
||||
template<size_t _v>
|
||||
using size_t_ = integral_constant<size_t, _v>;
|
||||
using size_ = integral_<size_t, _v>;
|
||||
|
||||
//! Computes the size of the type \p _Tp.
|
||||
//! Complexity \f$ O(1) \f$.
|
||||
template <typename _Tp>
|
||||
using sizeof_ = size_t_<sizeof(_Tp)>;
|
||||
using sizeof_ = size_<sizeof(_Tp)>;
|
||||
|
||||
//! Computes the alignment required for any instance of the type \p _Tp.
|
||||
//! Complexity \f$ O(1) \f$.
|
||||
template <typename _Tp>
|
||||
using alignof_ = size_t_<alignof(_Tp)>;
|
||||
using alignof_ = size_<alignof(_Tp)>;
|
||||
//! @}
|
||||
|
||||
//! The last position we can express for indexing
|
||||
using Npos = size_t_<index_t(-1)>;
|
||||
using Npos = size_<index_t(-1)>;
|
||||
|
||||
}}
|
||||
//!@}
|
||||
|
||||
+22
-37
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* \file invoke.h
|
||||
* \brief Template meta-programming utilities
|
||||
* \brief Template meta-programming utilities for callables
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
*
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* GNU Lesser General Public License for more detail.
|
||||
*
|
||||
* 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/>.
|
||||
@@ -36,26 +36,10 @@ namespace utl {
|
||||
namespace meta{
|
||||
|
||||
/*!
|
||||
* \name meta:: invoke
|
||||
*
|
||||
* \name invoke
|
||||
* All Metafunction classes shall contain apply, which is Metafunction
|
||||
*
|
||||
* Metafunction:
|
||||
* A metafunction is a class or a class template that represents a function invocable at compile-time.
|
||||
* An non-nullary metafunction is invoked by instantiating the class template with particular template
|
||||
* parameters (metafunction arguments). The result of the metafunction application is accessible
|
||||
* through the instantiation's nested type typedef.
|
||||
* All metafunction's arguments must be types (i.e. only type template parameters are allowed).
|
||||
* A metafunction can have a variable number of parameters.
|
||||
* A nullary metafunction is represented as a (template) class with a nested type typename member.
|
||||
*
|
||||
* Metafunction Class:
|
||||
* A metafunction class is a certain form of metafunction representation that enables higher-order
|
||||
* metaprogramming. More precisely, it's a class with a publicly-accessible nested Metafunction called
|
||||
* apply. Correspondingly, a metafunction class invocation is defined as invocation of its nested apply
|
||||
* metafunction.
|
||||
*
|
||||
* Concept here is `Invokable` (contains apply metafunction)
|
||||
* A meta-programming invoke() analogous. A meta:: `invocable` shall contain a nested
|
||||
* template type named `apply` which is bind to actual invocable meta-function.
|
||||
*/
|
||||
//! @{
|
||||
|
||||
@@ -78,7 +62,7 @@ namespace meta{
|
||||
|
||||
//! identity type alias
|
||||
template <typename _Tp>
|
||||
using identity_t = type_<identity<_Tp>>;
|
||||
using identity_t = eval<identity<_Tp>>;
|
||||
//! @}
|
||||
|
||||
//! Is applicable trait
|
||||
@@ -100,7 +84,7 @@ namespace meta{
|
||||
|
||||
template<typename F, typename... T>
|
||||
struct is_applicable_q_ {
|
||||
template<typename G, typename Ret= type_<use_<G, T...>>>
|
||||
template<typename G, typename Ret= eval<use_<G, T...>>>
|
||||
static Ret check (int); //< T.. can be passed to G
|
||||
template<typename...>
|
||||
static nil_ check (...); //< all other combinations
|
||||
@@ -121,17 +105,17 @@ namespace meta{
|
||||
|
||||
//! check if we can instantiate \p F with parameters \p T
|
||||
template<template<typename...> class F, typename... T>
|
||||
using is_applicable_t = type_<
|
||||
using is_applicable_t = eval<
|
||||
detail::is_applicable_<F, T...>
|
||||
>;
|
||||
//! check if we can instantiate \p Q with parameters \p T and the instant
|
||||
//! is different from \c nil_
|
||||
template<typename Q, typename... T>
|
||||
using is_applicable_qt = type_ <
|
||||
using is_applicable_qt = eval <
|
||||
// Extra check for quoted metafunctions to check return type
|
||||
if_ <
|
||||
not_same_<
|
||||
type_ <detail::is_applicable_q_ <Q, T...>>,
|
||||
eval <detail::is_applicable_q_ <Q, T...>>,
|
||||
nil_
|
||||
>,
|
||||
true_,
|
||||
@@ -140,7 +124,7 @@ namespace meta{
|
||||
>;
|
||||
//! check if we can instantiate \p F with parameters \p Is of type \p T
|
||||
template <typename T, template<T...> class F, T... Is>
|
||||
using is_applicable_it = type_<
|
||||
using is_applicable_it = eval<
|
||||
detail::is_applicable_i_<T, F, Is...>
|
||||
>;
|
||||
|
||||
@@ -199,7 +183,7 @@ namespace meta{
|
||||
template <template <typename...> class F>
|
||||
struct quote {
|
||||
template <typename... Args>
|
||||
using apply = type_<
|
||||
using apply = eval<
|
||||
defer<F, Args...> //!< defer here to avoid DR1430
|
||||
>;
|
||||
};
|
||||
@@ -209,24 +193,26 @@ namespace meta{
|
||||
struct quote_i {
|
||||
// requires meta::Integral
|
||||
template <typename... Ts>
|
||||
using apply = type_<
|
||||
using apply = eval<
|
||||
defer_i<T, F, Ts::type::value...> //!< defer here to avoid DR1430
|
||||
>;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Invoke the nested apply metafunction from \c Fn
|
||||
* Invoke the nested apply meta-function from \c Fn
|
||||
* with the arguments \c Args.
|
||||
* \note
|
||||
* This is like the std::invoke()
|
||||
*/
|
||||
template <typename Fn, typename... Args>
|
||||
using invoke = typename Fn::template apply<Args...>;
|
||||
|
||||
/*!
|
||||
* Invoke the nested apply metafunction from \c Fn
|
||||
* with the arguments \c Args.
|
||||
* Evaluate the invocation of the nested apply metafunction from \p Fn
|
||||
* with the arguments \p Args.
|
||||
*/
|
||||
template <typename Fn, typename... Args>
|
||||
using invoke_t = type_<invoke <Fn, Args...>>;
|
||||
using invoke_t = eval< invoke <Fn, Args...>>;
|
||||
|
||||
//! compose
|
||||
//! @{
|
||||
@@ -252,7 +238,7 @@ namespace meta{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create an invokable from other invocables by composition.
|
||||
* Create an invocable from other invocables by composition.
|
||||
* \note
|
||||
* This implies from N invocables in \p Fns the first N-1 has to be unary.
|
||||
* That because of the "return" type of metafunction. They can only return one
|
||||
@@ -290,7 +276,7 @@ namespace meta{
|
||||
};
|
||||
|
||||
/*
|
||||
* ========== predicates ============
|
||||
* ========== meta:: predicates ============
|
||||
*/
|
||||
template <typename T1>
|
||||
struct same_as {
|
||||
@@ -304,10 +290,9 @@ namespace meta{
|
||||
struct apply : not_same_<T1, T2> { };
|
||||
};
|
||||
|
||||
|
||||
//! @}
|
||||
}}
|
||||
|
||||
//! @}
|
||||
//! @}
|
||||
|
||||
#endif /* __utl_meta_invoke_h__ */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* \file logical.h
|
||||
* \brief Template meta-programming logic operator and type relations.
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -66,7 +66,7 @@ namespace meta{
|
||||
}
|
||||
|
||||
template <typename... _Ts>
|
||||
using or_ = type_<detail::_or_<_Ts...>>;
|
||||
using or_ = eval<detail::_or_<_Ts...>>;
|
||||
//! @}
|
||||
|
||||
//! AND implementation
|
||||
@@ -92,7 +92,7 @@ namespace meta{
|
||||
}
|
||||
|
||||
template <typename... _Ts>
|
||||
using and_ = type_<detail::_and_<_Ts...>>;
|
||||
using and_ = eval<detail::_and_<_Ts...>>;
|
||||
//! @}
|
||||
|
||||
//! same
|
||||
@@ -107,7 +107,7 @@ namespace meta{
|
||||
//! not same
|
||||
//! @{
|
||||
template<typename _T1, typename _T2>
|
||||
using not_same_ = not_<type_<same_<_T1, _T2>>>;
|
||||
using not_same_ = not_<eval<same_<_T1, _T2>>>;
|
||||
//! @}
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* \file /utl/core/version.h
|
||||
* \brief version and cpp version checks
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* \file operators.h
|
||||
* \brief Template meta-programming integral constant arithmetic
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -41,28 +41,28 @@ namespace meta {
|
||||
|
||||
//! Negation
|
||||
template <typename _Tp>
|
||||
using negate = integral_constant<decltype(-_Tp()), -_Tp()>;
|
||||
using negate = integral_<decltype(-_Tp()), -_Tp()>;
|
||||
//! Addition
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
using add = integral_constant<
|
||||
using add = integral_<
|
||||
decltype(_Tp1() + _Tp2()),
|
||||
_Tp1() + _Tp2()
|
||||
>;
|
||||
//! Multiplication
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
using mult = integral_constant<
|
||||
using mult = integral_<
|
||||
decltype(_Tp2() * _Tp2()),
|
||||
_Tp1() * _Tp2()
|
||||
>;
|
||||
//! Division
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
using divide = integral_constant<
|
||||
using divide = integral_<
|
||||
decltype(_Tp2() / _Tp2()),
|
||||
_Tp1() / _Tp2()
|
||||
>;
|
||||
//! Modulo
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
using modulo = integral_constant<
|
||||
using modulo = integral_<
|
||||
decltype(_Tp1() % _Tp2()),
|
||||
_Tp1() % _Tp2()
|
||||
>;
|
||||
@@ -108,23 +108,23 @@ namespace meta {
|
||||
//! @{
|
||||
|
||||
//! \return bitwise not (~) operation of its argument.
|
||||
template <typename _T> using bitnot_ = integral_c<typename _T::value_type, (typename _T::value_type)(~_T())>;
|
||||
template <typename _T> using bitnot_ = integral_<typename _T::value_type, (typename _T::value_type)(~_T())>;
|
||||
//! \return bitwise and (&) operation of its arguments
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
using bitand_ = integral_c<decltype(_Tp1() & _Tp2()), _Tp1() & _Tp2()>;
|
||||
using bitand_ = integral_<decltype(_Tp1() & _Tp2()), _Tp1() & _Tp2()>;
|
||||
//! \return bitwise or (|) operation of its arguments.
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
using bitor_ = integral_c<decltype(_Tp1() | _Tp2()), _Tp1() | _Tp2()>;
|
||||
using bitor_ = integral_<decltype(_Tp1() | _Tp2()), _Tp1() | _Tp2()>;
|
||||
|
||||
//! \return bitwise xor (^) operation of its arguments.
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
using bitxor_ = integral_c<decltype(_Tp1() ^ _Tp2()), _Tp1() ^ _Tp2()>;
|
||||
using bitxor_ = integral_<decltype(_Tp1() ^ _Tp2()), _Tp1() ^ _Tp2()>;
|
||||
//! \return the result of bitwise shift left (<<) operation on _Tp.
|
||||
template <typename _Tp, typename shift>
|
||||
using shift_left = integral_c<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() << shift())>;
|
||||
using shift_left = integral_<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() << shift())>;
|
||||
//! \return the result of bitwise shift right (>>) operation on _Tp.
|
||||
template <typename _Tp, typename shift>
|
||||
using shift_right = integral_c<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() >> shift())>;
|
||||
using shift_right = integral_<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() >> shift())>;
|
||||
//! @}
|
||||
}}
|
||||
//!@}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* \file selection.h
|
||||
* \brief Template meta-programming type selections.
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -60,7 +60,7 @@ namespace meta{
|
||||
}
|
||||
//! Select one type or another depending on a compile-time Boolean.
|
||||
template <bool B, typename... Args>
|
||||
using if_c = type_<detail::if_c_<B, Args...>>;
|
||||
using if_c = eval<detail::if_c_<B, Args...>>;
|
||||
|
||||
//! Select one type or another depending on a compile-time Boolean type
|
||||
template <typename If, typename... Args>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* \file sfinae.h
|
||||
* \brief Template meta-programming SFINAE helpers
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -42,7 +42,7 @@ namespace meta {
|
||||
}
|
||||
//! Well formed only if \p If is true
|
||||
template <bool If>
|
||||
using when = type_<detail::when_<If>>;
|
||||
using when = eval<detail::when_<If>>;
|
||||
|
||||
//! Well formed only if all of \p Ifs are \c true
|
||||
template <bool ...Ifs>
|
||||
@@ -52,7 +52,7 @@ namespace meta {
|
||||
//! @}
|
||||
|
||||
//! select _Tp if \p If is true, else SFINAE
|
||||
//! We implement eneble_if so we don't have to pull entire \c <type_traits> from stl
|
||||
//! We implement enable_if so we don't have to pull entire \c <type_traits> from stl
|
||||
//! @{
|
||||
template <bool If, typename _Tp = void>
|
||||
struct enable_if {
|
||||
@@ -67,13 +67,13 @@ namespace meta {
|
||||
|
||||
//! Publicly recognized alias template for enable_if
|
||||
template<bool If, typename _Tp = void>
|
||||
using enable_if_t = type_<
|
||||
using enable_if_t = eval<
|
||||
enable_if<If, _Tp>
|
||||
>;
|
||||
|
||||
//! Uniform alias template for use_if
|
||||
template<bool If, typename _Tp = void>
|
||||
using use_if_t = type_<
|
||||
using use_if_t = eval<
|
||||
enable_if<If, _Tp>
|
||||
>;
|
||||
//! @}
|
||||
|
||||
+44
-42
@@ -2,7 +2,7 @@
|
||||
* \file typelist.h
|
||||
* \brief A template parameter "container"
|
||||
*
|
||||
* Copyright (C) 2018 Christos Choutouridis
|
||||
* 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
|
||||
@@ -53,9 +53,9 @@ namespace meta {
|
||||
* l1 a {};
|
||||
* \endcode
|
||||
*
|
||||
* boost::hana[3] suggest a more powerful scheme were type invariant structures can be used
|
||||
* boost::hana[3] suggests a more powerful scheme were type invariant structures can be used
|
||||
* for metaprograming also. This lib does not need (yet) this kind of power (we afraid the
|
||||
* responsibility that come along). So a simple python-like list with some extra vector-like
|
||||
* responsibility that comes along). So a simple python-like list with some extra vector-like
|
||||
* element access functionalities and no iterators is good enough(for now).
|
||||
*
|
||||
* [1]: https://www.boost.org/doc/
|
||||
@@ -115,7 +115,7 @@ namespace meta {
|
||||
* \return The size of the typelist
|
||||
*/
|
||||
template <typename List>
|
||||
using size = size_t_<List::size()>;
|
||||
using size = size_<List::size()>;
|
||||
|
||||
/*!
|
||||
* An Boolean constant wrapper that returns if the typelist is empty
|
||||
@@ -152,6 +152,8 @@ namespace meta {
|
||||
|
||||
/*!
|
||||
* Apply
|
||||
* An analogous to apply() implementation for tuples. We just use
|
||||
* Our typelist<> and integer_sequence<> types.
|
||||
*/
|
||||
//! @{
|
||||
namespace apply_impl {
|
||||
@@ -166,7 +168,7 @@ namespace meta {
|
||||
//! Sequence == integer_sequence<>
|
||||
template <typename Fn, typename T, T... Is>
|
||||
struct apply_<Fn, integer_sequence<T, Is...>> {
|
||||
using type = invoke<Fn, integral_c<T, Is>...>;
|
||||
using type = invoke<Fn, integral_<T, Is>...>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -194,7 +196,7 @@ namespace meta {
|
||||
|
||||
template <typename T> struct _as_pointer__ { using type = T*; };
|
||||
template <typename T> struct _as_pointer__<T*> { using type = T*; };
|
||||
template <typename T> using as_pointer_ = type_<
|
||||
template <typename T> using as_pointer_ = eval<
|
||||
_as_pointer__<T>
|
||||
>;
|
||||
|
||||
@@ -227,7 +229,7 @@ namespace meta {
|
||||
* Complexity \f$ O(N) \f$.
|
||||
*/
|
||||
template <typename List, index_t N>
|
||||
using at_c = type_<
|
||||
using at_c = eval<
|
||||
at_impl::at_<List, N>
|
||||
>;
|
||||
|
||||
@@ -256,7 +258,7 @@ namespace meta {
|
||||
//! Return the first element in \c meta::typelist \p List.
|
||||
//! Complexity \f$ O(1) \f$.
|
||||
template <typename List>
|
||||
using front = type_<
|
||||
using front = eval<
|
||||
front_impl::front_<List>
|
||||
>;
|
||||
//! @}
|
||||
@@ -278,7 +280,7 @@ namespace meta {
|
||||
//! Return the last element in \c meta::typelist \p List.
|
||||
//! Complexity \f$ O(N) \f$.
|
||||
template <typename List>
|
||||
using back = type_<
|
||||
using back = eval<
|
||||
back_impl::back_<List>
|
||||
>;
|
||||
//! @}
|
||||
@@ -320,7 +322,7 @@ namespace meta {
|
||||
* where \f$ N \f$ is the number of lists passed to the algorithm.
|
||||
*/
|
||||
template <typename... Lists>
|
||||
using cat = type_<
|
||||
using cat = eval<
|
||||
cat_impl::cat_<Lists...>
|
||||
>;
|
||||
//! @}
|
||||
@@ -339,7 +341,7 @@ namespace meta {
|
||||
typename Fn>
|
||||
struct fold_<typelist<Head, Tail...>, V, Fn> {
|
||||
// recursive call of fold_ by consuming typelist and invoking Fn
|
||||
using type = type_<
|
||||
using type = eval<
|
||||
fold_<
|
||||
typelist<Tail...>,
|
||||
invoke<Fn, V, Head>,
|
||||
@@ -367,7 +369,7 @@ namespace meta {
|
||||
* \param Fn The binary Invocable
|
||||
*/
|
||||
template <typename List, typename V, typename Fn>
|
||||
using fold = type_<fold_impl::fold_<List, V, Fn>>;
|
||||
using fold = eval<fold_impl::fold_<List, V, Fn>>;
|
||||
|
||||
//! accumulate is an stl name for fold
|
||||
template <typename List, typename V, typename Fn>
|
||||
@@ -387,7 +389,7 @@ namespace meta {
|
||||
// recursive call inside invoke. This way the 2nd argument of Fn
|
||||
// becoming the recursive "thing", inside Fn<>
|
||||
using type = invoke <
|
||||
Fn, Head, type_<
|
||||
Fn, Head, eval<
|
||||
rev_fold_ <
|
||||
typelist<Tail...>,
|
||||
V,
|
||||
@@ -420,7 +422,7 @@ namespace meta {
|
||||
* \param Fn The binary Invocable
|
||||
*/
|
||||
template <typename List, typename V, typename Fn>
|
||||
using rev_fold = type_<
|
||||
using rev_fold = eval<
|
||||
rev_fold_impl::rev_fold_<List, V, Fn>
|
||||
>;
|
||||
//! @}
|
||||
@@ -430,7 +432,7 @@ namespace meta {
|
||||
* Complexity \f$ O(1) \f$
|
||||
*/
|
||||
template <typename List, typename... Ts>
|
||||
using push_front = type_<
|
||||
using push_front = eval<
|
||||
apply <
|
||||
bind_front<quote<typelist>, Ts...>, List
|
||||
>
|
||||
@@ -441,7 +443,7 @@ namespace meta {
|
||||
* Complexity \f$ O(1) \f$
|
||||
*/
|
||||
template <typename List, typename... Ts>
|
||||
using push_back = type_<
|
||||
using push_back = eval<
|
||||
apply <
|
||||
bind_back<quote<typelist>, Ts...>, List
|
||||
>
|
||||
@@ -462,7 +464,7 @@ namespace meta {
|
||||
* Complexity \f$ O(N) \f$
|
||||
*/
|
||||
template <typename List>
|
||||
using reverse = type_<
|
||||
using reverse = eval<
|
||||
reverse_impl::reverse_<List>
|
||||
>;
|
||||
//! @}
|
||||
@@ -485,7 +487,7 @@ namespace meta {
|
||||
* Complexity \f$ O(1) \f$
|
||||
*/
|
||||
template <typename List>
|
||||
using pop_front = type_<
|
||||
using pop_front = eval<
|
||||
pop_front_impl::pop_front_<List>
|
||||
>;
|
||||
//! @}
|
||||
@@ -509,7 +511,7 @@ namespace meta {
|
||||
* heavy(2 reverse operations).
|
||||
*/
|
||||
template <typename List>
|
||||
using pop_back = type_ <
|
||||
using pop_back = eval <
|
||||
pop_back_impl::pop_back_<List>
|
||||
>;
|
||||
//! @}
|
||||
@@ -551,7 +553,7 @@ namespace meta {
|
||||
* \endcode
|
||||
*/
|
||||
template <typename... Args>
|
||||
using transform = type_<
|
||||
using transform = eval<
|
||||
transform_impl::transform_<typelist<Args...>>
|
||||
>;
|
||||
//! @}
|
||||
@@ -597,7 +599,7 @@ namespace meta {
|
||||
* \endcode
|
||||
*/
|
||||
template <typename... Args>
|
||||
using transform_lazy = type_<
|
||||
using transform_lazy = eval<
|
||||
transform_lazy_impl::transform_lazy_<typelist<Args...>>
|
||||
>;
|
||||
//! @}
|
||||
@@ -614,8 +616,8 @@ namespace meta {
|
||||
// Recursive call to find_if_ until Fn returns true_
|
||||
using type = if_ <
|
||||
invoke_t<Fn, Head>,
|
||||
index_t_<N>, // done, return current index
|
||||
type_<find_if_< // not done, re-call find_if_ with the Tail...
|
||||
index_<N>, // done, return current index
|
||||
eval<find_if_< // not done, re-call find_if_ with the Tail...
|
||||
typelist<Tail...>, Fn, N+1>
|
||||
>
|
||||
>;
|
||||
@@ -630,7 +632,7 @@ namespace meta {
|
||||
|
||||
/*!
|
||||
* Search for the first \c Item on the \p List for which the predicate \p Pred
|
||||
* returns true_ when `type_<invoke<Pred, Item>>`
|
||||
* returns true_ when `eval<invoke<Pred, Item>>`
|
||||
*
|
||||
* Complexity \f$ O(N) \f$
|
||||
*
|
||||
@@ -640,7 +642,7 @@ namespace meta {
|
||||
* or Npos otherwise.
|
||||
*/
|
||||
template<typename List, typename Pred>
|
||||
using find_if = type_<
|
||||
using find_if = eval<
|
||||
find_if_impl::find_if_<List, Pred, 0>
|
||||
>;
|
||||
|
||||
@@ -663,7 +665,7 @@ namespace meta {
|
||||
using type = if_ <
|
||||
invoke_t<Fn, Head>,
|
||||
typelist<Head, Tail...>, // done, return the typelist starting from here
|
||||
type_<seek_if_< // not done, re-call seek_if_ with the Tail...
|
||||
eval<seek_if_< // not done, re-call seek_if_ with the Tail...
|
||||
typelist<Tail...>, Fn, N+1>
|
||||
>
|
||||
>;
|
||||
@@ -678,7 +680,7 @@ namespace meta {
|
||||
|
||||
/*!
|
||||
* Search for the first \c Item on the \p List for which the predicate \p Pred
|
||||
* returns true_ when `type_<invoke<Pred, Item>>` and return the rest of the \p List
|
||||
* returns true_ when `eval<invoke<Pred, Item>>` and return the rest of the \p List
|
||||
* starting from that position as new typelist
|
||||
*
|
||||
* Complexity \f$ O(N) \f$
|
||||
@@ -688,7 +690,7 @@ namespace meta {
|
||||
* \return An integral constant with the location of the first match, on Npos otherwise
|
||||
*/
|
||||
template <typename List, typename Pred>
|
||||
using seek_if = type_<
|
||||
using seek_if = eval<
|
||||
seek_if_impl::seek_if_<List, Pred, 0>
|
||||
>;
|
||||
/*!
|
||||
@@ -711,10 +713,10 @@ namespace meta {
|
||||
// returning true_
|
||||
using type = if_ <
|
||||
invoke_t<Fn, Head>,
|
||||
type_<
|
||||
eval<
|
||||
count_if_<typelist<Tail...>, Fn, N+1> // increase and re-call
|
||||
>,
|
||||
type_<
|
||||
eval<
|
||||
count_if_<typelist<Tail...>, Fn, N> // re-call without increasing
|
||||
>
|
||||
>;
|
||||
@@ -723,13 +725,13 @@ namespace meta {
|
||||
// At the end of the List return the counter
|
||||
template<typename Fn, size_t N>
|
||||
struct count_if_<typelist<>, Fn, N> {
|
||||
using type = size_t_<N>;
|
||||
using type = size_<N>;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Count all \c Items on the \p List for which the predicate \p Pred
|
||||
* returns true_ when `type_<invoke<Pred, Item>>`
|
||||
* returns true_ when `eval<invoke<Pred, Item>>`
|
||||
*
|
||||
* Complexity \f$ O(N) \f$
|
||||
*
|
||||
@@ -738,7 +740,7 @@ namespace meta {
|
||||
* \return The total count of occurrences as an integral constant of size_t
|
||||
*/
|
||||
template <typename List, typename Pred>
|
||||
using count_if = type_<
|
||||
using count_if = eval<
|
||||
count_if_impl::count_if_<List, Pred, 0>
|
||||
>;
|
||||
|
||||
@@ -761,8 +763,8 @@ namespace meta {
|
||||
// of items for which the invoke of Fn returns true_
|
||||
using type = if_ <
|
||||
invoke_t <Fn, Head>,
|
||||
type_<filter_<typelist<Tail...>, Fn, cat<L, typelist<Head>>>>, // Add the element and re-call
|
||||
type_<filter_<typelist<Tail...>, Fn, L>> // re-call with the same list
|
||||
eval<filter_<typelist<Tail...>, Fn, cat<L, typelist<Head>>>>, // Add the element and re-call
|
||||
eval<filter_<typelist<Tail...>, Fn, L>> // re-call with the same list
|
||||
>;
|
||||
};
|
||||
|
||||
@@ -775,7 +777,7 @@ namespace meta {
|
||||
|
||||
/*!
|
||||
* Return a new typelist with elements, the elements of \p List that satisfy the
|
||||
* invocable \p Pred such that `type_<invoke<Pred, Item>>` is \c true_
|
||||
* invocable \p Pred such that `eval<invoke<Pred, Item>>` is \c true_
|
||||
*
|
||||
* Complexity \f$ O(N) \f$
|
||||
*
|
||||
@@ -783,7 +785,7 @@ namespace meta {
|
||||
* \param Pred A unary invocable predicate
|
||||
*/
|
||||
template <typename List, typename Pred>
|
||||
using filter = type_<
|
||||
using filter = eval<
|
||||
filter_impl::filter_<List, Pred, typelist<>>
|
||||
>;
|
||||
//! @}
|
||||
@@ -800,8 +802,8 @@ namespace meta {
|
||||
// of items based on invocation of Fn
|
||||
using type = if_ <
|
||||
invoke_t<Fn, Head>,
|
||||
type_<replace_if_<typelist<Tail...>, Fn, T, cat<Ret, typelist<T>>>>, // re-call with change to T
|
||||
type_<replace_if_<typelist<Tail...>, Fn, T, cat<Ret, typelist<Head>>>> // re-call with no change
|
||||
eval<replace_if_<typelist<Tail...>, Fn, T, cat<Ret, typelist<T>>>>, // re-call with change to T
|
||||
eval<replace_if_<typelist<Tail...>, Fn, T, cat<Ret, typelist<Head>>>> // re-call with no change
|
||||
>;
|
||||
};
|
||||
|
||||
@@ -820,18 +822,18 @@ namespace meta {
|
||||
*
|
||||
* \param List The input typelist
|
||||
* \param Pred A unary invocable predicate
|
||||
* \param T The new type to replace the item of the \p List, when type_<invoke<Pred, Item>>
|
||||
* \param T The new type to replace the item of the \p List, when eval<invoke<Pred, Item>>
|
||||
* returns \c true_
|
||||
*/
|
||||
template<typename List, typename Pred, typename T>
|
||||
using replace_if = type_<
|
||||
using replace_if = eval<
|
||||
replace_if_impl::replace_if_<List, Pred, T, typelist<>>
|
||||
>;
|
||||
|
||||
//! Alias wrapper that returns a new \c typelist where all instances of type \p T have
|
||||
//! been replaced with \p U.
|
||||
template <typename List, typename T, typename U>
|
||||
using replace = type_ <
|
||||
using replace = eval <
|
||||
replace_if <List, same_as<T>, U>
|
||||
>;
|
||||
//! @}
|
||||
|
||||
@@ -35,21 +35,21 @@ namespace meta {
|
||||
|
||||
//! If same type resolves to _Ret, else SFINAE
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
using use_if_same_t = type_<
|
||||
using use_if_same_t = eval<
|
||||
enable_if<
|
||||
same_<_T1, _T2>::value, _Ret
|
||||
>
|
||||
>;
|
||||
//! If not same type resolves to _Ret, else SFINAE
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
using use_if_not_same_t = type_<
|
||||
using use_if_not_same_t = eval<
|
||||
enable_if<
|
||||
!same_<_T1, _T2>::value, _Ret
|
||||
>
|
||||
>;
|
||||
//! If any type (_T1 or _T2) type resolves to _Ret, else to SFINAE
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
using use_if_any_t = type_<
|
||||
using use_if_any_t = eval<
|
||||
enable_if<
|
||||
or_<_T1, _T2>::value, _Ret
|
||||
>
|
||||
@@ -57,7 +57,7 @@ namespace meta {
|
||||
|
||||
//! If both type (_T1 and _T2) type resolves to _Ret, else to SFINAE
|
||||
template <typename _T1, typename _T2, typename _Ret =_T1>
|
||||
using use_if_both_t = type_<
|
||||
using use_if_both_t = eval<
|
||||
enable_if<
|
||||
and_<_T1, _T2>::value, _Ret
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user