Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm building a small MPL module in one of my utility libraries for fun and learning experience.

One of the problems I'm trying to solve is getting a list of all indices where a sequence of types appears inside another sequence of types.

Example:

static_assert(is_same
<
    List<int, char, int, int, char, int, double, int, char>
        ::IdxsOfSeq<int, char>,
    ListInt<0, 3, 7>
>());

The above code is valid and works as intended. However, finding out the indices of a subsequence in a long type sequence becomes very slow very fast.

Searching in a list with 20 or 30 elements can take up to 30 seconds of compilation time.

That would rarely be useful, but I'm also experimenting with compile-time strings implemented as character lists.

The current implementation of IdxsOfSeq basically uses std::index_sequence to perform a naive string matching algorithm over the type sequence.

The naive algorithm requires no preprocessing time, but the execution of the type matching requires a lot of computation time.

This is my current implementation of the string matching algorithm.

// Matches<bool, int> returns a ListInt<TStart> is the boolean
// is true, otherwise an empty ListInt<>
template<bool TAllTrue, int TStart> 
struct Matches;

template<int TStart> 
struct Matches<true, TStart> 
{ 
    using Type = ListInt<TStart>; 
};

template<int TStart> 
struct Matches<false, TStart>  
{ 
    using Type = ListInt<>; 
};



// GetMatch<TS, TM, TStart, TMIdxs>::Type checks if every type
// of TS (the source type sequence) starting from the index TStart
// matches every type in TM (the subsequence to find)
template<typename TS, typename TM, int TStart, typename TMIdxs> 
struct GetMatch;

template<typename TS, typename TM, int TStart, SizeT... TMIdxs> 
struct GetMatch<TS, TM, TStart, IdxSeq<TMIdxs...>>
{
    using Type = typename Matches
    <
        // True if all the types inside AreAllTrue are std::true_type
        AreAllTrue
        <
            // Type checking with index sequence expansion
            std::is_same_t
            <
                typename TS::template At<TStart + TMIdxs>,
                typename TM::template At<TMIdxs>
            >...
        >{}(),
        TStart
    >::Type;
};



// Main helper template
// Finds every occurrence of the list TM inside TS and returns its index
template<typename TS, typename TM, typename TSIdxs, typename TMIdxs>
struct IdxsOfSeqHlpr;

template<typename TS, typename TM, SizeT... TSIdxs, typename TMIdxs> 
struct IdxsOfSeqHlpr<TS, TM, IdxSeq<TSIdxs...>, TMIdxs>
{
    // ConcatLists (obviously) concatenates the contents of the
    // lists passed as template parameters in a single list
    using Type = typename ConcatLists
    <
        ListInt<>, 
        typename GetMatch<TS, TM, TSIdxs, TMIdxs>::Type...
    >::Type;
};

// If the subsequence to match is empty, return an empty ListInt<>
template<typename TS, SizeT... TSIdxs, typename TMIdxs> 
struct IdxsOfSeqHlpr<TS, List<>, IdxSeq<TSIdxs...>, TMIdxs>
{
    using Type = ListInt<>;
};



// Main typedef
// 
template<typename TS, typename TM> 
using IdxsOfSeq = typename IdxsOfSeqHlpr
<
    // Source list
    TS, 

    // Subsequence to match
    TM, 

    // Index sequence of the source list
    // Starts from 0, ends at (source_list_size - matching_list_size + 1)
    std::make_index_sequence
    <
        getClampedMin(int(TS::size - TM::size + 1), 0)
    >, 

    // Index sequence of the subsequence to match
    std::make_index_sequence<TM::size>
>::Type;

Is there any part of the algorithm that can easily be optimized?

Or is it better to rewrite the solution from scratch, using another algorithm?

share|improve this question
    
Your question title. Yes. I understand some of these words. |: I hope you get some answers soon, it seems like an interesting question. –  Dan Pantry Mar 6 at 23:17
    
I would vote to close if I could. Seems a bit off topic. Seems you are looking for advice that would be better served on SO (you would definitely get more experienced eye balls on it over there). –  Loki Astari Mar 7 at 2:09
    
@LokiAstari: I actually posted this question on SO before posting it here, and I was told it was off-topic for SO and to post it on Code Review. –  Vittorio Romeo Mar 7 at 12:04
    
@VittorioRomeo: Then you should have got the moderators to move the question. Posting it a second time does not help. –  Loki Astari Mar 7 at 12:14
    
@LokiAstari eh? "it should be on SO" "oh but I was told to come here" "SHOULD HAVE BEEN MOVED THEN" what does that add, exactly, to the question? this question is on-topic here on CR (and off topic on SO). –  Dan Pantry Mar 7 at 13:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.