interprocess/test/set_test.hpp
2015-06-09 14:53:24 +02:00

595 lines
21 KiB
C++

////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2012. 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.
//
////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_TEST_SET_TEST_HEADER
#define BOOST_INTERPROCESS_TEST_SET_TEST_HEADER
#include <boost/interprocess/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include "print_container.hpp"
#include <boost/move/utility_core.hpp>
#include "get_process_id_name.hpp"
#include <functional>
namespace boost{
namespace interprocess{
namespace test{
template<class ManagedSharedMemory
,class MyShmSet
,class MyStdSet
,class MyShmMultiSet
,class MyStdMultiSet>
int set_test ()
{
typedef typename MyShmSet::value_type IntType;
const int memsize = 65536;
const char *const shMemName = test::get_process_id_name();
const int max = 100;
try{
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
segment.reserve_named_objects(100);
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmSet *shmset =
segment.template construct<MyShmSet>("MyShmSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset = new MyStdSet;
MyShmMultiSet *shmmultiset =
segment.template construct<MyShmMultiSet>("MyShmMultiSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
//Test construction from a range
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i/2;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect3[i] = boost::move(move_me);
}
MyShmSet *shmset2 =
segment.template construct<MyShmSet>("MyShmSet2")
( ::boost::make_move_iterator(&aux_vect[0])
, ::boost::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset2 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyShmMultiSet *shmmultiset2 =
segment.template construct<MyShmMultiSet>("MyShmMultiSet2")
( ::boost::make_move_iterator(&aux_vect3[0])
, ::boost::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset2, stdset2)){
std::cout << "Error in construct<MyShmSet>(MyShmSet2)" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset2, stdmultiset2)){
std::cout << "Error in construct<MyShmMultiSet>(MyShmMultiSet2)" << std::endl;
return 1;
}
//ordered range insertion
for(int i = 0; i < 50; ++i){
IntType move_me(i);
aux_vect[i] = boost::move(move_me);
}
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i;
}
for(int i = 0; i < 50; ++i){
IntType move_me(i);
aux_vect3[i] = boost::move(move_me);
}
MyShmSet *shmset3 =
segment.template construct<MyShmSet>("MyShmSet3")
( ordered_unique_range
, ::boost::make_move_iterator(&aux_vect[0])
, ::boost::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset3 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyShmMultiSet *shmmultiset3 =
segment.template construct<MyShmMultiSet>("MyShmMultiSet3")
( ordered_range
, ::boost::make_move_iterator(&aux_vect3[0])
, ::boost::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset3 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset3, stdset3)){
std::cout << "Error in construct<MyShmSet>(MyShmSet3)" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset3, stdmultiset3)){
std::cout << "Error in construct<MyShmMultiSet>(MyShmMultiSet3)" << std::endl;
return 1;
}
segment.destroy_ptr(shmset2);
segment.destroy_ptr(shmmultiset2);
delete stdset2;
delete stdmultiset2;
segment.destroy_ptr(shmset3);
segment.destroy_ptr(shmmultiset3);
delete stdset3;
delete stdmultiset3;
}
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
return 1;
}
for(int i = 0; i < max/2; ++i){
IntType move_me(i);
shmset->insert(boost::move(move_me));
stdset->insert(i);
IntType move_me2(i);
shmmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
return 1;
}
//
shmset->insert(IntType(i));
stdset->insert(i);
shmmultiset->insert(IntType(i));
stdmultiset->insert(i);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
return 1;
}
}
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(boost::move(move_me)" << std::endl;
return 1;
}
typename MyShmSet::iterator it;
typename MyShmSet::const_iterator cit = it;
(void)cit;
shmset->erase(shmset->begin()++);
stdset->erase(stdset->begin()++);
shmmultiset->erase(shmmultiset->begin()++);
stdmultiset->erase(stdmultiset->begin()++);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->erase(shmset->begin()++)" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->erase(shmmultiset->begin()++)" << std::endl;
return 1;
}
shmset->erase(shmset->begin());
stdset->erase(stdset->begin());
shmmultiset->erase(shmmultiset->begin());
stdmultiset->erase(stdmultiset->begin());
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->erase(shmset->begin())" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->erase(shmmultiset->begin())" << std::endl;
return 1;
}
//Swapping test
std::less<IntType> lessfunc;
MyShmSet tmpshmeset2 (lessfunc, segment.get_segment_manager());
MyStdSet tmpstdset2;
MyShmMultiSet tmpshmemultiset2(lessfunc, segment.get_segment_manager());
MyStdMultiSet tmpstdmultiset2;
shmset->swap(tmpshmeset2);
stdset->swap(tmpstdset2);
shmmultiset->swap(tmpshmemultiset2);
stdmultiset->swap(tmpstdmultiset2);
shmset->swap(tmpshmeset2);
stdset->swap(tmpstdset2);
shmmultiset->swap(tmpshmemultiset2);
stdmultiset->swap(tmpstdmultiset2);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->swap(tmpshmeset2)" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->swap(tmpshmemultiset2)" << std::endl;
return 1;
}
//Insertion from other container
//Initialize values
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = boost::move(move_me);
}
shmset->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
shmmultiset->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::make_move_iterator(aux_vect3 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(::boost::make_move_iterator(&aux_vect[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(::boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
return 1;
}
for(int i = 0, j = static_cast<int>(shmset->size()); i < j; ++i){
IntType erase_me(i);
shmset->erase(erase_me);
stdset->erase(i);
shmmultiset->erase(erase_me);
stdmultiset->erase(i);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->erase(erase_me)" << shmset->size() << " " << stdset->size() << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->erase(erase_me)" << std::endl;
return 1;
}
}
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = boost::move(move_me);
}
IntType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect4[i] = boost::move(move_me);
}
IntType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect5[i] = boost::move(move_me);
}
shmset->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
shmset->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::make_move_iterator(aux_vect3 + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
stdset->insert(aux_vect2, aux_vect2 + 50);
shmmultiset->insert(::boost::make_move_iterator(&aux_vect4[0]), ::boost::make_move_iterator(aux_vect4 + 50));
shmmultiset->insert(::boost::make_move_iterator(&aux_vect5[0]), ::boost::make_move_iterator(aux_vect5 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(::boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(::boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
return 1;
}
shmset->erase(*shmset->begin());
stdset->erase(*stdset->begin());
shmmultiset->erase(*shmmultiset->begin());
stdmultiset->erase(*stdmultiset->begin());
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->erase(*shmset->begin())" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->erase(*shmmultiset->begin())" << std::endl;
return 1;
}
}
for(int i = 0; i < max/2; ++i){
IntType move_me(i);
shmset->insert(shmset->begin(), boost::move(move_me));
stdset->insert(stdset->begin(), i);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2));
stdmultiset->insert(stdmultiset->begin(), i);
//
shmset->insert(shmset->begin(), IntType(i));
stdset->insert(stdset->begin(), i);
shmmultiset->insert(shmmultiset->begin(), IntType(i));
stdmultiset->insert(stdmultiset->begin(), i);
}
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(boost::move(move_me)) try 2" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(boost::move(move_me2)) try 2" << std::endl;
return 1;
}
for(int i = 0; i < max; ++i){
{
IntType move_me(i);
shmset->insert(shmset->begin(), boost::move(move_me));
stdset->insert(stdset->begin(), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2));
stdmultiset->insert(stdmultiset->begin(), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(shmset->begin(), boost::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2))" << std::endl;
return 1;
}
IntType move_me3(i);
shmset->insert(shmset->end(), boost::move(move_me3));
stdset->insert(stdset->end(), i);
IntType move_me4(i);
shmmultiset->insert(shmmultiset->end(), boost::move(move_me4));
stdmultiset->insert(stdmultiset->end(), i);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(shmset->end(), boost::move(move_me3))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(shmmultiset->end(), boost::move(move_me4))" << std::endl;
return 1;
}
}
{
IntType move_me(i);
shmset->insert(shmset->upper_bound(move_me), boost::move(move_me));
stdset->insert(stdset->upper_bound(i), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::move(move_me2));
stdmultiset->insert(stdmultiset->upper_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(shmset->upper_bound(move_me), boost::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::move(move_me2))" << std::endl;
return 1;
}
}
{
IntType move_me(i);
IntType move_me2(i);
shmset->insert(shmset->lower_bound(move_me), boost::move(move_me2));
stdset->insert(stdset->lower_bound(i), i);
//PrintContainers(shmset, stdset);
move_me2 = i;
shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::move(move_me2));
stdmultiset->insert(stdmultiset->lower_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset)){
std::cout << "Error in shmset->insert(shmset->lower_bound(move_me), boost::move(move_me2))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
std::cout << "Error in shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::move(move_me2))" << std::endl;
return 1;
}
}
}
//Compare count with std containers
for(int i = 0; i < max; ++i){
IntType count_me(i);
if(shmset->count(count_me) != stdset->count(i)){
return -1;
}
if(shmmultiset->count(count_me) != stdmultiset->count(i)){
return -1;
}
}
//Now do count exercise
shmset->erase(shmset->begin(), shmset->end());
shmmultiset->erase(shmmultiset->begin(), shmmultiset->end());
shmset->clear();
shmmultiset->clear();
for(int j = 0; j < 3; ++j)
for(int i = 0; i < 100; ++i){
IntType move_me(i);
shmset->insert(boost::move(move_me));
IntType move_me2(i);
shmmultiset->insert(boost::move(move_me2));
IntType count_me(i);
if(shmset->count(count_me) != typename MyShmMultiSet::size_type(1)){
std::cout << "Error in shmset->count(count_me)" << std::endl;
return 1;
}
if(shmmultiset->count(count_me) != typename MyShmMultiSet::size_type(j+1)){
std::cout << "Error in shmmultiset->count(count_me)" << std::endl;
return 1;
}
}
segment.template destroy<MyShmSet>("MyShmSet");
delete stdset;
segment.destroy_ptr(shmmultiset);
delete stdmultiset;
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated()){
std::cout << "Error in segment.all_memory_deallocated()" << std::endl;
return 1;
}
}
catch(...){
shared_memory_object::remove(shMemName);
throw;
}
shared_memory_object::remove(shMemName);
return 0;
}
template<class ManagedSharedMemory
,class MyShmSet
,class MyStdSet
,class MyShmMultiSet
,class MyStdMultiSet>
int set_test_copyable ()
{
typedef typename MyShmSet::value_type IntType;
const int memsize = 65536;
const char *const shMemName = test::get_process_id_name();
const int max = 100;
try{
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
segment.reserve_named_objects(100);
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmSet *shmset =
segment.template construct<MyShmSet>("MyShmSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset = new MyStdSet;
MyShmMultiSet *shmmultiset =
segment.template construct<MyShmMultiSet>("MyShmMultiSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
for(int i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(boost::move(move_me));
stdset->insert(i);
IntType move_me2(i);
shmmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
{
//Now, test copy constructor
MyShmSet shmsetcopy(*shmset);
MyStdSet stdsetcopy(*stdset);
if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
return 1;
MyShmMultiSet shmmsetcopy(*shmmultiset);
MyStdMultiSet stdmsetcopy(*stdmultiset);
if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
return 1;
//And now assignment
shmsetcopy = *shmset;
stdsetcopy = *stdset;
if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
return 1;
shmmsetcopy = *shmmultiset;
stdmsetcopy = *stdmultiset;
if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
return 1;
}
segment.destroy_ptr(shmset);
segment.destroy_ptr(shmmultiset);
delete stdset;
delete stdmultiset;
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return 1;
}
catch(...){
shared_memory_object::remove(shMemName);
throw;
}
shared_memory_object::remove(shMemName);
return 0;
}
} //namespace test{
} //namespace interprocess{
} //namespace boost{
#include <boost/interprocess/detail/config_end.hpp>
#endif