Is there a way to:
1) remove item at index:
// Removes item at index N, e.g. Remove<2, a, b, c, d> results in <a, b, d>
template<std::size_t N, typename ...Args>
struct Remove {
// ???
};
2) replace item at index:
// Replaces item at index N with T, e.g. Replace<2, x, a, b, c, d> results in <a, b, x, d>
template<std::size_t N, typename T, typename ...Args>
struct Replace {
// ???
};
3) replace items in range
// Replaces items in range [N1, N2] with T, e.g. ReplaceRange<2, 3, x, a, b, c, d> results in <a, b, x>
template<std::size_t N1, std::size_t N2, typename T, typename ...Args>
struct ReplaceRange {
// ???
};
I want it to be used like that
class is_true {
public:
bool operator()() const { return true; }
};
class is_false {
public:
bool operator()() const { return false; }
};
class And {
};
class Or {
};
Filter f<is_true, And, is_true, Or, is_false>();
Now, I want to fold this to:
< FilterOr < FilterAnd <is_true, is_true>, is_false > >
Where
template<typename Lhs, typename Rhs>
class FilterAnd {
public:
bool operator()() const { return Lhs() && Rhs(); }
};
template<typename Lhs, typename Rhs>
class FilterOr {
public:
bool operator()() const { return Lhs() || Rhs(); }
};
So, I'm trying to do the following:
class Filter {
public:
template <typename ...Args>
void apply() {
holder_ = FilterHolder<typename FoldOperator<Or, FilterOr, typename FoldOperator<And, FilterAnd, Args...>::type >::type >();
}
}
FoldOperator basically removes operator arguments, and replaces operator with Filter class, e.g. for arguments <is_true, And, is_true>, I want to remove arguments (is_true) and replace operator (And) with Filter: FilterAnd<is_true, is_true> where arguments are the same as was removed from the list. So, I need replace/remove templates to perform that.
Thanks in advance.
This is way easier in C++14 with std::index_sequence, so I've used that. There are a bunch of implementations you can find of this online.
I use std::tuple to marshal everything around.
For Replace, I used std::conditional to choose either T or the correct tuple element for each type index.
For Remove, I take the decltype of tuple_catting either an empty tuple or tuple containing the correct tuple element for a non-removed type index.
namespace detail{
template<std::size_t N, typename T, typename Tuple, std::size_t... Idx>
auto replace (std::index_sequence<Idx...>) ->
std::tuple<std::conditional_t<N == Idx,
T,
std::tuple_element_t<N, Tuple>>...>;
template<std::size_t N, typename Tuple, std::size_t... Idx>
auto remove (std::index_sequence<Idx...>) ->
decltype(std::tuple_cat(
std::declval<
std::conditional_t<(N == Idx),
std::tuple<>,
std::tuple<std::tuple_element_t<Idx, Tuple>>
>
>()...
));
}
template <std::size_t N, typename T, typename... Args>
using Replace = decltype(detail::replace<N,T,std::tuple<Args...>>
(std::index_sequence_for<Args...>{}));
template <std::size_t N, typename... Args>
using Remove = decltype(detail::remove<N,std::tuple<Args...>>
(std::index_sequence_for<Args...>{}));
ReplaceRange is left as an exercise to the reader.
Live Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With