[c++] Сравниваем со статическим массивом
От: Warturtle  
Дата: 30.08.05 15:04
Оценка: :)
Проблема несколько надумана (на самом деле ее нет=)), но все же. Бывает так, что нужно сравнить динамический массив со статическим (размер которого заранее известен). Например, со строкой вида
char szSTRING[] = "wonderful string";


Можно написать нечто вроде:
void Func(char const *psz, size_t nLen)
{
    if (sizeof(szSTRING) <= nLen + 1) {
        if (psz[0] == 'w'
            && psz[0] == 'o'
            && psz[1] == 'n'
            && psz[2] == 'd'
            && psz[3] == 'e'
            && psz[4] == 'r'
            && psz[5] == 'f'
            && psz[6] == 'u'
            && psz[7] == 'l'
            && psz[8] == ' '
            && psz[9] == 's'
            && psz[10] == 't'
            && psz[11] == 'r'
            && psz[12] == 'i'
            && psz[13] == 'n'
            && psz[14] == 'g')
        {
            // че-то делаем...
        }
    }
}

а можно и не париться:
void Func(char const *psz, size_t nLen)
{
    if (::strncmp(szSTRING, psz,nLen) == 0) {
        // че-то делаем...
    }
}

Но мы ведь ищем легких путей!
Поэтому делаем "совсем с обратной стороны":
#include <iostream>
#include <algorithm>
using namespace std;

// [url=http://rsdn.ru/Forum/Message.aspx?mid=265122&only=1]товарищ[/url]дал стране угля:
template< class T, size_t N > char (&LengthOf (T(&)[N]) )[N];
#define length_of(arr) sizeof(LengthOf(arr)) \
  /**/

#if !defined(_MSC_VER)
#  define __forceinline inline
#endif

//////////////////////////////////////////////////////////////////////////
// FindMismatch - generalized mismatch search
//

template< class T, size_t t_nCount, size_t t_nStart = 0 >
struct FindMismatch 
{
    enum { IDX = t_nStart + t_nCount - 1 };
    typedef T const * const ArrayT;
    __forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
    {
        //cout << "IDX == " << IDX << endl
        //     << "\tlhs[IDX] == " << lhs[IDX] << endl
        //     << "\trhs[IDX] == " << rhs[IDX] << endl
        //     << flush;

        return lhs[IDX] == rhs[IDX] ?
            FindMismatch< T, t_nCount - 1, t_nStart >::Do(lhs, rhs) : IDX;
    }
};
template< class T, size_t t_nStart >
struct FindMismatch< T, 1, t_nStart > 
{
    typedef T const * const ArrayT;
    __forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
    {
        //cout << "IDX == " << t_nStart << endl
        //     << "\tlhs[t_nStart] == " << lhs[t_nStart] << endl
        //     << "\trhs[t_nStart] == " << rhs[t_nStart] << endl
        //     << flush;

        return lhs[t_nStart] == rhs[t_nStart] ? (size_t)-1 : t_nStart;
    }
};


//////////////////////////////////////////////////////////////////////////
// ArrayStuff
//

template< class CharT = char >
struct ArrayStuff
{
    template< size_t N >
    __forceinline static size_t Compare(CharT const *pStr, CharT const (&symb_arr)[N])
    {
        enum { LEN = length_of(symb_arr) - 1 };
        return FindMismatch< CharT, LEN >::Do(pStr, symb_arr);
    }


    template< size_t t_nIdx, class T, template <class T1, size_t, size_t> class HasDo >
    struct RT2CT
    {
        typedef T const * const ArrayT;
        __forceinline static size_t Get(size_t n, ArrayT lhs, ArrayT rhs)
        {
            return n < t_nIdx ?
                RT2CT< t_nIdx - 1, T, HasDo >::Get(n, lhs, rhs)
                : HasDo< T, t_nIdx, 0 >::Do(lhs, rhs);
        }
    };
    template< class T, template <class T1, size_t, size_t> class HasDo >
    struct RT2CT<1, T, HasDo >
    {
        typedef T const * const ArrayT;
        __forceinline static size_t Get(size_t n, ArrayT lhs, ArrayT rhs)
        {
            return n == 1 ?
                HasDo< T, 1, 0 >::Do(lhs, rhs) : (size_t)-1;
        }
    };
    template< size_t N >
    __forceinline static int Compare(CharT const *pStr, size_t nLen, CharT const(&symb_arr)[N])
    {
        enum { LEN = length_of(symb_arr) - 1 };
        if (nLen < LEN) {
            //cout << "!!! nLen (" << nLen << ") < LEN (" << LEN << ") !!! " << endl;
            return RT2CT< LEN, CharT, FindMismatch >::Get(nLen, pStr, symb_arr);
        }
        else {
            return FindMismatch<CharT, LEN >::Do(pStr, symb_arr);
        }
    }
};


int main()
{
    char const *pstr = "abcdef";
    cout << "ArrayStuff<char>::Compare(\""<< pstr <<"\", \"abcdeF\") == "
         << ArrayStuff<char>::Compare(pstr, "abcdeF") << endl
         << flush;

    cout << "ArrayStuff<char>::Compare(\""<< pstr <<"\", 3, \"abcQWE\") == "
         << ArrayStuff<char>::Compare(pstr, 3, "abcQWE") << endl
         << flush;

    ::system("PAUSE");
    return 0;
}
Re: [c++] Сравниваем со статическим массивом
От: MaximE Великобритания  
Дата: 30.08.05 16:15
Оценка:
Warturtle wrote:

> Проблема несколько надумана (на самом деле ее нет=)), но все же. Бывает так, что нужно сравнить динамический массив со статическим (размер которого заранее известен). Например, со строкой вида

>
> char szSTRING[] = "wonderful string";
>

>
> Можно написать нечто вроде:
>

[]

> }
>

> а можно и не париться:
>

[]

>


Скачай SIP Express Router и посмотри как там строки сравнивают.
Posted via RSDN NNTP Server 1.9
Re[2]: [c++] Сравниваем со статическим массивом
От: Warturtle  
Дата: 30.08.05 16:39
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Скачай SIP Express Router и посмотри как там строки сравнивают.


А куда именно посмотреть? Исходников там немало =)
Re[3]: [c++] Сравниваем со статическим массивом
От: MaximE Великобритания  
Дата: 31.08.05 18:13
Оценка:
On Tue, 30 Aug 2005 20:39:23 +0400, Warturtle <5570@users.rsdn.ru> wrote:

> Здравствуйте, MaximE, Вы писали:

>
> ME>Скачай SIP Express Router и посмотри как там строки сравнивают.
>
> А куда именно посмотреть? Исходников там немало =)

Они, похоже, уже отказываются от того метода.

http://cvs.berlios.de/cgi-bin/viewcvs.cgi/ser/sip_router/parser/obsolete/strs.h?rev=1.3&amp;content-type=text/vnd.viewcvs-markup

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: [c++] Сравниваем со статическим массивом
От: Warturtle  
Дата: 01.09.05 15:49
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>On Tue, 30 Aug 2005 20:39:23 +0400, Warturtle <5570@users.rsdn.ru> wrote:


>> Здравствуйте, MaximE, Вы писали:

>>
>> ME>Скачай SIP Express Router и посмотри как там строки сравнивают.
>>
>> А куда именно посмотреть? Исходников там немало =)

ME>Они, похоже, уже отказываются от того метода.


ME>http://cvs.berlios.de/cgi-bin/viewcvs.cgi/ser/sip_router/parser/obsolete/strs.h?rev=1.3&amp;content-type=text/vnd.viewcvs-markup


Ну так это только для строк, причем небольшой длины годится, если я правильно понял смысл, и не слишком сокрашает объем писанины=).
А так и для любых стат. массивов.
Можно даже усовершенствовать немного (если сравнивать с начала):

#include <iostream>
#include <algorithm>
using namespace std;

// http://rsdn.ru/Forum/Message.aspx?mid=265122&only=1
template< class T, size_t N > char (&LengthOf (T(&)[N]) )[N];
#define length_of(arr) sizeof(LengthOf(arr)) \
  /**/

#if !defined(_MSC_VER)
#  define __forceinline inline
#endif

//////////////////////////////////////////////////////////////////////////
// FindMismatch2 - generalized mismatch search (from begin)
//

template< class T, size_t t_nSize, size_t t_nCount >
struct FindMismatch2
{
    typedef T const * ArrayT;
    __forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
    {
        return *lhs++ == *rhs++ ?
            FindMismatch2< T, t_nSize, t_nCount - 1 >::Do(lhs, rhs)
            : t_nSize - t_nCount;
    }
};
template< class T, size_t t_nSize >
struct FindMismatch2< T, t_nSize, 1 >
{
    typedef T const * ArrayT;
    __forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
    {
        return *lhs == *rhs ? (size_t)-1 : t_nSize - 1;
    }
};


//////////////////////////////////////////////////////////////////////////
// ArrayStuff
//

template< class ElemT = char >
struct ArrayStuff
{
    template< size_t N >
    __forceinline static size_t Compare2(ElemT const *pStr, ElemT const (&symb_arr)[N])
    {
        enum { LEN = length_of(symb_arr) - 1 };
        return FindMismatch2< ElemT, LEN, LEN >::Do(pStr, symb_arr);
    }

    template<  class T, size_t t_nSize, size_t t_nIdx >
    struct RT2CT2
    {
        typedef T const * ArrayT;
        __forceinline static size_t Get(size_t n, ArrayT lhs, ArrayT rhs)
        {
            return n < t_nIdx ?
                RT2CT2< T, t_nSize, t_nIdx - 1 >::Get(n, lhs, rhs)
                : FindMismatch2< T, t_nSize, t_nIdx >::Do(lhs, rhs);
        }
    };
    template< class T, size_t t_nSize >
    struct RT2CT2< T, t_nSize, 1 >
    {
        typedef T const * ArrayT;
        __forceinline static size_t Get(size_t n, ArrayT lhs, ArrayT rhs)
        {
            return n == 1 ?
                FindMismatch2< T, t_nSize, 1 >::Do(lhs, rhs) : (size_t)-1;
        }
    };
    template< size_t N >
    __forceinline static int Compare2(ElemT const *pStr, size_t nLen, ElemT const(&symb_arr)[N])
    {
        enum { LEN = length_of(symb_arr) - 1 };
        if (nLen < LEN) {
            return RT2CT2< ElemT, LEN, LEN >::Get(nLen, pStr, symb_arr);
        }
        else {
            return FindMismatch2< ElemT, LEN, LEN >::Do(pStr, symb_arr);
        }
    }
};


int main()
{
    char const *pstr = "abcdef";
    cout << "ArrayStuff<char>::Compare(\""<< pstr <<"\", \"abcdeF\") == "
         << ArrayStuff<char>::Compare2(pstr, "abcdeF") << endl
         << flush;

    cout << "ArrayStuff<char>::Compare(\""<< pstr <<"\", "<< ::strlen(pstr) <<", \"abcdefQWERTY\") == "
         << ArrayStuff<char>::Compare2(pstr, ::strlen(pstr), "abcdefQWERTY") << endl
         << flush;

    ::system("PAUSE");
    return 0;
}
Re[5]: [c++] Сравниваем со статическим массивом
От: MaximE Великобритания  
Дата: 01.09.05 16:05
Оценка:
Здравствуйте, Warturtle, Вы писали:

[]

W>А так и для любых стат. массивов.

W>Можно даже усовершенствовать немного (если сравнивать с начала):

Бесполезно здесь совершенствовать — алгоритм ерундовый. http://en.wikipedia.org/wiki/String_searching_algorithm
Re[6]: [c++] Сравниваем со статическим массивом
От: Warturtle  
Дата: 02.09.05 10:04
Оценка: +1
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Warturtle, Вы писали:


ME>[]


W>>А так и для любых стат. массивов.

W>>Можно даже усовершенствовать немного (если сравнивать с начала):

ME>Бесполезно здесь совершенствовать — алгоритм ерундовый. http://en.wikipedia.org/wiki/String_searching_algorithm


Причем здесь алгоритм??? Сравнивается два куска одинаковой длины. Поэтому поэлементное сравнение — единственный разумный способ выяснить совпадают они или нет. Просто не используется цикл, а разворачивается в цепочку if-ов на этапе компиляции (если конечно функции "заинлайнятся").
Re[7]: [c++] Сравниваем со статическим массивом
От: MaximE Великобритания  
Дата: 02.09.05 11:27
Оценка:
Здравствуйте, Warturtle, Вы писали:

ME>>Бесполезно здесь совершенствовать — алгоритм ерундовый. http://en.wikipedia.org/wiki/String_searching_algorithm


