Beispiel #1
0
void TestHeapOperations (void)
{
    static const int c_Values [31] = {	// 31 values make a full 4-layer tree
	93, 92, 90, 86, 83, 86, 77, 40, 72, 36, 68, 82, 62, 67, 63, 15,
	26, 26, 49, 21, 11, 62, 67, 27, 29, 30, 35, 23, 59, 35, 29
    };
    vector<int> v;
    v.reserve (VectorSize(c_Values));
    for (uoff_t i = 0; i < VectorSize(c_Values); ++ i) {
	v.push_back (c_Values[i]);
	push_heap (v.begin(), v.end());
	cout << "------------------------------------------------\n";
	if (!is_heap (v.begin(), v.end()))
	    cout << "Is NOT a heap\n";
	PrintHeap (v);
    }
    cout << "------------------------------------------------\n";
    cout << "make_heap on the full range:\n";
    v.resize (VectorSize (c_Values));
    copy (VectorRange(c_Values), v.begin());
    make_heap (v.begin(), v.end());
    PrintHeap (v);
    if (!is_heap (v.begin(), v.end()))
	cout << "Is NOT a heap\n";
    cout << "------------------------------------------------\n";
    cout << "pop_heap:\n";
    pop_heap (v.begin(), v.end());
    v.pop_back();
    PrintHeap (v);
    if (!is_heap (v.begin(), v.end()))
	cout << "Is NOT a heap\n";

    cout << "------------------------------------------------\n";
    cout << "sort_heap:\n";
    v.resize (VectorSize (c_Values));
    copy (VectorRange(c_Values), v.begin());
    make_heap (v.begin(), v.end());
    sort_heap (v.begin(), v.end());
    foreach (vector<int>::const_iterator, i, v)
	cout << *i;
    cout << endl;

    cout << "------------------------------------------------\n";
    cout << "priority_queue push and pop:\n";
    priority_queue<int> q;
    for (uoff_t i = 0; i < VectorSize(c_Values); ++ i)
	q.push (c_Values[i]);
    while (!q.empty()) {
	cout << q.top();
	q.pop();
    }
    cout << endl;
}
Beispiel #2
0
void TestCML (void)
{
    const char hello[] = "Hello world!";
    const char* phello = hello; // const storage is sometimes copied on pointing

    cmemlink a, b;
    a.link (phello, VectorSize(hello));
    if (a.begin() != phello)
	cout.format ("a.begin() failed: %p != %p\n", a.begin(), phello);
    a.link (VectorRange (hello));
    if (*(const char*)(a.begin() + 5) != hello[5])
	cout.format ("begin()[5] failed: %c != %c\n", *(const char*)(a.begin() + 5), VectorElement(hello,5));
    if (a.size() != VectorSize(hello))
	cout << "link to VectorRange doesn't work\n";
    if (0 != memcmp (a.begin(), hello, VectorSize(hello)))
	cout << "memcmp failed on cmemlink\n";
    b.static_link (hello);
    WriteCML (a);
    WriteCML (b);
    if (!(a == b))
	cout << "operator== failed on cmemlink\n";
    b.resize (VectorSize(hello) - 5);
    a = b;
    WriteCML (a);
}
Beispiel #3
0
void TestCML (void)
{
    const char hello[] = "Hello world!";
    const char* phello = hello; // const storage is sometimes copied on pointing

    cmemlink a, b;
    a.link (phello, VectorSize(hello));
    if (a.begin() != phello) {
	cout << "a.begin() failed: " << ios::hex << uintptr_t(a.begin());
        cout << " != " << uintptr_t(phello) << ios::dec << endl;
    }
    a.link (VectorRange (hello));
    if (*(const char*)(a.begin() + 5) != hello[5]) {
	cout << "begin()[5] failed: " << *(const char*)(a.begin() + 5);
	cout << " != " << hello[5] << endl;
    }
    if (a.size() != VectorSize(hello))
	cout << "link to VectorRange doesn't work" << endl;
    if (0 != memcmp (a.begin(), hello, VectorSize(hello)))
	cout << "memcmp failed on cmemlink" << endl;
    b.static_link (hello);
    WriteCML (a);
    WriteCML (b);
    if (!(a == b))
	cout << "operator== failed on cmemlink" << endl;
    b.resize (VectorSize(hello) - 5);
    a = b;
    WriteCML (a);
}
Beispiel #4
0
int main() {
	VectorInt vi {1,2,3,4,5,6,7,8};

	for(auto& v : VectorRange(vi)) {
		LOG("%f", v);
	}
}
Beispiel #5
0
void TestString (void)
{
    const char c_TestString1[] = "123456789012345678901234567890";
    const char c_TestString2[] = "abcdefghijklmnopqrstuvwxyz";
    const char c_TestString3[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string s1 (c_TestString1);
    string s2 (VectorRange (c_TestString2));
    string s3 (s1);

    cout << s1 << endl;
    cout << s2 << endl;
    cout << s3 << endl;
    s3.reserve (48);
    s3.resize (20);

    uoff_t i;
    for (i = 0; i < s3.length(); ++ i)
	s3.at(i) = s3.at(i);
    for (i = 0; i < s3.length(); ++ i)
	s3[i] = s3[i];
    cout << s3 << endl;
    cout << "s3.size() = " << s3.size();
    cout << ", max_size() = ";
    if (s3.max_size() == SIZE_MAX - 1)
	cout << "(SIZE_MAX/elsize)-1";
    else
	cout << s3.max_size();
    cout << ", capacity() = " << s3.capacity() << endl;

    s1.unlink();
    s1 = c_TestString2;
    s1 += c_TestString3;
    s1 += '$';
    cout << s1 << endl;

    s1 = "Hello";
//    s2.unlink(); // Removed by Penrillian: Silly thing to do - s2 has allocated memory.
    s2 = "World";
    s3 = s1 + s2;
    cout << s3 << endl;
    s3 = "Concatenated ";
    s3 += s1.c_str();
    s3 += s2;
    s3 += " string.";
    cout << s3 << endl;

    if (s1 < s2)
	cout << "s1 < s2" << endl;
    if (s1 == s1)
	cout << "s1 == s1" << endl;
    if (s1[0] != s1[0])
	cout << "s1[0] != s1[0]" << endl;

    string s4;
    s4.link (s1);
    if (s1 == s4)
	cout << "s1 == s4" << endl;

    s1 = c_TestString1;
    string s5 (s1.begin() + 4, s1.begin() + 4 + 5);
    string s6 (s1.begin() + 4, s1.begin() + 4 + 5);
    if (s5 == s6)
	cout << s5 << " == " << s6 << endl;
    string tail (s1.begin() + 7, s1.end());
    cout << "&s1[7] = " << tail << endl;

    cout << "initial:\t\t" << s1.data() << endl;
    cout << "erase(5,find(9)-5)\t";
    s1.erase (5, s1.find ('9')-5);
    cout << s1 << endl;
    cout << "erase(5,5)\t\t";
    s1.erase (s1.begin() + 5, 2U);
    s1.erase (5, 3);
    assert (!*s1.end());
    cout << s1 << endl;
    cout << "push_back('x')\t\t";
    s1.push_back ('x');
    assert (!*s1.end());
    cout << s1 << endl;
    cout << "pop_back()" << endl;
    s1.pop_back();
    assert (!*s1.end());
    cout << "insert(10,#)\t\t";
    s1.insert (s1.begin() + 10, '#');
    assert (!*s1.end());
    cout << s1 << endl;
    cout << "replace(0,5,@)\t\t";
    s1.replace (s1.begin(), s1.begin() + 5, 1, '@');
    assert (!*s1.end());
    cout << s1 << endl;

    s1 = c_TestString1;
    cout << "8 found at " << s1.find ('8') << endl;
    cout << "9 found at " << s1.find ("9") << endl;
    cout << "7 rfound at " << s1.rfind ('7') << endl;
    cout << "7 rfound again at " << s1.rfind ('7', s1.rfind ('7') - 1) << endl;
    cout << "67 rfound at " << s1.rfind ("67") << endl;
    if (s1.rfind("X") == string::npos)
	cout << "X was not rfound" << endl;
    else
	cout << "X rfound at " << s1.rfind ("X") << endl;
    uoff_t poundfound = s1.find ("#");
    if (poundfound != string::npos)
	cout << "# found at " << poundfound << endl;
    cout << "[456] found at " << s1.find_first_of ("456") << endl;
    cout << "[456] last found at " << s1.find_last_of ("456") << endl;

    s2.clear();
    assert (!*s2.end());
    if (s2.empty())
	cout << "s2 is empty [" << s2 << "], capacity " << s2.capacity() << " bytes" << endl;

    s2.format ("<const] %d, %s, 0x%08X", 42, "[rfile>", 0xDEADBEEF);
    cout << "<" << s2.length() << " bytes of " << s2.capacity();
    cout << "> Format '" << s2 << '\''<< endl;
    MyFormat ("'<const] %d, %s, 0x%08X'", 42, "[rfile>", 0xDEADBEEF);
}
Beispiel #6
0
/*--------------------------------------------------------------------
  EVSdesignMtxStats() - computes statistics about design relevant for
  optimization. stats should have at least 6 elements. Returns 1 is
  the design is singular, 0 otherwise.  ERROR: This needs to be
  modified to compute the VRF differently when there are different
  numbers of stimuli in each event type.x
  -------------------------------------------------------------------*/
int EVSdesignMtxStats(MATRIX *Xtask, MATRIX *Xnuis, EVSCH *EvSch, MATRIX *C, MATRIX *W)
{
  MATRIX *X=NULL, *Xt=NULL, *XtX=NULL;
  MATRIX *iXtX=NULL, *VRF=NULL, *Ct=NULL, *CiXtX=NULL, *CiXtXCt=NULL;
  int r,m,nTaskAvgs,nNuisAvgs,nAvgs,Cfree,J;
  float diagsum;
  double dtmp, dtmp1, dtmp2;

  X = MatrixHorCat(Xtask,Xnuis,NULL);
  nTaskAvgs = Xtask->cols;
  if (Xnuis != NULL) nNuisAvgs = Xnuis->cols;
  else              nNuisAvgs = 0;
  nAvgs     = X->cols;

  if (W != NULL) X = MatrixMultiply(W,X,NULL);

  Xt = MatrixTranspose(X,Xt);
  XtX = MatrixMultiply(Xt,X,XtX);

  /* Compute the Inverse */
  iXtX = MatrixInverse(XtX,NULL);

  Cfree = 0;
  if (C==NULL)
  {
    C = MatrixZero(nTaskAvgs,nAvgs,NULL);
    for (m=0; m < nTaskAvgs; m++) C->rptr[m+1][m+1] = 1;
    Cfree = 1;
  }
  J = C->rows;
  Ct = MatrixTranspose(C,NULL);

  /* Make sure that it was actually inverted */
  if (iXtX != NULL)
  {
    r = 0;

    CiXtX   = MatrixMultiply(C,iXtX,NULL);
    CiXtXCt = MatrixMultiply(CiXtX,Ct,NULL);

    VRF = MatrixAlloc(J,1,MATRIX_REAL);

    diagsum = 0.0;
    for (m=0; m < J; m++)
    {/* exctract diag */
      diagsum += CiXtXCt->rptr[m+1][m+1];
      VRF->rptr[m+1][1] = 1.0/(CiXtXCt->rptr[m+1][m+1]);
    }
    EvSch->eff = 1.0/diagsum;
    if (J>1) EvSch->vrfstd = VectorStdDev(VRF,&dtmp);
    else    EvSch->vrfstd = 0.0;
    EvSch->vrfavg = dtmp;
    EvSch->vrfrange = VectorRange(VRF,&dtmp1,&dtmp2);
    EvSch->vrfmin = dtmp1;
    EvSch->vrfmax = dtmp2;

    MatrixFree(&iXtX);
    MatrixFree(&CiXtX);
    MatrixFree(&CiXtXCt);
    MatrixFree(&VRF);
  }
  else r = 1;

  MatrixFree(&X);
  MatrixFree(&Xt);
  MatrixFree(&XtX);
  if (Cfree) MatrixFree(&C);
  MatrixFree(&Ct);

  return(r);
}
Beispiel #7
0
static void TestAlgorithms (void)
{
    static const int c_TestNumbers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15, 16, 17, 18 };
    const int* first = c_TestNumbers;
    const int* last = first + VectorSize(c_TestNumbers);
    intvec_t v, buf;
    v.assign (first, last);
    PrintVector (v);

    cout << "swap(1,2)\n";
    swap (v[0], v[1]);
    PrintVector (v);
    v.assign (first, last);

    cout << "copy(0,8,9)\n";
    copy (v.begin(), v.begin() + 8, v.begin() + 9);
    PrintVector (v);
    v.assign (first, last);

    cout << "copy with back_inserter\n";
    v.clear();
    copy (first, last, back_inserter(v));
    PrintVector (v);
    v.assign (first, last);

    cout << "copy with inserter\n";
    v.clear();
    copy (first, first + 5, inserter(v, v.begin()));
    copy (first, first + 5, inserter(v, v.begin() + 3));
    PrintVector (v);
    v.assign (first, last);

    cout << "copy_n(0,8,9)\n";
    copy_n (v.begin(), 8, v.begin() + 9);
    PrintVector (v);
    v.assign (first, last);

    cout << "copy_if(is_even)\n";
    intvec_t v_even;
    copy_if (v, back_inserter(v_even), &is_even);
    PrintVector (v_even);
    v.assign (first, last);

    cout << "for_each(printint)\n{ ";
    for_each (v, &printint);
    cout << "}\n";

    cout << "for_each(reverse_iterator, printint)\n{ ";
    for_each (v.rbegin(), v.rend(), &printint);
    cout << "}\n";

    cout << "find(10)\n";
    cout.format ("10 found at offset %zd\n", abs_distance (v.begin(), find (v, 10)));

    cout << "count(13)\n";
    cout.format ("%zu values of 13, %zu values of 18\n", count(v,13), count(v,18));

    cout << "transform(sqr)\n";
    transform (v, &sqr);
    PrintVector (v);
    v.assign (first, last);

    cout << "replace(13,666)\n";
    replace (v, 13, 666);
    PrintVector (v);
    v.assign (first, last);

    cout << "fill(13)\n";
    fill (v, 13);
    PrintVector (v);
    v.assign (first, last);

    cout << "fill_n(5, 13)\n";
    fill_n (v.begin(), 5, 13);
    PrintVector (v);
    v.assign (first, last);

    cout << "fill 64083 uint8_t(0x41) ";
    TestBigFill<uint8_t> (64083, 0x41);
    cout << "fill 64083 uint16_t(0x4142) ";
    TestBigFill<uint16_t> (64083, 0x4142);
    cout << "fill 64083 uint32_t(0x41424344) ";
    TestBigFill<uint32_t> (64083, 0x41424344);
    cout << "fill 64083 float(0.4242) ";
    TestBigFill<float> (64083, 0x4242f);
#if HAVE_INT64_T
    cout << "fill 64083 uint64_t(0x4142434445464748) ";
    TestBigFill<uint64_t> (64083, UINT64_C(0x4142434445464748));
#else
    cout << "No 64bit types available on this platform\n";
#endif

    cout << "copy 64083 uint8_t(0x41) ";
    TestBigCopy<uint8_t> (64083, 0x41);
    cout << "copy 64083 uint16_t(0x4142) ";
    TestBigCopy<uint16_t> (64083, 0x4142);
    cout << "copy 64083 uint32_t(0x41424344) ";
    TestBigCopy<uint32_t> (64083, 0x41424344);
    cout << "copy 64083 float(0.4242) ";
    TestBigCopy<float> (64083, 0.4242f);
#if HAVE_INT64_T
    cout << "copy 64083 uint64_t(0x4142434445464748) ";
    TestBigCopy<uint64_t> (64083, UINT64_C(0x4142434445464748));
#else
    cout << "No 64bit types available on this platform\n";
#endif

    cout << "generate(genint)\n";
    generate (v, &genint);
    PrintVector (v);
    v.assign (first, last);

    cout << "rotate(4)\n";
    rotate (v, 7);
    rotate (v, -3);
    PrintVector (v);
    v.assign (first, last);

    cout << "merge with (3,5,10,11,11,14)\n";
    const int c_MergeWith[] = { 3,5,10,11,11,14 };
    intvec_t vmerged;
    merge (v.begin(), v.end(), VectorRange(c_MergeWith), back_inserter(vmerged));
    PrintVector (vmerged);
    v.assign (first, last);

    cout << "inplace_merge with (3,5,10,11,11,14)\n";
    v.insert (v.end(), VectorRange(c_MergeWith));
    inplace_merge (v.begin(), v.end() - VectorSize(c_MergeWith), v.end());
    PrintVector (v);
    v.assign (first, last);

    cout << "remove(13)\n";
    remove (v, 13);
    PrintVector (v);
    v.assign (first, last);

    cout << "remove (elements 3, 4, 6, 15, and 45)\n";
    vector<uoff_t> toRemove;
    toRemove.push_back (3);
    toRemove.push_back (4);
    toRemove.push_back (6);
    toRemove.push_back (15);
    toRemove.push_back (45);
    typedef index_iterate<intvec_t::iterator, vector<uoff_t>::iterator> riiter_t;
    riiter_t rfirst = index_iterator (v.begin(), toRemove.begin());
    riiter_t rlast = index_iterator (v.begin(), toRemove.end());
    remove (v, rfirst, rlast);
    PrintVector (v);
    v.assign (first, last);

    cout << "unique\n";
    unique (v);
    PrintVector (v);
    v.assign (first, last);

    cout << "reverse\n";
    reverse (v);
    PrintVector (v);
    v.assign (first, last);

    cout << "lower_bound(10)\n";
    PrintVector (v);
    cout.format ("10 begins at position %zd\n", abs_distance (v.begin(), lower_bound (v, 10)));
    v.assign (first, last);

    cout << "upper_bound(10)\n";
    PrintVector (v);
    cout.format ("10 ends at position %zd\n", abs_distance (v.begin(), upper_bound (v, 10)));
    v.assign (first, last);

    cout << "equal_range(10)\n";
    PrintVector (v);
    TestEqualRange (v);
    v.assign (first, last);

    cout << "sort\n";
    reverse (v);
    PrintVector (v);
    random_shuffle (v);
    sort (v);
    PrintVector (v);
    v.assign (first, last);

    cout << "stable_sort\n";
    reverse (v);
    PrintVector (v);
    random_shuffle (v);
    stable_sort (v);
    PrintVector (v);
    v.assign (first, last);

    cout << "is_sorted\n";
    random_shuffle (v);
    const bool bNotSorted = is_sorted (v.begin(), v.end());
    sort (v);
    const bool bSorted = is_sorted (v.begin(), v.end());
    cout << "unsorted=" << bNotSorted << ", sorted=" << bSorted << endl;
    v.assign (first, last);

    cout << "find_first_of\n";
    static const int c_FFO[] = { 10000, -34, 14, 27 };
    cout.format ("found 14 at position %zd\n", abs_distance (v.begin(), find_first_of (v.begin(), v.end(), VectorRange(c_FFO))));
    v.assign (first, last);

    static const int LC1[] = { 3, 1, 4, 1, 5, 9, 3 };
    static const int LC2[] = { 3, 1, 4, 2, 8, 5, 7 };
    static const int LC3[] = { 1, 2, 3, 4 };
    static const int LC4[] = { 1, 2, 3, 4, 5 };
    cout << "lexicographical_compare";
    cout << "\nLC1 < LC2 == " << lexicographical_compare (VectorRange(LC1), VectorRange(LC2));
    cout << "\nLC2 < LC2 == " << lexicographical_compare (VectorRange(LC2), VectorRange(LC2));
    cout << "\nLC3 < LC4 == " << lexicographical_compare (VectorRange(LC3), VectorRange(LC4));
    cout << "\nLC4 < LC1 == " << lexicographical_compare (VectorRange(LC4), VectorRange(LC1));
    cout << "\nLC1 < LC4 == " << lexicographical_compare (VectorRange(LC1), VectorRange(LC4));

    cout << "\nmax_element\n";
    cout.format ("max element is %d\n", *max_element (v.begin(), v.end()));
    v.assign (first, last);

    cout << "min_element\n";
    cout.format ("min element is %d\n", *min_element (v.begin(), v.end()));
    v.assign (first, last);

    cout << "partial_sort\n";
    reverse (v);
    partial_sort (v.begin(), v.iat(v.size() / 2), v.end());
    PrintVector (v);
    v.assign (first, last);

    cout << "partial_sort_copy\n";
    reverse (v);
    buf.resize (v.size());
    partial_sort_copy (v.begin(), v.end(), buf.begin(), buf.end());
    PrintVector (buf);
    v.assign (first, last);

    cout << "partition\n";
    partition (v.begin(), v.end(), &is_even);
    PrintVector (v);
    v.assign (first, last);

    cout << "stable_partition\n";
    stable_partition (v.begin(), v.end(), &is_even);
    PrintVector (v);
    v.assign (first, last);

    cout << "next_permutation\n";
    buf.resize (3);
    iota (buf.begin(), buf.end(), 1);
    PrintVector (buf);
    while (next_permutation (buf.begin(), buf.end()))
	PrintVector (buf);
    cout << "prev_permutation\n";
    reverse (buf);
    PrintVector (buf);
    while (prev_permutation (buf.begin(), buf.end()))
	PrintVector (buf);
    v.assign (first, last);

    cout << "reverse_copy\n";
    buf.resize (v.size());
    reverse_copy (v.begin(), v.end(), buf.begin());
    PrintVector (buf);
    v.assign (first, last);

    cout << "rotate_copy\n";
    buf.resize (v.size());
    rotate_copy (v.begin(), v.iat (v.size() / 3), v.end(), buf.begin());
    PrintVector (buf);
    v.assign (first, last);

    static const int c_Search1[] = { 5, 6, 7, 8, 9 }, c_Search2[] = { 10, 10, 11, 14 };
    cout << "search\n";
    cout.format ("{5,6,7,8,9} at %zd\n", abs_distance (v.begin(), search (v.begin(), v.end(), VectorRange(c_Search1))));
    cout.format ("{10,10,11,14} at %zd\n", abs_distance (v.begin(), search (v.begin(), v.end(), VectorRange(c_Search2))));
    cout << "find_end\n";
    cout.format ("{5,6,7,8,9} at %zd\n", abs_distance (v.begin(), find_end (v.begin(), v.end(), VectorRange(c_Search1))));
    cout.format ("{10,10,11,14} at %zd\n", abs_distance (v.begin(), find_end (v.begin(), v.end(), VectorRange(c_Search2))));
    cout << "search_n\n";
    cout.format ("{14} at %zd\n", abs_distance (v.begin(), search_n (v.begin(), v.end(), 1, 14)));
    cout.format ("{13,13} at %zd\n", abs_distance (v.begin(), search_n (v.begin(), v.end(), 2, 13)));
    cout.format ("{10,10,10} at %zd\n", abs_distance (v.begin(), search_n (v.begin(), v.end(), 3, 10)));
    v.assign (first, last);

    cout << "includes\n";
    static const int c_Includes[] = { 5, 14, 15, 18, 20 };
    cout << "includes=" << includes (v.begin(), v.end(), VectorRange(c_Includes)-1);
    cout << ", not includes=" << includes (v.begin(), v.end(), VectorRange(c_Includes));
    cout << endl;

    static const int c_Set1[] = { 1, 2, 3, 4, 5, 6 }, c_Set2[] = { 4, 4, 6, 7, 8 };
    intvec_t::iterator setEnd;
    cout << "set_difference\n";
    v.resize (4);
    setEnd = set_difference (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
    PrintVector (v);
    assert (setEnd == v.end());
    cout << "set_symmetric_difference\n";
    v.resize (7);
    setEnd = set_symmetric_difference (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
    PrintVector (v);
    assert (setEnd == v.end());
    cout << "set_intersection\n";
    v.resize (2);
    setEnd = set_intersection (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
    PrintVector (v);
    assert (setEnd == v.end());
    cout << "set_union\n";
    v.resize (9);
    setEnd = set_union (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
    PrintVector (v);
    assert (setEnd == v.end());
    v.assign (first, last);
}
Beispiel #8
0
void TestUTF8 (void)
{
    cout << "Generating Unicode characters ";
    vector<wchar_t> srcChars;
    srcChars.resize (0xFFFF);
    iota (srcChars.begin(), srcChars.end(), 0);
    cout << size_t(srcChars[0]) << " - " << size_t(srcChars.back()) << endl;

    cout << "Encoding to utf8." << endl;
    string encoded;
    encoded.reserve (srcChars.size() * 4);
    copy (srcChars, utf8out (back_inserter(encoded)));
    const char c_ProperEncoding[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    if (encoded.compare (encoded.begin(), encoded.begin() + VectorSize(c_ProperEncoding), VectorRange(c_ProperEncoding))) {
	cout << "Encoding failed: ";
	for (string::const_iterator i = encoded.begin(); i != encoded.begin() + VectorSize(c_ProperEncoding); ++ i)
	    cout << uint32_t(*i);
	cout << endl;
    }

    cout << "Decoding back." << endl;
    vector<wchar_t> decChars;
    assert( decChars.size() == 0 );
    Widen (encoded, decChars);

    cout << "Comparing." << endl;
    cout << "src = " << srcChars.size();
    cout << " chars, encoded = " << encoded.size();
    cout << " chars, decoded = " << decChars.size() << endl;
    size_t nDiffs = 0;
    for (uoff_t i = 0; i < min (srcChars.size(), decChars.size()); ++ i) {
	if (srcChars[i] != decChars[i]) {
	    cout << uint32_t(srcChars[i]) << " != " << uint32_t(decChars[i]) << endl;
	    ++ nDiffs;
	}
    }
    cout << nDiffs << " differences between src and decoded." << endl;

    cout << "Testing wide character string::insert" << endl;
    string ws ("1234567890", 10);

    ws.insert (0, wchar_t(1234));
    ws.insert (3, wchar_t(2345));
    const wchar_t c_WChars[2] = { 3456, 4567 };
    ws.insert (3, VectorRange(c_WChars), 2);
    ws.insert (ws.utf_length(), wchar_t(5678));
    cout << "Values[" << ws.utf_length() << "]:";
    for (string::utf8_iterator j = ws.utf8_begin(); j < ws.utf8_end(); ++ j)
	cout << ' ' << (uint32_t) *j;
    cout << endl;

    cout << "Character offsets:";
    for (string::utf8_iterator k = ws.utf8_begin(); k < ws.utf8_end(); ++ k)
	cout << ' ' << distance (ws.begin(), k.base());
    cout << endl;

    cout << "Erasing character " << ws.utf_length() - 1 << ": ";
    ws.erase (ws.utf_length() - 1);
    Widen (ws, decChars);
    DumpWchars (decChars);
    cout << endl;

    cout << "Erasing characters 3-5: ";
    ws.erase (3, 2);
    Widen (ws, decChars);
    DumpWchars (decChars);
    cout << endl;
}