| ////////////////////////////////////////////////////////////////////////////// |
| // |
| // (C) Copyright Ion Gaztanaga 2004-2009. 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/interprocess for documentation. |
| // |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| #include <boost/interprocess/detail/config_begin.hpp> |
| #include <boost/interprocess/managed_shared_memory.hpp> |
| #include <boost/interprocess/allocators/allocator.hpp> |
| #include <boost/interprocess/containers/vector.hpp> |
| #include <boost/interprocess/containers/string.hpp> |
| #include <boost/interprocess/offset_ptr.hpp> |
| #include <string> |
| #include <vector> |
| #include <algorithm> |
| #include <cstring> |
| #include <cstdio> |
| #include <cstddef> |
| #include <new> |
| #include "dummy_test_allocator.hpp" |
| #include "check_equal_containers.hpp" |
| #include "expand_bwd_test_allocator.hpp" |
| #include "expand_bwd_test_template.hpp" |
| #include "allocator_v1.hpp" |
| #include "get_process_id_name.hpp" |
| |
| using namespace boost::interprocess; |
| |
| typedef test::dummy_test_allocator<char> DummyCharAllocator; |
| typedef basic_string<char, std::char_traits<char>, DummyCharAllocator> DummyString; |
| typedef test::dummy_test_allocator<DummyString> DummyStringAllocator; |
| typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator; |
| typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString; |
| typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator; |
| |
| //Explicit instantiations of interprocess::basic_string |
| template class basic_string<char, std::char_traits<char>, DummyCharAllocator>; |
| template class basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator>; |
| //Explicit instantiation of interprocess::vectors of interprocess::strings |
| template class vector<DummyString, DummyStringAllocator>; |
| template class vector<DummyWString, DummyWStringAllocator>; |
| |
| struct StringEqual |
| { |
| template<class Str1, class Str2> |
| bool operator ()(const Str1 &string1, const Str2 &string2) const |
| { |
| if(string1.size() != string2.size()) |
| return false; |
| return std::char_traits<typename Str1::value_type>::compare |
| (string1.c_str(), string2.c_str(), string1.size()) == 0; |
| } |
| }; |
| |
| //Function to check if both lists are equal |
| template<class StrVector1, class StrVector2> |
| bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2) |
| { |
| StringEqual comp; |
| return std::equal(strvect1->begin(), strvect1->end(), |
| strvect2->begin(), comp); |
| } |
| |
| template<class CharType, template<class T, class SegmentManager> class AllocatorType > |
| int string_test() |
| { |
| typedef std::allocator<CharType> StdAllocatorChar; |
| typedef std::basic_string<CharType, std::char_traits<CharType>, StdAllocatorChar> StdString; |
| typedef std::allocator<StdString> StdStringAllocator; |
| typedef vector<StdString, StdStringAllocator> StdStringVector; |
| typedef AllocatorType<CharType, managed_shared_memory::segment_manager> ShmemAllocatorChar; |
| typedef basic_string<CharType, std::char_traits<CharType>, ShmemAllocatorChar> ShmString; |
| typedef AllocatorType<ShmString, managed_shared_memory::segment_manager> ShmemStringAllocator; |
| typedef vector<ShmString, ShmemStringAllocator> ShmStringVector; |
| |
| const int MaxSize = 100; |
| |
| std::string process_name; |
| test::get_process_id_name(process_name); |
| |
| //Create shared memory |
| shared_memory_object::remove(process_name.c_str()); |
| { |
| managed_shared_memory segment |
| (create_only, |
| process_name.c_str(),//segment name |
| 65536); //segment size in bytes |
| |
| ShmemAllocatorChar shmallocator (segment.get_segment_manager()); |
| |
| //Initialize vector with a range or iterators and allocator |
| ShmStringVector *shmStringVect = |
| segment.construct<ShmStringVector> |
| (anonymous_instance, std::nothrow) //object name |
| (shmallocator); |
| |
| StdStringVector *stdStringVect = new StdStringVector; |
| |
| ShmString auxShmString (segment.get_segment_manager()); |
| StdString auxStdString(StdString(auxShmString.begin(), auxShmString.end() )); |
| |
| CharType buffer [20]; |
| |
| //First, push back |
| for(int i = 0; i < MaxSize; ++i){ |
| auxShmString = "String"; |
| auxStdString = "String"; |
| std::sprintf(buffer, "%i", i); |
| auxShmString += buffer; |
| auxStdString += buffer; |
| shmStringVect->push_back(auxShmString); |
| stdStringVect->push_back(auxStdString); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
| return 1; |
| } |
| |
| //Now push back moving |
| for(int i = 0; i < MaxSize; ++i){ |
| auxShmString = "String"; |
| auxStdString = "String"; |
| std::sprintf(buffer, "%i", i); |
| auxShmString += buffer; |
| auxStdString += buffer; |
| shmStringVect->push_back(boost::interprocess::move(auxShmString)); |
| stdStringVect->push_back(auxStdString); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
| return 1; |
| } |
| |
| //push front |
| for(int i = 0; i < MaxSize; ++i){ |
| auxShmString = "String"; |
| auxStdString = "String"; |
| std::sprintf(buffer, "%i", i); |
| auxShmString += buffer; |
| auxStdString += buffer; |
| shmStringVect->insert(shmStringVect->begin(), auxShmString); |
| stdStringVect->insert(stdStringVect->begin(), auxStdString); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
| return 1; |
| } |
| |
| //Now push front moving |
| for(int i = 0; i < MaxSize; ++i){ |
| auxShmString = "String"; |
| auxStdString = "String"; |
| std::sprintf(buffer, "%i", i); |
| auxShmString += buffer; |
| auxStdString += buffer; |
| shmStringVect->insert(shmStringVect->begin(), boost::interprocess::move(auxShmString)); |
| stdStringVect->insert(stdStringVect->begin(), auxStdString); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
| return 1; |
| } |
| |
| //Now test long and short representation swapping |
| auxShmString = "String"; |
| auxStdString = "String"; |
| ShmString shm_swapper(segment.get_segment_manager()); |
| StdString std_swapper; |
| shm_swapper.swap(auxShmString); |
| std_swapper.swap(auxStdString); |
| if(!StringEqual()(auxShmString, auxStdString)) |
| return 1; |
| if(!StringEqual()(shm_swapper, std_swapper)) |
| return 1; |
| |
| shm_swapper.swap(auxShmString); |
| std_swapper.swap(auxStdString); |
| if(!StringEqual()(auxShmString, auxStdString)) |
| return 1; |
| if(!StringEqual()(shm_swapper, std_swapper)) |
| return 1; |
| |
| auxShmString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; |
| auxStdString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; |
| shm_swapper = ShmString (segment.get_segment_manager()); |
| std_swapper = StdString (); |
| shm_swapper.swap(auxShmString); |
| std_swapper.swap(auxStdString); |
| if(!StringEqual()(auxShmString, auxStdString)) |
| return 1; |
| if(!StringEqual()(shm_swapper, std_swapper)) |
| return 1; |
| |
| shm_swapper.swap(auxShmString); |
| std_swapper.swap(auxStdString); |
| if(!StringEqual()(auxShmString, auxStdString)) |
| return 1; |
| if(!StringEqual()(shm_swapper, std_swapper)) |
| return 1; |
| |
| //No sort |
| std::sort(shmStringVect->begin(), shmStringVect->end()); |
| std::sort(stdStringVect->begin(), stdStringVect->end()); |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
| |
| const CharType prefix [] = "Prefix"; |
| const int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1; |
| const CharType sufix [] = "Suffix"; |
| |
| for(int i = 0; i < MaxSize; ++i){ |
| (*shmStringVect)[i].append(sufix); |
| (*stdStringVect)[i].append(sufix); |
| (*shmStringVect)[i].insert((*shmStringVect)[i].begin(), |
| prefix, prefix + prefix_size); |
| (*stdStringVect)[i].insert((*stdStringVect)[i].begin(), |
| prefix, prefix + prefix_size); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
| |
| for(int i = 0; i < MaxSize; ++i){ |
| std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end()); |
| std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
| |
| for(int i = 0; i < MaxSize; ++i){ |
| std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end()); |
| std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
| |
| for(int i = 0; i < MaxSize; ++i){ |
| std::sort(shmStringVect->begin(), shmStringVect->end()); |
| std::sort(stdStringVect->begin(), stdStringVect->end()); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
| |
| for(int i = 0; i < MaxSize; ++i){ |
| (*shmStringVect)[i].replace((*shmStringVect)[i].begin(), |
| (*shmStringVect)[i].end(), |
| "String"); |
| (*stdStringVect)[i].replace((*stdStringVect)[i].begin(), |
| (*stdStringVect)[i].end(), |
| "String"); |
| } |
| |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
| |
| shmStringVect->erase(std::unique(shmStringVect->begin(), shmStringVect->end()), |
| shmStringVect->end()); |
| stdStringVect->erase(std::unique(stdStringVect->begin(), stdStringVect->end()), |
| stdStringVect->end()); |
| if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
| |
| //When done, delete vector |
| segment.destroy_ptr(shmStringVect); |
| delete stdStringVect; |
| } |
| shared_memory_object::remove(process_name.c_str()); |
| return 0; |
| } |
| |
| bool test_expand_bwd() |
| { |
| //Now test all back insertion possibilities |
| typedef test::expand_bwd_test_allocator<char> |
| allocator_type; |
| typedef basic_string<char, std::char_traits<char>, allocator_type> |
| string_type; |
| return test::test_all_expand_bwd<string_type>(); |
| } |
| |
| int main() |
| { |
| if(string_test<char, allocator>()){ |
| return 1; |
| } |
| |
| if(string_test<char, test::allocator_v1>()){ |
| return 1; |
| } |
| |
| if(!test_expand_bwd()) |
| return 1; |
| |
| return 0; |
| } |
| |
| #include <boost/interprocess/detail/config_end.hpp> |