W>Причем здесь алгоритм??? Сравнивается два куска одинаковой длины. Поэтому поэлементное сравнение — единственный разумный способ выяснить совпадают они или нет. Просто не используется цикл, а разворачивается в цепочку if-ов на этапе компиляции (если конечно функции "заинлайнятся").


Ерундовый в том плане, что сравнивает побайтно, куча кода, толку нет. memcmp/strcmp будут сравнивать словами.
Re[8]: [c++] Сравниваем со статическим массивом
От: Жива  
Дата: 04.09.05 10:02
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Warturtle, Вы писали:


ME>>>Бесполезно здесь совершенствовать — алгоритм ерундовый. http://en.wikipedia.org/wiki/String_searching_algorithm


W>>Причем здесь алгоритм??? Сравнивается два куска одинаковой длины. Поэтому поэлементное сравнение — единственный разумный способ выяснить совпадают они или нет. Просто не используется цикл, а разворачивается в цепочку if-ов на этапе компиляции (если конечно функции "заинлайнятся").


ME>Ерундовый в том плане, что сравнивает побайтно, куча кода, толку нет. memcmp/strcmp будут сравнивать словами.


А если массив не кратен слову?
----
Простите меня за мой французкий, все вопросы направляйте в компанию ОАО "Промт",
такой уж перевод с французкого на русский
Re[9]: [c++] Сравниваем со статическим массивом
От: MaximE Великобритания  
Дата: 04.09.05 11:10
Оценка:
Здравствуйте, Жива, Вы писали:

ME>>Ерундовый в том плане, что сравнивает побайтно, куча кода, толку нет. memcmp/strcmp будут сравнивать словами.


Ж>А если массив не кратен слову?


Сравнить все что можно словами, невыровненные начало и некратный конец сравнить побайтно.

Посмотри реализацию strcmp для своего компилятора.
Re[10]: [c++] Сравниваем со статическим массивом
От: Жива  
Дата: 04.09.05 12:05
Оценка: :)
Здравствуйте, MaximE, Вы писали:

ME>Сравнить все что можно словами, невыровненные начало и некратный конец сравнить побайтно.


ME>Посмотри реализацию strcmp для своего компилятора.


Все равно эти проверки влияют на производительность, но сравнение словами работает быстрее, с
этим согласен, особенно на больших массивах.
----
Простите меня за мой французкий, все вопросы направляйте в компанию ОАО "Промт",
такой уж перевод с французкого на русский
Re[8]: [c++] Сравниваем со статическим массивом
От: Warturtle  
Дата: 05.09.05 12:04
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Warturtle, Вы писали:


ME>>>Бесполезно здесь совершенствовать — алгоритм ерундовый. http://en.wikipedia.org/wiki/String_searching_algorithm


W>>Причем здесь алгоритм??? Сравнивается два куска одинаковой длины. Поэтому поэлементное сравнение — единственный разумный способ выяснить совпадают они или нет. Просто не используется цикл, а разворачивается в цепочку if-ов на этапе компиляции (если конечно функции "заинлайнятся").


ME>Ерундовый в том плане, что сравнивает побайтно, куча кода, толку нет. memcmp/strcmp будут сравнивать словами.


Ну это уже несколько в ином "плане" К тому же можно исправить

#include <iostream>
#include <algorithm>
using namespace std;


#if !defined(_MSC_VER)
#  define __forceinline inline
#endif

//////////////////////////////////////////////////////////////////////////
// FindMismatchRev - generalized mismatch search
//

template< class T, size_t t_nSize, size_t t_nCount >
struct FindMismatch2
{
    typedef T const * ArrayT;
    __forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
    {
        return *lhs++ == *rhs++ ?
            FindMismatch2< T, t_nSize, t_nCount - 1 >::Do(lhs, rhs)
            : t_nSize - t_nCount;
    }
};
template< class T, size_t t_nSize >
struct FindMismatch2< T, t_nSize, 1 >
{
    typedef T const * ArrayT;
    __forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
    {
        return *lhs == *rhs ? (size_t)-1 : t_nSize - 1;
    }
};


//////////////////////////////////////////////////////////////////////////
// ArrayStuff
//

template< class ElemT = char, class WordT = long >
struct ArrayStuff
{
    template<
        size_t N
        , bool t_fHasNoWords = (N*sizeof(ElemT)) / sizeof(WordT) == 0
        , bool t_fHasNoRest = (N*sizeof(ElemT)) % sizeof(WordT) == 0
        >
    struct CmpWithNullSizeCheck
    {
        __forceinline static size_t Do(ElemT const *pStr, ElemT const (&arr)[N])
        {
            enum {
                WORDS = sizeof(arr) / sizeof(WordT)
                , RESTC = sizeof(arr) % sizeof(WordT)
            };
            WordT const *pw = reinterpret_cast< WordT const* >(pStr);
            WordT const *rw = reinterpret_cast< WordT const* >(arr);
            size_t nWord = FindMismatch2< WordT, WORDS, WORDS >::Do(pw, rw);
            if (nWord != (size_t)-1) return nWord;

            char const *pc = reinterpret_cast< char const * >(pw + WORDS);
            char const *rc = reinterpret_cast< char const * >(arr + WORDS);
            size_t nRest = FindMismatch2< char, RESTC, RESTC >::Do(pc, rc);
            return nRest != (size_t)-1 ? WORDS : (size_t)-1;
        }
    };
    template< size_t N, bool t_nHasNoRest >
    struct CmpWithNullSizeCheck<N, true, t_nHasNoRest >
    {
        __forceinline static size_t Do(ElemT const *pStr, ElemT const (&arr)[N])
        {
            return FindMismatch2< ElemT, N, N >::Do(pStr, arr);
        }
    };

    template< size_t N, bool t_nHasNoWords >
    struct CmpWithNullSizeCheck<N, t_nHasNoWords, true >
    {
        __forceinline static size_t Do(ElemT const *pStr, ElemT const (&arr)[N])
        {
            enum { WORDS = sizeof(arr) / sizeof(WordT) };
            WordT const *pw = reinterpret_cast< WordT const* >(pStr);
            WordT const *rw = reinterpret_cast< WordT const* >(arr);
            size_t nWord = FindMismatch2< WordT, WORDS, WORDS >::Do(pw, rw);
            return nWord;
        }
    };


    template< size_t N >
    __forceinline static size_t Compare2(ElemT const *pStr, ElemT const (&arr)[N])
    {
        return CmpWithNullSizeCheck<
            N,
            (N*sizeof(ElemT)) / sizeof(WordT) == 0,
            (N*sizeof(ElemT)) % sizeof(WordT) == 0
            >::Do(pStr, arr);
    }
};


///////////////////////////////////////////////////////////////////////

int main()
{
    char const *pstr = "fghijkl";
    cout << "ArrayStuff<char, long >::Compare(\""<< pstr <<"\", \"fghIjkl\") == "
         << ArrayStuff<char, long >::Compare2(pstr, "fghIjkl") << endl
         << flush;

    cout << "ArrayStuff<char, long long >::Compare(\""<< pstr <<"\", \"fghIjkl\") == "
         << ArrayStuff<char, long long >::Compare2(pstr, "fghIjkl") << endl
         << flush;

    ::system("PAUSE");
    return 0;
}
Re: [c++] Сравниваем со статическим массивом
От: Warturtle  
Дата: 15.02.06 12:50
Оценка:
Здравствуйте, Warturtle, Вы писали:

W>Проблема несколько надумана (на самом деле ее нет=)), но все же. Бывает так, что нужно сравнить динамический массив со статическим (размер которого заранее известен). Например, со строкой вида

W>
W>char szSTRING[] = "wonderful string";
W>


W>Можно написать нечто вроде:

W>
W>void Func(char const *psz, size_t nLen)
W>{
W>    if (sizeof(szSTRING) <= nLen + 1) {
W>        if (psz[0] == 'w'
W>            && psz[0] == 'o'
W>            && psz[1] == 'n'
W>            && psz[2] == 'd'
W>            && psz[3] == 'e'
W>            && psz[4] == 'r'
W>            && psz[5] == 'f'
W>            && psz[6] == 'u'
W>            && psz[7] == 'l'
W>            && psz[8] == ' '
W>            && psz[9] == 's'
W>            && psz[10] == 't'
W>            && psz[11] == 'r'
W>            && psz[12] == 'i'
W>            && psz[13] == 'n'
W>            && psz[14] == 'g')
W>        {
W>            // че-то делаем...
W>        }
W>    }
W>}
W>

W>а можно и не париться:
W>
W>void Func(char const *psz, size_t nLen)
W>{
W>    if (::strncmp(szSTRING, psz,nLen) == 0) {
W>        // че-то делаем...
W>    }
W>}
W>

W>...

Надо уж закончить, раз начал. Окончательный вариант — без некоторых (а то и всех? ) ошибок + может сравнивать "сзаду-наперед":

#ifndef _ARRAY__STUFF___H____
#define _ARRAY__STUFF___H____

#if !defined(_MSC_VER)
#  define FORCE_INLINE inline
#else
#  define FORCE_INLINE __forceinline
#endif


//////////////////////////////////////////////////////////////////////////
// FindMismatch2 - generalized mismatch search
//

template< class IterT, bool t_fFwd >
struct Step
{
    static FORCE_INLINE IterT Do(IterT &i) { return i++; }
    static FORCE_INLINE IterT DoN(IterT const &i, size_t n) { return i + n; }
    template< size_t t_nSize, size_t t_nCount >
    struct Position
    {
        enum { value = t_nSize - t_nCount };
    };
};

template< class IterT >
struct Step< IterT, 0 >
{
    static FORCE_INLINE IterT Do(IterT &i) { return --i; }
    static FORCE_INLINE IterT DoN(IterT const &i, size_t n) { return i - n; }
    template< size_t t_nSize, size_t t_nCount >
    struct Position
    {
        enum { value = t_nCount - 1 };
    };
};

template< class T, size_t t_nSize, size_t t_nCount, bool t_fFwd >
struct FindMismatch2
{
    typedef T const * ArrayT;
    static FORCE_INLINE size_t Do(ArrayT lhs, ArrayT rhs)
    {
        typedef Step< ArrayT, t_fFwd > StepType;
        return *StepType::Do(lhs) == *StepType::Do(rhs) 
            ? FindMismatch2< T, t_nSize, t_nCount - 1, t_fFwd >::Do(lhs, rhs)
            : StepType::template Position< t_nSize, t_nCount >::value;
    }
};
template< class T, size_t t_nSize, bool t_fFwd >
struct FindMismatch2< T, t_nSize, 1, t_fFwd >
{
    typedef T const * ArrayT;
    static FORCE_INLINE size_t Do(ArrayT lhs, ArrayT rhs)
    {
        typedef Step< ArrayT, t_fFwd > StepType;
        return *StepType::Do(lhs) == *StepType::Do(rhs) 
            ? (size_t)-1 
            : StepType::template Position< t_nSize, 1 >::value;
    }
};


//////////////////////////////////////////////////////////////////////////
// ArrayStuff
//

template< class ElemT = char, class WordT = long >
struct ArrayStuff
{
protected:
    template<
          size_t N
        , bool t_fNoWords = (N*sizeof(ElemT)) / sizeof(WordT) == 0
        , bool t_fNoRest = (N*sizeof(ElemT)) % sizeof(WordT) == 0
        , bool t_fFwd = true
        >
    struct Compare
    {
        static FORCE_INLINE size_t Do(ElemT const *p, ElemT const *arr)
        {
            enum {
                  WORDS = (N * sizeof(ElemT)) / sizeof(WordT)
                , RESTC = ((N * sizeof(ElemT)) % sizeof(WordT)) / sizeof(ElemT)
            };
            WordT const *pw = reinterpret_cast< WordT const* >(p);
            WordT const *rw = reinterpret_cast< WordT const* >(arr);
            size_t nWord = FindMismatch2< WordT, WORDS, WORDS, t_fFwd >::Do(pw, rw);
            if (nWord != (size_t)-1) return nWord;

            typedef Step< WordT const*, t_fFwd > WordStep;
            ElemT const *pc = reinterpret_cast< ElemT const* >(
                WordStep::DoN(pw, WORDS)
            );
            ElemT const *rc = reinterpret_cast< ElemT const* >(
                WordStep::DoN(rw, WORDS)
            );
            size_t nRest = FindMismatch2< 
                ElemT, RESTC, RESTC, t_fFwd 
            >::Do(pc, rc);
            return nRest != (size_t)-1 ? WORDS : (size_t)-1;
        }
    };
    template< size_t N, bool t_fNoRest, bool t_fFwd >
    struct Compare< N, true, t_fNoRest, t_fFwd >
    {
        static FORCE_INLINE size_t Do(ElemT const *p, ElemT const *arr)
        {
            enum { direction = t_fFwd };
            return FindMismatch2< ElemT, N, N, t_fFwd >::Do(p, arr);
        }
    };

