Click here to Skip to main content
15,886,110 members
Articles / High Performance Computing / Vectorization

A C++ String Class

Rate me:
Please Sign up or sign in to vote.
4.96/5 (29 votes)
3 Jan 2015CPOL13 min read 120.7K   2.6K   93  
A fast, reference counted, copy-on-write string class
// StringsExample.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "hwinstring.h"
#include "hwindatetime.h"
#include "hwintext.h"

#include <iostream>
#include <fstream>

#include <atlstr.h>


using namespace harlinn::windows;
using namespace harlinn::windows::text;

void runCompare(const String& s1, const String& s2)
{
    std::wcout << L"Comparing:\"" << (s1?s1:L"") << L"\" and \"" << (s2?s2:L"") << std::endl;
    std::wcout << L"\tbool operator == (const String& other) const returned ";
    if(s1 == s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }
    std::wcout << L"\tbool operator != (const String& other) const returned ";
    if(s1 != s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }

    std::wcout << L"\tbool operator <= (const String& other) const returned ";
    if(s1 <= s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }

    std::wcout << L"\tbool operator < (const String& other) const returned ";
    if(s1 < s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }

    std::wcout << L"\tbool operator >= (const String& other) const returned ";
    if(s1 >= s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }
    std::wcout << L"\tbool operator > (const String& other) const returned ";
    if(s1 > s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }




}


