1

I already have a template that given a tuple and an index_sequence can create a new tuple having the elements indexed by that sequence. This function template is called project

I figured if I can somehow calculate the difference of two index_sequences then I'm done: I pass to project the difference of make_index_sequence<original_tuple_t> and the given one, which is assumed sorted and unique.

Is this a good approach? Do you know how to implement this?

2
  • Is the filter sequence sorted? Commented Nov 11, 2015 at 10:56
  • Yes we can assume that it is sorted and unique. Commented Nov 11, 2015 at 10:57

1 Answer 1

1

Here is a possible implementation.

First we'll start off with a simple trait to add a std::size_t onto the front of a std::index_sequence:

template <std::size_t First, typename Seq>
struct sequence_cat;

template <std::size_t First, std::size_t... Seq>
struct sequence_cat <First, std::index_sequence<Seq...>> {
    using type = std::index_sequence<First, Seq...>;   
};

//helper
template <std::size_t First, typename Seq>
using sequence_cat_t = typename sequence_cat<First, Seq>::type;

Now we'll define a trait called not_in_sequence which will recursively check the fronts of two std::index_sequences and filter off any from the first which occur in the second:

//empty first sequence
template <class First, class Second>
struct not_in_sequence {
    using type = std::index_sequence<>; 
};

//helper
template <class First, class Second>
using not_in_sequence_t = typename not_in_sequence<First, Second>::type;

//filter and recurse
template <std::size_t... First, std::size_t... Second, 
          std::size_t FirstHead, std::size_t SecondHead>
struct not_in_sequence <std::index_sequence<FirstHead, First...>,
                        std::index_sequence<SecondHead, Second...>> {
    using seq1 = std::index_sequence<First...>;
    using seq2 = std::index_sequence<Second...>;

    using type = 
        std::conditional_t<
            (FirstHead == SecondHead),
            not_in_sequence_t<seq1, seq2>,
            sequence_cat_t<
                FirstHead, 
                not_in_sequence_t<seq1, sequence_cat_t<SecondHead, seq2>>
            >
         >;   
}; 
//empty second sequence
template <std::size_t... First, std::size_t FirstHead>
struct not_in_sequence <std::index_sequence<FirstHead, First...>,
                        std::index_sequence<>> {
    using type = std::index_sequence<FirstHead, First...>;   
};

You can use not_in_sequence_t like so:

not_in_sequence_t<std::make_index_sequence<3>, std::index_sequence<0,2>>
//same as std::index_sequence<1>

There might be some edge-cases I've missed, but feel free to edit this as you like.

Live Demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.