// author : Hou Jie (侯捷)
// date : 2015/10/28
// compiler : DevC++ 5.11 (MinGW with GNU 4.9.9.2)
//
// 說明:這是侯捷 E-learning video "C++標準庫" 的實例程式.
// 該課程的所有測試都出現在此.
// 每一個小測試單元都被放進一個 namespace 中,
// 如此保持各單元間最大的獨立性.
// 每個 namespace 上方皆有該單元相應的 #include <...>
// 因此有可能整個程式重複含入 (included) 某些 headers.
// 這無所謂,因為每個 standard headers 都有自我防衛機制,不讓自己被 included 二次.
//
// 本文件用到若干 C++ 2.0 New Features,所以你必須在你的集成環境 (IDE) 上設定 "C++11 on".
// 如果你的編譯器報錯,應是因為我用到 (測試) GNU 標準庫的獨特 (非標準) 組件 (特別是 allocators),
// 將報錯語句改為註解 (comments) 即可通過編譯.
using namespace std;
const long ASIZE = 500000L;
//----------------------------------------------------
#include
#include
#include
#include
#include
using std::cin;
using std::cout;
using std::string;
//以下 MyString 是為了測試 containers with moveable elements 效果.
class MyString {
public:
static size_t DCtor; //累計 default-ctor 的呼叫次數
static size_t Ctor; //累計 ctor 的呼叫次數
static size_t CCtor; //累計 copy-ctor 的呼叫次數
static size_t CAsgn; //累計 copy-asgn 的呼叫次數
static size_t MCtor; //累計 move-ctor 的呼叫次數
static size_t MAsgn; //累計 move-asgn 的呼叫次數
static size_t Dtor; //累計 dtor 的呼叫次數
private:
char* _data;
size_t _len;
void _init_data(const char *s) {
_data = new char[_len+1];
memcpy(_data, s, _len);
_data[_len] = '\0';
}
public:
//default ctor
MyString() : _data(NULL), _len(0) { ++DCtor; }
//ctor
MyString(const char* p) : _len(strlen(p)) {
++Ctor;
_init_data(p);
}
// copy ctor
MyString(const MyString& str) : _len(str._len) {
++CCtor;
_init_data(str._data); //COPY
}
//move ctor, with "noexcept"
MyString(MyString&& str) noexcept : _data(str._data), _len(str._len) {
++MCtor;
str._len = 0;
str._data = NULL; //避免 delete (in dtor)
}
//copy assignment
MyString& operator=(const MyString& str) {
++CAsgn;
if (this != &str) {
if (_data) delete _data;
_len = str._len;
_init_data(str._data); //COPY!
}
else {
// Self Assignment, Nothing to do.
}
return *this;
}
//move assignment
MyString& operator=(MyString&& str) noexcept {
++MAsgn;
if (this != &str) {
if (_data) delete _data;
_len = str._len;
_data = str._data; //MOVE!
str._len = 0;
str._data = NULL; //避免 deleted in dtor
}
return *this;
}
//dtor
virtual ~MyString() {
++Dtor;
if (_data) {
delete _data;
}
}
bool
operator<(const MyString& rhs) const //為了讓 set 比較大小
{
return std::string(this->_data) < std::string(rhs._data); //借用事實:string 已能比較大小.
}
bool
operator==(const MyString& rhs) const //為了讓 set 判斷相等.
{
return std::string(this->_data) == std::string(rhs._data); //借用事實:string 已能判斷相等.
}
char* get() const { return _data; }
};
size_t MyString::DCtor=0;
size_t MyString::Ctor=0;
size_t MyString::CCtor=0;
size_t MyString::CAsgn=0;
size_t MyString::MCtor=0;
size_t MyString::MAsgn=0;
size_t MyString::Dtor=0;
namespace std //必須放在 std 內
{
template<>
struct hash
{
size_t
operator()(const MyString& s) const noexcept
{ return hash
//借用現有的 hash
};
}
//-----------------
//以下 MyStrNoMove 是為了測試 containers with no-moveable elements 效果.
class MyStrNoMove {
public:
static size_t DCtor; //累計 default-ctor 的呼叫次數
static size_t Ctor; //累計 ctor 的呼叫次數
static size_t CCtor; //累計 copy-ctor 的呼叫次數
static size_t CAsgn; //累計 copy-asgn 的呼叫次數
static size_t MCtor; //累計 move-ctor 的呼叫次數
static size_t MAsgn; //累計 move-asgn 的呼叫次數
static size_t Dtor; //累計 dtor 的呼叫次數
private:
char* _data;
size_t _len;
void _init_data(const char *s) {
_data = new char[_len+1];
memcpy(_data, s, _len);
_data[_len] = '\0';
}
public:
//default ctor
MyStrNoMove() : _data(NULL), _len(0) { ++DCtor; _init_data("jjhou"); }
//ctor
MyStrNoMove(const char* p) : _len(strlen(p)) {
++Ctor; _init_data(p);
}
// copy ctor
MyStrNoMove(const MyStrNoMove& str) : _len(str._len) {
++CCtor;
_init_data(str._data); //COPY
}
//copy assignment
MyStrNoMove& operator=(const MyStrNoMove& str) {
++CAsgn;
if (this != &str) {
if (_data) delete _data;
_len = str._len;
_init_data(str._data); //COPY!
}
else {
// Self Assignment, Nothing to do.
}
return *this;
}
//dtor
virtual ~MyStrNoMove() {
++Dtor;
if (_data) {
delete _data;
}
}
bool
operator<(const MyStrNoMove& rhs) const //為了讓 set 比較大小
{
return string(this->_data) < string(rhs._data); //借用事實:string 已能比較大小.
}
bool
operator==(const MyStrNoMove& rhs) const //為了讓 set 判斷相等.
{
return string(this->_data) == string(rhs._data); //借用事實:string 已能判斷相等.
}
char* get() const { return _data; }
};
size_t MyStrNoMove::DCtor=0;
size_t MyStrNoMove::Ctor=0;
size_t MyStrNoMove::CCtor=0;
size_t MyStrNoMove::CAsgn=0;
size_t MyStrNoMove::MCtor=0;
size_t MyStrNoMove::MAsgn=0;
size_t MyStrNoMove::Dtor=0;
namespace std //必須放在 std 內
{
template<>
struct hash
{
size_t
operator()(const MyStrNoMove& s) const noexcept
{ return hash
//借用現有的 hash
};
}
//----------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
using std::cin;
using std::cout;
using std::string;
using std::max;
using std::min;
namespace jj00
{
bool strLonger(const string& s1, const string& s2) {
return s1.size() < s2.size();
}
void test_misc()
{
cout << "\ntest_misc().......... \n";
//以下這些是標準庫的眾多容器的 max_size() 計算方式.
cout << size_t(-1) << endl; //4294967295
cout << size_t(-1)/sizeof(long) << endl; //1073741823
cout << size_t(-1)/sizeof(string) << endl; //1073741823
cout << size_t(-1)/sizeof(_List_node
cout << size_t(-1)/sizeof(_Fwd_list_node
cout << "RAND_MAX= " << RAND_MAX << endl; //32767
cout << min( {2,5,8,9,45,0,81} ) << endl; //0
cout << max( {2,5,8,9,45,0,81} ) << endl; //81
vector
cout << "max of zoo and hello : "
<< max(string("zoo"), string("hello")) << endl; //zoo
cout << "longest of zoo and hello : "
<< max(string("zoo"), string("hello"), strLonger) << endl; //hello
cout << hash
cout << hash
cout << "MyString(zoo) < MyString(hello) ==> " << (MyString("zoo") < MyString("hello")) << endl; //0
cout << "MyString(zoo) == MyString(hello) ==> " << (MyString("zoo") == MyString("hello")) << endl; //0
cout << "MyStrNoMove(zoo) < MyStrNoMove(hello) ==> " << (MyStrNoMove("zoo") < MyStrNoMove("hello")) << endl; //0
cout << "MyStrNoMove(zoo) == MyStrNoMove(hello) ==> " << (MyStrNoMove("zoo") == MyStrNoMove("hello")) << endl; //0
//以上建構了 6 個 MyString objects 和 4 個 MyStrNoMove objects,都是暫時生命.
}
}
//--------------------------------------------------
#include
template
void output_static_data(const T& myStr)
{
cout << typeid(myStr).name() << " -- " << endl;
cout << " CCtor=" << T::CCtor
<< " MCtor=" << T::MCtor
<< " CAsgn=" << T::CAsgn
<< " MAsgn=" << T::MAsgn
<< " Dtor=" << T::Dtor
<< " Ctor=" << T::Ctor
<< " DCtor=" << T::DCtor
<< endl;
}
#include
template
void test_moveable(M c1, NM c2, long& value)
{
char buf[10];
//測試 move
cout << "\n\ntest, with moveable elements" << endl;
typedef typename iterator_traits
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
snprintf(buf, 10, "%d", rand());
auto ite = c1.end();
c1.insert(ite, V1type(buf));
}
cout << "construction, milli-seconds : " << (clock()-timeStart) << endl;
cout << "size()= " << c1.size() << endl;
output_static_data(*(c1.begin()));
timeStart = clock();
M c11(c1);
cout << "copy, milli-seconds : " << (clock()-timeStart) << endl;
timeStart = clock();
M c12(std::move(c1));
cout << "move copy, milli-seconds : " << (clock()-timeStart) << endl;
timeStart = clock();
c11.swap(c12);
cout << "swap, milli-seconds : " << (clock()-timeStart) << endl;
//測試 non-moveable
cout << "\n\ntest, with non-moveable elements" << endl;
typedef typename iterator_traits
timeStart = clock();
for(long i=0; i< value; ++i)
{
snprintf(buf, 10, "%d", rand());
auto ite = c2.end();
c2.insert(ite, V2type(buf));
}
cout << "construction, milli-seconds : " << (clock()-timeStart) << endl;
cout << "size()= " << c2.size() << endl;
output_static_data(*(c2.begin()));
timeStart = clock();
NM c21(c2);
cout << "copy, milli-seconds : " << (clock()-timeStart) << endl;
timeStart = clock();
NM c22(std::move(c2));
cout << "move copy, milli-seconds : " << (clock()-timeStart) << endl;
timeStart = clock();
c21.swap(c22);
cout << "swap, milli-seconds : " << (clock()-timeStart) << endl;
}
//-----------------
long get_a_target_long()
{
long target=0;
cout << "target (0~" << RAND_MAX << "): ";
cin >> target;
return target;
}
string get_a_target_string()
{
long target=0;
char buf[10];
cout << "target (0~" << RAND_MAX << "): ";
cin >> target;
snprintf(buf, 10, "%d", target);
return string(buf);
}
int compareLongs(const void* a, const void* b)
{
return ( *(long*)a - *(long*)b );
}
int compareStrings(const void* a, const void* b)
{
if ( *(string*)a > *(string*)b )
return 1;
else if ( *(string*)a < *(string*)b )
return -1;
else
return 0;
}
//---------------------------------------------------
#include
#include
#include
#include
namespace jj01
{
void test_array()
{
cout << "\ntest_array().......... \n";
array
clock_t timeStart = clock();
for(long i=0; i< ASIZE; ++i) {
c[i] = rand();
}
cout << "milli-seconds : " << (clock()-timeStart) << endl; //
cout << "array.size()= " << c.size() << endl;
cout << "array.front()= " << c.front() << endl;
cout << "array.back()= " << c.back() << endl;
cout << "array.data()= " << c.data() << endl;
long target = get_a_target_long();
timeStart = clock();
::qsort(c.data(), ASIZE, sizeof(long), compareLongs);
long* pItem = (long*)::bsearch(&target, (c.data()), ASIZE, sizeof(long), compareLongs);
cout << "qsort()+bsearch(), milli-seconds : " << (clock()-timeStart) << endl; //
if (pItem != NULL)
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
namespace jj02
{
void test_vector(long& value)
{
cout << "\ntest_vector().......... \n";
vector
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.push_back(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
//曾經最高 i=58389486 then std::bad_alloc
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "vector.max_size()= " << c.max_size() << endl; //1073747823
cout << "vector.size()= " << c.size() << endl;
cout << "vector.front()= " << c.front() << endl;
cout << "vector.back()= " << c.back() << endl;
cout << "vector.data()= " << c.data() << endl;
cout << "vector.capacity()= " << c.capacity() << endl << endl;
string target = get_a_target_string();
{
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl << endl;
else
cout << "not found! " << endl << endl;
}
{
timeStart = clock();
sort(c.begin(), c.end());
cout << "sort(), milli-seconds : " << (clock()-timeStart) << endl;
timeStart = clock();
string* pItem = (string*)::bsearch(&target, (c.data()),
c.size(), sizeof(string), compareStrings);
cout << "bsearch(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != NULL)
cout << "found, " << *pItem << endl << endl;
else
cout << "not found! " << endl << endl;
}
c.clear();
test_moveable(vector
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
namespace jj03
{
void test_list(long& value)
{
cout << "\ntest_list().......... \n";
list
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.push_back(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "list.size()= " << c.size() << endl;
cout << "list.max_size()= " << c.max_size() << endl; //357913941
cout << "list.front()= " << c.front() << endl;
cout << "list.back()= " << c.back() << endl;
string target = get_a_target_string();
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
timeStart = clock();
c.sort();
cout << "c.sort(), milli-seconds : " << (clock()-timeStart) << endl;
c.clear();
test_moveable(list
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
namespace jj04
{
void test_forward_list(long& value)
{
cout << "\ntest_forward_list().......... \n";
forward_list
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.push_front(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "forward_list.max_size()= " << c.max_size() << endl; //536870911
cout << "forward_list.front()= " << c.front() << endl;
string target = get_a_target_string();
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
timeStart = clock();
c.sort();
cout << "c.sort(), milli-seconds : " << (clock()-timeStart) << endl;
c.clear();
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
namespace jj05
{
void test_deque(long& value)
{
cout << "\ntest_deque().......... \n";
deque
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.push_back(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "deque.size()= " << c.size() << endl;
cout << "deque.front()= " << c.front() << endl;
cout << "deque.back()= " << c.back() << endl;
cout << "deque.max_size()= " << c.max_size() << endl; //1073741821
string target = get_a_target_string();
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
timeStart = clock();
sort(c.begin(), c.end());
cout << "sort(), milli-seconds : " << (clock()-timeStart) << endl;
c.clear();
test_moveable(deque
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
namespace jj06
{
void test_multiset(long& value)
{
cout << "\ntest_multiset().......... \n";
multiset
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.insert(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "multiset.size()= " << c.size() << endl;
cout << "multiset.max_size()= " << c.max_size() << endl; //214748364
string target = get_a_target_string();
{
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target); //比 c.find(...) 慢很多
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
{
timeStart = clock();
auto pItem = c.find(target); //比 std::find(...) 快很多
cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
c.clear();
test_moveable(multiset
}
}
//---------------------------------------------------
#include
#include
//...\4.9.2\include\c++\backward\backward_warning.h
//[Warning] #warning This file includes at least one deprecated or antiquated header
//which may be removed without further notice at a future date.
//Please use a non-deprecated interface with equivalent functionality instead.
//For a listing of replacement headers and interfaces, consult the file backward_warning.h.
//To disable this warning use -Wno-deprecated. [-Wcpp]
#include
#include
#include
#include
#include
#include
namespace jj11
{
void test_hash_multiset(long& value)
{
cout << "\ntest_hash_multiset().......... \n";
__gnu_cxx::hash_multiset
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
//! c.insert(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
}
}
//---------------------------------------------------
#include
//...\4.9.2\include\c++\backward\backward_warning.h
//[Warning] #warning This file ... (如上個函數所言)
#include
#include
#include
#include
#include
#include
namespace jj12
{
void test_hash_multimap(long& value)
{
cout << "\ntest_hash_multimap().......... \n";
__gnu_cxx::hash_multimap
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
//c.insert(...
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
timeStart = clock();
//! auto ite = c.find(...
cout << "milli-seconds : " << (clock()-timeStart) << endl;
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
namespace jj13
{
void test_set(long& value)
{
cout << "\ntest_set().......... \n";
set
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.insert(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "set.size()= " << c.size() << endl;
cout << "set.max_size()= " << c.max_size() << endl; //214748364
string target = get_a_target_string();
{
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target); //比 c.find(...) 慢很多
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
{
timeStart = clock();
auto pItem = c.find(target); //比 std::find(...) 快很多
cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
}
}
//---------------------------------------------------
#include
unordered_map
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c[i] = string(buf);
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "unordered_map.size()= " << c.size() << endl; //357913941
cout << "unordered_map.max_size()= " << c.max_size() << endl;
long target = get_a_target_long();
timeStart = clock();
//! auto pItem = find(c.begin(), c.end(), target); //map 不適用 std::find()
auto pItem = c.find(target);
cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, value=" << (*pItem).second << endl;
else
cout << "not found! " << endl;
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
namespace jj17
{
void test_stack(long& value)
{
cout << "\ntest_stack().......... \n";
stack
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
c.pop();
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
{
stack
for(long i=0; i< 10; ++i) {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
c.pop();
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
}
{
stack
for(long i=0; i< 10; ++i) {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
c.pop();
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
}
{
stack
/*!
for(long i=0; i< 10; ++i) {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
c.pop();
cout << "stack.size()= " << c.size() << endl;
cout << "stack.top()= " << c.top() << endl;
//[Error] 'class std::set
//[Error] 'class std::set
//[Error] 'class std::set
*/
}
//!stack
//!stack
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
namespace jj18
{
void test_queue(long& value)
{
cout << "\ntest_queue().......... \n";
queue
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
c.pop();
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
{
queue
for(long i=0; i< 10; ++i) {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
c.pop();
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
}
{
queue
for(long i=0; i< 10; ++i) {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
//!c.pop(); //[Error] 'class std::vector
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
}
{
queue
/*!
for(long i=0; i< 10; ++i) {
snprintf(buf, 10, "%d", rand());
c.push(string(buf));
}
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
c.pop();
cout << "queue.size()= " << c.size() << endl;
cout << "queue.front()= " << c.front() << endl;
cout << "queue.back()= " << c.back() << endl;
//[Error] 'class std::set
//[Error] 'class std::set
//[Error] 'class std::set
*/
}
//! queue
//! queue
}
}
//---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//欲使用 std::allocator 以外的 allocator, 得自行 #include
#ifdef __GNUC__
#include
#include
#include
#include
#include
#include
#include
#endif
namespace jj20
{
//pass A object to function template impl(),
//而 A 本身是個 class template, 帶有 type parameter T,
//那麼有無可能在 impl() 中抓出 T, 創建一個 list
//以下先暫時迴避上述疑問.
void test_list_with_special_allocator()
{
#ifdef __GNUC__
cout << "\ntest_list_with_special_allocator().......... \n";
//不能在 switch case 中宣告,只好下面這樣. //1000000次
list
list
list
list
list
list
int choice;
long value;
cout << "select: "
<< " (1) std::allocator "
<< " (2) malloc_allocator "
<< " (3) new_allocator "
<< " (4) __pool_alloc "
<< " (5) __mt_alloc "
<< " (6) bitmap_allocator ";
cin >> choice;
if ( choice != 0 ) {
cout << "how many elements: ";
cin >> value;
}
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", i);
switch (choice)
{
case 1 : c1.push_back(string(buf));
break;
case 2 : c2.push_back(string(buf));
break;
case 3 : c3.push_back(string(buf));
break;
case 4 : c4.push_back(string(buf));
break;
case 5 : c5.push_back(string(buf));
break;
case 6 : c6.push_back(string(buf));
break;
default:
break;
}
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "a lot of push_back(), milli-seconds : " << (clock()-timeStart) << endl;
//test all allocators' allocate() & deallocate();
int* p;
allocator
p = alloc1.allocate(1);
alloc1.deallocate(p,1);
__gnu_cxx::malloc_allocator
p = alloc2.allocate(1);
alloc2.deallocate(p,1);
__gnu_cxx::new_allocator
p = alloc3.allocate(1);
alloc3.deallocate(p,1);
__gnu_cxx::__pool_alloc
p = alloc4.allocate(2);
alloc4.deallocate(p,2); //我刻意令參數為 2, 但這有何意義!! 一次要 2 個 ints?
__gnu_cxx::__mt_alloc
p = alloc5.allocate(1);
alloc5.deallocate(p,1);
__gnu_cxx::bitmap_allocator
p = alloc6.allocate(3);
alloc6.deallocate(p,3); //我刻意令參數為 3, 但這有何意義!! 一次要 3 個 ints?
#endif
}
}
//---------------------------------------------------
#include
#include
#include
#include
//#include
//欲使用 std::allocator 以外的 allocator, 得自行 #include
#include
#include
#include
#include
#include
#include
#include
namespace jj25
{
void test_components_sizeof()
{
cout << "\ntest_components_size().......... \n";
//containers
cout << "sizeof(array
cout << "sizeof(vector
cout << "sizeof(list
cout << "sizeof(forward_list
cout << "sizeof(deque
cout << "sizeof(stack
cout << "sizeof(queue
cout << "sizeof(set
cout << "sizeof(map
cout << "sizeof(multiset
cout << "sizeof(multimap
cout << "sizeof(unordered_set
cout << "sizeof(unordered_map
cout << "sizeof(unordered_multiset
cout << "sizeof(unordered_multimap
cout << "sizeof(_Rb_tree<...>)= " << sizeof(_Rb_tree
//iterators
cout << "sizeof(array
cout << "sizeof(vector
cout << "sizeof(list
cout << "sizeof(forward_list
cout << "sizeof(deque
//! cout << "sizeof(stack
//! cout << "sizeof(queue
cout << "sizeof(set
cout << "sizeof(map
cout << "sizeof(multiset
cout << "sizeof(multimap
cout << "sizeof(unordered_set
cout << "sizeof(unordered_map
cout << "sizeof(unordered_multiset
cout << "sizeof(unordered_multimap
cout << "sizeof(_Rb_tree<...>::iterator)= " << sizeof(_Rb_tree
//allocators
cout << "sizeof( std::allocator
cout << "sizeof(__gnu_cxx::malloc_allocator
cout << "sizeof(__gnu_cxx::new_allocator
cout << "sizeof(__gnu_cxx::__pool_alloc
cout << "sizeof(__gnu_cxx::bitmap_allocator
cout << "sizeof(__gnu_cxx::__mt_alloc
cout << "sizeof(__gnu_cxx::array_allocator
//==> 因為它有一個 ptr 指向 array 和一個 size_t 表示消耗到 array 哪兒
cout << "sizeof(__gnu_cxx::debug_allocator
}
}
//---------------------------------------------------
#include
#include
#include
#include
namespace jj30
{
void test_all_components()
{
cout << "\ntest_all_components().......... \n";
int ia[7] = { 27, 210, 12, 47, 109, 83, 40 };
vector
cout << count_if(vi.begin(), vi.end(),
not1(bind2nd(less
cout << endl;
}
}
//---------------------------------------------------
#include
#include
#include
namespace jj31
{
void test_Rb_tree()
{
//G2.9 vs. G2.9 :
//rb_tree => _Rb_tree,
//identity<> => _Identity<>
//insert_unique() => _M_insert_unique()
//insert_equal() => _M_insert_equal()
cout << "\ntest_Rb_tree().......... \n";
_Rb_tree
cout << itree.empty() << endl; //1
cout << itree.size() << endl; //0
itree._M_insert_unique(3);
itree._M_insert_unique(8);
itree._M_insert_unique(5);
itree._M_insert_unique(9);
itree._M_insert_unique(13);
itree._M_insert_unique(5); //no effect, since using insert_unique().
cout << itree.empty() << endl; //0
cout << itree.size() << endl; //5
cout << itree.count(5) << endl; //1
itree._M_insert_equal(5);
itree._M_insert_equal(5);
cout << itree.size() << endl; //7, since using insert_equal().
cout << itree.count(5) << endl; //3
}
}
//---------------------------------------------------
#include
#include
#include
#include
namespace jj32
{
/*
//下面的 hash
template<> struct hash
{
size_t operator()(string s) const {
return __stl_hash_string(s.c_str());
}
};
*/
void test_Hashtable()
{
cout << "\ntest_Hashtable().......... \n";
// hashtable 的模板參數個數 6=>10 (增加 hash policy 吧大概)
// 所以 G2.9的應用修改起來很麻煩。不改了, 以後再說.
}
}
//---------------------------------------------------
#include
#include
#include
namespace jj33
{
void _display_category(random_access_iterator_tag)
{ cout << "random_access_iterator" << endl; }
void _display_category(bidirectional_iterator_tag)
{ cout << "bidirectional_iterator" << endl; }
void _display_category(forward_iterator_tag)
{ cout << "forward_iterator" << endl; }
void _display_category(output_iterator_tag)
{ cout << "output_iterator" << endl; }
void _display_category(input_iterator_tag)
{ cout << "input_iterator" << endl; }
template
void display_category(I itr)
{
typename iterator_traits::iterator_category cagy;
_display_category(cagy);
cout << "typeid(itr).name()= " << typeid(itr).name() << endl << endl;
//The output depends on library implementation.
//The particular representation pointed by the
//returned valueis implementation-defined,
//and may or may not be different for different types.
}
void test_iterator_category()
{
cout << "\ntest_iterator_category().......... \n";
display_category(array
display_category(vector
display_category(list
display_category(forward_list
display_category(deque
display_category(set
display_category(map
display_category(multiset
display_category(multimap
display_category(unordered_set
display_category(unordered_map
display_category(unordered_multiset
display_category(unordered_multimap
display_category(istream_iterator
display_category(ostream_iterator
}
}
//---------------------------------------------------
#include
#include
#include
namespace jj34
{
int myfunc (int x, int y) {return x+2*y;}
struct myclass {
int operator()(int x, int y) {return x+3*y;}
} myobj;
void test_accumulate()
{
cout << "\ntest_accumulate().......... \n";
int init = 100;
int nums[] = {10,20,30};
cout << "using default accumulate: ";
cout << accumulate(nums,nums+3,init); //160
cout << '\n';
cout << "using functional's minus: ";
cout << accumulate(nums, nums+3, init, minus
cout << '\n';
cout << "using custom function: ";
cout << accumulate(nums, nums+3, init, myfunc); //220
cout << '\n';
cout << "using custom object: ";
cout << accumulate(nums, nums+3, init, myobj); //280
cout << '\n';
}
}
//---------------------------------------------------
#include
#include
#include
namespace jj35
{
void myfunc (int i) {
cout << ' ' << i;
}
struct myclass {
void operator() (int i) { cout << ' ' << i; }
} myobj;
void test_for_each()
{
cout << "\ntest_for_each().......... \n";
vector
myvec.push_back(10);
myvec.push_back(20);
myvec.push_back(30);
for_each (myvec.begin(), myvec.end(), myfunc);
cout << endl; //output: 10 20 30
for_each (myvec.begin(), myvec.end(), myobj); struct myclass { bool test_sort() int myints[] = {32,71,12,45,26,80,53,33}; // using default comparison (operator <): // using function as comp // using object as comp // print out content: cout << "\n\ntest_containers()......... \n"; switch (choice)
cout << endl; //output: 10 20 30
//since C++11, range-based for- statement
for (auto& elem : myvec)
elem += 5;
for (auto elem : myvec)
cout << ' ' << elem ; //output: 15 25 35
}
}
//---------------------------------------------------
#include
#include
#include
namespace jj36
{
bool myfunc (int i,int j) { return (i
bool operator() (int i,int j) { return (i
{
cout << "\ntest_sort().......... \n";
vector
sort(myvec.begin(), myvec.begin()+4); //(12 32 45 71)26 80 53 33
sort(myvec.begin()+4, myvec.end(), myfunc); // 12 32 45 71(26 33 53 80)
sort(myvec.begin(), myvec.end(), myobj); //(12 26 32 33 45 53 71 80)
cout << "\nmyvec contains:";
for (auto elem : myvec) //C++11 range-based for statement
cout << ' ' << elem ; //output: 12 26 32 33 45 53 71 80
// using reverse iterators and default comparison (operator <):
sort(myvec.rbegin(), myvec.rend());
// print out content:
cout << "\nmyvec contains:";
for (auto elem : myvec) //C++11 range-based for statement
cout << ' ' << elem ; //output: 80 71 53 45 33 32 26 12
// using explicitly default comparison (operator <):
sort(myvec.begin(), myvec.end(), less
// print out content:
cout << "\nmyvec contains:";
for (auto elem : myvec) //C++11 range-based for statement
cout << ' ' << elem ; //output: 12 26 32 33 45 53 71 80
// using another comparision criteria (operator >):
sort(myvec.begin(), myvec.end(), greater
// print out content:
cout << "\nmyvec contains:";
for (auto elem : myvec) //C++11 range-based for statement
cout << ' ' << elem ; //output: 80 71 53 45 33 32 26 12
}
}
//---------------------------------------------------
#include
namespace jjxx
{
void test_containers()
{
int choice;
long value;
srand(time(NULL));
cout << "select: \n";
cout << " (1)array (2)vector (3)list (4)forward_list (5)deque (6)multiset \n";
cout << " (7)multimap (8)unordered_multiset (9)unordered_multimap (10)slist \n";
cout << " (11)hash_multiset (12)hash_multimap (13)set (14)map (15)unordered_set \n";
cout << " (16)unordered_map (17)stack (18)queue \n";
cout << " (2),(3),(5),(6),(8) will test also moveable elements. \n";
cin >> choice;
if ( choice != 1 ) { //1 ==> array, use ASIZE
cout << "how many elements: ";
cin >> value;
}
{
case 1 : jj01::test_array();
break;
case 2 : jj02::test_vector(value);
//jj02::test_vector_with_move(value);
break;
case 3 : jj03::test_list(value);
break;
case 4 : jj04::test_forward_list(value);
break;
case 5 : jj05::test_deque(value);
break;
case 6 : jj06::test_multiset(value);
break;
case 7 : jj07::test_multimap(value);
break;
case 8 : jj08::test_unordered_multiset(value);
break;
case 9 : jj09::test_unordered_multimap(value);
break;
case 10: jj10::test_slist(value);
break;
case 11: jj11::test_hash_multiset(value);
break;
case 12: jj12::test_hash_multimap(value);
break;
case 13 : jj13::test_set(value);
break;
case 14 : jj14::test_map(value);
break;
case 15 : jj15::test_unordered_set(value);
break;
case 16 : jj16::test_unordered_map(value);
break;
case 17 : jj17::test_stack(value);
break;
case 18 : jj18::test_queue(value);
break;
default:
break;
}
}
}
//---------------------------------------------------
#include
int main(int argc, char** argv)
{
jj00::test_misc();
jjxx::test_containers();
jj20::test_list_with_special_allocator();
jj25::test_components_sizeof();
jj30::test_all_components();
jj31::test_Rb_tree();
jj32::test_Hashtable();
jj33::test_iterator_category();
jj34::test_accumulate();
jj35::test_for_each();
jj36::test_sort();
return 0;
}