📄 asequence.cpp
字号:
if( seq->first )
{
CvSeqBlock* block = seq->first;
CvSeqBlock* prev_block = block->prev;
int delta_idx = seq->first->start_index;
for( ;; )
{
CHECK_CONDITION( sum == block->start_index - delta_idx &&
block->count > 0 && block->prev == prev_block &&
prev_block->next == block,
"Sequence blocks are inconsistent" );
sum += block->count;
prev_block = block;
block = block->next;
if( block == seq->first ) break;
}
CHECK_CONDITION( block->prev->count * seq->elem_size +
block->prev->data <= seq->block_max,
"block->data or block_max pointer are incorrect" );
}
CHECK_CONDITION( seq->total == sum && sum == total, "total number is undefined" );
test_exit:
*msg = message_string;
return code;
}
static int check_get_seq_elem( CvSeq* seq, simple_seq* sseq,
AtsRandState* rng_state, int iters,
const char** msg, CvStatus * _result )
{
const char* message_string = *msg;
CvStatus result = *_result;
int i = 0, code = TRS_OK;
assert( seq->total == sseq->count );
atsRandSetBounds( rng_state, -sseq->count*3/2, sseq->count*3/2 );
for( i = 0; i < iters; i++ )
{
CvSeqBlock* block = 0;
CvSeqBlock* block1 = 0;
int idx = atsRand32s( rng_state );
int idx0 = (unsigned)idx < (unsigned)(sseq->count) ? idx : idx < 0 ?
idx + sseq->count : idx - sseq->count;
int flag = atsRand32s(rng_state) & 1;
int bad_range = (unsigned)idx0 >= (unsigned)(sseq->count);
char* elem = cvGetSeqElem( seq, idx, flag ? &block : 0 );
if( bad_range )
{
CHECK_CONDITION( elem == 0,
"cvGetSeqElem doesn't "
"handle \"out of range\" properly" );
}
else
{
CHECK_CONDITION( elem != 0 &&
!memcmp( elem, simple_seq_elem( sseq, idx0), elem_size ) &&
(!flag || block != 0 &&
(unsigned)(idx0 - block->start_index +
seq->first->start_index) <= (unsigned)(block->count)),
"cvGetSeqElem is incorrect" );
flag = atsRand32s(rng_state) & 1;
idx = cvSeqElemIdx(seq, elem, flag ? &block1 : 0 );
CHECK_CONDITION( idx >= 0 && idx == idx0 &&
(!flag || block1 != 0 && (!block || block1 == block)),
"cvSeqElemIdx is incorrect" );
}
}
test_exit:
*msg = message_string;
*_result = result;
return code;
}
static int check_get_seq_reading( CvSeq* seq, simple_seq* sseq,
AtsRandState* rng_state, int iters,
const char** msg, CvStatus * _result )
{
const int max_val = 3*5 + 2;
const char* message_string = *msg;
CvStatus result = *_result;
int i = 0, code = TRS_OK, pos;
int total = seq->total;
CvSeqReader reader;
char* elem;
elem_type el;
elem = (char*)icvAlloc( sseq->elem_size );
assert( total == sseq->count );
atsRandSetBounds( rng_state, 0, 2 );
pos = atsRand32s( rng_state );
if( total == 0 )
{
cvStartReadSeq( seq, &reader, pos );
/*CHECK_CONDITION( cvStartReadSeq( seq, &reader, pos ) < 0,
"start reading doesn't fail on empty seq" );*/
goto test_exit;
}
cvStartReadSeq( seq, &reader, pos );
DO_CV_ACTION( cvStartReadSeq, ( seq, &reader, pos ) );
pos = pos ? seq->total - 1 : 0;
CHECK_CONDITION( pos == cvGetSeqReaderPos(&reader),
"initial position of reader is wrong" );
for( i = 0; i < iters; i++ )
{
int op;
atsRandSetBounds( rng_state, 0, max_val );
op = atsRand32s( rng_state );
if( op >= max_val - 2 )
{
int new_pos, new_pos0;
int bad_range;
int is_relative = op == max_val - 1;
atsRandSetBounds( rng_state, -total, total );
new_pos = atsRand32s( rng_state );
new_pos0 = new_pos + (is_relative ? pos : 0 );
if( new_pos0 < 0 ) new_pos0 += total;
if( new_pos0 >= total ) new_pos0 -= total;
bad_range = (unsigned)new_pos0 >= (unsigned)total;
if( !bad_range )
{
DO_CV_ACTION( cvSetSeqReaderPos,
( &reader, new_pos, is_relative ) );
CHECK_CONDITION( new_pos0 == cvGetSeqReaderPos( &reader ),
"set reader position doesn't work" );
pos = new_pos0;
}
else
{
cvSetSeqReaderPos( &reader, new_pos, is_relative );
/*CHECK_CONDITION( cvSetSeqReaderPos( new_pos, is_relative, &reader ) < 0,
"set reader position doesn't handle \"out of range\"" );*/
CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ),
"reader doesn't leave previous position after wrong positioning" );
}
}
else
{
int direction = (op % 3) - 1;
if( direction > 0 )
{
CV_READ_SEQ_ELEM( el, reader )
}
else if( direction < 0 )
{
CV_REV_READ_SEQ_ELEM( el, reader )
}
else
{
el = (elem_type&)(reader.ptr[0]);
}
CHECK_CONDITION( !memcmp( &el, simple_seq_elem( sseq, pos), elem_size),
"reading is incorrect" );
pos += direction;
if( pos < 0 ) pos += total;
if( pos >= total ) pos -= total;
CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ),
"reader doesn't move position correctly after reading" );
}
}
test_exit:
icvFree( &elem );
*msg = message_string;
*_result = result;
return code;
}
static int test_multi_create( int count, CvSeq** seq,
int hdr_size, simple_seq** sseq,
CvMemStorage* storage, AtsRandState* rng_state,
const char** msg, CvStatus * _result )
{
const char* message_string = *msg;
CvStatus result = *_result;
CvSeqWriter* writer = 0;
int* pos = 0;
int* index = 0;
int j, count2;
int code = TRS_OK;
writer = (CvSeqWriter*)icvAlloc( count * sizeof(writer[0]));
index = (int*)icvAlloc(count * sizeof(index[0]));
pos = (int*)icvAlloc(count * sizeof(pos[0]));
assert( writer && index && pos );
for( j = 0; j < count; j++ )
{
pos[j] = -1;
index[j] = j;
}
for( count2 = count; count2 > 0; count2-- )
{
atsRandSetBounds( rng_state, 0, count2 );
for(;;)
{
int k = atsRand32s( rng_state );
int seq_idx = index[k];
if( pos[seq_idx] < 0 )
{
DO_CV_ACTION( cvStartWriteSeq,
( 0, hdr_size, elem_size, storage, writer + seq_idx ));
cvSetSeqBlockSize( writer[seq_idx].seq, atsRandPlain32s( rng_state ) % 10000 );
pos[seq_idx] = 0;
}
if( pos[seq_idx] == sseq[seq_idx]->count )
{
seq[seq_idx] = cvEndWriteSeq( writer + seq_idx );
/* del index */
memmove( index + k, index + k + 1, (count2 - k - 1)*sizeof(int));
break;
}
{
elem_type el = (elem_type&)(simple_seq_elem( sseq[seq_idx],
pos[seq_idx] )[0]);
CV_WRITE_SEQ_ELEM( el, writer[seq_idx] );
}
pos[seq_idx]++;
}
}
/*test_exit:*/
icvFree( &writer );
icvFree( &index );
icvFree( &pos );
*msg = message_string;
*_result = result;
return code;
}
static int test_seq_ops( int count, CvSeq** seq, simple_seq** sseq,
AtsRandState* rng_state, int iters,
const char** msg, CvStatus * _result )
{
const int max_op = 8;
const char* message_string = *msg;
CvStatus result = *_result;
int i, k, code = TRS_OK;
char* elem;
char* elem2;
int idx, num;
int seq_idx, op;
elem = (char*)icvAlloc( (max_struct_size + 1) * elem_size );
for( i = 0; i < iters; i++ )
{
atsRandSetBounds( rng_state, 0, count * max_op );
seq_idx = atsRand32s( rng_state );
op = seq_idx % max_op;
seq_idx /= max_op;
switch( op )
{
case 0: /* push */
if( sseq[seq_idx]->count == sseq[seq_idx]->max_count ) break;
atsbRand8s( rng_state, elem, elem_size );
push_simple_seq_elem( sseq[seq_idx], elem );
DO_CV_ACTION( cvSeqPush, ( seq[seq_idx], elem ));
idx = sseq[seq_idx]->count - 1;
elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
if( !elem2 )
{
message_string = "Push operation doesn't add the element";
code = TRS_FAIL;
goto test_exit;
}
CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
!memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
"The last sequence element is wrong after PUSH" );
break;
case 1: /* pop */
if( sseq[seq_idx]->count == 0 ) break;
idx = sseq[seq_idx]->count - 1;
DO_CV_ACTION( cvSeqPop, ( seq[seq_idx], elem ));
CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count - 1 &&
!memcmp( elem, simple_seq_elem(sseq[seq_idx],idx), elem_size),
"The popped sequence element isn't equal to last elem of simple seq" );
drop_simple_seq_elem( sseq[seq_idx] );
if( sseq[seq_idx]->count != 0 )
{
elem2 = cvGetSeqElem( seq[seq_idx], -1, 0 );
if( !elem2 )
{
message_string = "GetSequenceElementPtr fails after POP";
code = TRS_FAIL;
goto test_exit;
}
CHECK_CONDITION( !memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx-1), elem_size),
"The last sequence element is wrong after POP" );
}
else
{
CHECK_CONDITION( seq[seq_idx]->first == 0,
"The sequence doesn't become empty after final POP" );
}
break;
case 2: /* insert */
if( sseq[seq_idx]->count == sseq[seq_idx]->max_count ) break;
atsbRand8s( rng_state, elem, elem_size );
idx = atsRandPlain32s( rng_state ) % (sseq[seq_idx]->count + 1);
insert_simple_seq_elem( sseq[seq_idx], idx, elem );
DO_CV_ACTION( cvSeqInsert, ( seq[seq_idx], idx, elem ));
elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
if( !elem2 )
{
message_string = "Insert operation doesn't add the element";
code = TRS_FAIL;
goto test_exit;
}
CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
!memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
"The inserted sequence element is wrong" );
break;
case 3: /* remove */
if( sseq[seq_idx]->count == 0 ) break;
idx = atsRandPlain32s( rng_state ) % sseq[seq_idx]->count;
DO_CV_ACTION( cvSeqRemove, ( seq[seq_idx], idx ));
remove_simple_seq_elem( sseq[seq_idx], idx );
if( idx < sseq[seq_idx]->count )
{
elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
if( !elem2 )
{
message_string = "GetSequenceElementPtr fails after Remove";
code = TRS_FAIL;
goto test_exit;
}
CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
!memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
"The element after removed one is wrong" );
}
else
{
CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count,
"The sequence doesn't become empty after final POP" );
}
break;
case 4: /* batch push */
if( sseq[seq_idx]->count == sseq[seq_idx]->max_count ) break;
num = atsRandPlain32s( rng_state ) %
(sseq[seq_idx]->max_count - sseq[seq_idx]->count + 1);
atsbRand8s( rng_state, elem, num * elem_size );
for( k = 0; k < num; k++ )
{
push_simple_seq_elem( sseq[seq_idx], elem + k * elem_size );
}
DO_CV_ACTION( cvSeqPushMulti, ( seq[seq_idx], elem, num ));
idx = sseq[seq_idx]->count;
if( idx > 0 )
{
/* choose the random element among added */
idx = num > 0 ? atsRandPlain32s( rng_state ) % num + (idx - num) : idx - 1;
elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
if( !elem2 )
{
message_string = "Multi Push operation doesn't add the element";
code = TRS_FAIL;
goto test_exit;
}
CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
!memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
"The last sequence element is wrong after PUSH" );
}
else
{
CHECK_CONDITION( seq[seq_idx]->total == 0 && seq[seq_idx]->first == 0,
"Adding no elements to empty sequence fails" );
}
break;
case 5: /* multi pop */
if( sseq[seq_idx]->count == 0 ) break;
num = atsRandPlain32s( rng_state ) % (sseq[seq_idx]->count+1);
DO_CV_ACTION( cvSeqPopMulti, ( seq[seq_idx], elem, num ));
CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count - num,
"The multi pop left a wrong number of elements in the sequence" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -