Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template metaprogram to find similar consecutive typenames

I am new to template meta programming and was trying to create a program that would find if a parameter pack has consecutive same type names. For example <int, int>, <int, char, char> would return true and <int,char> and <int, char, int> would not.

I managed to write this piece of code but it seems to be comparing each value of parameter pack with itself. I am just looking for a way to iterate through the values of parameter pack to compare with it's consecutive element.

template<typename T, typename U>
struct sameTypename{
    enum {value = false};
};

template<typename T>
struct sameTypename<T, T>{
    enum {value = true};
};

template <typename T, typename ...args>
struct consTypename{
    enum {value = (sameTypename<consTypename<args...>, consTypename<args...>>::value)};
};

template <typename T>
struct consTypename<T, T>{
    enum {value = true};
};

template <typename T>
struct consTypename<T>{
    enum {value = false};
};
like image 289
Varunaditya Jadwal Avatar asked Dec 23 '22 03:12

Varunaditya Jadwal


2 Answers

Here you go:

#include <type_traits>

template <typename ...P> struct has_adjacent_same_types : std::false_type {};
template <typename A, typename B, typename ...P> struct has_adjacent_same_types<A, B, P...>
    : std::bool_constant<std::is_same_v<A,B> || has_adjacent_same_types<B, P...>::value> {};

I used : std::false_type {}; and : std::bool_constant<X> {}; instead of
{enum{value = false};}; and {enum{value = X};}; respectively, but that's simply a matter of preference.


Some of the features I used are from C++17. If you're using an older version, note that:

std::bool_constant and std::is_same_v are available only starting from C++17 (but that you can use std::integral_constant and std::is_same<>::value before).

(c) @max66

like image 135
HolyBlackCat Avatar answered Feb 15 '23 22:02

HolyBlackCat


A variation of the HolyBlackCat's solution.

template <typename ...>
struct has_adjacent_same_types : public std::false_type
 { };

template <typename T0, typename ... Ts>
struct has_adjacent_same_types<T0, T0, Ts...> : public std::true_type
 { };

template <typename T0, typename T1, typename ... Ts>
struct has_adjacent_same_types<T0, T1, Ts...>
   : public has_adjacent_same_types<T1, Ts...>
 { };

Two simpler specializations instead of only one, more complex.

Substantially is the same things (I suppose) but I find it a little clear to read and understand.

like image 44
max66 Avatar answered Feb 15 '23 23:02

max66