void runExample()
{
    String s;
    std::wcout << L"Empty string:" << (s?L"Not null" : L"null") << std::endl;

    String sCopy(s);
    std::wcout << L"Copy of empty string:" << (sCopy?L"Not null" : L"null") << std::endl;

    String sFillWithChars(3,L'H');
    std::wcout << L"Filled with chars (3,L'H'):" << sFillWithChars << std::endl;

    String sFillWithChars2(nullptr,1,L"ello",4,L'H');
    std::wcout << L"Filled with chars (nullptr,1,L\"ello\",4,L'H'):" << sFillWithChars2 << std::endl;


    String sFillWithChars3(nullptr,1,L"el",2,L"lo",2,L'H');
    std::wcout << L"Filled with chars (nullptr,1,L\"el\",2,L\"lo\",2,L'H'):" << sFillWithChars3 << std::endl;


    String sCopy2(sFillWithChars3);
    std::wcout << L"Copy of string:" << sCopy2 << std::endl;

    String sPlainString(L"Plain String");
    std::wcout << L"Plain String:" << sPlainString << std::endl;

    s = L"Hello!";
    std::wcout << L"String assignment (const wchar_t*):" << s << std::endl;

    s = s.c_str() + 1;
    std::wcout << L"String assignment from inside string (s = s.c_str() + 1):" << s << std::endl;

    s = sPlainString;
    std::wcout << L"String assignment (const String&):" << s << std::endl;

    String s1 = L"Hello";
    String s2 = L"Hello";

    runCompare(s1,s2);
    s2 = L"Hellp";
    runCompare(s1,s2);

    s2 = L"Helln";
    runCompare(s1,s2);

    String s3 = s1 + s2;
    std::wcout << L"String operator + (const String& str1,const String& str2) returned:" << s3 << std::endl;

    s1 = String();
    s3 = s1 + s2;
    std::wcout << L"String operator + (const String& str1,const String& str2) for empty str1 returned:" << s3 << std::endl;

    s1 = L"Hello";
    s2 = String();
    s3 = s1 + s2;
    std::wcout << L"String operator + (const String& str1,const String& str2) for empty str2 returned:" << s3 << std::endl;


    std::wcout << L"String::size_type pos = s1.IndexOfAnyOf(L\"qwrty\") returned: ";
    String::size_type pos = s1.IndexOfAnyOf(L"qwrty");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wstring ws = L"Hello";
    std::wcout << L"std::wstring::size_type wspos = ws.find_first_of(L\"qwrty\") returned: ";
    std::wstring::size_type wspos = ws.find_first_of(L"qwrty");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOfAnyOf(L\"olp\") returned: ";
    pos = s1.IndexOfAnyOf(L"olp");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_first_of(L\"olp\") returned: ";
    wspos = ws.find_first_of(L"olp");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOfAnyBut(L\"olh\") returned: ";
    pos = s1.IndexOfAnyBut(L"olh");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }


    std::wcout << L"std::wstring::size_type wspos = ws.find_first_not_of(L\"olh\") returned: ";
    wspos = ws.find_first_not_of(L"olh");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOfAnyBut(L\"olhr\") returned: ";
    pos = s1.IndexOfAnyBut(L"olhr");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_first_not_of(L\"olhr\") returned: ";
    wspos = ws.find_first_not_of(L"olhr");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }



    std::wcout << L"String::size_type pos = s1.IndexOfAnyBut(L\"eH\") returned: ";
    pos = s1.IndexOfAnyBut(L"eH");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_first_not_of(L\"eH\") returned: ";
    wspos = ws.find_first_not_of(L"eH");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"qwrty\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"qwrty");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"qwrty\") returned: ";
    wspos = ws.find_last_of(L"qwrty");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"olp\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"olp");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }


    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"olp\") returned: ";
    wspos = ws.find_last_of(L"olp");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"hey\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"hey");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"hey\") returned: ";
    wspos = ws.find_last_of(L"hey");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }



    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"zxcH\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"zxcH");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"zxcH\") returned: ";
    wspos = ws.find_last_of(L"zxcH");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyBut(L\"o\") returned: ";
    pos = s1.LastIndexOfAnyBut(L"o");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_not_of(L\"o\") returned: ";
    wspos = ws.find_last_not_of(L"o");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyBut(L\"ol\") returned: ";
    pos = s1.LastIndexOfAnyBut(L"ol");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_not_of(L\"ol\") returned: ";
    wspos = ws.find_last_not_of(L"ol");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"qwrt\") returned: ";
    pos = s1.IndexOf(L"qwrt");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"qwrt\") returned: ";
    wspos = ws.find(L"qwrt");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOf(L\"H\") returned: ";
    pos = s1.IndexOf(L"H");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"H\") returned: ";
    wspos = ws.find(L"H");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"He\") returned: ";
    pos = s1.IndexOf(L"He");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"He\") returned: ";
    wspos = ws.find(L"He");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"o\") returned: ";
    pos = s1.IndexOf(L"o");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"o\") returned: ";
    wspos = ws.find(L"o");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"lo\") returned: ";
    pos = s1.IndexOf(L"lo");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"lo\") returned: ";
    wspos = ws.find(L"lo");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOf(L\"ll\") returned: ";
    pos = s1.IndexOf(L"ll");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"ll\") returned: ";
    wspos = ws.find(L"ll");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"qwrt\") returned: ";
    pos = s1.LastIndexOf(L"qwrt");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"qwrt\") returned: ";
    wspos = ws.rfind(L"qwrt");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"ll\") returned: ";
    pos = s1.LastIndexOf(L"ll");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"ll\") returned: ";
    wspos = ws.rfind(L"ll");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"H\") returned: ";
    pos = s1.LastIndexOf(L"H");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"H\") returned: ";
    wspos = ws.rfind(L"H");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"He\") returned: ";
    pos = s1.LastIndexOf(L"He");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"He\") returned: ";
    wspos = ws.rfind(L"He");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"o\") returned: ";
    pos = s1.LastIndexOf(L"o");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"o\") returned: ";
    wspos = ws.rfind(L"o");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"lo\") returned: ";
    pos = s1.LastIndexOf(L"lo");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"lo\") returned: ";
    wspos = ws.rfind(L"lo");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    wchar_t wbuffer[10] = {0,};

    std::wcout << L"s1.CopyTo(wbuffer,1) copied: ";
    s1.CopyTo(wbuffer,1);
    std::wcout << wbuffer << std::endl;

    std::wcout << L"ws.copy(wbuffer,1) copied: ";
    ws.copy(wbuffer,1);
    std::wcout << wbuffer << std::endl;


    std::wcout << L"s1.CopyTo(wbuffer,1,4) copied: ";
    s1.CopyTo(wbuffer,1,4);
    std::wcout << wbuffer << std::endl;

    std::wcout << L"ws.copy(wbuffer,1,4) copied: ";
    ws.copy(wbuffer,1,4);
    std::wcout << wbuffer << std::endl;

    
    std::wcout << L"s2 = s1.SubString(0) copied: ";
    s2 = s1.SubString(0);
    std::wcout << s2 << std::endl;

    std::wcout << L"ws2 = ws.substr(0) copied: ";
    std::wstring ws2 = ws.substr(0);
    std::wcout << ws2 << std::endl;

    std::wcout << L"s2 = s1.SubString(1,2) copied: ";
    s2 = s1.SubString(1,2);
    std::wcout << s2 << std::endl;

    std::wcout << L"ws2 = ws.substr(1,2) copied: ";
    ws2 = ws.substr(1,2);
    std::wcout << ws2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.UpperCase(): ";
    s2.UpperCase();
    std::wcout << s2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.LowerCase(): ";
    s2.LowerCase();
    std::wcout << s2 << std::endl;


    s2 = s1;
    std::wcout << L"s2.Remove(0): ";
    s2.Remove(0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(0): ";
    ws2.erase(0);
    std::wcout << ws2 << std::endl;


    s2 = s1;
    std::wcout << L"s2.Remove(0,0): ";
    s2.Remove(0,0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(0,0): ";
    ws2.erase(0,0);
    std::wcout << ws2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.Remove(0,1): ";
    s2.Remove(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(0,1): ";
    ws2.erase(0,1);
    std::wcout << ws2 << std::endl;


    s2 = s1;
    std::wcout << L"s2.Remove(4,1): ";
    s2.Remove(4,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(4,1): ";
    ws2.erase(4,1);
    std::wcout << ws2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.RemoveRange(4,5): ";
    s2.RemoveRange(4,5);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.RemoveRange(0,1): ";
    s2.RemoveRange(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.RemoveRange(1,2): ";
    s2.RemoveRange(1,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Keep(0): ";
    s2.Keep(0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(1): ";
    s2.Keep(1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Keep(0,1): ";
    s2.Keep(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(0,2): ";
    s2.Keep(0,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(1,1): ";
    s2.Keep(1,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(1,2): ";
    s2.Keep(1,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(5): ";
    s2.Keep(5);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Keep(3,6): ";
    s2.Keep(3,6);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(5,6): ";
    s2.Keep(5,6);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.KeepRange(0,0): ";
    s2.KeepRange(0,0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.KeepRange(0,1): ";
    s2.KeepRange(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.KeepRange(0,2): ";
    s2.KeepRange(0,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.KeepRange(1,3): ";
    s2.KeepRange(1,3);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.KeepRange(5,6): ";
    s2.KeepRange(5,6);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Insert(L\"Say \"): ";
    s2.Insert(L"Say ");
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Insert(L\" world\",100): ";
    s2.Insert(L" world",100);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.TrimRight(): ";
    s2.TrimRight();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;

    s2 = s1;
    std::wcout << L"s2.TrimLeft(): ";
    s2.TrimLeft();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;


    s2 = s1;
    std::wcout << L"s2.Trim(): ";
    s2.Trim();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;

    s1 = L"  hello  ";

    s2 = s1;
    std::wcout << L"s2.TrimRight(): ";
    s2.TrimRight();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;

    s2 = s1;
    std::wcout << L"s2.TrimLeft(): ";
    s2.TrimLeft();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;


    s2 = s1;
    std::wcout << L"s2.Trim(): ";
    s2.Trim();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;


    s1 = L"   ";

    s2 = s1;
    std::wcout << L"s2.TrimRight(): ";
    s2.TrimRight();
    std::wcout << L'\'' <<(s2?s2:L"") << L'\'' << std::endl;

    s2 = s1;
    std::wcout << L"s2.TrimLeft(): ";
    s2.TrimLeft();
    std::wcout << L'\'' <<(s2?s2:L"") << L'\'' << std::endl;


    s2 = s1;
    std::wcout << L"s2.Trim(): ";
    s2.Trim();
    std::wcout << L'\'' <<(s2?s2:L"") << L'\'' << std::endl;
    
    s1 = L"Hello";

    for(auto c : s1)
    {
        std::wcout << L'\'' << c << L'\'' << std::endl;
    }

    for(auto& c : s1)
    {
        c = c+1;
    }

    for(auto& c : s1)
    {
        std::wcout << L'\'' << c << L'\'' << std::endl;
    }


    s1 = String();

    for(auto c : s1)
    {
        std::wcout << L'\'' << L"This should not happen" << L'\'' << std::endl;
    }



    s1 = L"Hello";

    
    std::wcout << L"String::size_type pos = s1.IndexOf([](wchar_t c) -> bool {...}) returned: ";
    pos = s1.IndexOf([](wchar_t c) -> bool
    {
        return c == L'l';
    });
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf([](wchar_t c) -> bool {...}) returned: ";
    pos = s1.LastIndexOf([](wchar_t c) -> bool
    {
        return c == L'l';
    });
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }
    



}


void StringVectorOfEmptyStringsInitialize()
{
    std::vector<String> v;
    Stopwatch stopwatch;
    stopwatch.Start();
    v.resize(100000);
    stopwatch.Stop();
    std::wcout << L"std::vector<String> v; v.resize(100000); " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorOfEmptyStringsInitialize()
{
    std::vector<std::wstring> v;
    Stopwatch stopwatch;
    stopwatch.Start();
    v.resize(100000);
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> v; v.resize(100000); " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorOfEmptyStringsInitialize()
{
    std::vector<CStringW> v;
    Stopwatch stopwatch;
    stopwatch.Start();
    v.resize(100000);
    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> v; v.resize(100000); " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


//wchar_t* smallStrings[] = {L"The",L"Quick",L"Fox",L"Jumped"};
/*
std::vector<String> v; v.resize(100000); 0.4088
std::vector<std::wstring> v; v.resize(100000); 1.5721
std::vector<String> initialize with small strings: 14.1969
std::vector<std::wstring> initialize with small strings: 4.6244
std::vector<String> Get total length (425000) : 2.4355
std::vector<std::wstring> Get total length (425000) : 3.5326
std::vector<String> assign to: 1.8704
std::vector<std::wstring> assign to: 3.6208
std::vector<String> initialize with small strings push_back: 11.7914
std::vector<std::wstring> initialize with small strings push_back: 4.5539
std::vector<String> initialize with small strings: 8.9747
std::vector<std::wstring> initialize with small strings: 2.8478
std::vector<String> append to: 3.645
std::vector<std::wstring> append to: 5.4127
*/
wchar_t* smallStrings[] = {L"C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\Include",
    L"C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\lib",
    L"C:\\VS11\\VC\\atlmfc\\include",
    L"C:\\VS11\\VC\\lib"
};

void StringVectorInitializeSmallStrings(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i] = smallStrings[i%4];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> initialize with small strings: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorInitializeSmallStrings(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i] = smallStrings[i%4];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> initialize with small strings: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}





void CStringVectorInitializeSmallStrings(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i] = smallStrings[i%4];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> initialize with small strings: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorGetTotalLength(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000;i++)
    {
        totalLength += v[i].length();
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> Get total length (" << totalLength << L") : " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorGetTotalLength(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000;i++)
    {
        totalLength += v[i].length();
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> Get total length (" << totalLength << L") : " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorGetTotalLength(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000;i++)
    {
        const auto& s = v[i];
        totalLength += s.GetLength();
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> Get total length (" << totalLength << L") : " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void StringVectorAssignTo(const std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] = v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> assign to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorAssignTo(const std::vector<std::wstring>& v,std::vector<std::wstring>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] = v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> assign to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorAssignTo(const std::vector<CStringW>& v,std::vector<CStringW>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] = v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> assign to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorInitializeSmallStringsPushBack(std::vector<String>& v)
{
    Stopwatch stopwatch;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v.push_back(String( smallStrings[i%4] ));
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> initialize with small strings push_back: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorInitializeSmallStringsPushBack(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v.push_back(std::wstring( smallStrings[i%4] ));
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> initialize with small strings push_back: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorInitializeSmallStringsPushBack(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v.push_back(CStringW( smallStrings[i%4] ));
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> initialize with small strings push_back: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorAppendTo(std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] += v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> append to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorAppendTo(std::vector<std::wstring>& v,std::vector<std::wstring>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] += v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> append to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorAppendTo(std::vector<CStringW>& v,std::vector<CStringW>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] += v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> append to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorAppendCharTo(std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto destLength = dest.length();
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t i = 0; i < 10; i++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringBuilderVectorAppendCharTo(std::vector<String>& v,std::vector<StringBuilder>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t i = 0; i < 10; i++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<StringBuilder> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringBuilderVectorAppendCharTo(std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        auto& dest = v2[i];
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t iii = 0; iii < 10; iii++)
        {
            StringBuilder sb;
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                sb += c;
            }
            dest += sb.ToString();
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> StringBuilder append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorAppendCharTo(std::vector<std::wstring>& v,std::vector<std::wstring>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto destLength = dest.length();
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t iii = 0; iii < 10; iii++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorAppendCharTo(std::vector<CStringW>& v,std::vector<CStringW>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto destLength = dest.GetLength();
        auto& source = v[i];
        auto sourceLength = source.GetLength();
        for(size_t iii = 0; iii < 10; iii++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorSort(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    std::sort(v.begin(),v.end());

    stopwatch.Stop();
    std::wcout << L"std::vector<String> sort: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorSort(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    std::sort(v.begin(),v.end());

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> sort: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorSort(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    std::sort(v.begin(),v.end());

    stopwatch.Stop();
    std::wcout << L"std::vector<String> sort: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void StringVectorSimpleIndexOfAnyOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = s.IndexOfAnyOf(L"7b");
        
        if(pos != String::npos)
        {
            found++;
        }
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> Simple IndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorSimple_find_first_of(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = s.find_first_of(L"7b");
        
        if(pos != String::npos)
        {
            found++;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> Simple find_first_of:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorSimpleFindOneOf(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = s.FindOneOf(L"7b");
        
        if(pos != String::npos)
        {
            found++;
        }
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> Simple IndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorIndexOfAnyOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.IndexOfAnyOf(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> IndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVector_find_first_of(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.find_first_of(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find_first_of:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}



void StringVectorLastIndexOfAnyOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = s.length();
        do
        {
            pos = s.LastIndexOfAnyOf(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> LastIndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVector_find_last_of(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = s.length();
        do
        {
            pos = s.find_last_of(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find_last_of:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void StringVectorIndexOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.IndexOf(L"lib",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> IndexOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVector_find(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.find(L"lib",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorFind(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.Find(L"lib",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> Find:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorIndexOfChar(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.IndexOf(L'7',start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> IndexOf char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorIndexOfChar(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = std::wstring::npos;
        size_t start = 0;
        do
        {
            pos = s.find(L'7',start);
            if(pos != std::wstring::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != std::wstring::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorIndexOfChar(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        int pos = -1;
        int start = 0;
        do
        {
            pos = s.Find(L'7',start);
            if(pos >= 0)
            {
                start = pos +1;
                found++;
            }

        }while(pos >= 0);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> Find char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}



void StringVectorLastIndexOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = String::npos;
        do
        {
            pos = s.LastIndexOf(L"lib",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> LastIndexOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVector_rfind(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = std::wstring::npos;
        size_t start = std::wstring::npos;
        do
        {
            pos = s.rfind(L"lib",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> rfind:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorLastIndexOfChar(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = String::npos;
        do
        {
            pos = s.LastIndexOf(L'7',start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> LastIndexOf char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorLastIndexOfChar(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = std::wstring::npos;
        size_t start = std::wstring::npos;
        do
        {
            pos = s.rfind(L'7',start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != std::wstring::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> rfind char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorInsertString(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Insert(L"Text",3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> insert string: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorInsertString(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].insert(3,L"Text");
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> insert string: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorInsertString(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Insert(3,L"Text");
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> insert string: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorRemove(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Remove(2,3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> remove: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorRemove(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].erase(2,3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> remove: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorRemove(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Delete(2,3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> remove: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorDataAccess(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalBS = 0;
    stopwatch.Start();

    for(int ii = 0; ii < 1000;ii++)
    {
        for(size_t i = 0; i < size; i++)
        {
            const wchar_t* p = v[i].c_str();
            totalBS += *p;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> data access: ("<< totalBS << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorDataAccess(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalBS = 0;
    stopwatch.Start();

    for(int ii = 0; ii < 1000;ii++)
    {
        for(size_t i = 0; i < size; i++)
        {
            const wchar_t* p = v[i].c_str();
            totalBS += *p;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> data access: ("<< totalBS << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorDataAccess(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalBS = 0;
    stopwatch.Start();

    for(int ii = 0; ii < 1000;ii++)
    {
        for(size_t i = 0; i < size; i++)
        {
            const wchar_t* p = v[i];
            totalBS += *p;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> data access: ("<< totalBS << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

const size_t maxRecursion = 10000;

String StringRecursion(const String& arg,size_t recursionLevel)
{
    String result = arg + L"Hi";
    if(recursionLevel < maxRecursion)
    {
        recursionLevel++;
        result = StringRecursion(result,recursionLevel);
    }
    return result;
}

std::wstring StringRecursion(const std::wstring& arg,size_t recursionLevel)
{
    std::wstring result = arg + L"Hi";
    if(recursionLevel < maxRecursion)
    {
        recursionLevel++;
        result = StringRecursion(result,recursionLevel);
    }
    return result;
}

CStringW StringRecursion(const CStringW& arg,size_t recursionLevel)
{
    CStringW result = arg + L"Hi";
    if(recursionLevel < maxRecursion)
    {
        recursionLevel++;
        result = StringRecursion(result,recursionLevel);
    }
    return result;
}


void StringRecursion( )
{
    Stopwatch stopwatch;
    stopwatch.Start();
    String s = L"String";

    s = StringRecursion(s,0);

    stopwatch.Stop();
    std::wcout << L"String recursion(" << s.length() << L" ): " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringRecursion( )
{
    Stopwatch stopwatch;
    stopwatch.Start();
    std::wstring s = L"String";

    s = StringRecursion(s,0);

    stopwatch.Stop();
    std::wcout << L"std::wstring recursion (" << s.length() << L" ): " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringRecursion( )
{
    Stopwatch stopwatch;
    stopwatch.Start();
    CStringW s = L"String";

    s = StringRecursion(s,0);

    stopwatch.Stop();
    std::wcout << L"CStringW recursion(" << s.GetLength() << L" ): " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


int _tmain(int argc, _TCHAR* argv[])
{
    //runExample();

    std::wcout << L"sizeof(String): " << sizeof(String)  << std::endl;
    std::wcout << L"sizeof(std::wstring): " << sizeof(std::wstring)  << std::endl;
    std::wcout << L"sizeof(CStringW): " << sizeof(CStringW)  << std::endl;

    std::wcout << std::endl;

    std::vector<String> strings;
    std::vector<std::wstring> wstrings;
    std::vector<CStringW> cstrings;

    std::vector<String> strings2;
    std::vector<std::wstring> wstrings2;
    std::vector<CStringW> cstrings2;

    strings.resize(100000);
    wstrings.resize(100000);
    cstrings.resize(100000);

    strings2.resize(100000);
    wstrings2.resize(100000);
    cstrings2.resize(100000);

    StringVectorOfEmptyStringsInitialize();
    wstringVectorOfEmptyStringsInitialize();
    CStringVectorOfEmptyStringsInitialize();

    std::wcout << std::endl;

    StringVectorInitializeSmallStrings(strings);
    wstringVectorInitializeSmallStrings(wstrings);
    CStringVectorInitializeSmallStrings(cstrings);

    std::wcout << std::endl;

    StringVectorGetTotalLength(strings);
    wstringVectorGetTotalLength(wstrings);
    CStringVectorGetTotalLength(cstrings);

    std::wcout << std::endl;

    StringVectorAssignTo(strings,strings2);
    wstringVectorAssignTo(wstrings,wstrings2);
    CStringVectorAssignTo(cstrings,cstrings2);
    std::wcout << std::endl;

    std::vector<String> strings3;
    strings3.reserve(100000);

    std::vector<std::wstring> wstrings3;
    wstrings3.reserve(100000);

    std::vector<CStringW> cstrings3;
    cstrings3.reserve(100000);


    StringVectorInitializeSmallStringsPushBack(strings3);
    wstringVectorInitializeSmallStringsPushBack(wstrings3);
    CStringVectorInitializeSmallStringsPushBack(cstrings3);
    std::wcout << std::endl;

    std::vector<String> strings4;
    std::vector<std::wstring> wstrings4;
    std::vector<CStringW> cstrings4;

    strings4.resize(100000);
    wstrings4.resize(100000);
    cstrings4.resize(100000);
    StringVectorInitializeSmallStrings(strings4);
    wstringVectorInitializeSmallStrings(wstrings4);
    CStringVectorInitializeSmallStrings(cstrings4);
    std::wcout << std::endl;

    StringVectorAppendTo(strings3,strings4);
    wstringVectorAppendTo(wstrings3,wstrings4);
    CStringVectorAppendTo(cstrings3,cstrings4);
    std::wcout << std::endl;

    std::vector<StringBuilder> stringBuilders;
    stringBuilders.resize(100000);
    for(size_t i = 0; i < 100000;i++)
    {
        stringBuilders[i].Append(strings4[i]);
    }

    std::vector<String> strings5 = strings4;

    StringVectorAppendCharTo(strings3,strings4);
    StringBuilderVectorAppendCharTo(strings3,stringBuilders);
    StringBuilderVectorAppendCharTo(strings3,strings5);
    wstringVectorAppendCharTo(wstrings3,wstrings4);
    CStringVectorAppendCharTo(cstrings3,cstrings4);
    std::wcout << std::endl;

    StringVectorSort(strings4);
    wstringVectorSort(wstrings4);
    CStringVectorSort(cstrings4);
    std::wcout << std::endl;

    StringVectorSimpleIndexOfAnyOf(strings4);
    wstringVectorSimple_find_first_of(wstrings4);
    CStringVectorSimpleFindOneOf(cstrings4);
    std::wcout << std::endl;

    StringVectorIndexOfAnyOf(strings4);
    wstringVector_find_first_of(wstrings4);
    std::wcout << std::endl;

    StringVectorLastIndexOfAnyOf(strings4);
    wstringVector_find_last_of(wstrings4);
    std::wcout << std::endl;

    StringVectorIndexOf(strings4);
    wstringVector_find(wstrings4);
    CStringVectorFind(cstrings4);
    std::wcout << std::endl;

    StringVectorLastIndexOf(strings4);
    wstringVector_rfind(wstrings4);
    std::wcout << std::endl;

    StringVectorIndexOfChar(strings4);
    wstringVectorIndexOfChar(wstrings4);
    CStringVectorIndexOfChar(cstrings4);
    std::wcout << std::endl;

    StringVectorLastIndexOfChar(strings4);
    wstringVectorLastIndexOfChar(wstrings4);
    std::wcout << std::endl;


    StringVectorInsertString(strings4);
    wstringVectorInsertString(wstrings4);
    CStringVectorInsertString(cstrings4);
    std::wcout << std::endl;


    StringVectorRemove(strings4);
    wstringVectorRemove(wstrings4);
    CStringVectorRemove(cstrings4);
    std::wcout << std::endl;

    StringVectorDataAccess(strings4);
    wstringVectorDataAccess(wstrings4);
    CStringVectorDataAccess(cstrings4);
    std::wcout << std::endl;

    StringRecursion( );
    wstringRecursion( );
    CStringRecursion( );
    std::wcout << std::endl;



	return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Sea Surveillance AS
Norway Norway
Chief Architect - Sea Surveillance AS.

Specializing in integrated operations and high performance computing solutions.

I’ve been fooling around with computers since the early eighties, I’ve even done work on CP/M and MP/M.

Wrote my first “real” program on a BBC micro model B based on a series in a magazine at that time. It was fun and I got hooked on this thing called programming ...

A few Highlights:

  • High performance application server development
  • Model Driven Architecture and Code generators
  • Real-Time Distributed Solutions
  • C, C++, C#, Java, TSQL, PL/SQL, Delphi, ActionScript, Perl, Rexx
  • Microsoft SQL Server, Oracle RDBMS, IBM DB2, PostGreSQL
  • AMQP, Apache qpid, RabbitMQ, Microsoft Message Queuing, IBM WebSphereMQ, Oracle TuxidoMQ
  • Oracle WebLogic, IBM WebSphere
  • Corba, COM, DCE, WCF
  • AspenTech InfoPlus.21(IP21), OsiSoft PI


More information about what I do for a living can be found at: harlinn.com or LinkedIn

You can contact me at espen@harlinn.no

Comments and Discussions