os/ossrv/genericopenlibs/cppstdlib/stl/test/eh/test_algo.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/***********************************************************************************
sl@0
     2
  test_algo.cpp
sl@0
     3
sl@0
     4
 * Copyright (c) 1997
sl@0
     5
 * Mark of the Unicorn, Inc.
sl@0
     6
 *
sl@0
     7
 * Permission to use, copy, modify, distribute and sell this software
sl@0
     8
 * and its documentation for any purpose is hereby granted without fee,
sl@0
     9
 * provided that the above copyright notice appear in all copies and
sl@0
    10
 * that both that copyright notice and this permission notice appear
sl@0
    11
 * in supporting documentation.  Mark of the Unicorn makes no
sl@0
    12
 * representations about the suitability of this software for any
sl@0
    13
 * purpose.  It is provided "as is" without express or implied warranty.
sl@0
    14
sl@0
    15
***********************************************************************************/
sl@0
    16
#include "Tests.h"
sl@0
    17
#include "LeakCheck.h"
sl@0
    18
#include "SortClass.h"
sl@0
    19
sl@0
    20
#if defined (EH_NEW_HEADERS)
sl@0
    21
# include <algorithm>
sl@0
    22
# include <cassert>
sl@0
    23
#else
sl@0
    24
# include <algo.h>
sl@0
    25
# include <assert.h>
sl@0
    26
#endif
sl@0
    27
sl@0
    28
#if defined (EH_NEW_IOSTREAMS)
sl@0
    29
# include <iostream>
sl@0
    30
#else
sl@0
    31
# include <iostream.h>
sl@0
    32
#endif
sl@0
    33
sl@0
    34
//
sl@0
    35
// SortBuffer -- a buffer of SortClass objects that can be used to test sorting.
sl@0
    36
//
sl@0
    37
struct SortBuffer
sl@0
    38
{
sl@0
    39
    enum { kBufferSize = 100 };
sl@0
    40
sl@0
    41
    SortClass* begin() { return items; }
sl@0
    42
    const SortClass* begin() const { return items; }
sl@0
    43
    SortClass* end() { return items + kBufferSize; }
sl@0
    44
    const SortClass* end() const { return items + kBufferSize; }
sl@0
    45
sl@0
    46
  // Sort each half of the buffer and reset the address of each element
sl@0
    47
  // so that merge() can be tested for stability.
sl@0
    48
    void PrepareMerge()
sl@0
    49
    {
sl@0
    50
        EH_STD::sort( begin(), begin() + ( end() - begin() )/2 );
sl@0
    51
        EH_STD::sort( begin() + ( end() - begin() )/2, end() );
sl@0
    52
        for ( SortClass* p = begin(); p != end(); p++ )
sl@0
    53
            p->ResetAddress();
sl@0
    54
    }
sl@0
    55
sl@0
    56
  SortBuffer()
sl@0
    57
  {
sl@0
    58
    PrepareMerge();
sl@0
    59
  }
sl@0
    60
sl@0
    61
  SortBuffer( const SortBuffer& rhs )
sl@0
    62
  {
sl@0
    63
    SortClass* q = begin();
sl@0
    64
    for ( const SortClass* p = rhs.begin() ; p != rhs.end(); p++,q++ )
sl@0
    65
      *q = *p;
sl@0
    66
  }
sl@0
    67
sl@0
    68
private:
sl@0
    69
    SortClass items[kBufferSize];
sl@0
    70
};
sl@0
    71
sl@0
    72
//
sl@0
    73
// less_by_reference -- a functor for comparing objects against a
sl@0
    74
//   constant value.
sl@0
    75
//
sl@0
    76
template <class T>
sl@0
    77
struct less_by_reference
sl@0
    78
{
sl@0
    79
    less_by_reference( const T& arg ) : fArg(arg) {}
sl@0
    80
    bool operator()( const T& x ) const { return x < fArg; }
sl@0
    81
private:
sl@0
    82
    const T& fArg;
sl@0
    83
};
sl@0
    84
sl@0
    85
struct test_stable_partition
sl@0
    86
{
sl@0
    87
    test_stable_partition( const SortBuffer& buf )
sl@0
    88
        : orig( buf ), partitionPoint(SortClass::kRange / 2) {
sl@0
    89
        gTestController.SetCurrentTestName("stable_partition()");
sl@0
    90
        }
sl@0
    91
sl@0
    92
    void operator()( SortBuffer& buf ) const
sl@0
    93
    {
sl@0
    94
        less_by_reference<SortClass> throw_cmp( partitionPoint );
sl@0
    95
sl@0
    96
        SortClass* d = EH_STD::stable_partition( buf.begin(), buf.end(), throw_cmp );
sl@0
    97
sl@0
    98
    // If we get here no exception occurred during the operation.
sl@0
    99
    // Stop any potential failures that might occur during verification.
sl@0
   100
        gTestController.CancelFailureCountdown();
sl@0
   101
sl@0
   102
        // Prepare an array of counts of the occurrence of each value in
sl@0
   103
        // the legal range.
sl@0
   104
        unsigned counts[SortClass::kRange];
sl@0
   105
        EH_STD::fill_n( counts, (int)SortClass::kRange, 0 );
sl@0
   106
        for ( const SortClass *q = orig.begin(); q != orig.end(); q++ )
sl@0
   107
            counts[ q->value() ]++;
sl@0
   108
sl@0
   109
        less_by_reference<TestClass> cmp( partitionPoint );
sl@0
   110
        for ( const SortClass* p = buf.begin(); p != buf.end(); p++ )
sl@0
   111
        {
sl@0
   112
          // Check that adjacent items with the same value haven't been
sl@0
   113
          // reordered. This could be a more thorough test.
sl@0
   114
            if ( p != buf.begin() && p->value() == p[-1].value() )
sl@0
   115
                EH_ASSERT( p->GetAddress() > p[-1].GetAddress() );
sl@0
   116
sl@0
   117
            // Check that the partitioning worked.
sl@0
   118
            EH_ASSERT( (p < d) == cmp( *p ) );
sl@0
   119
sl@0
   120
            // Decrement the appropriate count for each value.
sl@0
   121
            counts[ p->value() ]--;
sl@0
   122
        }
sl@0
   123
sl@0
   124
        // Check that the values were only rearranged, and none were lost.
sl@0
   125
        for ( unsigned j = 0; j < SortClass::kRange; j++ )
sl@0
   126
            EH_ASSERT( counts[j] == 0 );
sl@0
   127
    }
sl@0
   128
sl@0
   129
private:
sl@0
   130
    const SortBuffer& orig;
sl@0
   131
    SortClass partitionPoint;
sl@0
   132
};
sl@0
   133
sl@0
   134
void assert_sorted_version( const SortBuffer& orig, const SortBuffer& buf );
sl@0
   135
sl@0
   136
/*===================================================================================
sl@0
   137
  assert_sorted_version
sl@0
   138
sl@0
   139
  EFFECTS: Asserts that buf is a stable-sorted version of orig.
sl@0
   140
====================================================================================*/
sl@0
   141
void assert_sorted_version( const SortBuffer& orig, const SortBuffer& buf )
sl@0
   142
{
sl@0
   143
  // Stop any potential failures that might occur during verification.
sl@0
   144
    gTestController.CancelFailureCountdown();
sl@0
   145
sl@0
   146
    // Prepare an array of counts of the occurrence of each value in
sl@0
   147
    // the legal range.
sl@0
   148
    unsigned counts[SortClass::kRange];
sl@0
   149
    EH_STD::fill_n( counts, (int)SortClass::kRange, 0 );
sl@0
   150
    for ( const SortClass *q = orig.begin(); q != orig.end(); q++ )
sl@0
   151
        counts[ q->value() ]++;
sl@0
   152
sl@0
   153
  // Check that each element is greater than the previous one, or if they are
sl@0
   154
  // equal, that their order has been preserved.
sl@0
   155
    for ( const SortClass* p = buf.begin(); p != buf.end(); p++ )
sl@0
   156
    {
sl@0
   157
        if ( p != buf.begin() )
sl@0
   158
            EH_ASSERT( p->value() > p[-1].value()
sl@0
   159
                    || p->value() == p[-1].value() && p->GetAddress() > p[-1].GetAddress() );
sl@0
   160
    // Decrement the appropriate count for each value.
sl@0
   161
        counts[ p->value() ]--;
sl@0
   162
    }
sl@0
   163
sl@0
   164
  // Check that the values were only rearranged, and none were lost.
sl@0
   165
    for ( unsigned j = 0; j < SortClass::kRange; j++ )
sl@0
   166
        EH_ASSERT( counts[j] == 0 );
sl@0
   167
}
sl@0
   168
sl@0
   169
//
sl@0
   170
// The test operators
sl@0
   171
//
sl@0
   172
struct test_stable_sort_1
sl@0
   173
{
sl@0
   174
    test_stable_sort_1( const SortBuffer& buf )
sl@0
   175
        : orig( buf ) {
sl@0
   176
        gTestController.SetCurrentTestName("stable_sort() #1");
sl@0
   177
        }
sl@0
   178
sl@0
   179
    void operator()( SortBuffer& buf ) const
sl@0
   180
    {
sl@0
   181
        EH_STD::stable_sort( buf.begin(), buf.end() );
sl@0
   182
        assert_sorted_version( orig, buf );
sl@0
   183
    }
sl@0
   184
sl@0
   185
private:
sl@0
   186
    const SortBuffer& orig;
sl@0
   187
};
sl@0
   188
sl@0
   189
struct test_stable_sort_2
sl@0
   190
{
sl@0
   191
    test_stable_sort_2( const SortBuffer& buf )
sl@0
   192
        : orig( buf ) {
sl@0
   193
            gTestController.SetCurrentTestName("stable_sort() #2");
sl@0
   194
        }
sl@0
   195
sl@0
   196
    void operator()( SortBuffer& buf ) const
sl@0
   197
    {
sl@0
   198
      EH_STD::stable_sort( buf.begin(), buf.end(), EH_STD::less<SortClass>() );
sl@0
   199
      assert_sorted_version( orig, buf );
sl@0
   200
    }
sl@0
   201
sl@0
   202
private:
sl@0
   203
    const SortBuffer& orig;
sl@0
   204
};
sl@0
   205
sl@0
   206
struct test_inplace_merge_1
sl@0
   207
{
sl@0
   208
    test_inplace_merge_1( SortBuffer& buf )
sl@0
   209
        : orig( buf ) {
sl@0
   210
        gTestController.SetCurrentTestName("inplace_merge #1()");
sl@0
   211
        }
sl@0
   212
sl@0
   213
    void operator()( SortBuffer& buf ) const
sl@0
   214
    {
sl@0
   215
        EH_STD::inplace_merge( buf.begin(), buf.begin() + ( buf.end() - buf.begin() )/2, buf.end() );
sl@0
   216
        assert_sorted_version( orig, buf );
sl@0
   217
    }
sl@0
   218
sl@0
   219
private:
sl@0
   220
    const SortBuffer& orig;
sl@0
   221
};
sl@0
   222
sl@0
   223
struct test_inplace_merge_2
sl@0
   224
{
sl@0
   225
    test_inplace_merge_2( SortBuffer& buf )
sl@0
   226
        : orig( buf ) {
sl@0
   227
        gTestController.SetCurrentTestName("inplace_merge() #2");
sl@0
   228
        }
sl@0
   229
sl@0
   230
    void operator()( SortBuffer& buf ) const
sl@0
   231
    {
sl@0
   232
        EH_STD::inplace_merge( buf.begin(), buf.begin() + ( buf.end() - buf.begin() )/2, buf.end(),
sl@0
   233
                       EH_STD::less<SortClass>() );
sl@0
   234
        assert_sorted_version( orig, buf );
sl@0
   235
    }
sl@0
   236
sl@0
   237
private:
sl@0
   238
    const SortBuffer& orig;
sl@0
   239
};
sl@0
   240
sl@0
   241
void test_algo()
sl@0
   242
{
sl@0
   243
    SortBuffer mergeBuf;
sl@0
   244
    mergeBuf.PrepareMerge();
sl@0
   245
sl@0
   246
    EH_STD::cerr<<"EH test : testing algo.h"<<EH_STD::endl;
sl@0
   247
    WeakCheck( mergeBuf, test_inplace_merge_1( mergeBuf ) );
sl@0
   248
    WeakCheck( mergeBuf, test_inplace_merge_2( mergeBuf ) );
sl@0
   249
sl@0
   250
    SortBuffer buf;
sl@0
   251
    WeakCheck( buf, test_stable_sort_1( buf ) );
sl@0
   252
    WeakCheck( buf, test_stable_sort_2( buf ) );
sl@0
   253
    WeakCheck( buf, test_stable_partition( buf ) );
sl@0
   254
}