[c++] Сравниваем со статическим массивом
Проблема несколько надумана (на самом деле ее нет=)), но все же. Бывает так, что нужно сравнить динамический массив со статическим (размер которого заранее известен). Например, со строкой вида
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++] Сравниваем со статическим массивом
Здравствуйте, 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&content-type=text/vnd.viewcvs-markup
--
Maxim Yegorushkin Posted via RSDN NNTP Server 1.9
Re[4]: [c++] Сравниваем со статическим массивом
Здравствуйте, 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&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++] Сравниваем со статическим массивом
Здравствуйте, 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++] Сравниваем со статическим массивом
Здравствуйте, 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, Вы писали:
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____
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить