////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include "dummy_test_allocator.hpp" #include "check_equal_containers.hpp" #include "expand_bwd_test_allocator.hpp" #include "expand_bwd_test_template.hpp" #include "propagate_allocator_test.hpp" using namespace boost::container; typedef test::dummy_test_allocator DummyCharAllocator; typedef basic_string, DummyCharAllocator> DummyString; typedef test::dummy_test_allocator DummyStringAllocator; typedef test::dummy_test_allocator DummyWCharAllocator; typedef basic_string, DummyWCharAllocator> DummyWString; typedef test::dummy_test_allocator DummyWStringAllocator; namespace boost { namespace container { //Explicit instantiations of container::basic_string template class basic_string, DummyCharAllocator>; template class basic_string, DummyWCharAllocator>; template class basic_string, test::simple_allocator >; template class basic_string, test::simple_allocator >; template class basic_string, std::allocator >; template class basic_string, std::allocator >; //Explicit instantiation of container::vectors of container::strings template class vector; template class vector; }} struct StringEqual { template bool operator ()(const Str1 &string1, const Str2 &string2) const { if(string1.size() != string2.size()) return false; return std::char_traits::compare (string1.c_str(), string2.c_str(), string1.size()) == 0; } }; //Function to check if both lists are equal template bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2) { StringEqual comp; return std::equal(strvect1->begin(), strvect1->end(), strvect2->begin(), comp); } template struct string_literals; template<> struct string_literals { static const char *String() { return "String"; } static const char *Prefix() { return "Prefix"; } static const char *Suffix() { return "Suffix"; } static const char *LongString() { return "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } static void sprintf_number(char *buf, int number) { std::sprintf(buf, "%i", number); } }; template<> struct string_literals { static const wchar_t *String() { return L"String"; } static const wchar_t *Prefix() { return L"Prefix"; } static const wchar_t *Suffix() { return L"Suffix"; } static const wchar_t *LongString() { return L"LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } static void sprintf_number(wchar_t *buffer, unsigned int number) { //For compilers without wsprintf, print it backwards const wchar_t *digits = L"0123456789"; wchar_t *buf = buffer; while(1){ int rem = number % 10; number = number / 10; *buf = digits[rem]; ++buf; if(!number){ *buf = 0; break; } } } }; template int string_test() { typedef std::basic_string StdString; typedef vector StdStringVector; typedef basic_string BoostString; typedef vector BoostStringVector; const int MaxSize = 100; //Create shared memory { BoostStringVector *boostStringVect = new BoostStringVector; StdStringVector *stdStringVect = new StdStringVector; BoostString auxBoostString; StdString auxStdString(StdString(auxBoostString.begin(), auxBoostString.end() )); CharType buffer [20]; //First, push back for(int i = 0; i < MaxSize; ++i){ auxBoostString = string_literals::String(); auxStdString = string_literals::String(); string_literals::sprintf_number(buffer, i); auxBoostString += buffer; auxStdString += buffer; boostStringVect->push_back(auxBoostString); stdStringVect->push_back(auxStdString); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ return 1; } //Now push back moving for(int i = 0; i < MaxSize; ++i){ auxBoostString = string_literals::String(); auxStdString = string_literals::String(); string_literals::sprintf_number(buffer, i); auxBoostString += buffer; auxStdString += buffer; boostStringVect->push_back(boost::move(auxBoostString)); stdStringVect->push_back(auxStdString); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ return 1; } //push front for(int i = 0; i < MaxSize; ++i){ auxBoostString = string_literals::String(); auxStdString = string_literals::String(); string_literals::sprintf_number(buffer, i); auxBoostString += buffer; auxStdString += buffer; boostStringVect->insert(boostStringVect->begin(), auxBoostString); stdStringVect->insert(stdStringVect->begin(), auxStdString); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ return 1; } //Now push front moving for(int i = 0; i < MaxSize; ++i){ auxBoostString = string_literals::String(); auxStdString = string_literals::String(); string_literals::sprintf_number(buffer, i); auxBoostString += buffer; auxStdString += buffer; boostStringVect->insert(boostStringVect->begin(), boost::move(auxBoostString)); stdStringVect->insert(stdStringVect->begin(), auxStdString); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ return 1; } //Now test long and short representation swapping //Short first auxBoostString = string_literals::String(); auxStdString = string_literals::String(); BoostString boost_swapper; StdString std_swapper; boost_swapper.swap(auxBoostString); std_swapper.swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) return 1; if(!StringEqual()(boost_swapper, std_swapper)) return 1; boost_swapper.swap(auxBoostString); std_swapper.swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) return 1; if(!StringEqual()(boost_swapper, std_swapper)) return 1; //Shrink_to_fit auxBoostString.shrink_to_fit(); StdString(auxStdString).swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) return 1; //Reserve + shrink_to_fit auxBoostString.reserve(boost_swapper.size()*2+1); auxStdString.reserve(std_swapper.size()*2+1); if(!StringEqual()(auxBoostString, auxStdString)) return 1; auxBoostString.shrink_to_fit(); StdString(auxStdString).swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) return 1; //Long string auxBoostString = string_literals::LongString(); auxStdString = string_literals::LongString(); boost_swapper = BoostString(); std_swapper = StdString(); boost_swapper.swap(auxBoostString); std_swapper.swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) return 1; if(!StringEqual()(boost_swapper, std_swapper)) return 1; boost_swapper.swap(auxBoostString); std_swapper.swap(auxStdString); //Shrink_to_fit auxBoostString.shrink_to_fit(); StdString(auxStdString).swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) return 1; auxBoostString.clear(); auxStdString.clear(); auxBoostString.shrink_to_fit(); StdString(auxStdString).swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) return 1; //No sort std::sort(boostStringVect->begin(), boostStringVect->end()); std::sort(stdStringVect->begin(), stdStringVect->end()); if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; const CharType *prefix = string_literals::Prefix(); const int prefix_size = std::char_traits::length(prefix); const CharType *sufix = string_literals::Suffix(); for(int i = 0; i < MaxSize; ++i){ (*boostStringVect)[i].append(sufix); (*stdStringVect)[i].append(sufix); (*boostStringVect)[i].insert((*boostStringVect)[i].begin(), prefix, prefix + prefix_size); (*stdStringVect)[i].insert((*stdStringVect)[i].begin(), prefix, prefix + prefix_size); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; for(int i = 0; i < MaxSize; ++i){ std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end()); std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; for(int i = 0; i < MaxSize; ++i){ std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end()); std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; for(int i = 0; i < MaxSize; ++i){ std::sort(boostStringVect->begin(), boostStringVect->end()); std::sort(stdStringVect->begin(), stdStringVect->end()); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; for(int i = 0; i < MaxSize; ++i){ (*boostStringVect)[i].replace((*boostStringVect)[i].begin(), (*boostStringVect)[i].end(), string_literals::String()); (*stdStringVect)[i].replace((*stdStringVect)[i].begin(), (*stdStringVect)[i].end(), string_literals::String()); } if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; boostStringVect->erase(std::unique(boostStringVect->begin(), boostStringVect->end()), boostStringVect->end()); stdStringVect->erase(std::unique(stdStringVect->begin(), stdStringVect->end()), stdStringVect->end()); if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; //Check addition { typedef std::basic_string StdString; typedef basic_string BoostString; BoostString bs2 = string_literals::String(); StdString ss2 = string_literals::String(); BoostString bs3 = string_literals::Suffix(); StdString ss3 = string_literals::Suffix(); BoostString bs4 = bs2 + bs3; StdString ss4 = ss2 + ss3; if(!StringEqual()(bs4, ss4)){ return 1; } bs4 = bs2 + BoostString(); ss4 = ss2 + StdString(); if(!StringEqual()(bs4, ss4)){ return 1; } bs4 = BoostString() + bs2; ss4 = StdString() + ss2; if(!StringEqual()(bs4, ss4)){ return 1; } bs4 = BoostString() + boost::move(bs2); ss4 = StdString() + boost::move(ss2); if(!StringEqual()(bs4, ss4)){ return 1; } bs2 = string_literals::String(); ss2 = string_literals::String(); bs4 = boost::move(bs2) + BoostString(); ss4 = boost::move(ss2) + StdString(); if(!StringEqual()(bs4, ss4)){ return 1; } bs2 = string_literals::String(); ss2 = string_literals::String(); bs4 = string_literals::Prefix() + boost::move(bs2); ss4 = string_literals::Prefix() + boost::move(ss2); if(!StringEqual()(bs4, ss4)){ return 1; } bs2 = string_literals::String(); ss2 = string_literals::String(); bs4 = boost::move(bs2) + string_literals::Suffix(); ss4 = boost::move(ss2) + string_literals::Suffix(); if(!StringEqual()(bs4, ss4)){ return 1; } bs2 = string_literals::String(); ss2 = string_literals::String(); bs4 = string_literals::Prefix() + bs2; ss4 = string_literals::Prefix() + ss2; if(!StringEqual()(bs4, ss4)){ return 1; } bs2 = string_literals::String(); ss2 = string_literals::String(); bs4 = bs2 + string_literals::Suffix(); ss4 = ss2 + string_literals::Suffix(); if(!StringEqual()(bs4, ss4)){ return 1; } } //When done, delete vector delete boostStringVect; delete stdStringVect; } return 0; } bool test_expand_bwd() { //Now test all back insertion possibilities typedef test::expand_bwd_test_allocator allocator_type; typedef basic_string, allocator_type> string_type; return test::test_all_expand_bwd(); } template class string_propagate_test_wrapper : public basic_string, A> { BOOST_COPYABLE_AND_MOVABLE(string_propagate_test_wrapper) typedef basic_string, A> Base; public: string_propagate_test_wrapper() : Base() {} string_propagate_test_wrapper(const string_propagate_test_wrapper &x) : Base(x) {} string_propagate_test_wrapper(BOOST_RV_REF(string_propagate_test_wrapper) x) : Base(boost::move(static_cast(x))) {} string_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(string_propagate_test_wrapper) x) { this->Base::operator=(x); return *this; } string_propagate_test_wrapper &operator=(BOOST_RV_REF(string_propagate_test_wrapper) x) { this->Base::operator=(boost::move(static_cast(x))); return *this; } void swap(string_propagate_test_wrapper &x) { this->Base::swap(x); } }; int main() { if(string_test()){ return 1; } if(string_test()){ return 1; } if(!test_expand_bwd()) return 1; if(!boost::container::test::test_propagate_allocator()) return 1; return 0; } #include