C++ : Folds over variadic templates
Code like the following motivates the need to compute conjunctions (and disjunctions) of predicate packs.
template <class T, class... Ts> struct recursive_unionI was much helped by a suitable implementation of{ // ... //'U' is not 'T' but 'T' is a recursive wrapper and 'U' is the type //contained in 'T' template <class U, class... Args, std::enable_if_t< and_< is_recursive_wrapper<T> , std::is_same<U, unwrap_recursive_wrapper_t<T>>>::value, int> = 0 > explicit recursive_union (constructor<U>, Args&&... args) noexcept (std::is_nothrow_constructible<U, Args...>::value) : v (std::forward<Args>(args)...) {} // ... };
and_<> credited to Jonathan Wakely. A more general approach to is to use fold.
#include <type_traits>
namespace pgs {
template<class F, class Acc, class... Ts>
struct fold_left : Acc {
};
template <class F, class Acc, class T, class... Ts>
struct fold_left<F, Acc, T, Ts...> :
fold_left <F, typename F::template apply<Acc, T>::type, Ts...> {
};
//or
struct or_helper {
template <class Acc, class T>
struct apply : std::integral_constant<bool, Acc::value || T::value> {
};
};
template <class... Ts>
struct or_ : fold_left <or_helper, std::false_type, Ts...> {
};
//and
struct and_helper {
template <class Acc, class T>
struct apply : std::integral_constant<bool, Acc::value && T::value> {
};
};
template <class... Ts>
struct and_ : fold_left <and_helper, std::true_type, Ts...> {
};
}//namespace pgs