    template< size_t N, bool t_fNoWords, bool t_fFwd >
    struct Compare< N, t_fNoWords, true, t_fFwd >
    {
        static FORCE_INLINE size_t Do(ElemT const *p, ElemT const *arr)
        {
            enum { WORDS = (N * sizeof(ElemT)) / sizeof(WordT) };
            WordT const *pw = reinterpret_cast< WordT const* >(p);
            WordT const *rw = reinterpret_cast< WordT const* >(arr);
            size_t nWord = FindMismatch2< WordT, WORDS, WORDS, t_fFwd >::Do(pw, rw);
            return nWord;
        }
    };

public:
    template< size_t N >
    static FORCE_INLINE size_t DiffPos(ElemT const *p, ElemT const (&arr)[N])
    {
        return Compare<
              N
            , (N*sizeof(ElemT)) / sizeof(WordT) == 0
            , (N*sizeof(ElemT)) % sizeof(WordT) == 0
            , true
        >::Do(p, arr);
    }
    template< size_t N >
    static FORCE_INLINE bool Equal(ElemT const *p, ElemT const (&arr)[N])
    {
        return Compare<
              N
            , (N*sizeof(ElemT)) / sizeof(WordT) == 0
            , (N*sizeof(ElemT)) % sizeof(WordT) == 0
            , true
        >::Do(p, arr) == (size_t)-1;
    }
    template< size_t N >
    static FORCE_INLINE size_t DiffPosRev(ElemT const *p, ElemT const (&arr)[N])
    {
        return Compare<
              N
            , (N*sizeof(ElemT)) / sizeof(WordT) == 0
            , (N*sizeof(ElemT)) % sizeof(WordT) == 0
            , false
        >::Do(p + N, arr + N);
    }
    template< size_t N >
    static FORCE_INLINE bool EqualRev(ElemT const *p, ElemT const (&arr)[N])
    {
        return Compare<
              N
            , (N*sizeof(ElemT)) / sizeof(WordT) == 0
            , (N*sizeof(ElemT)) % sizeof(WordT) == 0
            , false
        >::Do(p + N, arr + N) == (size_t)-1;
    }

    template< size_t N >
    static FORCE_INLINE size_t StrDiffPos(ElemT const *psz, ElemT const (&arr)[N])
    {
        enum { L = N - 1 };
        return Compare<
              L
            , (L * sizeof(ElemT)) / sizeof(WordT) == 0
            , (L * sizeof(ElemT)) % sizeof(WordT) == 0
            , true
        >::Do(psz, arr);
    }
    template< size_t N >
    static FORCE_INLINE bool StrEqual(ElemT const *psz, ElemT const (&arr)[N])
    {
        enum { L = N - 1 };
        return Compare<
              L
            , (L * sizeof(ElemT)) / sizeof(WordT) == 0
            , (L * sizeof(ElemT)) % sizeof(WordT) == 0
            , true
        >::Do(psz, arr) == (size_t)-1;
    }
    template< size_t N >
    static FORCE_INLINE size_t StrDiffPosRev(ElemT const *psz, ElemT const (&arr)[N])
    {
        enum { L = N - 1 };
        return Compare<
              L
            , (L * sizeof(ElemT)) / sizeof(WordT) == 0
            , (L * sizeof(ElemT)) % sizeof(WordT) == 0
            , false
        >::Do(psz + L, arr + L);
    }
    template< size_t N >
    static FORCE_INLINE bool StrEqualRev(ElemT const *psz, ElemT const (&arr)[N])
    {
        enum { L = N - 1 };
        return Compare<
              L
            , (L * sizeof(ElemT)) / sizeof(WordT) == 0
            , (L * sizeof(ElemT)) % sizeof(WordT) == 0
            , false
        >::Do(psz + L, arr + L) == (size_t)-1;
    }
};

#endif //_ARRAY__STUFF___H____
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.