-\r
-#pragma warning(disable:4786)\r
-\r
-#include <set>\r
-#include "sorted_vector.h"\r
-#include <iostream>\r
-#include "assert.h"\r
-#include <time.h>\r
-#include <iomanip>\r
-\r
-struct STest{\r
- std::string s;\r
- int id;\r
-};\r
-\r
-STest MakeSTest()\r
-{\r
- static int id= 0;\r
- int nLen= rand()%10;\r
- char* letters[]={"0","1"};\r
- STest stest;\r
- \r
- for(int i=0;i<nLen;i++){\r
- stest.s+= letters[rand()%2];\r
- }\r
- stest.id= ++id;\r
- return stest;\r
-}\r
-\r
-bool operator<(const STest& t0,const STest& t1)\r
-{\r
- int nCmp;\r
- return (nCmp=t0.s.compare(t1.s))<0||nCmp==0 && t0.id<t1.id;\r
-}\r
-\r
-\r
-class SimpTimer{\r
-public:\r
- SimpTimer(const char* msg):m_msg(msg),m_start(clock()){}\r
- ~SimpTimer()\r
- {\r
- m_stop = clock();\r
- std::cout << "CPU usage (" << std::setw(35) << m_msg.c_str() << ") = " \r
- << (double)(m_stop - m_start)/ CLOCKS_PER_SEC\r
- << " seconds" << std::endl;\r
- }\r
-private:\r
- time_t m_start, m_stop;\r
- std::string m_msg;\r
-};\r
-\r
-\r
-template<class It,class Pred>\r
-bool is_unique(It beg,It beyond,Pred pred)\r
-{\r
- return std::adjacent_find(beg,beyond,std::not2(pred))==beyond;\r
-}\r
-template<class FwIt,class Pred>\r
-FwIt unsorted_find(FwIt beg,FwIt beyond,Pred pred)\r
-{\r
- for(FwIt prev ;(prev=beg)!=beyond && ++beg!=beyond;){\r
- if( pred(*beg,*prev) ){\r
- return prev;\r
- }\r
- }\r
- return beyond;\r
-}\r
-template<class T>\r
-void TestSet(std::vector<T>& v)\r
-{\r
- std::set<T> std_set;\r
- {SimpTimer t("build std::set");\r
- for(unsigned i=0;i<v.size();i++){\r
- std_set.insert(v[i]);\r
- }\r
- }\r
- {SimpTimer t("find in std::set");\r
- for(unsigned i=0;i<v.size();i++){\r
- std::set<T>::iterator it= std_set.find(v[i]);\r
- std::set<T>::size_type nCount= std_set.count(v[i]);\r
- assert( nCount==0 && it==std_set.end()\r
- || nCount!=0 && it!=std_set.end());\r
- }\r
- }\r
-}\r
-template<class T>\r
-void TestSortedVector_AsSet(std::vector<T>& v)\r
-{ \r
- codeproject::sorted_vector<T,true> svec;\r
- {SimpTimer t("build sortedvec_set (naiv)");\r
- for(unsigned i=0;i<v.size();i++){\r
- svec.insert(v[i]);\r
- }\r
- }\r
- assert(is_unique(svec.begin(),svec.end(),svec.key_comp()));\r
- codeproject::sorted_vector<T,true> svec1;\r
- {SimpTimer t("build sortedvec_set (opt.)");\r
- codeproject::sorted_vector<T,true>::Cont& vec= svec1.get_container();\r
- for(unsigned i=0;i<v.size();i++){\r
- vec.push_back(v[i]);\r
- \r
- }\r
- svec1.sort();\r
- }\r
- assert(svec==svec1);\r
- assert(is_unique(svec1.begin(),svec1.end(),svec1.key_comp()));\r
-\r
- {SimpTimer t("find in sortedvec_set");\r
- for(unsigned i=0;i<v.size();i++){\r
- codeproject::sorted_vector<T,true>::iterator it= svec1.find(v[i]);\r
- codeproject::sorted_vector<T,true>::size_type nCount= svec1.count(v[i]);\r
- assert( nCount==0 && it==svec1.end()\r
- || nCount!=0 && it!=svec1.end());\r
- }\r
- }\r
- for(unsigned i=0;i<v.size();i++){svec1.erase(v[i]);}\r
- assert(svec1.empty());\r
-}\r
-template<class T>\r
-void TestMultiSet(std::vector<T>& v)\r
-{\r
- std::multiset<T> svec;\r
-\r
- {SimpTimer t("build multiset");\r
- for(unsigned i=0;i<v.size();i++){\r
- svec.insert(v[i]);\r
- }\r
- }\r
- assert(unsorted_find(svec.begin(),svec.end(),svec.key_comp())==svec.end());\r
- {SimpTimer t("find in multiset");\r
- for(unsigned i=0;i<v.size();i++){\r
- std::multiset<T>::iterator it= svec.find(v[i]);\r
- std::multiset<T>::size_type nCount= svec.count(v[i]);\r
- assert( nCount==0 && it==svec.end()\r
- || nCount!=0 && it!=svec.end());\r
- }\r
- }\r
-}\r
-\r
-template<class T>\r
-void TestSortedVector_AsMultiSet(std::vector<T>& v)\r
-{\r
- codeproject::sorted_vector<T> svec;\r
- {SimpTimer t("build sortedvec_multiset (naiv)");\r
- for(unsigned i=0;i<v.size();i++){\r
- svec.insert(v[i]);\r
- }\r
- }\r
- codeproject::sorted_vector<T> svec1;\r
- {SimpTimer t("build sortedvec_multiset (opt.)");\r
- codeproject::sorted_vector<T>::Cont& vec= svec1.get_container();\r
- for(unsigned i=0;i<v.size();i++){\r
- vec.push_back(v[i]);\r
- \r
- }\r
- svec1.stable_sort();\r
- }\r
- assert(svec==svec1);\r
- assert(unsorted_find(svec.begin(),svec.end(),svec.key_comp())==svec.end());\r
- {SimpTimer t("find in sortedvec_multiset");\r
- for(unsigned i=0;i<v.size();i++){\r
- int n= rand();\r
- codeproject::sorted_vector<T>::iterator it= svec1.find(v[i]);\r
- codeproject::sorted_vector<T>::size_type nCount= svec1.count(v[i]);\r
- assert( nCount==0 && it==svec1.end()\r
- || nCount!=0 && it!=svec1.end());\r
- }\r
- }\r
-/*test various functions*/\r
- const codeproject::sorted_vector<T> svec2(svec);\r
- assert(svec==svec2);\r
- for(unsigned i=0;i<v.size();i++){assert(svec2.find(v[i])!=svec2.end());}\r
- codeproject::sorted_vector<T> svec3(v.begin(),v.end());\r
- assert(svec3==svec2);\r
- codeproject::sorted_vector<T> svec4(v.begin(),v.begin()+(v.end()-v.begin())/2);\r
- svec4= svec3;\r
- assert(svec4==svec3);\r
- while(svec4.size()>0){\r
- svec4.pop_back();\r
- }\r
-}\r
-\r
-\r
-\r
-\r
-template<class T>\r
-void ExecTests(std::vector<T>& v)\r
-{\r
- std::cout << "std::set versus 'sorted_vector as set'" << std::endl; \r
- TestSet(v);\r
- TestSortedVector_AsSet(v);\r
- std::cout << "std::multiset versus 'sorted_vector as multiset'" << std::endl;\r
- TestMultiSet(v);\r
- TestSortedVector_AsMultiSet(v);\r
-}\r
-\r
-template<class T,class Pred>\r
-void TestSetOperations(const std::vector<T>& v0,\r
- const std::vector<T>& v1,\r
- const std::vector<T>& v2,\r
- Pred pred)\r
-{\r
-//A) compute the result of the set-operation: (v0-v1)+v2 - intersect(v1,v2)\r
- codeproject::sorted_vector<T,true,Pred> svec(v0.begin(),v0.end(),pred);\r
- codeproject::sorted_vector<T,true,Pred> svec_v1(pred); svec_v1= v1;\r
- codeproject::sorted_vector<T,true,Pred> svec_v2(pred); svec_v2= v2;\r
- unsigned i,j;\r
- for(i=0;i<v1.size();i++){svec.erase(v1[i]);}\r
- for(j=0;j<v2.size();j++){svec.insert(v2[j]);}\r
- unsigned m;\r
- for(m=0;m<svec_v1.size();m++){\r
- if( svec_v2.find(svec_v1[m])!=svec_v2.end() ){\r
- svec.erase(svec_v1[m]);\r
- }\r
- }\r
-//B) compute the result of the set-operation (v0+v2)-v1\r
- codeproject::sorted_vector<T,true,Pred> svec1(v0.begin(),v0.end(),pred);\r
- for(unsigned k=0;k<v2.size();k++){svec1.insert(v2[k]);}\r
- for(unsigned l=0;l<v1.size();l++){svec1.erase(v1[l]);}\r
- codeproject::sorted_vector<T,true,Pred>::size_type nSize= svec.size();\r
- codeproject::sorted_vector<T,true,Pred>::size_type nSize1= svec1.size();\r
-//test whether results are the same\r
- assert(svec==svec1);\r
-}\r
-\r
-\r
-codeproject::sorted_vector<int,true> \r
-BuildIntersection(std::vector<int>& v0,std::vector<int>& v1)\r
-{\r
- codeproject::sorted_vector<int,true> svec(v0.begin(),v0.end());\r
- codeproject::sorted_vector<int,true> svecIntersection;\r
- for(unsigned i=0;i<v1.size();i++){\r
- if( svec.find(v1[i])!=svec.end() ){\r
- svecIntersection.insert(v1[i]);\r
- }\r
- }\r
- return svecIntersection;\r
-}\r
-codeproject::sorted_vector<int,true> \r
-BuildIntersection1(std::vector<int>& v0,std::vector<int>& v1)\r
-{\r
- codeproject::sorted_vector<int,true> svec(v0.begin(),v0.end());\r
- codeproject::sorted_vector<int,true> svecIntersection;\r
- codeproject::sorted_vector<int,true>::Cont& vInterSect= \r
- svecIntersection.get_container();\r
- for(unsigned i=0;i<v1.size();i++){\r
- if( svec.find(v1[i])!=svec.end() ){\r
- vInterSect.push_back(v1[i]);\r
- }\r
- }\r
- svecIntersection.sort();\r
- return svecIntersection;\r
-}\r
-\r
-\r
-struct ltstr\r
-{\r
- bool operator()(const char* s1, const char* s2) const\r
- {\r
- return strcmp(s1, s2) < 0;\r
- }\r
-};\r
-\r
-int SGITest()\r
-{\r
- using namespace std;\r
- using namespace codeproject;\r
- const int N = 6;\r
- const char* a[N] = {"isomer", "ephemeral", "prosaic", \r
- "nugatory", "artichoke", "serif"};\r
- const char* b[N] = {"flat", "this", "artichoke",\r
- "frigate", "prosaic", "isomer"};\r
-\r
- sorted_vector<const char*,true,ltstr> A(a, a + N);\r
- sorted_vector<const char*,true,ltstr> B(b, b + N);\r
- sorted_vector<const char*,true,ltstr> C;\r
-\r
- cout << "Set A: ";\r
- copy(A.begin(), A.end(), ostream_iterator<const char*>(cout, " "));\r
- cout << endl;\r
- cout << "Set B: ";\r
- copy(B.begin(), B.end(), ostream_iterator<const char*>(cout, " ")); \r
- cout << endl;\r
-\r
- cout << "Union: ";\r
- set_union(A.begin(), A.end(), B.begin(), B.end(),\r
- ostream_iterator<const char*>(cout, " "),\r
- ltstr()); \r
- cout << endl;\r
- return 0;\r
-}\r
-\r
-void TestAllSet()\r
-{\r
- using namespace std;\r
- using namespace codeproject;\r
- typedef sorted_vector<const char*,true,ltstr> StrSet;\r
- StrSet months;\r
- months.insert("jan");\r
- months.insert("feb");\r
- months.insert("mar");\r
- months.insert("apr");\r
- months.insert("may");\r
- months.insert("jun");\r
- months.insert("jul");\r
- months.insert("aug");\r
- months.insert("sep");\r
- months.insert("oct");\r
- months.insert("nov");\r
- months.insert("dec");\r
- StrSet::iterator it= months.find("jul");\r
- assert(strcmp(*it,"jul")==0);\r
- cout << "previous of jul (in alphabetical order) is " << (it[-1]) << endl;\r
- cout << "next of jul (in alphabetical order) is " << (it[1]) << endl;\r
-\r
- cout << "months in alphabetical order: " << endl;\r
- copy(months.begin(),months.end(),ostream_iterator<const char*>(cout," ")); \r
- cout << endl << "months in reverse alphabetical order: " << endl;\r
- copy(months.rbegin(),months.rend(),ostream_iterator<const char*>(cout," "));\r
- /*test count*/\r
- {\r
- for(StrSet::iterator it= months.begin();it!=months.end();++it){\r
- assert(months.count(*it)==1);\r
- }\r
- }\r
- /*test copy construction and comparison operators*/\r
- StrSet monthsCopy(months);\r
- assert( months==monthsCopy \r
- && months<=monthsCopy && months>=monthsCopy\r
- && !(months<monthsCopy) && !(months>monthsCopy));\r
-\r
- std::pair<StrSet::iterator,StrSet::iterator> pairMismatch=\r
- mismatch(months.begin(),months.end(),monthsCopy.begin());\r
- assert(pairMismatch.first==months.end() && pairMismatch.second==monthsCopy.end());\r
-\r
- /*test insertion of already present element*/\r
- copy(months.begin(),months.end(),inserter(monthsCopy,monthsCopy.begin()));\r
- assert(months.size()==monthsCopy.size());\r
-\r
- /*test insert member functions*/\r
- months.insert(monthsCopy.begin(),monthsCopy.end());\r
- assert(months==monthsCopy);\r
- StrSet months1(months.begin(),months.begin()+3);\r
- months1.insert(months.begin()+1,months.end());\r
- assert(months1==months);\r
- months1.insert("aug");\r
- months1.insert("xxx");\r
- months1.insert(months1.find("xxx"),"yyy");\r
- months1.insert("zzz");\r
- assert(months1>months && months1.size()==months.size()+3);\r
- /*test erase member functions*/\r
- months1.erase(months1.find("xxx"),months1.end());\r
- assert(months1.size()==months.size());\r
-\r
- /*test lower_bound,upper_bound,equal_range*/\r
- assert( strcmp(*months.lower_bound("jul"),"jul")==0);\r
- \r
-\r
- cout << endl;\r
-}\r
-\r
-\r
-int main()\r
-{\r
-//timed tests\r
- std::vector<int> v;\r
- int i;\r
- for(i=0;i<50000;i++){v.push_back(rand());}\r
- std::cout << "--------------Tests with element type int-------------" << std::endl;\r
- ExecTests(v);\r
- \r
- std::vector<STest> vt;\r
- for(i=0;i<50000;i++){vt.push_back(MakeSTest());}\r
- std::cout << "-Tests with element type 'STest' (string,int)--------" << std::endl;\r
- ExecTests(v);\r
-\r
-//set operations-test\r
- std::vector<int> v1,v2;\r
- for(i=0;i<10000;i++){v1.push_back(rand());}\r
- for(i=0;i<10000;i++){v2.push_back(rand());}\r
- TestSetOperations(v,v1,v2,std::greater<int>());\r
-\r
- assert(BuildIntersection(v1,v2)==BuildIntersection1(v1,v2));\r
- SGITest();\r
- TestAllSet();\r
- return 0;\r
-}
\ No newline at end of file
+
+#pragma warning(disable:4786)
+
+#include <set>
+#include "sorted_vector.h"
+#include <iostream>
+#include "assert.h"
+#include <time.h>
+#include <iomanip>
+#include <iterator> // ostream_iterator
+#include <cstring> // strcmp
+
+struct STest{
+ std::string s;
+ int id;
+};
+
+STest MakeSTest()
+{
+ static int id= 0;
+ int nLen= rand()%10;
+ const char* letters[]={"0","1"};
+ STest stest;
+
+ for(int i=0;i<nLen;i++){
+ stest.s+= letters[rand()%2];
+ }
+ stest.id= ++id;
+ return stest;
+}
+
+bool operator<(const STest& t0,const STest& t1)
+{
+ int nCmp;
+ return (nCmp=t0.s.compare(t1.s))<0||nCmp==0 && t0.id<t1.id;
+}
+
+
+class SimpTimer{
+public:
+ SimpTimer(const char* msg):m_msg(msg),m_start(clock()){}
+ ~SimpTimer()
+ {
+ m_stop = clock();
+ std::cout << "CPU usage (" << std::setw(35) << m_msg.c_str() << ") = "
+ << (double)(m_stop - m_start)/ CLOCKS_PER_SEC
+ << " seconds" << std::endl;
+ }
+private:
+ time_t m_start, m_stop;
+ std::string m_msg;
+};
+
+
+template<class It,class Pred>
+bool is_unique(It beg,It beyond,Pred pred)
+{
+ return std::adjacent_find(beg,beyond,std::not2(pred))==beyond;
+}
+template<class FwIt,class Pred>
+FwIt unsorted_find(FwIt beg,FwIt beyond,Pred pred)
+{
+ for(FwIt prev ;(prev=beg)!=beyond && ++beg!=beyond;){
+ if( pred(*beg,*prev) ){
+ return prev;
+ }
+ }
+ return beyond;
+}
+template<class T>
+void TestSet(std::vector<T>& v)
+{
+ std::set<T> std_set;
+ {SimpTimer t("build std::set");
+ for(unsigned i=0;i<v.size();i++){
+ std_set.insert(v[i]);
+ }
+ }
+ {SimpTimer t("find in std::set");
+ for(unsigned i=0;i<v.size();i++){
+ typename std::set<T>::iterator it= std_set.find(v[i]);
+ typename std::set<T>::size_type nCount= std_set.count(v[i]);
+ assert( nCount==0 && it==std_set.end()
+ || nCount!=0 && it!=std_set.end());
+ }
+ }
+}
+template<class T>
+void TestSortedVector_AsSet(std::vector<T>& v)
+{
+ codeproject::sorted_vector<T,true> svec;
+ {SimpTimer t("build sortedvec_set (naiv)");
+ for(unsigned i=0;i<v.size();i++){
+ svec.insert(v[i]);
+ }
+ }
+ assert(is_unique(svec.begin(),svec.end(),svec.key_comp()));
+ codeproject::sorted_vector<T,true> svec1;
+ {SimpTimer t("build sortedvec_set (opt.)");
+ typename codeproject::sorted_vector<T,true>::Cont& vec= svec1.get_container();
+ for(unsigned i=0;i<v.size();i++){
+ vec.push_back(v[i]);
+
+ }
+ svec1.sort();
+ }
+ assert(svec==svec1);
+ assert(is_unique(svec1.begin(),svec1.end(),svec1.key_comp()));
+
+ {SimpTimer t("find in sortedvec_set");
+ for(unsigned i=0;i<v.size();i++){
+ typename codeproject::sorted_vector<T,true>::iterator it= svec1.find(v[i]);
+ typename codeproject::sorted_vector<T,true>::size_type nCount= svec1.count(v[i]);
+ assert( nCount==0 && it==svec1.end()
+ || nCount!=0 && it!=svec1.end());
+ }
+ }
+ for(unsigned i=0;i<v.size();i++){svec1.erase(v[i]);}
+ assert(svec1.empty());
+}
+template<class T>
+void TestMultiSet(std::vector<T>& v)
+{
+ std::multiset<T> svec;
+
+ {SimpTimer t("build multiset");
+ for(unsigned i=0;i<v.size();i++){
+ svec.insert(v[i]);
+ }
+ }
+ assert(unsorted_find(svec.begin(),svec.end(),svec.key_comp())==svec.end());
+ {SimpTimer t("find in multiset");
+ for(unsigned i=0;i<v.size();i++){
+ typename std::multiset<T>::iterator it= svec.find(v[i]);
+ typename std::multiset<T>::size_type nCount= svec.count(v[i]);
+ assert( nCount==0 && it==svec.end()
+ || nCount!=0 && it!=svec.end());
+ }
+ }
+}
+
+template<class T>
+void TestSortedVector_AsMultiSet(std::vector<T>& v)
+{
+ codeproject::sorted_vector<T> svec;
+ {SimpTimer t("build sortedvec_multiset (naiv)");
+ for(unsigned i=0;i<v.size();i++){
+ svec.insert(v[i]);
+ }
+ }
+ codeproject::sorted_vector<T> svec1;
+ {SimpTimer t("build sortedvec_multiset (opt.)");
+ typename codeproject::sorted_vector<T>::Cont& vec= svec1.get_container();
+ for(unsigned i=0;i<v.size();i++){
+ vec.push_back(v[i]);
+
+ }
+ svec1.stable_sort();
+ }
+ assert(svec==svec1);
+ assert(unsorted_find(svec.begin(),svec.end(),svec.key_comp())==svec.end());
+ {SimpTimer t("find in sortedvec_multiset");
+ for(unsigned i=0;i<v.size();i++){
+ int n= rand();
+ typename codeproject::sorted_vector<T>::iterator it= svec1.find(v[i]);
+ typename codeproject::sorted_vector<T>::size_type nCount= svec1.count(v[i]);
+ assert( nCount==0 && it==svec1.end()
+ || nCount!=0 && it!=svec1.end());
+ }
+ }
+/*test various functions*/
+ const codeproject::sorted_vector<T> svec2(svec);
+ assert(svec==svec2);
+ for(unsigned i=0;i<v.size();i++){assert(svec2.find(v[i])!=svec2.end());}
+ codeproject::sorted_vector<T> svec3(v.begin(),v.end());
+ assert(svec3==svec2);
+ codeproject::sorted_vector<T> svec4(v.begin(),v.begin()+(v.end()-v.begin())/2);
+ svec4= svec3;
+ assert(svec4==svec3);
+ while(svec4.size()>0){
+ svec4.pop_back();
+ }
+}
+
+
+
+
+template<class T>
+void ExecTests(std::vector<T>& v)
+{
+ std::cout << "std::set versus 'sorted_vector as set'" << std::endl;
+ TestSet(v);
+ TestSortedVector_AsSet(v);
+ std::cout << "std::multiset versus 'sorted_vector as multiset'" << std::endl;
+ TestMultiSet(v);
+ TestSortedVector_AsMultiSet(v);
+}
+
+template<class T,class Pred>
+void TestSetOperations(const std::vector<T>& v0,
+ const std::vector<T>& v1,
+ const std::vector<T>& v2,
+ Pred pred)
+{
+//A) compute the result of the set-operation: (v0-v1)+v2 - intersect(v1,v2)
+ codeproject::sorted_vector<T,true,Pred> svec(v0.begin(),v0.end(),pred);
+ codeproject::sorted_vector<T,true,Pred> svec_v1(pred); svec_v1= v1;
+ codeproject::sorted_vector<T,true,Pred> svec_v2(pred); svec_v2= v2;
+ unsigned i,j;
+ for(i=0;i<v1.size();i++){svec.erase(v1[i]);}
+ for(j=0;j<v2.size();j++){svec.insert(v2[j]);}
+ unsigned m;
+ for(m=0;m<svec_v1.size();m++){
+ if( svec_v2.find(svec_v1[m])!=svec_v2.end() ){
+ svec.erase(svec_v1[m]);
+ }
+ }
+//B) compute the result of the set-operation (v0+v2)-v1
+ codeproject::sorted_vector<T,true,Pred> svec1(v0.begin(),v0.end(),pred);
+ for(unsigned k=0;k<v2.size();k++){svec1.insert(v2[k]);}
+ for(unsigned l=0;l<v1.size();l++){svec1.erase(v1[l]);}
+ typename codeproject::sorted_vector<T,true,Pred>::size_type nSize= svec.size();
+ typename codeproject::sorted_vector<T,true,Pred>::size_type nSize1= svec1.size();
+//test whether results are the same
+ assert(svec==svec1);
+}
+
+
+codeproject::sorted_vector<int,true>
+BuildIntersection(std::vector<int>& v0,std::vector<int>& v1)
+{
+ codeproject::sorted_vector<int,true> svec(v0.begin(),v0.end());
+ codeproject::sorted_vector<int,true> svecIntersection;
+ for(unsigned i=0;i<v1.size();i++){
+ if( svec.find(v1[i])!=svec.end() ){
+ svecIntersection.insert(v1[i]);
+ }
+ }
+ return svecIntersection;
+}
+codeproject::sorted_vector<int,true>
+BuildIntersection1(std::vector<int>& v0,std::vector<int>& v1)
+{
+ codeproject::sorted_vector<int,true> svec(v0.begin(),v0.end());
+ codeproject::sorted_vector<int,true> svecIntersection;
+ codeproject::sorted_vector<int,true>::Cont& vInterSect=
+ svecIntersection.get_container();
+ for(unsigned i=0;i<v1.size();i++){
+ if( svec.find(v1[i])!=svec.end() ){
+ vInterSect.push_back(v1[i]);
+ }
+ }
+ svecIntersection.sort();
+ return svecIntersection;
+}
+
+
+struct ltstr
+{
+ bool operator()(const char* s1, const char* s2) const
+ {
+ return strcmp(s1, s2) < 0;
+ }
+};
+
+int SGITest()
+{
+ using namespace std;
+ using namespace codeproject;
+ const int N = 6;
+ const char* a[N] = {"isomer", "ephemeral", "prosaic",
+ "nugatory", "artichoke", "serif"};
+ const char* b[N] = {"flat", "this", "artichoke",
+ "frigate", "prosaic", "isomer"};
+
+ sorted_vector<const char*,true,ltstr> A(a, a + N);
+ sorted_vector<const char*,true,ltstr> B(b, b + N);
+ sorted_vector<const char*,true,ltstr> C;
+
+ cout << "Set A: ";
+ copy(A.begin(), A.end(), std::ostream_iterator<const char*>(cout, " "));
+ cout << endl;
+ cout << "Set B: ";
+ copy(B.begin(), B.end(), std::ostream_iterator<const char*>(cout, " "));
+ cout << endl;
+
+ cout << "Union: ";
+ set_union(A.begin(), A.end(), B.begin(), B.end(),
+ std::ostream_iterator<const char*>(cout, " "),
+ ltstr());
+ cout << endl;
+ return 0;
+}
+
+void TestAllSet()
+{
+ using namespace std;
+ using namespace codeproject;
+ typedef sorted_vector<const char*,true,ltstr> StrSet;
+ StrSet months;
+ months.insert("jan");
+ months.insert("feb");
+ months.insert("mar");
+ months.insert("apr");
+ months.insert("may");
+ months.insert("jun");
+ months.insert("jul");
+ months.insert("aug");
+ months.insert("sep");
+ months.insert("oct");
+ months.insert("nov");
+ months.insert("dec");
+ StrSet::iterator it= months.find("jul");
+ assert(strcmp(*it,"jul")==0);
+ cout << "previous of jul (in alphabetical order) is " << (it[-1]) << endl;
+ cout << "next of jul (in alphabetical order) is " << (it[1]) << endl;
+
+ cout << "months in alphabetical order: " << endl;
+ copy(months.begin(),months.end(),std::ostream_iterator<const char*>(cout," "));
+ cout << endl << "months in reverse alphabetical order: " << endl;
+ copy(months.rbegin(),months.rend(),std::ostream_iterator<const char*>(cout," "));
+ /*test count*/
+ {
+ for(StrSet::iterator it= months.begin();it!=months.end();++it){
+ assert(months.count(*it)==1);
+ }
+ }
+ /*test copy construction and comparison operators*/
+ StrSet monthsCopy(months);
+ assert( months==monthsCopy
+ && months<=monthsCopy && months>=monthsCopy
+ && !(months<monthsCopy) && !(months>monthsCopy));
+
+ std::pair<StrSet::iterator,StrSet::iterator> pairMismatch=
+ mismatch(months.begin(),months.end(),monthsCopy.begin());
+ assert(pairMismatch.first==months.end() && pairMismatch.second==monthsCopy.end());
+
+ /*test insertion of already present element*/
+ copy(months.begin(),months.end(),inserter(monthsCopy,monthsCopy.begin()));
+ assert(months.size()==monthsCopy.size());
+
+ /*test insert member functions*/
+ months.insert(monthsCopy.begin(),monthsCopy.end());
+ assert(months==monthsCopy);
+ StrSet months1(months.begin(),months.begin()+3);
+ months1.insert(months.begin()+1,months.end());
+ assert(months1==months);
+ months1.insert("aug");
+ months1.insert("xxx");
+ months1.insert(months1.find("xxx"),"yyy");
+ months1.insert("zzz");
+ assert(months1>months && months1.size()==months.size()+3);
+ /*test erase member functions*/
+ months1.erase(months1.find("xxx"),months1.end());
+ assert(months1.size()==months.size());
+
+ /*test lower_bound,upper_bound,equal_range*/
+ assert( strcmp(*months.lower_bound("jul"),"jul")==0);
+
+
+ cout << endl;
+}
+
+
+int main()
+{
+//timed tests
+ std::vector<int> v;
+ int i;
+ for(i=0;i<50000;i++){v.push_back(rand());}
+ std::cout << "--------------Tests with element type int-------------" << std::endl;
+ ExecTests(v);
+
+ std::vector<STest> vt;
+ for(i=0;i<50000;i++){vt.push_back(MakeSTest());}
+ std::cout << "-Tests with element type 'STest' (string,int)--------" << std::endl;
+ ExecTests(v);
+
+//set operations-test
+ std::vector<int> v1,v2;
+ for(i=0;i<10000;i++){v1.push_back(rand());}
+ for(i=0;i<10000;i++){v2.push_back(rand());}
+ TestSetOperations(v,v1,v2,std::greater<int>());
+
+ assert(BuildIntersection(v1,v2)==BuildIntersection1(v1,v2));
+ SGITest();
+ TestAllSet();
+ return 0;
+}
+
-/* STL-conforming "sorted vector" container\r
- *\r
- * (C) 2002 Martin Holzherr (holzherr@infobrain.com). All rights reserved.\r
- *\r
- * Permission is granted to use, distribute and modify this code provided that:\r
- * · this copyright notice appears,\r
- * · \r
- * The author welcomes any suggestions on the code or reportings of actual\r
- * use of the code. Please send your comments to holzherr@infobrain.com.\r
- *\r
- * The author makes NO WARRANTY or representation, either express or implied,\r
- * with respect to this code, its quality, accuracy, merchantability, or\r
- * fitness for a particular purpose. This software is provided "AS IS", and\r
- * you, its user, assume the entire risk as to its quality and accuracy.\r
- *\r
- * Created: November 19th, 2002\r
- * Last modified: November 27th, 2002 \r
- (changed namespace from std to codeproject;\r
- uses template member functions for MSCVER>=1300)\r
- \r
- */\r
-\r
-#ifndef SORTED_VECTOR_\r
-#define SORTED_VECTOR_\r
-#define VERSION_SORTED_VECTOR_ 0x00010010\r
-\r
-\r
-#include <algorithm>\r
-#include <vector>\r
-#include <utility>\r
-#include <functional>\r
-\r
-#pragma pack(push,8)\r
-#pragma warning(push,3)\r
-\r
-\r
-namespace codeproject{\r
- // TEMPLATE CLASS sorted_vector\r
-\r
- template<class K, bool bNoDuplicates= false,class Pr = std::less<K>, class A = std::allocator<K> >\r
- class sorted_vector {\r
-public:\r
- typedef sorted_vector<K,bNoDuplicates,Pr,A> Myt_;\r
- typedef std::vector<K,A> Cont;\r
- typedef Cont::allocator_type allocator_type;\r
- typedef Cont::size_type size_type;\r
- typedef Cont::difference_type difference_type;\r
- typedef Cont::reference reference;\r
- typedef Cont::const_reference const_reference;\r
- typedef Cont::value_type value_type;\r
- typedef K key_type;\r
- typedef Cont::iterator iterator;\r
- typedef Cont::const_iterator const_iterator;\r
- typedef Pr key_compare;\r
- typedef Pr value_compare;\r
-\r
- typedef Cont::const_reverse_iterator\r
- const_reverse_iterator;\r
- typedef Cont::reverse_iterator reverse_iterator;\r
-\r
- typedef std::pair<iterator, iterator> Pairii_;\r
- typedef std::pair<const_iterator, const_iterator> Paircc_;\r
- typedef std::pair<iterator, bool> Pairib_;\r
- explicit sorted_vector(const Pr& pred = Pr(),const A& al = A())\r
- :key_compare_(pred),vec_(al){}\r
-#if (_MSC_VER >= 1300)\r
- template<class It>\r
- sorted_vector(It first, It beyond, \r
- const Pr& pred = Pr(),const A& al = A())\r
- :key_compare_(pred),vec_(first,beyond,al)\r
- {stable_sort();}\r
-#else\r
- sorted_vector(const_iterator first, const_iterator beyond, \r
- const Pr& pred = Pr(),const A& al = A())\r
- :key_compare_(pred),vec_(first,beyond,al)\r
- {stable_sort();}\r
-#endif\r
- sorted_vector(const Myt_& x)\r
- : vec_(x.vec_),key_compare_(x.key_compare_)\r
- {}\r
- ~sorted_vector() {}\r
- Myt_& operator=(const Myt_& x) {vec_.operator=(x.vec_);\r
- key_compare_= x.key_compare_;\r
- return *this;}\r
- Myt_& operator=(const Cont& x){vec_.operator=(x);\r
- sort();return *this;}\r
- \r
- void reserve(size_type n) {vec_.reserve(n);}\r
- iterator begin() {return vec_.begin(); }\r
- const_iterator begin() const {return vec_.begin(); }\r
- iterator end() {return vec_.end();}\r
- const_iterator end() const {return vec_.end();}\r
- reverse_iterator rbegin() {return vec_.rbegin();}\r
- const_reverse_iterator rbegin() const \r
- {return vec_.rbegin();}\r
-\r
- reverse_iterator rend() {return vec_.rend();}\r
- const_reverse_iterator rend() const \r
- {return vec_.rend();}\r
-\r
-\r
- size_type size() const {return vec_.size();}\r
- size_type max_size() const {return vec_.max_size();}\r
- bool empty() const {return vec_.empty();}\r
- A get_allocator() const {return vec_.get_allocator();}\r
- const_reference at(size_type p) const {return vec_.at(p);}\r
- reference at(size_type p) {return vec_.at(p);}\r
- const_reference operator[](size_type p) const\r
- {return vec_.operator[](p);}\r
- \r
- reference operator[](size_type p) {return vec_.operator[](p);}\r
- reference front() {return vec_.front();}\r
- const_reference front() const {return vec_.front();}\r
- reference back() {return vec_.back();}\r
- const_reference back() const {return vec_.back();}\r
- void pop_back() {vec_.pop_back();}\r
-\r
- void assign(const_iterator first, const_iterator beyond) \r
- {vec_.assign(first,beyond);}\r
- void assign(size_type n, const K& x = K())\r
- {vec_.assign(n,x);}\r
-/*insert members*/\r
- Pairib_ insert(const value_type& x)\r
- {\r
- if(bNoDuplicates){\r
- iterator p= lower_bound(x);\r
- if(p==end()||key_compare_(x,*p)){\r
- return Pairib_(InsertImpl_(p,x),true);\r
- }else{\r
- return Pairib_(p,false);\r
- }\r
- }else{\r
- iterator p= upper_bound(x);\r
- return Pairib_(InsertImpl_(p,x),true);\r
- }\r
- }\r
- iterator insert(iterator it, const value_type& x)//it is the hint\r
- {\r
- if(it!=end() ){\r
- if(bNoDuplicates){\r
- if(key_compare_(*it,x)){\r
- if((it+1)==end()||KeyCompare_Gt_(*(it+1),x)){//use hint\r
- return InsertImpl_(it+1,x);\r
- }else if(KeyCompare_Geq_(*(it+1),x)){\r
- return end();\r
- }\r
- }\r
- }else{\r
- if( KeyCompare_Leq_(*it,x)\r
- &&((it+1)==end()||KeyCompare_Geq_(*(it+1),x))){\r
- return InsertImpl_(it+1,x);\r
- }\r
- }\r
- }\r
- return insert(x).first;\r
- }\r
-#if (_MSC_VER >= 1300)\r
- template<class It>\r
- void insert(It first, It beyond)\r
- {\r
- size_type n= std::distance(first,beyond);\r
- reserve(size()+n);\r
- for( ;first!=beyond;++first){\r
- insert(*first);\r
- }\r
- }\r
-#else\r
- void insert(const_iterator first, const_iterator beyond)\r
- {\r
- size_type n= std::distance(first,beyond);\r
- reserve(size()+n);\r
- for( ;first!=beyond;++first){\r
- insert(*first);\r
- }\r
- }\r
-#endif\r
- iterator erase(iterator p) {return vec_.erase(p);}\r
- iterator erase(iterator first, iterator beyond)\r
- {return vec_.erase(first,beyond);}\r
- size_type erase(const K& key) \r
- {\r
- Pairii_ begEnd= equal_range(key);\r
- size_type n= std::distance(begEnd.first,begEnd.second);\r
- erase(begEnd.first,begEnd.second);\r
- return n;\r
- }\r
- void clear() {return vec_.clear();}\r
- \r
- bool Eq_(const Myt_& x) const \r
- {return (size() == x.size()\r
- && std::equal(begin(), end(), x.begin())); }\r
- bool Lt_(const Myt_& x) const\r
- {return (std::lexicographical_compare(begin(), end(),\r
- x.begin(), x.end()));}\r
- void swap(Myt_& x)\r
- {vec_.swap(x.vec_);std::swap(key_compare_,x.key_compare_);}\r
- \r
- friend void swap(Myt_& x, Myt_& Y_)\r
- {x.swap(Y_); }\r
-\r
- key_compare key_comp() const {return key_compare_; }\r
- value_compare value_comp() const {return (key_comp()); }\r
- iterator find(const K& k)\r
- { iterator p = lower_bound(k);\r
- return (p==end()||key_compare_(k, *p))? end():p;\r
- }\r
- const_iterator find(const K& k) const\r
- {const_iterator p = lower_bound(k);\r
- return (p==end()||key_compare_(k,*p))?end():p;}\r
- size_type count(const K& k) const\r
- {Paircc_ Ans_ = equal_range(k);\r
- size_type n = std::distance(Ans_.first, Ans_.second);\r
- return (n); }\r
- iterator lower_bound(const K& k)\r
- {return std::lower_bound(begin(), end(), k, key_compare_); }\r
- const_iterator lower_bound(const K& k) const\r
- {return std::lower_bound(begin(), end(), k, key_compare_); }\r
- iterator upper_bound(const K& k)\r
- {return std::upper_bound(begin(), end(), k, key_compare_); }\r
- const_iterator upper_bound(const K& k) const\r
- {return std::upper_bound(begin(), end(), k, key_compare_); }\r
- Pairii_ equal_range(const K& k)\r
- {return std::equal_range(begin(), end(), k, key_compare_); }\r
- Paircc_ equal_range(const K& k) const\r
- {return std::equal_range(begin(), end(), k, key_compare_); }\r
-\r
-/*functions for use with direct std::vector-access*/\r
- Cont& get_container()\r
- {return vec_;}\r
- void sort()//restore sorted order after low level access \r
- { std::sort(vec_.begin(),vec_.end(),key_compare_);\r
- if( bNoDuplicates ){\r
- vec_.erase(Unique_(),vec_.end());\r
- }\r
- }\r
- void stable_sort()//restore sorted order after low level access \r
- { std::stable_sort(vec_.begin(),vec_.end(),key_compare_);\r
- if( bNoDuplicates ){\r
- erase(Unique_(),end());\r
- }\r
- } \r
-protected:\r
- iterator Unique_()\r
- { iterator front_= vec_.begin(),out_= vec_.end(),end_=vec_.end();\r
- bool bCopy_= false;\r
- for(iterator prev_; (prev_=front_)!=end_ && ++front_!=end_; ){\r
- if( key_compare_(*prev_,*front_)){\r
- if(bCopy_){\r
- *out_= *front_;\r
- out_++;\r
- }\r
- }else{\r
- if(!bCopy_){out_=front_;bCopy_=true;}\r
- }\r
- }\r
- return out_;\r
- }\r
- iterator InsertImpl_(iterator p,const value_type& x)\r
- {return vec_.insert(p,x);}\r
- bool KeyCompare_Leq_(const K& ty0,const K& ty1)\r
- {return !key_compare_(ty1,ty0);}\r
- bool KeyCompare_Geq_(const K& ty0,const K& ty1)\r
- {return !key_compare_(ty0,ty1);}\r
- bool KeyCompare_Gt_(const K& ty0,const K& ty1)\r
- {return key_compare_(ty1,ty0);}\r
-\r
- key_compare key_compare_;\r
- Cont vec_;\r
-};\r
-\r
-\r
-template<class K,bool bNoDuplicates,class Pr, class A> inline\r
- bool operator==(const sorted_vector<K, bNoDuplicates,Pr,A>& x,\r
- const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)\r
- {return x.Eq_(Y_); }\r
-template<class K,bool bNoDuplicates,class Pr, class A> inline\r
- bool operator!=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,\r
- const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)\r
- {return !(x == Y_); }\r
-template<class K,bool bNoDuplicates,class Pr, class A> inline\r
- bool operator<(const sorted_vector<K, bNoDuplicates,Pr,A>& x,\r
- const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)\r
- {return x.Lt_(Y_);}\r
-template<class K,bool bNoDuplicates,class Pr,class A> inline\r
- bool operator>(const sorted_vector<K, bNoDuplicates,Pr,A>& x,\r
- const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)\r
- {return Y_ < x; }\r
-template<class K,bool bNoDuplicates,class Pr, class A> inline\r
- bool operator<=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,\r
- const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)\r
- {return !(Y_ < x); }\r
-template<class K, bool bNoDuplicates,class Pr,class A> inline\r
- bool operator>=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,\r
- const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)\r
- {return (!(x < Y_)); }\r
-}\r
-#pragma warning(pop)\r
-#pragma pack(pop)\r
-#elif VERSION_SORTED_VECTOR_ != 0x00010010\r
-#error You have included two sorted_vector.h with different version numbers\r
-#endif\r
+/* STL-conforming "sorted vector" container
+ *
+ * (C) 2002 Martin Holzherr (holzherr@infobrain.com). All rights reserved.
+ *
+ * Permission is granted to use, distribute and modify this code provided that:
+ * · this copyright notice appears,
+ * ·
+ * The author welcomes any suggestions on the code or reportings of actual
+ * use of the code. Please send your comments to holzherr@infobrain.com.
+ *
+ * The author makes NO WARRANTY or representation, either express or implied,
+ * with respect to this code, its quality, accuracy, merchantability, or
+ * fitness for a particular purpose. This software is provided "AS IS", and
+ * you, its user, assume the entire risk as to its quality and accuracy.
+ *
+ * Created: November 19th, 2002
+ * Last modified: November 27th, 2002
+ (changed namespace from std to codeproject;
+ uses template member functions for MSCVER>=1300)
+
+ */
+
+#ifndef SORTED_VECTOR_
+#define SORTED_VECTOR_
+#define VERSION_SORTED_VECTOR_ 0x00010010
+
+
+#include <algorithm>
+#include <vector>
+#include <utility>
+#include <functional>
+
+#pragma pack(push,8)
+#pragma warning(push,3)
+
+
+namespace codeproject{
+ // TEMPLATE CLASS sorted_vector
+
+ template<class K, bool bNoDuplicates= false,class Pr = std::less<K>, class A = std::allocator<K> >
+ class sorted_vector {
+public:
+ typedef sorted_vector<K,bNoDuplicates,Pr,A> Myt_;
+ typedef typename std::vector<K,A> Cont;
+ typedef typename Cont::allocator_type allocator_type;
+ typedef typename Cont::size_type size_type;
+ typedef typename Cont::difference_type difference_type;
+ typedef typename Cont::reference reference;
+ typedef typename Cont::const_reference const_reference;
+ typedef typename Cont::value_type value_type;
+ typedef K key_type;
+ typedef typename Cont::iterator iterator;
+ typedef typename Cont::const_iterator const_iterator;
+ typedef Pr key_compare;
+ typedef Pr value_compare;
+ typedef typename Cont::const_reverse_iterator const_reverse_iterator;
+ typedef typename Cont::reverse_iterator reverse_iterator;
+
+ typedef typename std::pair<iterator, iterator> Pairii_;
+ typedef typename std::pair<const_iterator, const_iterator> Paircc_;
+ typedef typename std::pair<iterator, bool> Pairib_;
+
+ explicit sorted_vector(const Pr& pred = Pr(),const A& al = A())
+ :key_compare_(pred),vec_(al){}
+#if !(_MSC_VER >= 1300)
+ template<class It>
+ sorted_vector(It first, It beyond,
+ const Pr& pred = Pr(),const A& al = A())
+ :key_compare_(pred),vec_(first,beyond,al)
+ {stable_sort();}
+#else
+ sorted_vector(const_iterator first, const_iterator beyond,
+ const Pr& pred = Pr(),const A& al = A())
+ :key_compare_(pred),vec_(first,beyond,al)
+ {stable_sort();}
+#endif
+ sorted_vector(const Myt_& x)
+ : vec_(x.vec_),key_compare_(x.key_compare_)
+ {}
+ ~sorted_vector() {}
+ Myt_& operator=(const Myt_& x) {vec_.operator=(x.vec_);
+ key_compare_= x.key_compare_;
+ return *this;}
+ Myt_& operator=(const Cont& x){vec_.operator=(x);
+ sort();return *this;}
+
+ void reserve(size_type n) {vec_.reserve(n);}
+ iterator begin() {return vec_.begin(); }
+ const_iterator begin() const {return vec_.begin(); }
+ iterator end() {return vec_.end();}
+ const_iterator end() const {return vec_.end();}
+ reverse_iterator rbegin() {return vec_.rbegin();}
+ const_reverse_iterator rbegin() const
+ {return vec_.rbegin();}
+
+ reverse_iterator rend() {return vec_.rend();}
+ const_reverse_iterator rend() const
+ {return vec_.rend();}
+
+
+ size_type size() const {return vec_.size();}
+ size_type max_size() const {return vec_.max_size();}
+ bool empty() const {return vec_.empty();}
+ A get_allocator() const {return vec_.get_allocator();}
+ const_reference at(size_type p) const {return vec_.at(p);}
+ reference at(size_type p) {return vec_.at(p);}
+ const_reference operator[](size_type p) const
+ {return vec_.operator[](p);}
+
+ reference operator[](size_type p) {return vec_.operator[](p);}
+ reference front() {return vec_.front();}
+ const_reference front() const {return vec_.front();}
+ reference back() {return vec_.back();}
+ const_reference back() const {return vec_.back();}
+ void pop_back() {vec_.pop_back();}
+
+ void assign(const_iterator first, const_iterator beyond)
+ {vec_.assign(first,beyond);}
+ void assign(size_type n, const K& x = K())
+ {vec_.assign(n,x);}
+/*insert members*/
+ Pairib_ insert(const value_type& x)
+ {
+ if(bNoDuplicates){
+ iterator p= lower_bound(x);
+ if(p==end()||key_compare_(x,*p)){
+ return Pairib_(InsertImpl_(p,x),true);
+ }else{
+ return Pairib_(p,false);
+ }
+ }else{
+ iterator p= upper_bound(x);
+ return Pairib_(InsertImpl_(p,x),true);
+ }
+ }
+ iterator insert(iterator it, const value_type& x)//it is the hint
+ {
+ if(it!=end() ){
+ if(bNoDuplicates){
+ if(key_compare_(*it,x)){
+ if((it+1)==end()||KeyCompare_Gt_(*(it+1),x)){//use hint
+ return InsertImpl_(it+1,x);
+ }else if(KeyCompare_Geq_(*(it+1),x)){
+ return end();
+ }
+ }
+ }else{
+ if( KeyCompare_Leq_(*it,x)
+ &&((it+1)==end()||KeyCompare_Geq_(*(it+1),x))){
+ return InsertImpl_(it+1,x);
+ }
+ }
+ }
+ return insert(x).first;
+ }
+#if (_MSC_VER >= 1300)
+ template<class It>
+ void insert(It first, It beyond)
+ {
+ size_type n= std::distance(first,beyond);
+ reserve(size()+n);
+ for( ;first!=beyond;++first){
+ insert(*first);
+ }
+ }
+#else
+ void insert(const_iterator first, const_iterator beyond)
+ {
+ size_type n= std::distance(first,beyond);
+ reserve(size()+n);
+ for( ;first!=beyond;++first){
+ insert(*first);
+ }
+ }
+#endif
+ iterator erase(iterator p) {return vec_.erase(p);}
+ iterator erase(iterator first, iterator beyond)
+ {return vec_.erase(first,beyond);}
+ size_type erase(const K& key)
+ {
+ Pairii_ begEnd= equal_range(key);
+ size_type n= std::distance(begEnd.first,begEnd.second);
+ erase(begEnd.first,begEnd.second);
+ return n;
+ }
+ void clear() {return vec_.clear();}
+
+ bool Eq_(const Myt_& x) const
+ {return (size() == x.size()
+ && std::equal(begin(), end(), x.begin())); }
+ bool Lt_(const Myt_& x) const
+ {return (std::lexicographical_compare(begin(), end(),
+ x.begin(), x.end()));}
+ void swap(Myt_& x)
+ {vec_.swap(x.vec_);std::swap(key_compare_,x.key_compare_);}
+
+ friend void swap(Myt_& x, Myt_& Y_)
+ {x.swap(Y_); }
+
+ key_compare key_comp() const {return key_compare_; }
+ value_compare value_comp() const {return (key_comp()); }
+ iterator find(const K& k)
+ { iterator p = lower_bound(k);
+ return (p==end()||key_compare_(k, *p))? end():p;
+ }
+ const_iterator find(const K& k) const
+ {const_iterator p = lower_bound(k);
+ return (p==end()||key_compare_(k,*p))?end():p;}
+ size_type count(const K& k) const
+ {Paircc_ Ans_ = equal_range(k);
+ size_type n = std::distance(Ans_.first, Ans_.second);
+ return (n); }
+ iterator lower_bound(const K& k)
+ {return std::lower_bound(begin(), end(), k, key_compare_); }
+ const_iterator lower_bound(const K& k) const
+ {return std::lower_bound(begin(), end(), k, key_compare_); }
+ iterator upper_bound(const K& k)
+ {return std::upper_bound(begin(), end(), k, key_compare_); }
+ const_iterator upper_bound(const K& k) const
+ {return std::upper_bound(begin(), end(), k, key_compare_); }
+ Pairii_ equal_range(const K& k)
+ {return std::equal_range(begin(), end(), k, key_compare_); }
+ Paircc_ equal_range(const K& k) const
+ {return std::equal_range(begin(), end(), k, key_compare_); }
+
+/*functions for use with direct std::vector-access*/
+ Cont& get_container()
+ {return vec_;}
+ void sort()//restore sorted order after low level access
+ { std::sort(vec_.begin(),vec_.end(),key_compare_);
+ if( bNoDuplicates ){
+ vec_.erase(Unique_(),vec_.end());
+ }
+ }
+ void stable_sort()//restore sorted order after low level access
+ { std::stable_sort(vec_.begin(),vec_.end(),key_compare_);
+ if( bNoDuplicates ){
+ erase(Unique_(),end());
+ }
+ }
+protected:
+ iterator Unique_()
+ { iterator front_= vec_.begin(),out_= vec_.end(),end_=vec_.end();
+ bool bCopy_= false;
+ for(iterator prev_; (prev_=front_)!=end_ && ++front_!=end_; ){
+ if( key_compare_(*prev_,*front_)){
+ if(bCopy_){
+ *out_= *front_;
+ out_++;
+ }
+ }else{
+ if(!bCopy_){out_=front_;bCopy_=true;}
+ }
+ }
+ return out_;
+ }
+ iterator InsertImpl_(iterator p,const value_type& x)
+ {return vec_.insert(p,x);}
+ bool KeyCompare_Leq_(const K& ty0,const K& ty1)
+ {return !key_compare_(ty1,ty0);}
+ bool KeyCompare_Geq_(const K& ty0,const K& ty1)
+ {return !key_compare_(ty0,ty1);}
+ bool KeyCompare_Gt_(const K& ty0,const K& ty1)
+ {return key_compare_(ty1,ty0);}
+
+ key_compare key_compare_;
+ Cont vec_;
+};
+
+
+template<class K,bool bNoDuplicates,class Pr, class A> inline
+ bool operator==(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
+ const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
+ {return x.Eq_(Y_); }
+template<class K,bool bNoDuplicates,class Pr, class A> inline
+ bool operator!=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
+ const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
+ {return !(x == Y_); }
+template<class K,bool bNoDuplicates,class Pr, class A> inline
+ bool operator<(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
+ const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
+ {return x.Lt_(Y_);}
+template<class K,bool bNoDuplicates,class Pr,class A> inline
+ bool operator>(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
+ const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
+ {return Y_ < x; }
+template<class K,bool bNoDuplicates,class Pr, class A> inline
+ bool operator<=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
+ const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
+ {return !(Y_ < x); }
+template<class K, bool bNoDuplicates,class Pr,class A> inline
+ bool operator>=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
+ const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
+ {return (!(x < Y_)); }
+}
+#pragma warning(pop)
+#pragma pack(pop)
+#elif VERSION_SORTED_VECTOR_ != 0x00010010
+#error You have included two sorted_vector.h with different version numbers
+#endif