Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Compile-time palindrome check

What should I do to check whether an integer array is palindrome (e.g. 1 3 10 3 1 is palindrome) in compile time?

The possible framework could be:

template <int...>
class IntArray;

template <int... values>
class Palindrome<IntArray<values...>>;

static_assert(Palindrome<IntArray<1, 2, 1>>::check == true);

I know this question seems to be meaningless, but I’m just curious about the grammar that I should use.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I’ve read the posts and blogs about compile-time fibonacci calculation, but got nothing inspiring.

Could anyone tell me how to implement this or what material should I read/learn?

Thanks in advance.

I know little about compile-time programming, the most complicated problem that I can tackle with compile-time programming is like this:


template<int a, int b>
struct max_template {
    static constexpr int value = a > b ? a : b;
};

constexpr int max_fun(int a, int b) {
    return a > b ? a : b;
}

// or

template <unsigned N>
struct Fibonacci
{
    enum
    {
        value = Fibonacci<N-1>::value + Fibonacci<N-2>::value
    };
};

template <>
struct Fibonacci<1>
{
    enum
    {
        value = 1
    };
};

template <>
struct Fibonacci<0>
{
    enum
    {
        value = 0
    };
};

>Solution :

It’s more or less trivial in C++17 unless you have a limitation to use purely functional constructs:

template<int...>
class IntArray;

template<class>
struct IsPalindrome;

template<int... values>
struct IsPalindrome<IntArray<values...>> {
    static constexpr bool value = []{
        constexpr int arr[] = {values...};
        constexpr std::size_t N = std::size(arr);
        for (std::size_t i = 0; i < N / 2; ++i)
            if (arr[i] != arr[N - 1 - i])
                return false;
        return true;
    }();
};

static_assert( IsPalindrome<IntArray<0, 1, 2, 3, 2, 1, 0>>::value);
static_assert(!IsPalindrome<IntArray<0, 1, 2, 3, 4, 1, 0>>::value);

Purely function implementation is more lengthy but works even in C++11:

template<class, int>
struct PushBack;

template<int... values, int value>
struct PushBack<IntArray<values...>, value> {
    using type = IntArray<values..., value>;
};

template<class>
struct Reverse;

template<>
struct Reverse<IntArray<>> {
    using type = IntArray<>;
};

template<int first, int... rest>
struct Reverse<IntArray<first, rest...>> {
    using type = typename PushBack<
        typename Reverse<IntArray<rest...>>::type, 
        first
    >::type;
};

template<class IntArray>
using IsPalindrome = 
    std::is_same<IntArray, typename Reverse<IntArray>::type>;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading