diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 3e2fb25..ed2d7da 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -1,4 +1,4 @@ -# Boost.Interproces library documentation Jamfile --------------------------------- +# Boost.Interprocess library documentation Jamfile --------------------------------- # # Copyright Ion Gaztañaga 2005-2006. Use, modification and # distribution is subject to the Boost Software License, Version diff --git a/doc/code/Attic/doc_anonymous_conditionA.cpp b/doc/code/Attic/doc_anonymous_conditionA.cpp index 65bfba5..aba35bb 100644 --- a/doc/code/Attic/doc_anonymous_conditionA.cpp +++ b/doc/code/Attic/doc_anonymous_conditionA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_anonymous_conditionB.cpp b/doc/code/Attic/doc_anonymous_conditionB.cpp index b359c47..a943c67 100644 --- a/doc/code/Attic/doc_anonymous_conditionB.cpp +++ b/doc/code/Attic/doc_anonymous_conditionB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,13 +17,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_anonymous_mutexA.cpp b/doc/code/Attic/doc_anonymous_mutexA.cpp index 7644b67..5cb33a9 100644 --- a/doc/code/Attic/doc_anonymous_mutexA.cpp +++ b/doc/code/Attic/doc_anonymous_mutexA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_mutex_shared_data.hpp" #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_anonymous_mutexB.cpp b/doc/code/Attic/doc_anonymous_mutexB.cpp index 03bcec0..8b5c150 100644 --- a/doc/code/Attic/doc_anonymous_mutexB.cpp +++ b/doc/code/Attic/doc_anonymous_mutexB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_mutex_shared_data.hpp" #include @@ -13,13 +14,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_anonymous_semaphoreA.cpp b/doc/code/Attic/doc_anonymous_semaphoreA.cpp index 296a596..5cc178b 100644 --- a/doc/code/Attic/doc_anonymous_semaphoreA.cpp +++ b/doc/code/Attic/doc_anonymous_semaphoreA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_semaphore_shared_data.hpp" @@ -14,7 +15,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -23,7 +24,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_anonymous_semaphoreB.cpp b/doc/code/Attic/doc_anonymous_semaphoreB.cpp index 2ffa6b4..e53e238 100644 --- a/doc/code/Attic/doc_anonymous_semaphoreB.cpp +++ b/doc/code/Attic/doc_anonymous_semaphoreB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_semaphore_shared_data.hpp" @@ -11,13 +12,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_anonymous_upgradable_mutexA.cpp b/doc/code/Attic/doc_anonymous_upgradable_mutexA.cpp index 1d10f20..57df06d 100644 --- a/doc/code/Attic/doc_anonymous_upgradable_mutexA.cpp +++ b/doc/code/Attic/doc_anonymous_upgradable_mutexA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_upgradable_mutex_shared_data.hpp" #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_anonymous_upgradable_mutexB.cpp b/doc/code/Attic/doc_anonymous_upgradable_mutexB.cpp index 72812d6..7eb945c 100644 --- a/doc/code/Attic/doc_anonymous_upgradable_mutexB.cpp +++ b/doc/code/Attic/doc_anonymous_upgradable_mutexB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_upgradable_mutex_shared_data.hpp" #include @@ -13,13 +14,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_cont.cpp b/doc/code/Attic/doc_cont.cpp index c3d7d49..5b6f3f9 100644 --- a/doc/code/Attic/doc_cont.cpp +++ b/doc/code/Attic/doc_cont.cpp @@ -2,6 +2,7 @@ #include #include + #include #include int main () diff --git a/doc/code/Attic/doc_move_containers.cpp b/doc/code/Attic/doc_move_containers.cpp new file mode 100644 index 0000000..6c0006e --- /dev/null +++ b/doc/code/Attic/doc_move_containers.cpp @@ -0,0 +1,69 @@ + #include + #include + + #include + #include + #include + #include + #include + + int main () + { + using namespace boost::interprocess; + + //Typedefs + typedef managed_shared_memory::segment_manager SegmentManager; + typedef allocator CharAllocator; + typedef basic_string + ,CharAllocator> MyShmString; + typedef allocator StringAllocator; + typedef vector MyShmStringVector; + + //Remove old shared memory and create new one + shared_memory_object::remove("myshm"); + managed_shared_memory shm(create_only, "myshm", 10000); + + //Create allocators + CharAllocator charallocator (shm.get_segment_manager()); + StringAllocator stringallocator(shm.get_segment_manager()); + + //Create a vector of strings in shared memory. + MyShmStringVector *myshmvector = + shm.construct("myshmvector")(stringallocator); + + //Insert 50 strings in shared memory. The strings will be allocated + //only once and no string copy-constructor will be called when inserting + //strings, leading to a great performance. + MyShmString string_to_compare(charallocator); + string_to_compare = "this is a long, long, long, long, long, long, string..."; + + myshmvector->reserve(50); + for(int i = 0; i < 50; ++i){ + MyShmString move_me(string_to_compare); + //In the following line, no string copy-constructor will be called. + //"move_me"'s contents will be transferred to the string created in + //the vector + myshmvector->push_back(move(move_me)); + + //The source string is in default constructed state + assert(move_me.empty()); + + //The newly created string will be equal to the "move_me"'s old contents + assert(myshmvector->back() == string_to_compare); + } + + //Now erase a string... + myshmvector->pop_back(); + + //...And insert one in the first position. + //No string copy-constructor or assignments will be called, but + //move constructors and move-assignments. No memory allocation + //function will be called in this operations!! + myshmvector->insert(myshmvector->begin(), move(string_to_compare)); + + //Destroy vector. This will free all strings that the vector contains + shm.destroy_ptr(myshmvector); + return 0; + } + + #include diff --git a/doc/code/Attic/doc_named_conditionA.cpp b/doc/code/Attic/doc_named_conditionA.cpp index 65bfba5..aba35bb 100644 --- a/doc/code/Attic/doc_named_conditionA.cpp +++ b/doc/code/Attic/doc_named_conditionA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_named_conditionB.cpp b/doc/code/Attic/doc_named_conditionB.cpp index b359c47..a943c67 100644 --- a/doc/code/Attic/doc_named_conditionB.cpp +++ b/doc/code/Attic/doc_named_conditionB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,13 +17,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_named_mutex.cpp b/doc/code/Attic/doc_named_mutex.cpp index efca8a4..999088d 100644 --- a/doc/code/Attic/doc_named_mutex.cpp +++ b/doc/code/Attic/doc_named_mutex.cpp @@ -16,7 +16,7 @@ //Do some operations... - //Write to console atomically + //Write to file atomically scoped_lock lock(mutex); file << "Process name, "; file << "This is iteration #" << i; @@ -29,4 +29,4 @@ } return 0; - } \ No newline at end of file + } diff --git a/doc/code/Attic/doc_shared_memory.cpp b/doc/code/Attic/doc_shared_memory.cpp index 5ee5441..a830dbf 100644 --- a/doc/code/Attic/doc_shared_memory.cpp +++ b/doc/code/Attic/doc_shared_memory.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include @@ -13,7 +14,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -22,7 +23,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/Attic/doc_shared_memory2.cpp b/doc/code/Attic/doc_shared_memory2.cpp index 92ab95e..f997cc3 100644 --- a/doc/code/Attic/doc_shared_memory2.cpp +++ b/doc/code/Attic/doc_shared_memory2.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include @@ -10,13 +11,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_only //read-write mode + ,read_only //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_only //Map it as read-write + ,read_only //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_conditionA.cpp b/doc/code/doc_anonymous_conditionA.cpp index 65bfba5..aba35bb 100644 --- a/doc/code/doc_anonymous_conditionA.cpp +++ b/doc/code/doc_anonymous_conditionA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_conditionB.cpp b/doc/code/doc_anonymous_conditionB.cpp index b359c47..a943c67 100644 --- a/doc/code/doc_anonymous_conditionB.cpp +++ b/doc/code/doc_anonymous_conditionB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,13 +17,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_mutexA.cpp b/doc/code/doc_anonymous_mutexA.cpp index 7644b67..5cb33a9 100644 --- a/doc/code/doc_anonymous_mutexA.cpp +++ b/doc/code/doc_anonymous_mutexA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_mutex_shared_data.hpp" #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_mutexB.cpp b/doc/code/doc_anonymous_mutexB.cpp index 03bcec0..8b5c150 100644 --- a/doc/code/doc_anonymous_mutexB.cpp +++ b/doc/code/doc_anonymous_mutexB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_mutex_shared_data.hpp" #include @@ -13,13 +14,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_semaphoreA.cpp b/doc/code/doc_anonymous_semaphoreA.cpp index 296a596..5cc178b 100644 --- a/doc/code/doc_anonymous_semaphoreA.cpp +++ b/doc/code/doc_anonymous_semaphoreA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_semaphore_shared_data.hpp" @@ -14,7 +15,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -23,7 +24,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_semaphoreB.cpp b/doc/code/doc_anonymous_semaphoreB.cpp index 2ffa6b4..e53e238 100644 --- a/doc/code/doc_anonymous_semaphoreB.cpp +++ b/doc/code/doc_anonymous_semaphoreB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_anonymous_semaphore_shared_data.hpp" @@ -11,13 +12,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_upgradable_mutexA.cpp b/doc/code/doc_anonymous_upgradable_mutexA.cpp index 1d10f20..57df06d 100644 --- a/doc/code/doc_anonymous_upgradable_mutexA.cpp +++ b/doc/code/doc_anonymous_upgradable_mutexA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_upgradable_mutex_shared_data.hpp" #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_anonymous_upgradable_mutexB.cpp b/doc/code/doc_anonymous_upgradable_mutexB.cpp index 72812d6..7eb945c 100644 --- a/doc/code/doc_anonymous_upgradable_mutexB.cpp +++ b/doc/code/doc_anonymous_upgradable_mutexB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include "doc_upgradable_mutex_shared_data.hpp" #include @@ -13,13 +14,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_cont.cpp b/doc/code/doc_cont.cpp index c3d7d49..5b6f3f9 100644 --- a/doc/code/doc_cont.cpp +++ b/doc/code/doc_cont.cpp @@ -2,6 +2,7 @@ #include #include + #include #include int main () diff --git a/doc/code/doc_move_containers.cpp b/doc/code/doc_move_containers.cpp new file mode 100644 index 0000000..6c0006e --- /dev/null +++ b/doc/code/doc_move_containers.cpp @@ -0,0 +1,69 @@ + #include + #include + + #include + #include + #include + #include + #include + + int main () + { + using namespace boost::interprocess; + + //Typedefs + typedef managed_shared_memory::segment_manager SegmentManager; + typedef allocator CharAllocator; + typedef basic_string + ,CharAllocator> MyShmString; + typedef allocator StringAllocator; + typedef vector MyShmStringVector; + + //Remove old shared memory and create new one + shared_memory_object::remove("myshm"); + managed_shared_memory shm(create_only, "myshm", 10000); + + //Create allocators + CharAllocator charallocator (shm.get_segment_manager()); + StringAllocator stringallocator(shm.get_segment_manager()); + + //Create a vector of strings in shared memory. + MyShmStringVector *myshmvector = + shm.construct("myshmvector")(stringallocator); + + //Insert 50 strings in shared memory. The strings will be allocated + //only once and no string copy-constructor will be called when inserting + //strings, leading to a great performance. + MyShmString string_to_compare(charallocator); + string_to_compare = "this is a long, long, long, long, long, long, string..."; + + myshmvector->reserve(50); + for(int i = 0; i < 50; ++i){ + MyShmString move_me(string_to_compare); + //In the following line, no string copy-constructor will be called. + //"move_me"'s contents will be transferred to the string created in + //the vector + myshmvector->push_back(move(move_me)); + + //The source string is in default constructed state + assert(move_me.empty()); + + //The newly created string will be equal to the "move_me"'s old contents + assert(myshmvector->back() == string_to_compare); + } + + //Now erase a string... + myshmvector->pop_back(); + + //...And insert one in the first position. + //No string copy-constructor or assignments will be called, but + //move constructors and move-assignments. No memory allocation + //function will be called in this operations!! + myshmvector->insert(myshmvector->begin(), move(string_to_compare)); + + //Destroy vector. This will free all strings that the vector contains + shm.destroy_ptr(myshmvector); + return 0; + } + + #include diff --git a/doc/code/doc_named_conditionA.cpp b/doc/code/doc_named_conditionA.cpp index 65bfba5..aba35bb 100644 --- a/doc/code/doc_named_conditionA.cpp +++ b/doc/code/doc_named_conditionA.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,7 +17,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -25,7 +26,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_named_conditionB.cpp b/doc/code/doc_named_conditionB.cpp index b359c47..a943c67 100644 --- a/doc/code/doc_named_conditionB.cpp +++ b/doc/code/doc_named_conditionB.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include #include @@ -16,13 +17,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_named_mutex.cpp b/doc/code/doc_named_mutex.cpp index efca8a4..999088d 100644 --- a/doc/code/doc_named_mutex.cpp +++ b/doc/code/doc_named_mutex.cpp @@ -16,7 +16,7 @@ //Do some operations... - //Write to console atomically + //Write to file atomically scoped_lock lock(mutex); file << "Process name, "; file << "This is iteration #" << i; @@ -29,4 +29,4 @@ } return 0; - } \ No newline at end of file + } diff --git a/doc/code/doc_shared_memory.cpp b/doc/code/doc_shared_memory.cpp index 5ee5441..a830dbf 100644 --- a/doc/code/doc_shared_memory.cpp +++ b/doc/code/doc_shared_memory.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include @@ -13,7 +14,7 @@ shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -22,7 +23,7 @@ //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/code/doc_shared_memory2.cpp b/doc/code/doc_shared_memory2.cpp index 92ab95e..f997cc3 100644 --- a/doc/code/doc_shared_memory2.cpp +++ b/doc/code/doc_shared_memory2.cpp @@ -1,4 +1,5 @@ - #include + #include + #include #include #include @@ -10,13 +11,13 @@ shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_only //read-write mode + ,read_only //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_only //Map it as read-write + ,read_only //Map it as read-write ); //Get the address of the mapped region diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index e8048b2..a6dcc98 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -1,6 +1,6 @@ [library Interprocess [quickbook 1.4] - [version 1.0] + [version 2006-10-13] [authors [Gaztañaga, Ion]] [copyright 2005- 2006 Ion Gaztañaga] [purpose Interprocess communication utilities] @@ -60,8 +60,8 @@ memory to another process, and you are done. Let's see the example: //An special shared memory from which we are //able to allocate raw memory buffers. - //First remove any old shared memory of the same name and - //create the shared memory segment and initialize needed resources + //First remove any old shared memory of the same name, create + //the shared memory segment and initialize needed resources shared_memory_object::remove("MySharedMemory"); managed_shared_memory segment (create_only, @@ -91,6 +91,7 @@ memory to another process, and you are done. Let's see the example: In receiver process one just could write the following lines: [/ doc_ipc_messageB.cpp] + [c++] #include @@ -299,7 +300,7 @@ just if it was any other object. Just execute this first process: [c++] - #include +#include #include #include @@ -549,7 +550,7 @@ To manage shared memory, you just need to include the following header: [c++] - #include + #include [endsect] @@ -568,7 +569,7 @@ just as if it was a file: shared_memory_object shm_obj (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); * To open or create a shared memory segment: @@ -579,7 +580,7 @@ just as if it was a file: shared_memory_object shm_obj (open_or_create //open or create ,"shared_memory" //name - ,memory_mappable::read_only //read-only mode + ,read_only //read-only mode ); * To only open a shared memory segment. Throws if does not exist: @@ -590,7 +591,7 @@ just as if it was a file: shared_memory_object shm_obj (open_only //only open ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); When a shared memory object is created, its size is 0. @@ -635,7 +636,7 @@ is a `memory_mappable` object: //Map the second half of the memory mapped_region region ( shm //Memory-mappable object - , mapped_region::read_write//Access mode + , read_write//Access mode , ShmSize/2 //Offset from the beginning of shm , ShmSize-ShmSize/2 //Length of the region ); @@ -659,16 +660,17 @@ For more details regarding `mapped_region` see the [section:shared_memory_a_simple_example A Simple Example] -Let's see a simple example of shared memory use. A server process creates a file, -maps it and initializes all the bytes to a value. After that, +Let's see a simple example of shared memory use. A server process creates a +shared memory object, maps it and initializes all the bytes to a value. After that, a client process opens the shared memory, maps it, and checks that the data is correctly initialized. This is the server process: -[/ doc_shared_memory.cppW] +[/ doc_shared_memory.cpp] [c++] - #include + #include + #include #include #include @@ -676,20 +678,23 @@ that the data is correctly initialized. This is the server process: { using namespace boost::interprocess; try{ + //Erase previous shared memory + shared_memory_object::remove("shared_memory"); + //Create a shared memory object. shared_memory_object shm - (create_only //only open - ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + (create_only //only create + ,"shared_memory" //name + ,read_write //read-write mode ); - //Set the size of the shared memory segment + //Set size shm.truncate(1000); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region @@ -712,7 +717,7 @@ Now the client process: [c++] - #include + #include #include int main () @@ -721,15 +726,15 @@ Now the client process: try{ //Open already created shared memory object. shared_memory_object shm - (open_only //only create + (open_only //only open ,"shared_memory" //name - ,memory_mappable::read_only//read-only mode + ,read_only//read-only mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_only //Map it as read-only + ,read_only //Map it as read-only ); //Get the address of the mapped region @@ -822,7 +827,7 @@ To manage mapped files, you just need to include the following header: [c++] - #include + #include [endsect] @@ -837,7 +842,7 @@ achieved in [*Boost.Interprocess] creating a `file_mapping` object: using boost::interprocess; file_mapping m_file ("/usr/home/file" //filename - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); Now we can use the newly created object to create mapped regions. For more details @@ -862,7 +867,7 @@ devices that have also mapping capabilities: //Map the second half of the file mapped_region region ( m_file //Memory-mappable object - , mapped_region::read_write//Access mode + , read_write//Access mode , FileSize/2 //Offset from the beginning of shm , FileSize-FileSize/2 //Length of the region ); @@ -917,7 +922,7 @@ that the data is correctly initialized. This is the server process: [c++] - #include + #include #include #include #include @@ -938,12 +943,12 @@ that the data is correctly initialized. This is the server process: fbuf.close(); //Create a file mapping. - file_mapping m_file("file.bin", memory_mappable::read_write); + file_mapping m_file("file.bin", read_write); //Map the whole file in this process mapped_region region (m_file //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); if(region.get_size() != 10000) @@ -969,7 +974,7 @@ Now the client process: [c++] - #include + #include #include #include #include @@ -979,12 +984,12 @@ Now the client process: using namespace boost::interprocess; try{ //Open the file mapping - file_mapping m_file ("file.bin", memory_mappable::read_only); + file_mapping m_file ("file.bin", read_only); //Map the whole file in this process mapped_region region (m_file //What to map - ,mapped_region::read_only //Map it as read-only + ,read_only //Map it as read-only ); //Get the address of the mapped region @@ -1087,7 +1092,7 @@ To map an object in a fixed address, the user can specify that address in the [c++] mapped_region region ( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , 0 //Map from offset 0 , 0 //Map until the end , (void*)0x3F000000 //Map it exactly there @@ -1116,7 +1121,7 @@ parameters should be multiples of that value. This value is, tipically, 4KB or 8 //These might fail because the offset is not a multiple of the page size //and we are using fixed address mapping mapped_region region1( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , 1 //Map from offset 1 , 1 //Map 1 byte , (void*)0x3F000000 //Aligned mapping address @@ -1124,7 +1129,7 @@ parameters should be multiples of that value. This value is, tipically, 4KB or 8 //These might fail because the address is not a multiple of the page size mapped_region region2( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , 0 //Map from offset 0 , 1 //Map 1 byte , (void*)0x3F000001 //Not aligned mapping address @@ -1139,7 +1144,7 @@ more resources than necessary. If the user specifies the following 1 byte mappin //Map one byte of the shared memory object. //A whole memory page will be used for this. mapped_region region ( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , 0 //Map from offset 0 , 1 //Map 1 byte ); @@ -1153,7 +1158,7 @@ mapped regions for a file with as size = 2*page_size bytes: //Map the first quarter of the file //This will use a whole page mapped_region region1( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , 0 //Map from offset 0 , page_size/2 //Map page_size/2 bytes ); @@ -1161,7 +1166,7 @@ mapped regions for a file with as size = 2*page_size bytes: //Map the rest of the file //This will use a 2 pages mapped_region region2( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , page_size/2 //Map from offset 0 , 3*page_size/2 //Map page_size/2 bytes ); @@ -1172,14 +1177,14 @@ page size. The mapping with the minimum resource usage would be to map whole pag //Map the whole first half: uses 1 page mapped_region region1( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , 0 //Map from offset 0 , page_size //Map page_size/2 bytes ); //Map the second half: uses 1 page mapped_region region2( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , page_size //Map from offset 0 , page_size //Map page_size/2 bytes ); @@ -1194,7 +1199,7 @@ function that returns that value: //This mapping will optimally use system resources mapped_region region ( shm //Map shared memory - , mapped_region::read_write //Map it as read-write + , read_write //Map it as read-write , 0 //Map from offset 0 , page_size //Map whole page ); @@ -1592,7 +1597,7 @@ the the cyclic buffer and start writing traces: [c++] - #include + #include #include #include "doc_anonymous_mutex_shared_data.hpp" #include @@ -1610,7 +1615,7 @@ the the cyclic buffer and start writing traces: shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -1619,7 +1624,7 @@ the the cyclic buffer and start writing traces: //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region @@ -1662,7 +1667,7 @@ and starts writing traces: [c++] - #include + #include #include #include "doc_anonymous_mutex_shared_data.hpp" #include @@ -1676,13 +1681,13 @@ and starts writing traces: shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region @@ -1874,7 +1879,7 @@ to indicate that there are no more messages to print: [c++] - #include + #include #include #include #include "doc_anonymous_condition_shared_data.hpp" @@ -1891,7 +1896,7 @@ to indicate that there are no more messages to print: shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -1900,7 +1905,7 @@ to indicate that there are no more messages to print: //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region @@ -1945,7 +1950,7 @@ until the "last message" message is received: [c++] - #include + #include #include #include #include "doc_anonymous_condition_shared_data.hpp" @@ -1962,13 +1967,13 @@ until the "last message" message is received: shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region @@ -2100,7 +2105,7 @@ is full: [c++] - #include + #include #include #include "doc_anonymous_semaphore_shared_data.hpp" @@ -2116,7 +2121,7 @@ is full: shared_memory_object shm (create_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Set size @@ -2125,7 +2130,7 @@ is full: //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region @@ -2161,7 +2166,7 @@ to it's own buffer: [c++] - #include + #include #include #include "doc_anonymous_semaphore_shared_data.hpp" @@ -2174,13 +2179,13 @@ to it's own buffer: shared_memory_object shm (open_only //only create ,"shared_memory" //name - ,memory_mappable::read_write //read-write mode + ,read_write //read-write mode ); //Map the whole shared memory in this process mapped_region region (shm //What to map - ,mapped_region::read_write //Map it as read-write + ,read_write //Map it as read-write ); //Get the address of the mapped region @@ -3417,7 +3422,40 @@ This will produce a compilation error: [endsect] -[section:file_lock_careful Be Careful With Iostream Writing] +[section:file_lock_not_thread_safe Caution: Synchronization limitations] + +If you plan to use file locks just like a named mutex, be careful, because portable +file locks have synchronization limitations, mainly because different implementations +(POSIX, Windows) offer different guarantees. Interprocess file locks have the following +limitations: + +* It's unspecified if a `file_lock` synchronizes [*two threads from the same process]. +* It's unspecified if a process can use two `file_lock` objects pointing to the same file. + +The first limitation comes mainly from POSIX, since a file handle is a per-process attribute +and not a per-thread attribute. This means that if a thread uses a `file_lock` object to lock +a file, other threads will see the file as locked. +Windows file locking mechanism, on the other hand, offer thread-synchronization guarantees +so a thread trying to lock the already locked file, would block. + +The second limitation comes from the fact that file locking synchronization state +is tied with a single file descriptor in Windows. This means that if two `file_lock` +objects are created pointing to the same file, no synchronization is guaranteed. In +POSIX, when two file descriptors are used to lock a file if a descriptor is closed, +all file locks set by the calling process are cleared. + +To sum up, if you plan to use file locking in your processes, use the following +restrictions: + +* [*For each file, use a single `file_lock` object per process.] +* [*Use the same thread to lock and unlock a file.] +* If you are using a std::fstream/native file handle to write to the file + while using file locks on that file, [*don't close the file before + releasing all the locks of the file.] + +[endsect] + +[section:file_lock_careful_iostream Be Careful With Iostream Writing] As we've seen file locking can be useful to synchronize two processes reading and writing to a file, but [*make sure data is written to the file] @@ -3470,13 +3508,13 @@ processes. The memory segment can be mapped in different address in each process shared_memory_object shm_obj (open_only //open or create ,"shared_memory" //name - ,memory_mappable::read_only //read-only mode + ,read_only //read-only mode ); //Map the whole shared memory mapped_region region ( shm //Memory-mappable object - , mapped_region::read_write //Access mode + , read_write //Access mode ); //This address can be different in each process @@ -4715,6 +4753,7 @@ in the managed memory segment just like any other object with [*Boost.Interproce [c++] #include + #include #include int main () @@ -4853,6 +4892,93 @@ Let's see an example: [endsect] +[section:stl_container_move_semantics Move semantics in Interprocess containers] + +[*Boost.Interprocess] containers support move semantics, which means that the contents +of a container can be moved from a container two another one, without any copying. The +contents of the source container are transferred to the target container and the source +container is left in default-constructed state. + +When using containers of containers, we can also use move-semantics to insert +objects in the container, avoiding unnecessary copies. + + +To transfer the contents of a container to another one, use +`boost::interprocess::move()` function, as shown in the example. For more details +about functions supporting move-semantics, see the reference section of +Boost.Interprocess containers: + +[/doc_move_containers.cpp] + +[c++] + + #include + #include + #include + #include + #include + + int main () + { + using namespace boost::interprocess; + + //Typedefs + typedef managed_shared_memory::segment_manager SegmentManager; + typedef allocator CharAllocator; + typedef basic_string + ,CharAllocator> MyShmString; + typedef allocator StringAllocator; + typedef vector MyShmStringVector; + + //Remove old shared memory and create new one + shared_memory_object::remove("myshm"); + managed_shared_memory shm(create_only, "myshm", 10000); + + //Create allocators + CharAllocator charallocator (shm.get_segment_manager()); + StringAllocator stringallocator(shm.get_segment_manager()); + + //Create a vector of strings in shared memory. + MyShmStringVector *myshmvector = + shm.construct("myshmvector")(stringallocator); + + //Insert 50 strings in shared memory. The strings will be allocated + //only once and no string copy-constructor will be called when inserting + //strings, leading to a great performance. + MyShmString string_to_compare(charallocator); + string_to_compare = "this is a long, long, long, long, long, long, string..."; + + myshmvector->reserve(50); + for(int i = 0; i < 50; ++i){ + MyShmString move_me(string_to_compare); + //In the following line, no string copy-constructor will be called. + //"move_me"'s contents will be transferred to the string created in + //the vector + myshmvector->push_back(move(move_me)); + + //The source string is in default constructed state + assert(move_me.empty()); + + //The newly created string will be equal to the "move_me"'s old contents + assert(myshmvector->back() == string_to_compare); + } + + //Now erase a string... + myshmvector->pop_back(); + + //...And insert one in the first position. + //No string copy-constructor or assignments will be called, but + //move constructors and move-assignments. No memory allocation + //function will be called in this operations!! + myshmvector->insert(myshmvector->begin(), move(string_to_compare)); + + //Destroy vector. This will free all strings that the vector contains + shm.destroy_ptr(myshmvector); + return 0; + } + +[endsect] + [endsect] [section:managed_heap_memory_external_buffer Managed Heap Memory And Managed External Buffer] @@ -5907,10 +6033,10 @@ basic_vectorbuf and basic_vectorstream here: Does not throw.*/ const vector_type &vector() const; - /*!Calls resize() method of the internal vector. + /*!Preallocates memory from the internal vector. Resets the stream to the first position. - Throws if the internals vector's resize throws.*/ - void resize(typename vector_type::size_type size); + Throws if the internals vector's memory allocation throws.*/ + void reserve(typename vector_type::size_type size); }; /*!A basic_iostream class that holds a character vector specified by CharVector @@ -5955,10 +6081,10 @@ basic_vectorbuf and basic_vectorstream here: Does not throw.*/ const vector_type &vector() const; - /*!Calls resize() method of the internal vector. + /*!Preallocates memory from the internal vector. Resets the stream to the first position. - Throws if the internals vector's resize throws.*/ - void resize(typename vector_type::size_type size); + Throws if the internals vector's memory allocation throws.*/ + void reserve(typename vector_type::size_type size); }; The vector type is templatized, so that we can use any type of vector: @@ -6004,7 +6130,7 @@ Let's see an example to see how to use vectorstream: shared_memory_object::remove("MySharedMemory"); managed_shared_memory segment( create_only, - "MySharedMemory", //segment name + "MySharedMemory",//segment name 65536); //segment size in bytes //Construct shared memory vector @@ -6072,7 +6198,6 @@ Let's see an example to see how to use vectorstream: segment.destroy_ptr(mystring); return 0; } - [endsect] @@ -6188,9 +6313,9 @@ alternative to sprintf/sscanf functions. Let's see an example: { shared_memory_object::remove("MySharedMemory"); //Create shared memory - managed_shared_memory segment(create_only - ,"MySharedMemory" //segment name - ,65536); + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); //Fill data std::vector data, data2; @@ -7111,11 +7236,12 @@ than the current copy semantics containers. [endsect] - [endsect] [section:thanks_to Thanks to...] +[section:thanks_to_people People] + Many people have contributed with ideas and revisions, so this is the place to thank them: @@ -7127,6 +7253,7 @@ thank them: * Thanks to [*Hiang Swee Chiang], [*Phil Endecott], [*Rene Rivera], [*Harold Pirtle], [*Paul Ryan] [*Shumin Wu], [*Michal Wozniak], [*Peter Johnson] + [*Alex Ott], [*Shane Guillory], [*Steven Wooding] and [*Kim Barrett] for their bug fixes and library testing. * Thanks to [*Martin Adrian] who suggested the use of Interprocess framework for user defined buffers. @@ -7139,7 +7266,7 @@ thank them: * Thanks to [*Daniel James] for his unordered_map/set family and his help with allocators. His great unordered implementation has been a reference to design exception safe containers. -* Thanks to [*Howard Hinnant] for his patience explaining allocator swapping, +* Thanks to [*Howard Hinnant] for his amazing help, specially explaining allocator swapping, move semantics and for developing upgradable mutex and lock transfer features. * Thanks to [*Pavel Vozenilek] for his continuous review process, suggestions, code and @@ -7150,6 +7277,71 @@ thank them: [endsect] +[section:thanks_to_license_notes License notes] + +[*Boost.Interprocess] STL containers are based on the SGI STL library implementation: + +Copyright (c) 1996,1997 Silicon Graphics Computer Systems, Inc. Permission to use, +copy, modify, distribute and sell this software and its documentation for any +purpose is hereby granted without fee, provided that the above copyright notice +appear in all copies and that both that copyright notice and this permission +notice appear in supporting documentation. Silicon Graphics makes no representations +about the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +Copyright (c) 1994 Hewlett-Packard Company Permission to use, copy, modify, +distribute and sell this software and its documentation for any purpose is hereby +granted without fee, provided that the above copyright notice appear in all copies +and that both that copyright notice and this permission notice appear in supporting +documentation. Hewlett-Packard Company makes no representations about the suitability +of this software for any purpose. It is provided "as is" without express or implied +warranty. + +[endsect] + +[endsect] + +[section:changes Changes...] + +[section:changes_interprocess_2006_10_13 Changes in Interprocess 2006-10-13...] + +* Implemented N1780 proposal to LWG issue 233: ['Insertion hints in associative containers] + in interprocess `boost::interprocess::multiset` and `boost::interprocess::multimap` class. + +* [*Source breaking]: A shared memory object is now used including + `shared_memory_object.hpp` header instead of `shared memory.hpp`. + +* [*ABI breaking]: Changed global mutex when initializing managed shared memory + and memory mapped files. This change tries to minimize deadlocks. + +* [*Source breaking]: Changed shared memory, memory mapped files and mapped region's + open mode to a single `boost::interprocess::mode_t` type. + +* Added extra WIN32_LEAN_AND_MEAN before including DateTime headers to avoid socket + redefinition errors when using Interprocess and Asio in windows. + +* [*ABI breaking]: `mapped_region` constructor no longer requires classes + derived from memory_mappable, but classes the fulfill the MemoryMappable concept. + +* Added in-place reallocation capabilities to basic_string. + +* [*ABI breaking]: Reimplemented and optimized small string optimization. The narrow + string class has zero byte overhead with an internal 11 byte buffer in 32 systems! + +* Added move semantics to containers. Experimental and not documented yet. Improves + performance when using containers of containers. + +* [*ABI breaking]: End nodes of node containers (list, slist, map/set) are now + embedded in the containers instead of allocated using the allocator. This + allows no-throw move-constructors and improves performance. + +* [*ABI breaking]: [*slist] and [*list] containers now have constant-time + ['size()] function. The size of the container is added as a member. + +[endsect] + +[endsect] + [section:references References and interesting links] Some useful references about C++ language, C++ internals, shared memory, diff --git a/example/Attic/print_container.hpp b/example/Attic/print_container.hpp new file mode 100644 index 0000000..d6c8525 --- /dev/null +++ b/example/Attic/print_container.hpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2004-2006. 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_PRINTCONTAINER_HPP +#define BOOST_PRINTCONTAINER_HPP +#include +#include + +#include +#include +#include + +struct PrintValues : public std::unary_function +{ + void operator() (int value) const + { + std::cout << value << " "; + } +}; + +template +void PrintContents(const Container &cont, const char *contName) +{ + std::cout<< "Printing contents of " << contName << std::endl; + std::for_each(cont.begin(), cont.end(), PrintValues()); + std::cout<< std::endl << std::endl; +} + +#include + +#endif //#ifndef BOOST_PRINTCONTAINER_HPP diff --git a/example/Attic/process_a_example.cpp b/example/Attic/process_a_example.cpp index ebab477..e978a4a 100644 --- a/example/Attic/process_a_example.cpp +++ b/example/Attic/process_a_example.cpp @@ -13,7 +13,7 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include #include #include diff --git a/example/Attic/process_a_fixed_example.cpp b/example/Attic/process_a_fixed_example.cpp index d10fe57..2b094ff 100644 --- a/example/Attic/process_a_fixed_example.cpp +++ b/example/Attic/process_a_fixed_example.cpp @@ -14,7 +14,7 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include #include #include diff --git a/example/Attic/process_b_example.cpp b/example/Attic/process_b_example.cpp index 023de00..01fb495 100644 --- a/example/Attic/process_b_example.cpp +++ b/example/Attic/process_b_example.cpp @@ -15,7 +15,7 @@ #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include using namespace boost::interprocess; diff --git a/example/Attic/process_b_fixed_example.cpp b/example/Attic/process_b_fixed_example.cpp index d60ce69..1807cf8 100644 --- a/example/Attic/process_b_fixed_example.cpp +++ b/example/Attic/process_b_fixed_example.cpp @@ -14,7 +14,7 @@ #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include #include diff --git a/example/print_container.hpp b/example/print_container.hpp new file mode 100644 index 0000000..d6c8525 --- /dev/null +++ b/example/print_container.hpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2004-2006. 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_PRINTCONTAINER_HPP +#define BOOST_PRINTCONTAINER_HPP +#include +#include + +#include +#include +#include + +struct PrintValues : public std::unary_function +{ + void operator() (int value) const + { + std::cout << value << " "; + } +}; + +template +void PrintContents(const Container &cont, const char *contName) +{ + std::cout<< "Printing contents of " << contName << std::endl; + std::for_each(cont.begin(), cont.end(), PrintValues()); + std::cout<< std::endl << std::endl; +} + +#include + +#endif //#ifndef BOOST_PRINTCONTAINER_HPP diff --git a/example/process_a_example.cpp b/example/process_a_example.cpp index ebab477..e978a4a 100644 --- a/example/process_a_example.cpp +++ b/example/process_a_example.cpp @@ -13,7 +13,7 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include #include #include diff --git a/example/process_a_fixed_example.cpp b/example/process_a_fixed_example.cpp index d10fe57..2b094ff 100644 --- a/example/process_a_fixed_example.cpp +++ b/example/process_a_fixed_example.cpp @@ -14,7 +14,7 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include #include #include diff --git a/example/process_b_example.cpp b/example/process_b_example.cpp index 023de00..01fb495 100644 --- a/example/process_b_example.cpp +++ b/example/process_b_example.cpp @@ -15,7 +15,7 @@ #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include using namespace boost::interprocess; diff --git a/example/process_b_fixed_example.cpp b/example/process_b_fixed_example.cpp index d60ce69..1807cf8 100644 --- a/example/process_b_fixed_example.cpp +++ b/example/process_b_fixed_example.cpp @@ -14,7 +14,7 @@ #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" #include #include diff --git a/proj/cygwin/MakeAll b/proj/cygwin/MakeAll new file mode 100644 index 0000000..8278d67 --- /dev/null +++ b/proj/cygwin/MakeAll @@ -0,0 +1,41 @@ + +ifndef CC +CC=g++ +endif + +BOOST_ROOT=../../../.. + +INTERPROCESS_CPP := $(wildcard ../../src/*.cpp) +INTERPROCESS_OBJ := $(patsubst ../../src/%.cpp, lib_%.o, $(INTERPROCESS_CPP)) + +INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp) +INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/cygwin/test_%.out, $(INTERPROCESSTEST_CPP)) + +INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp) +INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/cygwin/ex_%.out, $(INTERPROCESSEXAMPLE_CPP)) + +INTERPROCESSDOC_CPP := $(wildcard ../../doc/code/*.cpp) +INTERPROCESSDOC_OUT := $(patsubst ../../doc/code/%.cpp, ../../bin/cygwin/doc_%.out, $(INTERPROCESSDOC_CPP)) + +LIBDIR:= ../../../../stage/lib + +.PHONY: createdir clean + +all: createdir $(INTERPROCESSEXAMPLE_OUT) $(INTERPROCESSTEST_OUT) $(INTERPROCESSDOC_OUT) + @cd . + +createdir: + @mkdir -p ../../bin/cygwin + +../../bin/cygwin/test_%.out: ../../test/%.cpp + $(CC) -g $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR) -lboost_thread-gcc-mt -I$(BOOST_ROOT) -lstdc++ -o $@ + +../../bin/cygwin/ex_%.out: ../../example/%.cpp + $(CC) -g $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-gcc-mt -I$(BOOST_ROOT) -lstdc++ -o $@ + +../../bin/cygwin/doc_%.out: ../../doc/code/%.cpp + $(CC) -g $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-gcc-mt -I$(BOOST_ROOT) -lstdc++ -o $@ + +clean: + rm -f *.o + rm -f ../../bin/cygwin/* diff --git a/proj/qnx/MakeAll b/proj/qnx/MakeAll index d7bf2fc..2836184 100644 --- a/proj/qnx/MakeAll +++ b/proj/qnx/MakeAll @@ -26,13 +26,13 @@ createdir: @mkdir -p ../../bin/qnx ../../bin/qnx/test_%.out: ../../test/%.cpp - $(CC) $< -Wall -pedantic -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@ + $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@ ../../bin/qnx/ex_%.out: ../../example/%.cpp - $(CC) $< -Wall -pedantic -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@ + $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@ ../../bin/qnx/doc_%.out: ../../doc/code/%.cpp - $(CC) $< -Wall -pedantic -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@ + $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@ clean: rm -f *.o diff --git a/proj/vc7ide/Interprocess.sln b/proj/vc7ide/Interprocess.sln index 718965d..f014521 100644 --- a/proj/vc7ide/Interprocess.sln +++ b/proj/vc7ide/Interprocess.sln @@ -299,6 +299,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_test", "unique_p ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_containers", "doc_move_containers.vcproj", "{58C1B183-0296-EA42-EF04-005120054104}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -605,6 +609,10 @@ Global {571C3383-6092-A877-1238-B3786BAE7605}.Debug.Build.0 = Debug|Win32 {571C3383-6092-A877-1238-B3786BAE7605}.Release.ActiveCfg = Release|Win32 {571C3383-6092-A877-1238-B3786BAE7605}.Release.Build.0 = Release|Win32 + {58C1B183-0296-EA42-EF04-005120054104}.Debug.ActiveCfg = Debug|Win32 + {58C1B183-0296-EA42-EF04-005120054104}.Debug.Build.0 = Debug|Win32 + {58C1B183-0296-EA42-EF04-005120054104}.Release.ActiveCfg = Release|Win32 + {58C1B183-0296-EA42-EF04-005120054104}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/proj/vc7ide/doc_move_containers.vcproj b/proj/vc7ide/doc_move_containers.vcproj new file mode 100644 index 0000000..2560b28 --- /dev/null +++ b/proj/vc7ide/doc_move_containers.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/interprocesslib.vcproj b/proj/vc7ide/interprocesslib.vcproj index 8eace49..a06747b 100644 --- a/proj/vc7ide/interprocesslib.vcproj +++ b/proj/vc7ide/interprocesslib.vcproj @@ -193,6 +193,12 @@ + + + + @@ -231,9 +237,6 @@ - - @@ -270,34 +273,12 @@ - - - - - - - - - - - - - - - - + + @@ -310,15 +291,6 @@ - - - - - - @@ -332,9 +304,21 @@ + + + + + + + + - - - - + + @@ -387,21 +367,24 @@ RelativePath="..\..\..\..\boost\interprocess\managed_shared_memory.hpp"> - - + RelativePath="..\..\..\..\boost\interprocess\mapped_region.hpp"> + RelativePath="..\..\..\..\boost\interprocess\shared_memory_object.hpp"> + + + + @@ -414,6 +397,9 @@ + + @@ -423,9 +409,18 @@ + + + + + + @@ -441,15 +436,28 @@ + + + + + + + + - - + + + + + + + + + + @@ -545,6 +565,9 @@ + + diff --git a/test/allocator_v1.hpp b/test/allocator_v1.hpp new file mode 100644 index 0000000..bd3cfd9 --- /dev/null +++ b/test/allocator_v1.hpp @@ -0,0 +1,169 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2005-2006. 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_ALLOCATOR_V1_HPP +#define BOOST_INTERPROCESS_ALLOCATOR_V1_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*!\file + Describes an allocator_v1 that allocates portions of fixed size + memory buffer (shared memory, mapped file...) +*/ + +namespace boost { +namespace interprocess { +namespace test { + +/*!An STL compatible allocator_v1 that uses a segment manager as + memory source. The internal pointer type will of the same type (raw, smart) as + "typename SegmentManager::void_pointer" type. This allows + placing the allocator_v1 in shared memory, memory mapped-files, etc...*/ +template +class allocator_v1 +{ + private: + /*!Self type*/ + typedef allocator_v1 self_t; + + /*!Segment manager*/ + typedef SegmentManager segment_manager; + + /*!Pointer to void */ + typedef typename segment_manager::void_pointer aux_pointer_t; + + /*!Typedef to const void pointer */ + typedef typename + detail::template pointer_to_other + ::type cvoid_ptr; + + /*!Pointer to the allocator_v1*/ + typedef typename detail::pointer_to_other + ::type alloc_ptr_t; + + /*!Not assignable from related allocator_v1*/ + template + allocator_v1& operator=(const allocator_v1&); + + /*!Not assignable from other allocator_v1*/ + allocator_v1& operator=(const allocator_v1&); + + /*!Pointer to the allocator_v1*/ + alloc_ptr_t mp_mngr; + + public: + typedef T value_type; + typedef typename detail::pointer_to_other + ::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef typename workaround::random_it + ::reference reference; + typedef typename workaround::random_it + ::const_reference const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + /*!Obtains an allocator_v1 of other type*/ + template + struct rebind + { + typedef allocator_v1 other; + }; + + /*!Returns the segment manager. Never throws*/ + segment_manager* get_segment_manager()const + { return detail::get_pointer(mp_mngr); } + + /*!Returns address of mutable object. Never throws*/ + pointer address(reference value) const + { return pointer(boost::addressof(value)); } + + /*!Returns address of non mutable object. Never throws*/ + const_pointer address(const_reference value) const + { return const_pointer(boost::addressof(value)); } + + /*!Constructor from the segment manager. Never throws*/ + allocator_v1(segment_manager *segment_mngr) + : mp_mngr(segment_mngr) { } + + /*!Constructor from other allocator_v1. Never throws*/ + allocator_v1(const allocator_v1 &other) + : mp_mngr(other.get_segment_manager()){ } + + /*!Constructor from related allocator_v1. Never throws*/ + template + allocator_v1(const allocator_v1 &other) + : mp_mngr(other.get_segment_manager()){} + + /*!Allocates memory for an array of count elements. + Throws boost::interprocess::bad_alloc if there is no enough memory*/ + pointer allocate(size_type count, cvoid_ptr hint = 0) + { return pointer((value_type*)mp_mngr->allocate(count*sizeof(value_type))); } + + /*!Deallocates memory previously allocated. Never throws*/ + void deallocate(const pointer &ptr, size_type) + { mp_mngr->deallocate(detail::get_pointer(ptr)); } + + /*!Construct object, calling constructor. + Throws if T(const T&) throws*/ + void construct(const pointer &ptr, const_reference value) + { new(detail::get_pointer(ptr)) value_type(value); } + + /*!Destroys object. Throws if object's destructor throws*/ + void destroy(const pointer &ptr) + { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } + + /*!Returns the number of elements that could be allocated. Never throws*/ + size_type max_size() const + { return mp_mngr->get_size(); } + + /*!Swap segment manager. Does not throw. If each allocator_v1 is placed in + different memory segments, the result is undefined.*/ + friend void swap(self_t &alloc1, self_t &alloc2) + { detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); } +}; + +/*!Equality test for same type of allocator_v1*/ +template inline +bool operator==(const allocator_v1 &alloc1, + const allocator_v1 &alloc2) + { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); } + +/*!Inequality test for same type of allocator_v1*/ +template inline +bool operator!=(const allocator_v1 &alloc1, + const allocator_v1 &alloc2) + { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); } + +} //namespace test { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_ALLOCATOR_V1_HPP + diff --git a/test/allocexcept_test.cpp b/test/allocexcept_test.cpp index 3856db5..b7b4881 100644 --- a/test/allocexcept_test.cpp +++ b/test/allocexcept_test.cpp @@ -18,7 +18,7 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" struct InstanceCounter { diff --git a/test/barrier_test.cpp b/test/barrier_test.cpp index 43f5609..dba131f 100644 --- a/test/barrier_test.cpp +++ b/test/barrier_test.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace { @@ -51,6 +52,9 @@ void barrier_thread() int main () { + + try{ + boost::thread_group g; global_parameter = 0; @@ -58,6 +62,16 @@ int main () g.create_thread(&barrier_thread); g.join_all(); + } + catch(std::exception &e){ + std::cout << "Exception cached: " << e.what() << std::endl; + return 1; + } + catch(...){ + std::cout << "unkwnown exception catched" << std::endl; + return 1; + } + return 0; } diff --git a/test/cached_node_allocator_test.cpp b/test/cached_node_allocator_test.cpp index 653bf1c..b3909d0 100644 --- a/test/cached_node_allocator_test.cpp +++ b/test/cached_node_allocator_test.cpp @@ -10,164 +10,30 @@ #include #include -#include -#include -#include -#include -#include - #include -#include -#include #include -#include "printcontainer.hpp" - -/*****************************************************************/ -/* */ -/* This example repeats the same operations with std::list and */ -/* shmem_list using the cached node allocator */ -/* and compares the values of both containers */ -/* */ -/*****************************************************************/ +#include +#include "print_container.hpp" +#include "dummy_test_allocator.hpp" +#include "movable_int.hpp" +#include "list_test.hpp" using namespace boost::interprocess; //We will work with wide characters for shared memory objects //Alias node allocator type typedef cached_node_allocator - + cached_node_allocator_t; //Alias list types -typedef list MyShmList; -typedef std::list MyStdList; - -//Function to check if both lists are equal -bool CheckEqual(MyShmList *shmlist, MyStdList *stdlist) -{ - return std::equal(shmlist->begin(), shmlist->end(), stdlist->begin()); -} +typedef list MyShmList; int main () { - const int memsize = 1048576; - const char *const shMemName = "MySharedMemory"; - const int max = 100; + if(test::list_test()) + return 1; - shared_memory_object::remove(shMemName); - - //Create managed shared memory - wmanaged_shared_memory segment(create_only, shMemName, memsize); - - //Shared memory allocator must be always be initialized - //since it has no default constructor - MyShmList *shmlist = segment.construct - (L"MyVect") - (segment.get_segment_manager()); - - MyStdList *stdlist = new MyStdList; - - int i; - for(i = 0; i < max; ++i){ - shmlist->push_back(i); - stdlist->push_back(i); - } - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->erase(shmlist->begin()++); - stdlist->erase(stdlist->begin()++); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->pop_back(); - stdlist->pop_back(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->pop_front(); - stdlist->pop_front(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - std::vector aux_vect; - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, -1); - shmlist->assign(aux_vect.begin(), aux_vect.end()); - stdlist->assign(aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmlist, stdlist)) return 1; - #endif - - shmlist->sort(); - stdlist->sort(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, 0); - #endif - shmlist->insert(shmlist->begin(), aux_vect.begin(), aux_vect.end()); - stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end()); - - shmlist->unique(); - stdlist->unique(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->sort(std::greater()); - stdlist->sort(std::greater()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->resize(shmlist->size()/2); - stdlist->resize(stdlist->size()/2); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->remove(*shmlist->begin()); - stdlist->remove(*stdlist->begin()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - for(i = 0; i < max; ++i){ - shmlist->push_back(i); - stdlist->push_back(i); - } - if(!CheckEqual(shmlist, stdlist)) - return 1; - - MyShmList othershmlist(*shmlist); - MyStdList otherstdlist(*stdlist); - shmlist->splice(shmlist->begin(), othershmlist); - stdlist->splice(stdlist->begin(), otherstdlist); - if(!CheckEqual(shmlist, stdlist)) - return 1; - - othershmlist = *shmlist; - otherstdlist = *stdlist; - shmlist->merge(othershmlist, std::greater()); - stdlist->merge(otherstdlist, std::greater()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - MyShmList *shmlist2 = segment.construct - (L"MyVect2") - (segment.get_segment_manager()); - - shmlist->swap(*shmlist2); - segment.destroy(L"MyVect2"); - - //Allocators must be destroyed before shared memory is unmapped - { - cached_node_allocator_t al1 = shmlist->get_allocator(); - cached_node_allocator_t al2 = shmlist->get_allocator(); - - if(al1 != al2) - return 1; - - std::size_t max_chached2 = al1.get_max_cached_nodes()*2; - al2.set_max_cached_nodes(max_chached2); - - while(max_chached2--){ - al1.deallocate(al2.allocate(1), 1); - } - - swap(al1, al2); - } - - segment.destroy_ptr(shmlist); - - delete stdlist; return 0; } diff --git a/test/check_equal_containers.hpp b/test/check_equal_containers.hpp new file mode 100644 index 0000000..2108a78 --- /dev/null +++ b/test/check_equal_containers.hpp @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2006. 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_CHECK_EQUAL_CONTAINERS_HPP +#define BOOST_INTERPROCESS_TEST_CHECK_EQUAL_CONTAINERS_HPP + +#include +#include +#include +#include + +namespace boost{ +namespace interprocess{ +namespace test{ + +//Function to check if both containers are equal +template +bool CheckEqualContainers(MyShmCont *shmcont, MyStdCont *stdcont) +{ + if(shmcont->size() != stdcont->size()) + return false; + + typedef typename MyShmCont::value_type value_type; + + typename MyShmCont::iterator itshm(shmcont->begin()), itshmend(shmcont->end()); + typename MyStdCont::iterator itstd(stdcont->begin()); + for(; itshm != itshmend; ++itshm, ++itstd){ + value_type val(*itstd); + if(*itshm != val) + return false; + } + return true; +} + +template +bool CheckEqualPairContainers(MyShmCont *shmcont, MyStdCont *stdcont) +{ + if(shmcont->size() != stdcont->size()) + return false; + + typedef typename MyShmCont::key_type key_type; + typedef typename MyShmCont::mapped_type mapped_type; + + typename MyShmCont::iterator itshm(shmcont->begin()), itshmend(shmcont->end()); + typename MyStdCont::iterator itstd(stdcont->begin()); + for(; itshm != itshmend; ++itshm, ++itstd){ + if(itshm->first != key_type(itstd->first)) + return false; + + if(itshm->second != mapped_type(itstd->second)) + return false; + } + return true; +} +} //namespace test{ +} //namespace interprocess{ +} //namespace boost{ + +#include + +#endif //#ifndef BOOST_INTERPROCESS_TEST_CHECK_EQUAL_CONTAINERS_HPP diff --git a/test/condition_test_template.hpp b/test/condition_test_template.hpp index 474e13c..b32f82c 100644 --- a/test/condition_test_template.hpp +++ b/test/condition_test_template.hpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -379,10 +379,15 @@ void do_test_condition_queue_notify_all(void) template bool do_test_condition() { + std::cout << "do_test_condition_notify_one<" << typeid(Condition).name() << "," << typeid(Mutex).name() << std::endl; do_test_condition_notify_one(); + std::cout << "do_test_condition_notify_all<" << typeid(Condition).name() << "," << typeid(Mutex).name() << std::endl; do_test_condition_notify_all(); + std::cout << "do_test_condition_waits<" << typeid(Condition).name() << "," << typeid(Mutex).name() << std::endl; do_test_condition_waits(); + std::cout << "do_test_condition_queue_notify_one<" << typeid(Condition).name() << "," << typeid(Mutex).name() << std::endl; do_test_condition_queue_notify_one(); + std::cout << "do_test_condition_queue_notify_all<" << typeid(Condition).name() << "," << typeid(Mutex).name() << std::endl; do_test_condition_queue_notify_all(); return true; } diff --git a/test/data_test.cpp b/test/data_test.cpp index 7774e91..4cb6428 100644 --- a/test/data_test.cpp +++ b/test/data_test.cpp @@ -17,7 +17,7 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" using namespace boost::interprocess; diff --git a/test/deque_test.cpp b/test/deque_test.cpp index 9f9dea8..7443d09 100644 --- a/test/deque_test.cpp +++ b/test/deque_test.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -20,7 +19,15 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" +#include "check_equal_containers.hpp" +#include "dummy_test_allocator.hpp" +#include "movable_int.hpp" +#include +#include "allocator_v1.hpp" +#include +#include +#include //***************************************************************// // // @@ -30,118 +37,185 @@ // // //***************************************************************// -//Explicit instantiation to detect compilation errors -template class boost::interprocess::deque >; - using namespace boost::interprocess; -//Customize managed_shared_memory class - -typedef basic_managed_shared_memory - , - flat_map_index - > my_managed_shared_memory; - -//Alias allocator type -typedef allocator - shmem_node_allocator_t; - -//Alias deque types -typedef deque MyShmDeque; -typedef std::deque MyStdDeque; - -//template class deque; +//Explicit instantiation to detect compilation errors +template class boost::interprocess::deque >; //Function to check if both sets are equal -bool CheckEqual(MyShmDeque *shmdeque, MyStdDeque *stddeque) +template +bool copyable_only(V1 *shmdeque, V2 *stddeque, boost::false_type) { - if(shmdeque->size() != stddeque->size()) - return false; - return std::equal(shmdeque->begin(), shmdeque->end(), stddeque->begin()); + return true; } -int main () +//Function to check if both sets are equal +template +bool copyable_only(V1 *shmdeque, V2 *stddeque, boost::true_type) { - const int memsize = 655360; + typedef typename V1::value_type IntType; + std::size_t size = shmdeque->size(); + stddeque->insert(stddeque->end(), 50, 1); + shmdeque->insert(shmdeque->end(), 50, 1); + if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; + { + IntType move_me(1); + stddeque->insert(stddeque->begin()+size/2, 50, 1); + shmdeque->insert(shmdeque->begin()+size/2, 50, move(move_me)); + if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; + } + { + IntType move_me(2); + shmdeque->assign(shmdeque->size()/2, move(move_me)); + stddeque->assign(stddeque->size()/2, 2); + if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; + } + return true; +} + +template class AllocatorType > +bool do_test() +{ + //Customize managed_shared_memory class + typedef basic_managed_shared_memory + , + flat_map_index + > my_managed_shared_memory; + + //Alias AllocatorType type + typedef AllocatorType + shmem_allocator_t; + + //Alias deque types + typedef deque MyShmDeque; + typedef std::deque MyStdDeque; + const int Memsize = 65536; const char *const shMemName = "MySharedMemory"; const int max = 100; shared_memory_object::remove(shMemName); //Create shared memory - my_managed_shared_memory segment(create_only, shMemName, memsize); + my_managed_shared_memory segment(create_only, shMemName, Memsize); segment.reserve_named_objects(100); //Shared memory allocator must be always be initialized //since it has no default constructor - MyShmDeque *shmdeque = segment.construct("MyShmDeque") + MyShmDeque *shmdeque = segment.template construct("MyShmDeque") (segment.get_segment_manager()); MyStdDeque *stddeque = new MyStdDeque; - int i, j; - for(i = 0; i < max; ++i){ - shmdeque->insert(shmdeque->end(), i); - stddeque->insert(stddeque->end(), i); - } - if(!CheckEqual(shmdeque, stddeque)) return 1; + try{ + //Compare several shared memory deque operations with std::deque + int i; + for(i = 0; i < max; ++i){ + IntType move_me(i); + shmdeque->insert(shmdeque->end(), move(move_me)); + stddeque->insert(stddeque->end(), i); + } + if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; - MyShmDeque::iterator it; - MyShmDeque::const_iterator cit = it; + typename MyShmDeque::iterator it; + typename MyShmDeque::const_iterator cit = it; - shmdeque->erase(shmdeque->begin()++); - stddeque->erase(stddeque->begin()++); - if(!CheckEqual(shmdeque, stddeque)) return 1; + shmdeque->erase(shmdeque->begin()++); + stddeque->erase(stddeque->begin()++); + if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; - shmdeque->erase(shmdeque->begin()); - stddeque->erase(stddeque->begin()); - if(!CheckEqual(shmdeque, stddeque)) return 1; - - std::vector aux_vect; - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, -1); - shmdeque->insert(shmdeque->end(), aux_vect.begin(), aux_vect.end()); - stddeque->insert(stddeque->end(), aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmdeque, stddeque)) return 1; - #endif - - shmdeque->insert(shmdeque->begin()+shmdeque->size()/2, 50, aux_vect[0]); - stddeque->insert(stddeque->begin()+stddeque->size()/2, 50, aux_vect[0]); - if(!CheckEqual(shmdeque, stddeque)) return 1; - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - for(i = 0, j = static_cast(shmdeque->size()); i < j; ++i){ shmdeque->erase(shmdeque->begin()); stddeque->erase(stddeque->begin()); + if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; + + { + //Initialize values + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me (-1); + aux_vect[i] = move(move_me); + } + int aux_vect2[50]; + for(int i = 0; i < 50; ++i){ + aux_vect2[i] = -1; + } + + shmdeque->insert(shmdeque->end() + ,detail::make_move_iterator(&aux_vect[0]) + ,detail::make_move_iterator(aux_vect + 50)); + stddeque->insert(stddeque->end(), aux_vect2, aux_vect2 + 50); + if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; + + for(int i = 0, j = static_cast(shmdeque->size()); i < j; ++i){ + shmdeque->erase(shmdeque->begin()); + stddeque->erase(stddeque->begin()); + } + if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; + } + { + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me(-1); + aux_vect[i] = move(move_me); + } + int aux_vect2[50]; + for(int i = 0; i < 50; ++i){ + aux_vect2[i] = -1; + } + shmdeque->insert(shmdeque->begin() + ,detail::make_move_iterator(&aux_vect[0]) + ,detail::make_move_iterator(aux_vect + 50)); + stddeque->insert(stddeque->begin(), aux_vect2, aux_vect2 + 50); + if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; + } + + if(!copyable_only(shmdeque, stddeque + ,boost::integral_constant + ::value>())){ + return false; + } + + shmdeque->erase(shmdeque->begin()); + stddeque->erase(stddeque->begin()); + + if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; + + for(i = 0; i < max; ++i){ + IntType move_me(i); + shmdeque->insert(shmdeque->begin(), move(move_me)); + stddeque->insert(stddeque->begin(), i); + } + if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; + + segment.template destroy("MyShmDeque"); + delete stddeque; } - if(!CheckEqual(shmdeque, stddeque)) return 1; - #endif - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - shmdeque->insert(shmdeque->begin(), aux_vect.begin(), aux_vect.end()); - shmdeque->insert(shmdeque->begin(), aux_vect.begin(), aux_vect.end()); - stddeque->insert(stddeque->begin(), aux_vect.begin(), aux_vect.end()); - stddeque->insert(stddeque->begin(), aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmdeque, stddeque)) return 1; - #endif - - shmdeque->erase(shmdeque->begin()); - stddeque->erase(stddeque->begin()); - - if(!CheckEqual(shmdeque, stddeque)) return 1; - - for(i = 0; i < max; ++i){ - shmdeque->insert(shmdeque->begin(), i); - stddeque->insert(stddeque->begin(), i); + catch(std::exception &ex){ + std::cout << ex.what() << std::endl; + return false; } - if(!CheckEqual(shmdeque, stddeque)) return 1; - - segment.destroy("MyShmDeque"); - delete stddeque; + + std::cout << std::endl << "Test OK!" << std::endl; + return true; return 0; } +int main () +{ + if(!do_test()) + return 1; + + if(!do_test()) + return 1; + + if(!do_test()) + return 1; + + return 0; +} + + #include diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp new file mode 100644 index 0000000..48d8da9 --- /dev/null +++ b/test/dummy_test_allocator.hpp @@ -0,0 +1,159 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2005-2006. 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_DUMMY_TEST_ALLOCATOR_HPP +#define BOOST_INTERPROCESS_DUMMY_TEST_ALLOCATOR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*!\file + Describes an allocator to test expand capabilities +*/ + +namespace boost { +namespace interprocess { +namespace test { + +//This allocator just allows two allocations. The first one will return +//mp_buffer + m_offset configured in the constructor. The second one +//will return mp_buffer. +template +class dummy_test_allocator +{ + private: + typedef dummy_test_allocator self_t; + typedef void * aux_pointer_t; + typedef const void * cvoid_ptr; + + template + dummy_test_allocator& operator=(const dummy_test_allocator&); + + dummy_test_allocator& operator=(const dummy_test_allocator&); + + public: + typedef T value_type; + typedef T * pointer; + typedef const T * const_pointer; + typedef typename workaround::random_it + ::reference reference; + typedef typename workaround::random_it + ::const_reference const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef detail::version_type version; + + template + struct rebind + { typedef dummy_test_allocator other; }; + + /*!Default constructor. Never throws*/ + dummy_test_allocator() + {} + + /*!Constructor from other dummy_test_allocator. Never throws*/ + dummy_test_allocator(const dummy_test_allocator &other) + {} + + /*!Constructor from related dummy_test_allocator. Never throws*/ + template + dummy_test_allocator(const dummy_test_allocator &other) + {} + + pointer address(reference value) const + { return pointer(boost::addressof(value)); } + + const_pointer address(const_reference value) const + { return const_pointer(boost::addressof(value)); } + + pointer allocate(size_type, cvoid_ptr = 0) + { return 0; } + + void deallocate(const pointer &, size_type) + { } + + template + void construct(pointer, const Convertible &) + {} + + void destroy(pointer) + {} + + size_type max_size() const + { return 0; } + + friend void swap(self_t &, self_t &) + {} + + //Experimental version 2 dummy_test_allocator functions + + std::pair + allocation_command(allocation_type, + size_type, + size_type, + size_type &, const pointer & = 0) + { return std::pair(0, true); } + + /*!Returns maximum the number of objects the previously allocated memory + pointed by p can hold.*/ + size_type size(const pointer &) const + { return 0; } + + /*!Allocates just one object. Memory allocated with this function + must be deallocated only with deallocate_one(). + Throws boost::interprocess::bad_alloc if there is no enough memory*/ + pointer allocate_one() + { return pointer(0); } + + /*!Deallocates memory previously allocated with allocate_one(). + You should never use deallocate_one to deallocate memory allocated + with other functions different from allocate_one(). Never throws*/ + void deallocate_one(const pointer &) + {} +}; + +/*!Equality test for same type of dummy_test_allocator*/ +template inline +bool operator==(const dummy_test_allocator &alloc1, + const dummy_test_allocator &alloc2) +{ return false; } + +/*!Inequality test for same type of dummy_test_allocator*/ +template inline +bool operator!=(const dummy_test_allocator &alloc1, + const dummy_test_allocator &alloc2) +{ return true; } + +} //namespace test { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_DUMMY_TEST_ALLOCATOR_HPP + diff --git a/test/expand_bwd_test_allocator.hpp b/test/expand_bwd_test_allocator.hpp index 24f7df1..637982c 100644 --- a/test/expand_bwd_test_allocator.hpp +++ b/test/expand_bwd_test_allocator.hpp @@ -61,8 +61,10 @@ class expand_bwd_test_allocator typedef T value_type; typedef T * pointer; typedef const T * const_pointer; - typedef T & reference; - typedef const T & const_reference; + typedef typename workaround::random_it + ::reference reference; + typedef typename workaround::random_it + ::const_reference const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; @@ -94,7 +96,8 @@ class expand_bwd_test_allocator const_pointer address(const_reference value) const { return const_pointer(boost::addressof(value)); } - pointer allocate(size_type count, cvoid_ptr hint = 0); + pointer allocate(size_type count, cvoid_ptr hint = 0) + { return 0; } void deallocate(const pointer &ptr, size_type) { } @@ -124,9 +127,8 @@ class expand_bwd_test_allocator size_type preferred_size, size_type &received_size, const pointer &reuse = 0) { - if(!(command & expand_bwd)){ - assert(0); - } + //This allocator only expands backwards! + assert(m_allocations == 0 || (command & expand_bwd)); received_size = limit_size; @@ -146,6 +148,7 @@ class expand_bwd_test_allocator } else{ assert(0); + throw std::bad_alloc(); } return std::pair(0, true); } @@ -167,7 +170,6 @@ class expand_bwd_test_allocator void deallocate_one(const pointer &p) { return this->deallocate(p, 1); } - private: pointer mp_buffer; size_type m_size; difference_type m_offset; diff --git a/test/expand_bwd_test_template.hpp b/test/expand_bwd_test_template.hpp index 4501118..8cb036b 100644 --- a/test/expand_bwd_test_template.hpp +++ b/test/expand_bwd_test_template.hpp @@ -17,19 +17,22 @@ namespace boost { namespace interprocess { namespace test { -struct int_holder +template +struct value_holder { - int_holder(int val): m_value(val){} - int_holder(): m_value(0){} - ~int_holder(){ m_value = 0; } - bool operator == (const int_holder &other) const + value_holder(T val): m_value(val){} + value_holder(): m_value(0){} + ~value_holder(){ m_value = 0; } + bool operator == (const value_holder &other) const { return m_value == other.m_value; } - bool operator != (const int_holder &other) const + bool operator != (const value_holder &other) const { return m_value != other.m_value; } - int m_value; + T m_value; }; +typedef value_holder int_holder; + //Function to check if both sets are equal template static bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2) @@ -42,11 +45,12 @@ static bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2) template static bool CheckUninitializedIsZero(const Vector & v) { + typedef typename Vector::value_type value_type; typename Vector::size_type sz = v.size(); typename Vector::size_type extra = v.capacity() - v.size(); - int_holder comp; + value_type comp(0); - const int_holder *holder = &v[0] + sz; + const value_type *holder = &v[0] + sz; while(extra--){ if(*holder++ != comp) @@ -58,10 +62,11 @@ static bool CheckUninitializedIsZero(const Vector & v) //This function tests all the possible combinations when //inserting data in a vector and expanding backwards -template +template bool test_insert_with_expand_bwd() { - typedef std::vector IntVect; + typedef typename VectorWithExpandBwdAllocator::value_type value_type; + typedef std::vector Vect; const int MemorySize = 1000; //Distance old and new buffer @@ -85,24 +90,24 @@ bool test_insert_with_expand_bwd() for(int iteration = 0; iteration < Iterations; ++iteration) { - IntVect memory; + Vect memory; memory.resize(MemorySize); - IntVect initial_data; + Vect initial_data; initial_data.resize(InitialSize[iteration]); for(int i = 0; i < InitialSize[iteration]; ++i){ - initial_data[i] = i; + initial_data[i] = value_type(i); } - IntVect data_to_insert; + Vect data_to_insert; data_to_insert.resize(InsertSize[iteration]); for(int i = 0; i < InsertSize[iteration]; ++i){ - data_to_insert[i] = -i; + data_to_insert[i] = value_type(-i); } - expand_bwd_test_allocator alloc + expand_bwd_test_allocator alloc (&memory[0], memory.size(), Offset[iteration]); - IntVectorWithExpandBwdAllocator vector(alloc); + VectorWithExpandBwdAllocator vector(alloc); vector.insert( vector.begin() , initial_data.begin(), initial_data.end()); vector.insert( vector.begin() + Position[iteration] @@ -112,15 +117,7 @@ bool test_insert_with_expand_bwd() //Now check that values are equal if(!CheckEqualVector(vector, initial_data)){ std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl - << " Class: " << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl - << " Iteration: " << iteration << std::endl; - return false; - } - - //Now check that uninitialized values are zero - if(!CheckUninitializedIsZero(vector)){ - std::cout << "test_assign_with_expand_bwd::CheckUninitializedIsZero failed." << std::endl - << " Class: " << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl + << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl << " Iteration: " << iteration << std::endl; return false; } @@ -131,10 +128,11 @@ bool test_insert_with_expand_bwd() //This function tests all the possible combinations when //inserting data in a vector and expanding backwards -template +template bool test_assign_with_expand_bwd() { - typedef std::vector IntVect; + typedef typename VectorWithExpandBwdAllocator::value_type value_type; + typedef std::vector Vect; const int MemorySize = 200; const int Offset[] = { 50, 50, 50}; @@ -144,27 +142,27 @@ bool test_assign_with_expand_bwd() for(int iteration = 0; iteration alloc + expand_bwd_test_allocator alloc (&memory[0], memory.size(), Offset[iteration]); - IntVectorWithExpandBwdAllocator vector(alloc); + VectorWithExpandBwdAllocator vector(alloc); vector.insert( vector.begin() , initial_data.begin(), initial_data.end()); @@ -175,15 +173,7 @@ bool test_assign_with_expand_bwd() //Now check that values are equal if(!CheckEqualVector(vector, initial_data)){ std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl - << " Class: " << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl - << " Iteration: " << iteration << std::endl; - return false; - } - - //Now check that uninitialized values are zero - if(!CheckUninitializedIsZero(vector)){ - std::cout << "test_assign_with_expand_bwd::CheckUninitializedIsZero failed." << std::endl - << " Class: " << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl + << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl << " Iteration: " << iteration << std::endl; return false; } @@ -193,24 +183,24 @@ bool test_assign_with_expand_bwd() } //This function calls all tests -template +template bool test_all_expand_bwd() { std::cout << "Starting test_insert_with_expand_bwd." << std::endl << " Class: " - << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl; + << typeid(VectorWithExpandBwdAllocator).name() << std::endl; - if(!test_insert_with_expand_bwd()){ + if(!test_insert_with_expand_bwd()){ std::cout << "test_allocation_direct_deallocation failed. Class: " - << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl; + << typeid(VectorWithExpandBwdAllocator).name() << std::endl; return false; } std::cout << "Starting test_assign_with_expand_bwd." << std::endl << " Class: " - << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl; + << typeid(VectorWithExpandBwdAllocator).name() << std::endl; - if(!test_assign_with_expand_bwd()){ + if(!test_assign_with_expand_bwd()){ std::cout << "test_allocation_direct_deallocation failed. Class: " - << typeid(IntVectorWithExpandBwdAllocator).name() << std::endl; + << typeid(VectorWithExpandBwdAllocator).name() << std::endl; return false; } diff --git a/test/file_mapping_test.cpp b/test/file_mapping_test.cpp index 847ace1..03ffb05 100644 --- a/test/file_mapping_test.cpp +++ b/test/file_mapping_test.cpp @@ -13,7 +13,8 @@ #include #include -#include +#include +#include using namespace boost::interprocess; @@ -30,16 +31,16 @@ int main () { //Create a file mapping - file_mapping mapping("my_file", file_mapping::read_write); + file_mapping mapping("my_file", read_write); //Create two mapped regions, one half of the file each mapped_region region (mapping - ,mapped_region::read_write + ,read_write ,0 ,FileSize/2 ); mapped_region region2(mapping - ,mapped_region::read_write + ,read_write ,FileSize/2 ,FileSize - FileSize/2 ); @@ -100,11 +101,11 @@ int main () //Now check the pattern mapping a single read only mapped_region { //Create a file mapping - file_mapping mapping("my_file", file_mapping::read_only); + file_mapping mapping("my_file", read_only); //Create a single regions, mapping all the file mapped_region region (mapping - ,mapped_region::read_only + ,read_only ); //Check pattern diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp index 51a789c..7551d8b 100644 --- a/test/flat_tree_test.cpp +++ b/test/flat_tree_test.cpp @@ -16,8 +16,11 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" +#include "dummy_test_allocator.hpp" +#include "movable_int.hpp" #include "set_test.hpp" +#include "map_test.hpp" /*****************************************************************/ /* */ @@ -27,14 +30,33 @@ /* */ /*****************************************************************/ -//Explicit instantiation to detect compilation errors -template class boost::interprocess::flat_set, std::allocator >; -template class boost::interprocess::flat_multiset, std::allocator >; -template class boost::interprocess::flat_map, std::allocator > >; -template class boost::interprocess::flat_multimap, std::allocator > >; - using namespace boost::interprocess; +//Explicit instantiation to detect compilation errors +template class boost::interprocess::flat_set + + ,test::dummy_test_allocator >; + +template class boost::interprocess::flat_map + + ,test::dummy_test_allocator > >; + +template class boost::interprocess::flat_multiset + + ,test::dummy_test_allocator >; + +template class boost::interprocess::flat_multimap + + ,test::dummy_test_allocator > >; + //Customize managed_shared_memory class typedef basic_managed_shared_memory - shmem_node_allocator_t; + shmem_allocator_t; +typedef allocator + shmem_movable_allocator_t; +typedef allocator, managed_shared_memory::segment_manager> + shmem_pair_allocator_t; +typedef allocator, managed_shared_memory::segment_manager> + shmem_movable_pair_allocator_t; + +typedef allocator + shmem_move_copy_allocator_t; +typedef allocator, managed_shared_memory::segment_manager> + shmem_move_copy_pair_allocator_t; //Alias set types -typedef flat_set, shmem_node_allocator_t> MyShmSet; -typedef std::set MyStdSet; -typedef flat_multiset, shmem_node_allocator_t> MyShmMultiSet; -typedef std::multiset MyStdMultiSet; +typedef std::set MyStdSet; +typedef std::multiset MyStdMultiSet; +typedef std::map MyStdMap; +typedef std::multimap MyStdMultiMap; + +typedef flat_set, shmem_allocator_t> MyShmSet; +typedef flat_multiset, shmem_allocator_t> MyShmMultiSet; +typedef flat_map, shmem_pair_allocator_t> MyShmMap; +typedef flat_multimap, shmem_pair_allocator_t> MyShmMultiMap; + +typedef flat_set + ,shmem_movable_allocator_t> MyMovableShmSet; +typedef flat_multiset + ,shmem_movable_allocator_t> MyMovableShmMultiSet; +typedef flat_map + ,shmem_movable_pair_allocator_t> MyMovableShmMap; +typedef flat_multimap + ,shmem_movable_pair_allocator_t> MyMovableShmMultiMap; + +typedef flat_set + ,shmem_move_copy_allocator_t> MyMoveCopyShmSet; +typedef flat_multiset + ,shmem_move_copy_allocator_t> MyMoveCopyShmMultiSet; +typedef flat_map + ,shmem_move_copy_pair_allocator_t> MyMoveCopyShmMap; +typedef flat_multimap + ,shmem_move_copy_pair_allocator_t> MyMoveCopyShmMultiMap; int main() { using namespace boost::interprocess::test; - return set_test(); + ,MyStdMultiSet>()){ + return 1; + } + if (0 != set_test()){ + return 1; + } + + if (0 != set_test()){ + return 1; + } + + if (0 != map_test()){ + return 1; + } +/* + if (0 != map_test()){ + return 1; + } +*/ + if (0 != map_test()){ + return 1; + } + + return 0; } #include diff --git a/test/list_test.cpp b/test/list_test.cpp index c78e3da..b9e6b72 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -12,80 +12,37 @@ #include #include -#include +#include #include -#include -#include -#include +#include "dummy_test_allocator.hpp" +#include "list_test.hpp" +#include "movable_int.hpp" using namespace boost::interprocess; -typedef node_allocator - ShmemAllocator; +//Explicit instantiation to detect compilation errors +template class boost::interprocess::list >; -template class list; +typedef allocator ShmemAllocator; +typedef list MyList; -struct int_holder -{ - int_holder(int value) : m_int(value){} - bool operator==(int_holder other) const - { return m_int == other.m_int; } - bool operator<(int_holder other) const - { return m_int < other.m_int; } +typedef allocator ShmemMoveAllocator; +typedef list MyMoveList; - private: - int m_int; -}; - -typedef node_allocator - ShmemIntHolderAllocator; - -//Instantations to detect compilation errors -template class list; -template class list >; +typedef allocator ShmemCopyMoveAllocator; +typedef list MyCopyMoveList; int main () { - //Create shared memory - shared_memory_object::remove("MySharedMemory"); - managed_shared_memory segment - (create_only, - "MySharedMemory",//segment name - 65536); //segment size in bytes - - typedef list MyList; - typedef list MyIntHolderList; + if(test::list_test()) + return 1; - int initVal[] = {0, 1, 2, 3, 4, 5, 6 }; - const int *begVal = initVal; - const int *endVal = initVal + sizeof(initVal)/sizeof(initVal[0]); + if(test::list_test()) + return 1; - const ShmemAllocator alloc_inst (segment.get_segment_manager()); - - //Initialize vector with a range or iterators and allocator - MyList *mylist = - segment.find_or_construct - ("MyList", std::nothrow) //object name - (begVal, //first ctor parameter - endVal, //second ctor parameter - alloc_inst);//third ctor parameter - - //Use vector as you want - mylist->insert(mylist->end(), begVal, endVal); - // . . . - //When done, delete vector - segment.destroy("MyList"); - - const ShmemIntHolderAllocator & - alloc_int_holder(segment.get_segment_manager()); - - MyIntHolderList *myintholderlist = - segment.find_or_construct - ("MyList", std::nothrow) //object name - (alloc_int_holder); - - mylist->insert(mylist->end(), 0); - segment.destroy_ptr(myintholderlist); + if(test::list_test()) + return 1; return 0; } diff --git a/test/list_test.hpp b/test/list_test.hpp new file mode 100644 index 0000000..a70c046 --- /dev/null +++ b/test/list_test.hpp @@ -0,0 +1,227 @@ +//////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2006. 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_LIST_TEST_HEADER +#define BOOST_INTERPROCESS_TEST_LIST_TEST_HEADER + +#include "check_equal_containers.hpp" +#include +#include +#include +#include +#include "print_container.hpp" +#include +#include + +namespace boost{ +namespace interprocess{ +namespace test{ + +template +struct push_data_function +{ + template + int operator()(int max, MyShmList *shmlist, MyStdList *stdlist) const + { + typedef typename MyShmList::value_type IntType; + for(int i = 0; i < max; ++i){ + IntType move_me(i); + shmlist->push_back(move(move_me)); + stdlist->push_back(i); + } + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + return 0; + } +}; + +template<> +struct push_data_function +{ + template + int operator()(int max, MyShmList *shmlist, MyStdList *stdlist) const + { + typedef typename MyShmList::value_type IntType; + for(int i = 0; i < max; ++i){ + IntType move_me(i); + shmlist->push_front(move(move_me)); + stdlist->push_front(i); + } + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + return 0; + } +}; + +template +struct pop_back_function +{ + template + int operator()(MyShmList *shmlist, MyStdList *stdlist) const + { + shmlist->pop_back(); + stdlist->pop_back(); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + return 0; + } +}; + +template<> +struct pop_back_function +{ + template + int operator()(MyShmList *shmlist, MyStdList *stdlist) const + { + (void)shmlist; (void)stdlist; + return 0; + } +}; + + + +template +int list_test (bool copied_allocators_equal = true) +{ + typedef std::list MyStdList; + typedef typename MyShmList::value_type IntType; + const int memsize = 65536; + const char *const shMemName = "MySharedMemory"; + const int max = 100; + typedef push_data_function push_data_t; + + //Named new capable shared mem allocator + //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 + MyShmList *shmlist = segment.template construct("MyList") + (segment.get_segment_manager()); + + MyStdList *stdlist = new MyStdList; + + if(push_data_t()(max, shmlist, stdlist)){ + return 1; + } + + shmlist->erase(shmlist->begin()++); + stdlist->erase(stdlist->begin()++); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + + if(pop_back_function()(shmlist, stdlist)){ + return 1; + } + + shmlist->pop_front(); + stdlist->pop_front(); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + + { + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me(-1); + aux_vect[i] = move(move_me); + } + int aux_vect2[50]; + for(int i = 0; i < 50; ++i){ + aux_vect2[i] = -1; + } + shmlist->assign(detail::make_move_iterator(&aux_vect[0]) + ,detail::make_move_iterator(&aux_vect[50])); + stdlist->assign(&aux_vect2[0], &aux_vect2[50]); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + } + + if(copied_allocators_equal){ + shmlist->sort(); + stdlist->sort(); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + } + + { + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me(-1); + aux_vect[i] = move(move_me); + } + int aux_vect2[50]; + for(int i = 0; i < 50; ++i){ + aux_vect2[i] = -1; + } + shmlist->insert(shmlist->begin() + ,detail::make_move_iterator(&aux_vect[0]) + ,detail::make_move_iterator(&aux_vect[50])); + stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]); + } + + shmlist->unique(); + stdlist->unique(); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + + if(copied_allocators_equal){ + shmlist->sort(std::greater()); + stdlist->sort(std::greater()); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + } + + shmlist->resize(shmlist->size()/2); + stdlist->resize(stdlist->size()/2); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + + const IntType &value1 = *shmlist->begin(); + shmlist->remove(value1); + const int &value2 = *stdlist->begin(); + stdlist->remove(value2); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + + if(push_data_t()(max, shmlist, stdlist)){ + return 1; + } + + MyShmList othershmlist(shmlist->get_allocator()); + MyStdList otherstdlist; + + int listsize = (int)shmlist->size(); + + if(push_data_t()(listsize, shmlist, stdlist)){ + return 1; + } + + if(copied_allocators_equal){ + shmlist->splice(shmlist->begin(), othershmlist); + stdlist->splice(stdlist->begin(), otherstdlist); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + } + + listsize = (int)shmlist->size(); + + if(push_data_t()(listsize, shmlist, stdlist)){ + return 1; + } + + if(copied_allocators_equal){ + shmlist->merge(othershmlist, std::greater()); + stdlist->merge(otherstdlist, std::greater()); + if(!CheckEqualContainers(shmlist, stdlist)) return 1; + } + + segment.template destroy("MyList"); + delete stdlist; + return 0; +} + +} //namespace test{ +} //namespace interprocess{ +} //namespace boost{ + +#endif diff --git a/test/map_test.hpp b/test/map_test.hpp new file mode 100644 index 0000000..654760b --- /dev/null +++ b/test/map_test.hpp @@ -0,0 +1,274 @@ +//////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2006. 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_MAP_TEST_HEADER +#define BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER + +#include "check_equal_containers.hpp" +#include +#include +#include +#include "print_container.hpp" +#include +#include + +template +bool operator ==(std::pair &p1, std::pair &p2) +{ + return p1.first == p2.first && p1.second == p2.second; +} + +namespace boost{ +namespace interprocess{ +namespace test{ + +template +int map_test () +{ + typedef typename MyShmMap::key_type IntType; + typedef std::pair IntPairType; + typedef typename MyStdMap::value_type StdPairType; + const int memsize = 65536; + const char *const shMemName = "/MySharedMemory"; + const int max = 100; + + //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 + MyShmMap *shmmap = + segment.template construct("MyShmMap") + (std::less(), segment.get_segment_manager()); + + MyStdMap *stdmap = new MyStdMap; + + MyShmMultiMap *shmmultimap = + segment.template construct("MyShmMultiMap") + (std::less(), segment.get_segment_manager()); + + MyStdMultiMap *stdmultimap = new MyStdMultiMap; + + int i, j; + for(i = 0; i < max; ++i){ + shmmap->insert(move(IntPairType (move(IntType(i)), move(IntType(i))))); + stdmap->insert(StdPairType(i, i)); + shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmultimap->insert(StdPairType(i, i)); + } + + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + + typename MyShmMap::iterator it; + typename MyShmMap::const_iterator cit = it; + + shmmap->erase(shmmap->begin()++); + stdmap->erase(stdmap->begin()++); + shmmultimap->erase(shmmultimap->begin()++); + stdmultimap->erase(stdmultimap->begin()++); + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + + shmmap->erase(shmmap->begin()); + stdmap->erase(stdmap->begin()); + shmmultimap->erase(shmmultimap->begin()); + stdmultimap->erase(stdmultimap->begin()); + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + + //Swapping test + std::less lessfunc; + MyShmMap tmpshmemap2 (lessfunc, segment.get_segment_manager()); + MyStdMap tmpstdmap2; + MyShmMultiMap tmpshmemultimap2(lessfunc, segment.get_segment_manager()); + MyStdMultiMap tmpstdmultimap2; + shmmap->swap(tmpshmemap2); + stdmap->swap(tmpstdmap2); + shmmultimap->swap(tmpshmemultimap2); + stdmultimap->swap(tmpstdmultimap2); + shmmap->swap(tmpshmemap2); + stdmap->swap(tmpstdmap2); + shmmultimap->swap(tmpshmemultimap2); + stdmultimap->swap(tmpstdmultimap2); + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + + //Insertion from other container + //Initialize values + { + //This is really nasty, but we have no other simple choice + IntPairType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1)); + } + IntPairType aux_vect3[50]; + for(int i = 0; i < 50; ++i){ + new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1)); + } + + shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50)); + StdPairType stdpairtype(-1, -1); + constant_iterator constant_beg(stdpairtype, 50), constant_end; + stdmap->insert(constant_beg, constant_end); + shmmultimap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50)); + stdmultimap->insert(constant_beg, constant_end); + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + + for(int i = 0, j = static_cast(shmmap->size()); i < j; ++i){ + shmmap->erase(IntType(i)); + stdmap->erase(i); + shmmultimap->erase(IntType(i)); + stdmultimap->erase(i); + } + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + } + { + IntPairType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1)); + } + + IntPairType aux_vect3[50]; + for(int i = 0; i < 50; ++i){ + new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1)); + } + + IntPairType aux_vect4[50]; + for(int i = 0; i < 50; ++i){ + new(&aux_vect4[i])IntPairType(IntType(-1), IntType(-1)); + } + + IntPairType aux_vect5[50]; + for(int i = 0; i < 50; ++i){ + new(&aux_vect5[i])IntPairType(IntType(-1), IntType(-1)); + } + + shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50)); + shmmap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50)); + StdPairType stdpairtype(-1, -1); + constant_iterator constant_beg(stdpairtype, 50), constant_end; + stdmap->insert(constant_beg, constant_end); + stdmap->insert(constant_beg, constant_end); + shmmultimap->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50)); + shmmultimap->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50)); + stdmultimap->insert(constant_beg, constant_end); + stdmultimap->insert(constant_beg, constant_end); + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + + shmmap->erase(shmmap->begin()->first); + stdmap->erase(stdmap->begin()->first); + shmmultimap->erase(shmmultimap->begin()->first); + stdmultimap->erase(stdmultimap->begin()->first); + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + } + + for(i = 0; i < max; ++i){ + shmmap->insert(move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmap->insert(StdPairType(i, i)); + shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmultimap->insert(StdPairType(i, i)); + } + + if(!CheckEqualPairContainers(shmmap, stdmap)) return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1; + + for(i = 0; i < max; ++i){ + shmmap->insert(shmmap->begin(), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmap->insert(stdmap->begin(), StdPairType(i, i)); + //PrintContainers(shmmap, stdmap); + shmmultimap->insert(shmmultimap->begin(), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmultimap->insert(stdmultimap->begin(), StdPairType(i, i)); + //PrintContainers(shmmultimap, stdmultimap); + if(!CheckEqualPairContainers(shmmap, stdmap)) + return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) + return 1; + + shmmap->insert(shmmap->end(), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmap->insert(stdmap->end(), StdPairType(i, i)); + shmmultimap->insert(shmmultimap->end(), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmultimap->insert(stdmultimap->end(), StdPairType(i, i)); + if(!CheckEqualPairContainers(shmmap, stdmap)) + return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) + return 1; + + shmmap->insert(shmmap->lower_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i)); + //PrintContainers(shmmap, stdmap); + shmmultimap->insert(shmmultimap->lower_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i)); + //PrintContainers(shmmultimap, stdmultimap); + if(!CheckEqualPairContainers(shmmap, stdmap)) + return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) + return 1; + shmmap->insert(shmmap->upper_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i)); + //PrintContainers(shmmap, stdmap); + shmmultimap->insert(shmmultimap->upper_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i))))); + stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i)); + //PrintContainers(shmmultimap, stdmultimap); + if(!CheckEqualPairContainers(shmmap, stdmap)) + return 1; + if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) + return 1; + } + + //Compare count with std containers + for(i = 0; i < max; ++i){ + if(shmmap->count(IntType(i)) != stdmap->count(i)){ + return -1; + } + + if(shmmultimap->count(IntType(i)) != stdmultimap->count(i)){ + return -1; + } + } + + //Now do count exercise + shmmap->clear(); + shmmultimap->clear(); + + for(j = 0; j < 3; ++j) + for(i = 0; i < 100; ++i){ + shmmap->insert(move(IntPairType(move(IntType(i)), move(IntType(i))))); + shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i))))); + if(shmmap->count(IntType(i)) != typename MyShmMultiMap::size_type(1)) + return 1; + if(shmmultimap->count(IntType(i)) != typename MyShmMultiMap::size_type(j+1)) + return 1; + } + + segment.template destroy("MyShmMap"); + delete stdmap; + segment.destroy_ptr(shmmultimap); + delete stdmultimap; + + return 0; +} + +} //namespace test{ +} //namespace interprocess{ +} //namespace boost{ + +#endif //#ifndef BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER diff --git a/test/mapped_file_test.cpp b/test/mapped_file_test.cpp index 2a2e2c7..59a72e6 100644 --- a/test/mapped_file_test.cpp +++ b/test/mapped_file_test.cpp @@ -10,7 +10,8 @@ #include #include -#include +#include +#include #include "named_creation_template.hpp" #include #include @@ -30,28 +31,31 @@ struct file_destroyer //This wrapper is necessary to have a common constructor //in generic named_creation_template functions class mapped_file_creation_test_wrapper - : public file_destroyer, public boost::interprocess::mapped_file + : public file_destroyer + , public boost::interprocess::detail::managed_open_or_create_impl + { + typedef boost::interprocess::detail::managed_open_or_create_impl + mapped_file; public: mapped_file_creation_test_wrapper(boost::interprocess::detail::create_only_t) - : boost::interprocess::mapped_file - (boost::interprocess::create_only, FileName, FileSize) + : mapped_file(boost::interprocess::create_only, FileName, FileSize) {} mapped_file_creation_test_wrapper(boost::interprocess::detail::open_only_t) - : boost::interprocess::mapped_file - (boost::interprocess::open_only, FileName) + : mapped_file(boost::interprocess::open_only, FileName) {} mapped_file_creation_test_wrapper(boost::interprocess::detail::open_or_create_t) - : boost::interprocess::mapped_file - (boost::interprocess::open_or_create, FileName, FileSize) + : mapped_file(boost::interprocess::open_or_create, FileName, FileSize) {} }; int main () { using namespace boost::interprocess; + typedef boost::interprocess::detail::managed_open_or_create_impl + mapped_file; std::remove(FileName); test::test_named_creation(); @@ -59,17 +63,13 @@ int main () { mapped_file file1(create_only, FileName, FileSize); - //Compare size - if(file1.get_size() != FileSize) - return 1; - //Compare name if(std::strcmp(file1.get_name(), FileName) != 0){ return 1; } //Overwrite all memory - std::memset(file1.get_address(), 0, FileSize); + std::memset(file1.get_address(), 0, file1.get_size()); } std::remove(FileName); return 0; diff --git a/test/movable_int.hpp b/test/movable_int.hpp new file mode 100644 index 0000000..98cdc27 --- /dev/null +++ b/test/movable_int.hpp @@ -0,0 +1,141 @@ +/////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2006. 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_MOVABLE_INT_HEADER +#define BOOST_INTERPROCESS_TEST_MOVABLE_INT_HEADER + +#include +#include +#include + +namespace boost { +namespace interprocess { +namespace test { + +class movable_int +{ + movable_int(const movable_int&); + movable_int &operator= (const movable_int&); + + public: + + movable_int() + : m_int(0) + {} + + explicit movable_int(int a) + : m_int(a) + {} + + movable_int(const detail::moved_object &mmi) + : m_int(mmi.get().m_int) + { mmi.get().m_int = 0; } + + movable_int & operator= (const detail::moved_object &mmi) + { this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; } + + bool operator ==(const movable_int &mi) const + { return this->m_int == mi.m_int; } + + bool operator !=(const movable_int &mi) const + { return this->m_int != mi.m_int; } + + bool operator <(const movable_int &mi) const + { return this->m_int < mi.m_int; } + + bool operator <=(const movable_int &mi) const + { return this->m_int <= mi.m_int; } + + bool operator >=(const movable_int &mi) const + { return this->m_int >= mi.m_int; } + + bool operator >(const movable_int &mi) const + { return this->m_int > mi.m_int; } + + private: + int m_int; +}; + +class movable_and_copyable_int +{ + public: + + movable_and_copyable_int() + : m_int(0) + {} + + explicit movable_and_copyable_int(int a) + : m_int(a) + {} + + movable_and_copyable_int(const movable_and_copyable_int& mmi) + : m_int(mmi.m_int) + {} + + movable_and_copyable_int &operator= (const movable_and_copyable_int& mi) + { this->m_int = mi.m_int; return *this; } + + movable_and_copyable_int(const detail::moved_object &mmi) + : m_int(mmi.get().m_int) + { mmi.get().m_int = 0; } + + movable_and_copyable_int & operator= (const detail::moved_object &mmi) + { this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; } + + bool operator ==(const movable_and_copyable_int &mi) const + { return this->m_int == mi.m_int; } + + bool operator !=(const movable_and_copyable_int &mi) const + { return this->m_int != mi.m_int; } + + bool operator <(const movable_and_copyable_int &mi) const + { return this->m_int < mi.m_int; } + + bool operator <=(const movable_and_copyable_int &mi) const + { return this->m_int <= mi.m_int; } + + bool operator >=(const movable_and_copyable_int &mi) const + { return this->m_int >= mi.m_int; } + + bool operator >(const movable_and_copyable_int &mi) const + { return this->m_int > mi.m_int; } + + private: + int m_int; +}; + + +} //namespace test { +} //namespace interprocess { +} //namespace boost { + +namespace boost{ +namespace interprocess{ + +template<> +struct is_movable +{ + public: + enum { value = true }; +}; + +template<> +struct is_movable +{ + public: + enum { value = true }; +}; + +} //namespace interprocess{ +} //namespace boost{ + +#include + +#endif //#ifndef BOOST_INTERPROCESS_TEST_MOVABLE_INT_HEADER diff --git a/test/mutex_test.cpp b/test/mutex_test.cpp index 770d14b..51db1e4 100644 --- a/test/mutex_test.cpp +++ b/test/mutex_test.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "mutex_test_template.hpp" #include "named_creation_template.hpp" diff --git a/test/mutex_test_template.hpp b/test/mutex_test_template.hpp index b4a20b3..1c88d2c 100644 --- a/test/mutex_test_template.hpp +++ b/test/mutex_test_template.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gazta�ga 2004-2006. Distributed under the Boost +// (C) Copyright Ion Gaztañaga 2004-2006. 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) // diff --git a/test/named_condition_test.cpp b/test/named_condition_test.cpp index 8203ed1..01c9ff1 100644 --- a/test/named_condition_test.cpp +++ b/test/named_condition_test.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include "condition_test_template.hpp" diff --git a/test/named_recursive_mutex_test.cpp b/test/named_recursive_mutex_test.cpp index fc1d149..1f878dc 100644 --- a/test/named_recursive_mutex_test.cpp +++ b/test/named_recursive_mutex_test.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "mutex_test_template.hpp" #include "named_creation_template.hpp" diff --git a/test/named_semaphore_test.cpp b/test/named_semaphore_test.cpp index 90e2cd0..dc98584 100644 --- a/test/named_semaphore_test.cpp +++ b/test/named_semaphore_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gazta�ga 2004-2006. Distributed under the Boost +// (C) Copyright Ion Gaztañaga 2004-2006. 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) // @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include "named_creation_template.hpp" diff --git a/test/named_upgradable_mutex_test.cpp b/test/named_upgradable_mutex_test.cpp index 46996eb..793c51a 100644 --- a/test/named_upgradable_mutex_test.cpp +++ b/test/named_upgradable_mutex_test.cpp @@ -64,9 +64,11 @@ int main () named_upgradable_mutex::remove("named_upgradable_mutex"); test::test_named_creation(); +/* test::test_all_lock(); test::test_all_mutex(); test::test_all_sharable_mutex(); +*/ } catch(std::exception &ex){ std::cout << ex.what() << std::endl; diff --git a/test/node_allocator_test.cpp b/test/node_allocator_test.cpp index 5e78855..a0953a6 100644 --- a/test/node_allocator_test.cpp +++ b/test/node_allocator_test.cpp @@ -10,135 +10,29 @@ #include #include -#include -#include -#include -#include -#include - #include #include #include -#include "printcontainer.hpp" - -/*****************************************************************/ -/* */ -/* This example repeats the same operations with std::list and */ -/* interprocess::list using the node allocator */ -/* and compares the values of both containers */ -/* */ -/*****************************************************************/ +#include "print_container.hpp" +#include "dummy_test_allocator.hpp" +#include "movable_int.hpp" +#include "list_test.hpp" using namespace boost::interprocess; //We will work with wide characters for shared memory objects //Alias node allocator type typedef node_allocator - shmem_node_allocator_t; + shmem_node_allocator_t; //Alias list types typedef list MyShmList; -typedef std::list MyStdList; - -//Function to check if both lists are equal -bool CheckEqual(MyShmList *shmlist, MyStdList *stdlist) -{ - return std::equal(shmlist->begin(), shmlist->end(), stdlist->begin()); -} int main () { - const int memsize = 65536; - const char *const shMemName = "MySharedMemory"; - const int max = 100; + if(test::list_test()) + return 1; - //Named new capable shared mem allocator - //Create shared memory - shared_memory_object::remove(shMemName); - wmanaged_shared_memory segment(create_only, shMemName, memsize); - - segment.reserve_named_objects(100); - - //Shared memory allocator must be always be initialized - //since it has no default constructor - MyShmList *shmlist = segment.construct(L"MyList") - (segment.get_segment_manager()); - - MyStdList *stdlist = new MyStdList; - - int i; - for(i = 0; i < max; ++i){ - shmlist->push_back(i); - stdlist->push_back(i); - } - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->erase(shmlist->begin()++); - stdlist->erase(stdlist->begin()++); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->pop_back(); - stdlist->pop_back(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->pop_front(); - stdlist->pop_front(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - std::vector aux_vect; - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, -1); - shmlist->assign(aux_vect.begin(), aux_vect.end()); - stdlist->assign(aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmlist, stdlist)) return 1; - #endif - - shmlist->sort(); - stdlist->sort(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, 0); - #endif - shmlist->insert(shmlist->begin(), aux_vect.begin(), aux_vect.end()); - stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end()); - - shmlist->unique(); - stdlist->unique(); - shmlist->size(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->sort(std::greater()); - stdlist->sort(std::greater()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->resize(shmlist->size()/2); - stdlist->resize(stdlist->size()/2); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->remove(*shmlist->begin()); - stdlist->remove(*stdlist->begin()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - for(i = 0; i < max; ++i){ - shmlist->push_back(i); - stdlist->push_back(i); - } - - MyShmList othershmlist(*shmlist); - MyStdList otherstdlist(*stdlist); - shmlist->splice(shmlist->begin(), othershmlist); - stdlist->splice(stdlist->begin(), otherstdlist); - if(!CheckEqual(shmlist, stdlist)) return 1; - - othershmlist = *shmlist; - otherstdlist = *stdlist; - shmlist->merge(othershmlist, std::greater()); - stdlist->merge(otherstdlist, std::greater()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - segment.destroy(L"MyList"); - delete stdlist; return 0; } diff --git a/test/print_container.hpp b/test/print_container.hpp new file mode 100644 index 0000000..1083064 --- /dev/null +++ b/test/print_container.hpp @@ -0,0 +1,64 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztañaga 2004-2006. 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_PRINTCONTAINER_HPP +#define BOOST_PRINTCONTAINER_HPP + +#include +#include +#include +#include + +namespace boost{ +namespace interprocess{ +namespace test{ + +struct PrintValues : public std::unary_function +{ + void operator() (int value) const + { + std::cout << value << " "; + } +}; + +template +void PrintContents(const Container &cont, const char *contName) +{ + std::cout<< "Printing contents of " << contName << std::endl; + std::for_each(cont.begin(), cont.end(), PrintValues()); + std::cout<< std::endl << std::endl; +} + +//Function to dump data +template +void PrintContainers(MyShmCont *shmcont, MyStdCont *stdcont) +{ + typename MyShmCont::iterator itshm = shmcont->begin(), itshmend = shmcont->end(); + typename MyStdCont::iterator itstd = stdcont->begin(), itstdend = stdcont->end(); + + std::cout << "MyShmCont" << std::endl; + for(; itshm != itshmend; ++itshm){ + std::cout << *itshm << std::endl; + } + std::cout << "MyStdCont" << *itstd << std::endl; + + for(; itstd != itstdend; ++itstd){ + std::cout << *itstd << std::endl; + } +} + +} //namespace test{ +} //namespace interprocess{ +} //namespace boost{ + +#include + +#endif //#ifndef BOOST_PRINTCONTAINER_HPP diff --git a/test/private_node_allocator_test.cpp b/test/private_node_allocator_test.cpp index a02e30c..e50e52a 100644 --- a/test/private_node_allocator_test.cpp +++ b/test/private_node_allocator_test.cpp @@ -10,133 +10,29 @@ #include #include -#include -#include -#include -#include -#include - #include -#include -#include #include -#include "printcontainer.hpp" - -/*****************************************************************/ -/* */ -/* This example repeats the same operations with std::list and */ -/* interprocess::list using the private node allocator */ -/* and compares the values of both containers */ -/* */ -/*****************************************************************/ +#include +#include "print_container.hpp" +#include "dummy_test_allocator.hpp" +#include "movable_int.hpp" +#include "list_test.hpp" using namespace boost::interprocess; //We will work with wide characters for shared memory objects //Alias node allocator type typedef private_node_allocator - priv_node_allocator_t; + priv_node_allocator_t; //Alias list types -typedef list MyShmList; -typedef std::list MyStdList; - -//Function to check if both lists are equal -bool CheckEqual(MyShmList *shmlist, MyStdList *stdlist) -{ - return std::equal(shmlist->begin(), shmlist->end(), stdlist->begin()); -} +typedef list MyShmList; int main () { - const int memsize = 1048576; - const char *const shMemName = "MySharedMemory"; - const int max = 100; + if(test::list_test(false)) + return 1; - //Named new capable shared mem allocator - shared_memory_object::remove(shMemName); - wmanaged_shared_memory segment(create_only, shMemName, memsize); - - //Shared memory allocator must be always be initialized - //since it has no default constructor - MyShmList *shmlist = segment.construct - (L"MyVect") - (segment.get_segment_manager()); - - MyStdList *stdlist = new MyStdList; - - int i; - for(i = 0; i < max; ++i){ - shmlist->push_back(i); - stdlist->push_back(i); - } - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->erase(shmlist->begin()++); - stdlist->erase(stdlist->begin()++); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->pop_back(); - stdlist->pop_back(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->pop_front(); - stdlist->pop_front(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - std::vector aux_vect; - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, -1); - shmlist->assign(aux_vect.begin(), aux_vect.end()); - stdlist->assign(aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmlist, stdlist)) return 1; - #endif - - shmlist->sort(); - stdlist->sort(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, 0); - #endif - shmlist->insert(shmlist->begin(), aux_vect.begin(), aux_vect.end()); - stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end()); - - shmlist->unique(); - stdlist->unique(); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->sort(std::greater()); - stdlist->sort(std::greater()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->resize(shmlist->size()/2); - stdlist->resize(stdlist->size()/2); - if(!CheckEqual(shmlist, stdlist)) return 1; - - shmlist->remove(*shmlist->begin()); - stdlist->remove(*stdlist->begin()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - for(i = 0; i < max; ++i){ - shmlist->push_back(i); - stdlist->push_back(i); - } - - MyShmList othershmlist(*shmlist); - MyStdList otherstdlist(*stdlist); - shmlist->splice(shmlist->begin(), othershmlist); - stdlist->splice(stdlist->begin(), otherstdlist); - if(!CheckEqual(shmlist, stdlist)) return 1; - - othershmlist = *shmlist; - otherstdlist = *stdlist; - shmlist->merge(othershmlist, std::greater()); - stdlist->merge(otherstdlist, std::greater()); - if(!CheckEqual(shmlist, stdlist)) return 1; - - segment.destroy(L"MyVect"); - delete stdlist; return 0; } diff --git a/test/recursive_mutex_test.cpp b/test/recursive_mutex_test.cpp index 8e6be7f..7c81ca2 100644 --- a/test/recursive_mutex_test.cpp +++ b/test/recursive_mutex_test.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "mutex_test_template.hpp" #include "named_creation_template.hpp" @@ -19,7 +18,6 @@ int main () { using namespace boost::interprocess; - test::test_all_lock(); test::test_all_mutex(); test::test_all_recursive_lock(); diff --git a/test/set_test.hpp b/test/set_test.hpp index 898ad63..e8d33d5 100644 --- a/test/set_test.hpp +++ b/test/set_test.hpp @@ -11,48 +11,17 @@ #ifndef BOOST_INTERPROCESS_TEST_SET_TEST_HEADER #define BOOST_INTERPROCESS_TEST_SET_TEST_HEADER -#include +#include "check_equal_containers.hpp" #include -#include #include -#include #include -#include "printcontainer.hpp" +#include "print_container.hpp" +#include namespace boost{ namespace interprocess{ namespace test{ -//Function to dump data -template -void PrintContainers(MyShmSet *shmset, MyStdSet *stdset) -{ - typename MyShmSet::iterator itshm = shmset->begin(), itshmend = shmset->end(); - typename MyStdSet::iterator itstd = stdset->begin(), itstdend = stdset->end(); - - std::cout << "MyShmSet" << std::endl; - for(; itshm != itshmend; ++itshm){ - std::cout << *itshm << std::endl; - } - std::cout << "MyStdSet" << *itstd << std::endl; - - for(; itstd != itstdend; ++itstd){ - std::cout << *itstd << std::endl; - } -} - - -//Function to check if both sets are equal -template -bool CheckEqual(MyShmSet *shmset, MyStdSet *stdset) -{ - if(shmset->size() != stdset->size()) - return false; - return std::equal(shmset->begin(), shmset->end(), stdset->begin()); -} - template int set_test () { + typedef typename MyShmSet::value_type IntType; const int memsize = 65536; const char *const shMemName = "/MySharedMemory"; const int max = 100; @@ -72,25 +42,29 @@ int set_test () //Shared memory allocator must be always be initialized //since it has no default constructor - MyShmSet *shmset = segment.template construct("MyShmSet") - (std::less(), segment.get_segment_manager()); + MyShmSet *shmset = + segment.template construct("MyShmSet") + (std::less(), segment.get_segment_manager()); MyStdSet *stdset = new MyStdSet; - MyShmMultiSet *shmmultiset = segment.template construct("MyShmMultiSet") - (std::less(), segment.get_segment_manager()); + MyShmMultiSet *shmmultiset = + segment.template construct("MyShmMultiSet") + (std::less(), segment.get_segment_manager()); MyStdMultiSet *stdmultiset = new MyStdMultiSet; int i, j; for(i = 0; i < max; ++i){ - shmset->insert(i); + IntType move_me(i); + shmset->insert(move(move_me)); stdset->insert(i); - shmmultiset->insert(i); + IntType move_me2(i); + shmmultiset->insert(move(move_me2)); stdmultiset->insert(i); } - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; typename MyShmSet::iterator it; typename MyShmSet::const_iterator cit = it; @@ -99,18 +73,18 @@ int set_test () stdset->erase(stdset->begin()++); shmmultiset->erase(shmmultiset->begin()++); stdmultiset->erase(stdmultiset->begin()++); - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; shmset->erase(shmset->begin()); stdset->erase(stdset->begin()); shmmultiset->erase(shmmultiset->begin()); stdmultiset->erase(stdmultiset->begin()); - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; //Swapping test - std::less lessfunc; + std::less lessfunc; MyShmSet tmpshmeset2 (lessfunc, segment.get_segment_manager()); MyStdSet tmpstdset2; MyShmMultiSet tmpshmemultiset2(lessfunc, segment.get_segment_manager()); @@ -123,113 +97,165 @@ int set_test () stdset->swap(tmpstdset2); shmmultiset->swap(tmpshmemultiset2); stdmultiset->swap(tmpstdmultiset2); - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; //Insertion from other container - std::vector aux_vect; - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, -1); - shmset->insert(aux_vect.begin(), aux_vect.end()); - stdset->insert(aux_vect.begin(), aux_vect.end()); - shmmultiset->insert(aux_vect.begin(), aux_vect.end()); - stdmultiset->insert(aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; - #endif + //Initialize values + { + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me(-1); + aux_vect[i] = 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] = move(move_me); + } - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - for(i = 0, j = static_cast(shmset->size()); i < j; ++i){ - shmset->erase(i); - stdset->erase(i); - shmmultiset->erase(i); - stdmultiset->erase(i); + shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50)); + stdset->insert(aux_vect2, aux_vect2 + 50); + shmmultiset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50)); + stdmultiset->insert(aux_vect2, aux_vect2 + 50); + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; + + for(int i = 0, j = static_cast(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)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; } - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; - #endif + { + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me(-1); + aux_vect[i] = 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] = move(move_me); + } - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - shmset->insert(aux_vect.begin(), aux_vect.end()); - shmset->insert(aux_vect.begin(), aux_vect.end()); - stdset->insert(aux_vect.begin(), aux_vect.end()); - stdset->insert(aux_vect.begin(), aux_vect.end()); - shmmultiset->insert(aux_vect.begin(), aux_vect.end()); - shmmultiset->insert(aux_vect.begin(), aux_vect.end()); - stdmultiset->insert(aux_vect.begin(), aux_vect.end()); - stdmultiset->insert(aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; - #endif + IntType aux_vect4[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me(-1); + aux_vect4[i] = move(move_me); + } - shmset->erase(*shmset->begin()); - stdset->erase(*stdset->begin()); - shmmultiset->erase(*shmmultiset->begin()); - stdmultiset->erase(*stdmultiset->begin()); - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; + IntType aux_vect5[50]; + for(int i = 0; i < 50; ++i){ + IntType move_me(-1); + aux_vect5[i] = move(move_me); + } + + shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50)); + shmset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50)); + stdset->insert(aux_vect2, aux_vect2 + 50); + stdset->insert(aux_vect2, aux_vect2 + 50); + shmmultiset->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50)); + shmmultiset->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50)); + stdmultiset->insert(aux_vect2, aux_vect2 + 50); + stdmultiset->insert(aux_vect2, aux_vect2 + 50); + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; + + shmset->erase(*shmset->begin()); + stdset->erase(*stdset->begin()); + shmmultiset->erase(*shmmultiset->begin()); + stdmultiset->erase(*stdmultiset->begin()); + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; + } for(i = 0; i < max; ++i){ - shmset->insert(i); + IntType move_me(i); + shmset->insert(move(move_me)); stdset->insert(i); - shmmultiset->insert(i); + IntType move_me2(i); + shmmultiset->insert(move(move_me2)); stdmultiset->insert(i); } - if(!CheckEqual(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) return 1; + if(!CheckEqualContainers(shmset, stdset)) return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; for(i = 0; i < max; ++i){ - shmset->insert(shmset->begin(), i); + IntType move_me(i); + shmset->insert(shmset->begin(), move(move_me)); stdset->insert(stdset->begin(), i); //PrintContainers(shmset, stdset); - shmmultiset->insert(shmmultiset->begin(), i); + IntType move_me2(i); + shmmultiset->insert(shmmultiset->begin(), move(move_me2)); stdmultiset->insert(stdmultiset->begin(), i); //PrintContainers(shmmultiset, stdmultiset); - if(!CheckEqual(shmset, stdset)) + if(!CheckEqualContainers(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; - shmset->insert(shmset->end(), i); + IntType move_me3(i); + shmset->insert(shmset->end(), move(move_me3)); stdset->insert(stdset->end(), i); - shmmultiset->insert(shmmultiset->end(), i); + IntType move_me4(i); + shmmultiset->insert(shmmultiset->end(), move(move_me4)); stdmultiset->insert(stdmultiset->end(), i); - if(!CheckEqual(shmset, stdset)) + if(!CheckEqualContainers(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; - - shmset->insert(shmset->lower_bound(i), i); - stdset->insert(stdset->lower_bound(i), i); - //PrintContainers(shmset, stdset); - shmmultiset->insert(shmmultiset->lower_bound(i), i); - stdmultiset->insert(stdmultiset->lower_bound(i), i); - //PrintContainers(shmmultiset, stdmultiset); - if(!CheckEqual(shmset, stdset)) - return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) - return 1; - shmset->insert(shmset->upper_bound(i), i); + { + IntType move_me(i); + shmset->insert(shmset->upper_bound(move_me), move(move_me)); stdset->insert(stdset->upper_bound(i), i); //PrintContainers(shmset, stdset); - shmmultiset->insert(shmmultiset->upper_bound(i), i); + IntType move_me2(i); + shmmultiset->insert(shmmultiset->upper_bound(move_me2), move(move_me2)); stdmultiset->insert(stdmultiset->upper_bound(i), i); //PrintContainers(shmmultiset, stdmultiset); - if(!CheckEqual(shmset, stdset)) + if(!CheckEqualContainers(shmset, stdset)) return 1; - if(!CheckEqual(shmmultiset, stdmultiset)) + if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1; + } + { + IntType move_me(i); + shmset->insert(shmset->lower_bound(move_me), move(move_me2)); + stdset->insert(stdset->lower_bound(i), i); + //PrintContainers(shmset, stdset); + IntType move_me2(i); + shmmultiset->insert(shmmultiset->lower_bound(move_me2), move(move_me2)); + stdmultiset->insert(stdmultiset->lower_bound(i), i); + //PrintContainers(shmmultiset, stdmultiset); + if(!CheckEqualContainers(shmset, stdset)) + return 1; + if(!CheckEqualContainers(shmmultiset, stdmultiset)) + return 1; + } } //Compare count with std containers for(i = 0; i < max; ++i){ - if(shmset->count(i) != stdset->count(i)){ + IntType count_me(i); + if(shmset->count(count_me) != stdset->count(i)){ return -1; } - - if(shmmultiset->count(i) != stdmultiset->count(i)){ + if(shmmultiset->count(count_me) != stdmultiset->count(i)){ return -1; } } @@ -240,11 +266,14 @@ int set_test () for(j = 0; j < 3; ++j) for(i = 0; i < 100; ++i){ - shmset->insert(i); - shmmultiset->insert(i); - if(shmset->count(i) != typename MyShmMultiSet::size_type(1)) + IntType move_me(i); + shmset->insert(move(move_me)); + IntType move_me2(i); + shmmultiset->insert(move(move_me2)); + IntType count_me(i); + if(shmset->count(count_me) != typename MyShmMultiSet::size_type(1)) return 1; - if(shmmultiset->count(i) != typename MyShmMultiSet::size_type(j+1)) + if(shmmultiset->count(count_me) != typename MyShmMultiSet::size_type(j+1)) return 1; } diff --git a/test/sharable_mutex_test_template.hpp b/test/sharable_mutex_test_template.hpp index 7faeee3..95da5d4 100644 --- a/test/sharable_mutex_test_template.hpp +++ b/test/sharable_mutex_test_template.hpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/test/shared_memory_mapping_test.cpp b/test/shared_memory_mapping_test.cpp index e07762e..a49274d 100644 --- a/test/shared_memory_mapping_test.cpp +++ b/test/shared_memory_mapping_test.cpp @@ -13,7 +13,8 @@ #include #include -#include +#include +#include using namespace boost::interprocess; @@ -26,23 +27,23 @@ int main () shared_memory_object::remove("my_file"); //Create shared memory and file mapping - shared_memory_object mapping(create_only, "my_file", shared_memory_object::read_write); + shared_memory_object mapping(create_only, "my_file", read_write); mapping.truncate(FileSize); } { //Create a file mapping - shared_memory_object mapping(open_only, "my_file", shared_memory_object::read_write); + shared_memory_object mapping(open_only, "my_file", read_write); //Create two mapped regions, one half of the file each mapped_region region (mapping - ,mapped_region::read_write + ,read_write ,0 ,FileSize/2 ,0); mapped_region region2(mapping - ,mapped_region::read_write + ,read_write ,FileSize/2 ,FileSize - FileSize/2 ,0); @@ -66,9 +67,9 @@ int main () //See if the pattern is correct in the file using two mapped regions { //Create a file mapping - shared_memory_object mapping(open_only, "my_file", shared_memory_object::read_write); - mapped_region region(mapping, mapped_region::read_write, 0, FileSize/2, 0); - mapped_region region2(mapping, mapped_region::read_write, FileSize/2, 0/*FileSize - FileSize/2*/, 0); + shared_memory_object mapping(open_only, "my_file", read_write); + mapped_region region(mapping, read_write, 0, FileSize/2, 0); + mapped_region region2(mapping, read_write, FileSize/2, 0/*FileSize - FileSize/2*/, 0); unsigned char *checker = (unsigned char*)region.get_address(); //Check pattern @@ -96,11 +97,11 @@ int main () //Now check the pattern mapping a single read only mapped_region { //Create a file mapping - shared_memory_object mapping(open_only, "my_file", shared_memory_object::read_only); + shared_memory_object mapping(open_only, "my_file", read_only); //Create a single regions, mapping all the file mapped_region region (mapping - ,mapped_region::read_only); + ,read_only); //Check pattern unsigned char *pattern = static_cast(region.get_address()); @@ -121,149 +122,3 @@ int main () } #include - -/* -#include -#include -#include -#include -#include -#include - -char allchars [] = "abcdefghijklmnopqrstuvwxyz"; - -struct DictionaryValue -{ - std::string str; - std::size_t count; - bool operator == (const DictionaryValue &other) const - { return str == other.str; } -}; - -struct DictionaryHasher -: std::unary_function -{ - std::size_t operator()(const DictionaryValue &val) const - { - const char *str = val.str.data(); - std::size_t len = val.str.size(); - std::size_t hash = 0; - - for (;;) - { - switch (len) - { - case 0: - return hash; - - case 1: - hash *= 37; - hash += *(unsigned char *)str; - return hash; - - case 2: - hash *= 37; - hash += *(unsigned short *)str; - return hash; - - case 3: - hash *= 37; - hash += (*(unsigned short *)str << 8) + - ((unsigned char *)str)[2]; - return hash; - - default: - hash *= 37; - hash += *(long *)str; - str += 4; - len -= 4; - break; - } - } - } - -}; - -int main( int argc, char* argv[] ) -{ - std::size_t w_total = 0; - std::size_t l_total = 0; - std::size_t c_total = 0; - - typedef boost::unordered_set - ,boost::fast_pool_allocator - > Dictionary; - - Dictionary dictionary; - typedef Dictionary::iterator iterator; - DictionaryValue dict_value; - - std::ifstream input_file(argv[1], std::ios_base::in | std::ios_base::binary ); - input_file.seekg(0, std::ios::end); - - std::vector data(static_cast(input_file.tellg())); - input_file.seekg(0, std::ios::beg); - input_file.read(&data[0], static_cast(data.size())); - input_file.close(); - - std::size_t w_count = 0; - std::size_t w_diff = 'z'-'a'; - - for ( int a = 0; a < 100; ++a ) - { - std::string &word = dict_value.str; - word.reserve(64); - dict_value.count = 0; - - std::size_t w_cnt = 0; - std::size_t l_cnt = 0; - std::size_t c_cnt = 0; - bool inword = false; - std::size_t wstart = 0; - for ( std::size_t j = 0, size = data.size(); j < size; j++ ) - { - char c = data[j]; - if (c == '\n') - ++l_cnt; - if (c >= '0' && c <= '9') - { - } - else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') - { - if (!inword) - { - wstart = j; - inword = true; - ++w_cnt; - } - } - else if (inword) - { - word.assign(&data[wstart], &data[j]); - ++w_count; - std::size_t num = w_count%25; - word.insert(1, 1, allchars[num]); -// dictionary.insert(dict_value).first->count++; - inword = false; - } - ++c_cnt; - } - - if (inword) - { - word.assign(&data[wstart], &data[data.size()]); - ++w_count; - std::size_t num = w_count%25; - word.insert(1, 1, allchars[num]); -// dictionary.insert(dict_value).first->count++; - } - l_total += l_cnt; - w_total += w_cnt; - c_total += c_cnt; - } - - return 0; -} -*/ diff --git a/test/shared_memory_test.cpp b/test/shared_memory_test.cpp index b7eefaa..297ee72 100644 --- a/test/shared_memory_test.cpp +++ b/test/shared_memory_test.cpp @@ -10,7 +10,8 @@ #include #include -#include +#include +#include #include #include "named_creation_template.hpp" #include //for strcmp, memset @@ -19,9 +20,9 @@ static const std::size_t ShmSize = 1000; static const char * ShmName = "shared_memory"; -struct shared_memory_eraser +struct eraser { - ~shared_memory_eraser() + ~eraser() { boost::interprocess::shared_memory_object::remove(ShmName); } @@ -30,22 +31,24 @@ struct shared_memory_eraser //This wrapper is necessary to have a common constructor //in generic named_creation_template functions class shared_memory_creation_test_wrapper - : public boost::interprocess::shared_memory + : public eraser + , public boost::interprocess::detail::managed_open_or_create_impl + { + typedef boost::interprocess::detail::managed_open_or_create_impl + shared_memory; + public: shared_memory_creation_test_wrapper(boost::interprocess::detail::create_only_t) - : boost::interprocess::shared_memory - (boost::interprocess::create_only, ShmName, ShmSize) + : shared_memory(boost::interprocess::create_only, ShmName, ShmSize) {} shared_memory_creation_test_wrapper(boost::interprocess::detail::open_only_t) - : boost::interprocess::shared_memory - (boost::interprocess::open_only, ShmName) + : shared_memory(boost::interprocess::open_only, ShmName) {} shared_memory_creation_test_wrapper(boost::interprocess::detail::open_or_create_t) - : boost::interprocess::shared_memory - (boost::interprocess::open_or_create, ShmName, ShmSize) + : shared_memory(boost::interprocess::open_or_create, ShmName, ShmSize) {} }; @@ -53,6 +56,8 @@ class shared_memory_creation_test_wrapper int main () { using namespace boost::interprocess; + typedef detail::managed_open_or_create_impl shared_memory; + try{ shared_memory_object::remove(ShmName); test::test_named_creation(); @@ -62,17 +67,13 @@ int main () shared_memory_object::remove(ShmName); shared_memory shm1(create_only, ShmName, ShmSize); - //Compare size - if(shm1.get_size() != ShmSize) - return 1; - //Compare name if(std::strcmp(shm1.get_name(), ShmName) != 0){ return 1; } //Overwrite all memory - std::memset(shm1.get_address(), 0, ShmSize); + std::memset(shm1.get_address(), 0, shm1.get_size()); } } catch(std::exception &ex){ @@ -82,4 +83,3 @@ int main () } #include - diff --git a/test/slist_test.cpp b/test/slist_test.cpp index ca7f6a8..893f9fd 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -10,149 +10,40 @@ #include #include -#include -#include -#include -#include -#include - #include #include -#include -#include -#include "printcontainer.hpp" - - -/*****************************************************************/ -/* */ -/* This example repeats the same operations with std::list and */ -/* interprocess::slist using the node allocator */ -/* and compares the values of both containers */ -/* */ -/*****************************************************************/ +#include +#include +#include "dummy_test_allocator.hpp" +#include "list_test.hpp" +#include "movable_int.hpp" using namespace boost::interprocess; //Explicit instantiation to detect compilation errors -template class slist >; +template class boost::interprocess::slist >; -//We will work with narrow characters for shared memory objects -//Alias node allocator type -typedef node_allocator - shmem_node_allocator_t; +typedef allocator ShmemAllocator; +typedef slist MyList; -//Explicit instantiation to detect compilation errors -template class slist; +typedef allocator ShmemMoveAllocator; +typedef slist MyMoveList; -//Alias slist types -typedef slist MyShmSlist; -typedef std::list MyStdList; - -//Function to check if both slists are equal -bool CheckEqual(MyShmSlist *shmslist, MyStdList *stdlist) -{ - return std::equal(shmslist->begin(), shmslist->end(), stdlist->begin()); -} +typedef allocator ShmemCopyMoveAllocator; +typedef slist MyCopyMoveList; int main () { - const int memsize = 655360; - const char *const shMemName = "MySharedMemory"; - const int max = 100; + if(test::list_test()) + return 1; - //Create shared memory - shared_memory_object::remove(shMemName); - managed_shared_memory segment(create_only, shMemName, memsize); + if(test::list_test()) + return 1; - segment.reserve_named_objects(100); + if(test::list_test()) + return 1; - //Shared memory allocator must be always be initialized - //since it has no default constructor - MyShmSlist *shmslist = segment.construct("MyShmSlist") - (segment.get_segment_manager()); - - MyStdList *stdlist = new MyStdList; - - int i, j; - for(i = 0; i < max; ++i){ - shmslist->insert(shmslist->begin(), i); - stdlist->insert(stdlist->begin(), i); - } - if(!CheckEqual(shmslist, stdlist)) return 1; - - MyShmSlist::iterator it; - MyShmSlist::const_iterator cit = it; - - shmslist->erase(shmslist->begin()++); - stdlist->erase(stdlist->begin()++); - if(!CheckEqual(shmslist, stdlist)) return 1; - - shmslist->erase(shmslist->begin()); - stdlist->erase(stdlist->begin()); - if(!CheckEqual(shmslist, stdlist)) return 1; - - //Swapping test - MyShmSlist tmpshmslist2 (segment.get_segment_manager()); - MyStdList tmpstdlist2; - shmslist->swap(tmpshmslist2); - stdlist->swap(tmpstdlist2); - shmslist->swap(tmpshmslist2); - stdlist->swap(tmpstdlist2); - if(!CheckEqual(shmslist, stdlist)) return 1; - - //Insertion from other container - std::vector aux_vect; - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, -1); - shmslist->insert(shmslist->begin(), aux_vect.begin(), aux_vect.end()); - stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmslist, stdlist)) return 1; - #endif - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - for(i = 0, j = static_cast(shmslist->size()); i < j; ++i){ - shmslist->erase(shmslist->begin()); - stdlist->erase(stdlist->begin()); - } - if(!CheckEqual(shmslist, stdlist)) return 1; - #endif - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - shmslist->insert(shmslist->begin(), aux_vect.begin(), aux_vect.end()); - stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmslist, stdlist)) return 1; - #endif - - shmslist->remove(*shmslist->begin()); - stdlist->remove(*stdlist->begin()); - if(!CheckEqual(shmslist, stdlist)) return 1; - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - shmslist->insert(shmslist->begin(), aux_vect.begin(), aux_vect.end()); - stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmslist, stdlist)) return 1; - #endif - - tmpshmslist2.assign(shmslist->begin(), shmslist->end()); - tmpstdlist2.assign(stdlist->begin(), stdlist->end()); - shmslist->insert(shmslist->begin(), aux_vect.begin(), aux_vect.end()); - stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end()); - shmslist->splice(++shmslist->begin(), tmpshmslist2); - stdlist->splice(++stdlist->begin(), tmpstdlist2); - if(!CheckEqual(shmslist, stdlist)) return 1; - - shmslist->sort(); - stdlist->sort(); - if(!CheckEqual(shmslist, stdlist)) return 1; - - tmpshmslist2.assign(shmslist->begin(), shmslist->end()); - tmpstdlist2.assign(stdlist->begin(), stdlist->end()); - shmslist->merge(tmpshmslist2); - stdlist->merge(tmpstdlist2); - if(!CheckEqual(shmslist, stdlist)) return 1; - - segment.destroy("MyShmSlist"); - delete stdlist; return 0; } diff --git a/test/string_test.cpp b/test/string_test.cpp index ad8e7d3..fb8a7da 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -21,64 +21,61 @@ #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 "allocator_v1.hpp" using namespace boost::interprocess; -//Explicit instantiation of interprocess::basic_string -//Explicit instantiation of a interprocess::vector of interprocess::strings -typedef allocator ShmemAllocatorChar; -typedef basic_string, ShmemAllocatorChar> ShmString; -typedef allocator ShmemVectorAllocator; -typedef vector ShmStringVector; -template class basic_string, ShmemAllocatorChar>; -template class vector; +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; -typedef std::allocator StdAllocatorChar; -typedef std::basic_string, StdAllocatorChar> StdString; -typedef std::allocator StdVectorAllocator; -typedef vector StdStringVector; +//Explicit instantiations of interprocess::basic_string +template class basic_string, DummyCharAllocator>; +template class basic_string, DummyWCharAllocator>; +//Explicit instantiation of interprocess::vectors of interprocess::strings +template class vector; +template class vector; struct StringEqual { - bool operator ()(const StdString &stdstring, const ShmString &shmstring) const + template + bool operator ()(const Str1 &string1, const Str2 &string2) const { - return std::strcmp(stdstring.c_str(), shmstring.c_str()) == 0; - } - - bool operator ()(const ShmString &shmstring, const StdString &stdstring) const - { - return std::strcmp(stdstring.c_str(), shmstring.c_str()) == 0; + 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 -bool CheckEqual(ShmStringVector *shmvect, StdStringVector *stdvect) +template +bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2) { - return std::equal(stdvect->begin(), stdvect->end(), - shmvect->begin(), StringEqual() ); + StringEqual comp; + return std::equal(strvect1->begin(), strvect1->end(), + strvect2->begin(), comp); } -//Function to check if both lists are equal -bool Print(ShmStringVector *shmvect, StdStringVector *stdvect) +template class AllocatorType > +int string_test() { - std::cout << "shmvect: " << static_cast(shmvect->size()) << std::endl; - for(ShmStringVector::iterator beg = shmvect->begin(), - end = shmvect->end(); - beg != end; ++beg){ - std::cout << *beg << std::endl; - } + typedef std::allocator StdAllocatorChar; + typedef std::basic_string, StdAllocatorChar> StdString; + typedef std::allocator StdStringAllocator; + typedef vector StdStringVector; + typedef AllocatorType ShmemAllocatorChar; + typedef basic_string, ShmemAllocatorChar> ShmString; + typedef AllocatorType ShmemStringAllocator; + typedef vector ShmStringVector; - std::cout << "stdvect: " << static_cast(stdvect->size()) << std::endl; - for(StdStringVector::iterator beg = stdvect->begin(), - end = stdvect->end(); - beg != end; ++beg){ - std::cout << *beg << std::endl; - } - return true; -} - -int main () -{ const int MaxSize = 100; //Create shared memory @@ -92,8 +89,8 @@ int main () //Initialize vector with a range or iterators and allocator ShmStringVector *shmStringVect = - segment.find_or_construct - ("ShmStringVector", std::nothrow) //object name + segment.construct + (anonymous_instance, std::nothrow) //object name (shmallocator); StdStringVector *stdStringVect = new StdStringVector; @@ -101,10 +98,10 @@ int main () ShmString auxShmString (segment.get_segment_manager()); StdString auxStdString(StdString(auxShmString.begin(), auxShmString.end() )); - char buffer [20]; + CharType buffer [20]; - int i; - for(i = 0; i < MaxSize; ++i){ + //First, push back + for(int i = 0; i < MaxSize; ++i){ auxShmString = "String"; auxStdString = "String"; std::sprintf(buffer, "%i", i); @@ -114,32 +111,102 @@ int main () stdStringVect->push_back(auxStdString); } - if(!CheckEqual(shmStringVect, stdStringVect)){ - Print(shmStringVect, stdStringVect); + 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(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(), 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()(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; - if(!StringEqual()(auxShmString, auxStdString)) 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; - if(!CheckEqual(shmStringVect, stdStringVect)) return 1; - - const char prefix [] = "Prefix"; + const CharType prefix [] = "Prefix"; const int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1; - const char sufix [] = "Suffix"; + const CharType sufix [] = "Suffix"; - for(i = 0; i < MaxSize; ++i){ + for(int i = 0; i < MaxSize; ++i){ (*shmStringVect)[i].append(sufix); (*stdStringVect)[i].append(sufix); (*shmStringVect)[i].insert((*shmStringVect)[i].begin(), @@ -148,30 +215,30 @@ int main () prefix, prefix + prefix_size); } - if(!CheckEqual(shmStringVect, stdStringVect)) return 1; + if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; - for(i = 0; i < MaxSize; ++i){ + for(int i = 0; i < MaxSize; ++i){ std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end()); std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); } - if(!CheckEqual(shmStringVect, stdStringVect)) return 1; + if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; - for(i = 0; i < MaxSize; ++i){ + for(int i = 0; i < MaxSize; ++i){ std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end()); std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); } - if(!CheckEqual(shmStringVect, stdStringVect)) return 1; + if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; - for(i = 0; i < MaxSize; ++i){ + for(int i = 0; i < MaxSize; ++i){ std::sort(shmStringVect->begin(), shmStringVect->end()); std::sort(stdStringVect->begin(), stdStringVect->end()); } - if(!CheckEqual(shmStringVect, stdStringVect)) return 1; + if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; - for(i = 0; i < MaxSize; ++i){ + for(int i = 0; i < MaxSize; ++i){ (*shmStringVect)[i].replace((*shmStringVect)[i].begin(), (*shmStringVect)[i].end(), "String"); @@ -180,20 +247,45 @@ int main () "String"); } - if(!CheckEqual(shmStringVect, stdStringVect)) return 1; + 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()); -// Print(shmStringVect, stdStringVect); - if(!CheckEqual(shmStringVect, stdStringVect)) return 1; + if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; //When done, delete vector - segment.destroy("ShmStringVector"); + segment.destroy_ptr(shmStringVect); 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(); +} + +int main() +{ + if(string_test()){ + return 1; + } + + if(string_test()){ + return 1; + } + + if(!test_expand_bwd()) + return 1; + + return 0; +} + #include diff --git a/test/tree_test.cpp b/test/tree_test.cpp index 39cc9cc..2ad8fc6 100644 --- a/test/tree_test.cpp +++ b/test/tree_test.cpp @@ -7,6 +7,7 @@ // See http://www.boost.org/libs/interprocess for documentation. // ////////////////////////////////////////////////////////////////////////////// + #include #include @@ -16,8 +17,11 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" +#include "movable_int.hpp" +#include "dummy_test_allocator.hpp" #include "set_test.hpp" +#include "map_test.hpp" /////////////////////////////////////////////////////////////////// // // @@ -27,14 +31,33 @@ // // /////////////////////////////////////////////////////////////////// -//Explicit instantiation to detect compilation errors -template class boost::interprocess::set, std::allocator >; -template class boost::interprocess::multiset, std::allocator >; -template class boost::interprocess::map, std::allocator > >; -template class boost::interprocess::multimap, std::allocator > >; - using namespace boost::interprocess; +//Explicit instantiation to detect compilation errors +template class boost::interprocess::set + + ,test::dummy_test_allocator >; + +template class boost::interprocess::map + + ,test::dummy_test_allocator > >; + +template class boost::interprocess::multiset + + ,test::dummy_test_allocator >; + +template class boost::interprocess::multimap + + ,test::dummy_test_allocator > >; + //Customize managed_shared_memory class typedef basic_managed_shared_memory node allocator type typedef node_allocator shmem_node_allocator_t; +typedef node_allocator, 64, my_managed_shared_memory::segment_manager> + shmem_node_pair_allocator_t; +typedef node_allocator + shmem_movable_node_allocator_t; +typedef node_allocator, 64, my_managed_shared_memory::segment_manager> + shmem_movable_node_pair_allocator_t; +typedef node_allocator + shmem_move_copy_node_allocator_t; +typedef node_allocator, 64, my_managed_shared_memory::segment_manager> + shmem_move_copy_node_pair_allocator_t; -//Alias set types -typedef set, shmem_node_allocator_t> MyShmSet; +//Alias standard types typedef std::set MyStdSet; -typedef multiset, shmem_node_allocator_t> MyShmMultiSet; typedef std::multiset MyStdMultiSet; +typedef std::map MyStdMap; +typedef std::multimap MyStdMultiMap; + +//Alias non-movable types +typedef set, shmem_node_allocator_t> MyShmSet; +typedef multiset, shmem_node_allocator_t> MyShmMultiSet; +typedef map, shmem_node_pair_allocator_t> MyShmMap; +typedef multimap, shmem_node_pair_allocator_t> MyShmMultiMap; + +//Alias movable types +typedef set + ,shmem_movable_node_allocator_t> MyMovableShmSet; +typedef multiset, + shmem_movable_node_allocator_t> MyMovableShmMultiSet; +typedef map, + shmem_movable_node_pair_allocator_t> MyMovableShmMap; +typedef multimap, + shmem_movable_node_pair_allocator_t> MyMovableShmMultiMap; + +typedef set + ,shmem_move_copy_node_allocator_t> MyMoveCopyShmSet; +typedef multiset, + shmem_move_copy_node_allocator_t> MyMoveCopyShmMultiSet; +typedef map, + shmem_move_copy_node_pair_allocator_t> MyMoveCopyShmMap; +typedef multimap, + shmem_move_copy_node_pair_allocator_t> MyMoveCopyShmMultiMap; int main () { using namespace boost::interprocess::detail; - return test::set_test(); + ,MyStdMultiSet>()){ + return 1; + } + + if(0 != test::set_test()){ + return 1; + } + + if(0 != test::set_test()){ + return 1; + } + + if (0 != test::map_test()){ + return 1; + } + +// if (0 != test::map_test()){ +// return 1; +// } + + if (0 != test::map_test()){ + return 1; + } + + return 0; } - - #include +/* +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace boost::interprocess; + +template +int test() +{ + shared_memory_object::remove("shm"); + managed_shared_memory segment(create_only, "shm", 10000000); + + typedef allocator char_allocator_t; + typedef basic_string, char_allocator_t> string_t; + typedef allocator string_allocator_t; + typedef multiset, string_allocator_t> multiset_t; + typedef vector vector_t; + + boost::posix_time::ptime start_time, end_time; + boost::posix_time::ptime::time_duration_type duration; + string_allocator_t string_allocator(segment.get_segment_manager()); + + multiset_t *mset = segment.construct(anonymous_instance) + (std::less(), string_allocator); + + const char *prefix = "longlonglonglonglonglonglonglonglonglonglong prefix"; + + vector_t &strings = *segment.construct(anonymous_instance) + (NumDiffStrings, string_t(string_allocator)); + + for(int i = 0; i < NumDiffStrings; ++i){ + char buffer[256]; + std::sprintf(buffer, "prefix%d", i); + strings[i] = buffer; + for(int n = 0; n < NumStringRepeat; ++n){ +// mset->insert(mset->end(), strings[i]); + mset->insert(mset->lower_bound(strings[i]), strings[i]); +// mset->insert(mset->upper_bound(strings[i]), strings[i]); +// std::cout << std::endl << std::endl << std::endl << std::endl; +// multiset_t::iterator ib(mset->begin()), ie(mset->end()); +// for(; ib != ie; ++ib){ +// std::cout << *ib << std::endl; +// } + } + } + + start_time = boost::posix_time::microsec_clock::universal_time(); + + for(int n = 0; n < NumTestRepeat; ++n) + for(int i = 0; i < NumDiffStrings; ++i){ + int count = (int)mset->count(strings[i]); + if(count != NumStringRepeat){ + std::cout << "Error!" << std::endl; + multiset_t::iterator ib(mset->begin()), ie(mset->end()); + for(; ib != ie; ++ib){ + std::cout << *ib << std::endl; + } + + return 1; + } + } + + end_time = boost::posix_time::microsec_clock::universal_time(); + duration = end_time - start_time; + + std::cout << "duration: " << duration.total_seconds() << std::endl; + return 0; +} + +int main() +{ + if(0 != test<100000, 1, 50>()){ + return 1; + } + + if(0 != test<10000, 1, 500>()){ + return 1; + } + + if(0 != test<1000, 10, 1000>()){ + return 1; + } + + if(0 != test<100, 100, 10000>()){ + return 1; + } + + if(0 != test<10, 1000, 10000>()){ + return 1; + } + return 0; +} +*/ +/* +#include +#include +#include +#include +#include +#include +#include + +template +int test() +{ + typedef std::multiset multiset_t; + + boost::posix_time::ptime start_time, end_time; + boost::posix_time::ptime::time_duration_type duration; + + multiset_t mset; + + const char *prefix = "longlonglonglonglonglonglonglonglonglonglong prefix"; + + std::vector strings; + strings.resize(NumDiffStrings); + + for(int i = 0; i < NumDiffStrings; ++i){ + char buffer[256]; + std::sprintf(buffer, "prefix%d", i); + strings[i] = buffer; + for(int n = 0; n < NumStringRepeat; ++n) + mset.insert(strings[i]); + } + + start_time = boost::posix_time::microsec_clock::universal_time(); + + for(int n = 0; n < NumTestRepeat; ++n) + for(int i = 0; i < NumDiffStrings; ++i){ + int count = (int)mset.count(strings[i]); + if(count != NumStringRepeat){ + std::cout << "Error!" << std::endl; + return 1; + } + } + + end_time = boost::posix_time::microsec_clock::universal_time(); + duration = end_time - start_time; + + std::cout << "duration: " << duration.total_seconds() << std::endl; + return 0; +} + +int main() +{ + if(0 != test<100000, 1, 50>()){ + return 1; + } + + if(0 != test<10000, 1, 500>()){ + return 1; + } + + if(0 != test<1000, 10, 5000>()){ + return 1; + } + + if(0 != test<100, 100, 5000>()){ + return 1; + } + + if(0 != test<10, 1000, 5000>()){ + return 1; + } + return 0; +} +*/ +/* +#include +#include +#include +#include +#include + +template +void display(const Map &m) +{ + for(typename Map::const_iterator i = m.begin(), e = m.end(); i != e; ++i){ + std::cout << "(" << i->first << ", " << i->second << ")"; + } + std::cout << '\n'; +} + +int main() +{ + using namespace boost::interprocess; + typedef multimap Map; + typedef std::multimap StdMap; + typedef std::pair value_type; + Map m; + StdMap stdm; + m.insert(value_type(0, "zero")); + m.insert(value_type(1, "one")); + m.insert(value_type(2, "two")); + display(m); + m.insert(m.find(1), value_type(1, "ONE")); + display(m); + + stdm.insert(value_type(0, "zero")); + stdm.insert(value_type(1, "one")); + stdm.insert(value_type(2, "two")); + display(stdm); + stdm.insert(stdm.find(1), value_type(1, "ONE")); + display(stdm); + return 0; +} +*/ diff --git a/test/unique_ptr_test.cpp b/test/unique_ptr_test.cpp index b83335c..88b637c 100644 --- a/test/unique_ptr_test.cpp +++ b/test/unique_ptr_test.cpp @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include using namespace boost::interprocess; @@ -49,47 +52,40 @@ struct MyDeleter }; typedef unique_ptr my_unique_ptr_class; -/* -//Explicit instantiation of shared memory set -template class set - ,allocator - >; - typedef set ,allocator > MySet; -//Explicit instantiation of shared memory list -template class list - >; - - typedef list > MyList; -*/ -//This explicit instantiation fails -//Because, for example, this iterator copy expression fails: -// *target = *source; -// -//template class vector -// >; +typedef vector + > MyVector; + +typedef basic_string + ,allocator + > MyString; + +typedef allocator MyStrAllocator; + + +typedef vector MyStringVector; int main() { //Create managed shared memory shared_memory_object::remove("mysegment"); - managed_shared_memory segment(create_only, "mysegment", 1000); + managed_shared_memory segment(create_only, "mysegment", 10000); //Create to unique_ptr using dynamic allocation my_unique_ptr_class my_ptr (segment.construct(anonymous_instance)() @@ -105,30 +101,34 @@ int main() my_unique_ptr_class my_ptr3(0, segment.get_segment_manager()); my_unique_ptr_class my_ptr4(move(my_ptr3)); - //This does not compile -// my_unique_ptr_class my_ptr4 (my_ptr3); -/* //Construct a list and fill MyList list(segment.get_segment_manager()); //Insert from my_unique_ptr_class - list.push_back(my_ptr); - - //Insert from CONST my_unique_ptr_class - list.push_back(my_ptr2); + list.push_front(move(my_ptr)); + list.push_back(move(my_ptr2)); //Check pointers assert(my_ptr.get() == 0); assert(my_ptr2.get() == 0); assert(list.begin()->get() == ptr1); assert(list.rbegin()->get() == ptr2); +/* + MyList list2(move(list)); + list2.swap(move(MyList(segment.get_segment_manager()))); + list.swap(move(MyList(segment.get_segment_manager()))); +*/ + + assert(list.begin()->get() == ptr1); + assert(list.rbegin()->get() == ptr2); //Construct a set and fill - MySet set(std::less(), segment.get_segment_manager()); + typedef std::less set_less_t; + MySet set(set_less_t(), segment.get_segment_manager()); //Insert in set from list passing ownership - set.insert(*list.begin()); - set.insert(*list.rbegin()); + set.insert(move(*list.begin())); + set.insert(move(*list.rbegin())); //Check pointers assert(list.begin()->get() == 0); @@ -144,7 +144,47 @@ int main() assert(set.rbegin()->get() == ptr1); assert(set.begin()->get() == ptr2); } +/* + MySet set2(move(set)); + set2.swap(move(MySet(set_less_t(), segment.get_segment_manager()))); + set.swap(move(MySet(set_less_t(), segment.get_segment_manager()))); */ + + //Now with vector + MyVector vector(segment.get_segment_manager()); + + //Insert from my_unique_ptr_class + if(ptr1 < ptr2){ + vector.insert(vector.begin(), move(*set.begin())); + vector.insert(vector.end(), move(*set.rbegin())); + } + else{ + vector.insert(vector.begin(), move(*set.rbegin())); + vector.insert(vector.end(), move(*set.begin())); + } + + //Check pointers + assert(my_ptr.get() == 0); + assert(my_ptr2.get() == 0); + assert(vector.begin()->get() == ptr1); + assert(vector.rbegin()->get() == ptr2); + + MyVector vector2(move(vector)); + vector2.swap(vector); + + assert(vector.begin()->get() == ptr1); + assert(vector.rbegin()->get() == ptr2); + + MyStringVector strvect(segment.get_segment_manager()); + + char buffer[64]; + for(int i = 0; i < 100; ++i){ + MyString str(segment.get_segment_manager()); + sprintf(buffer, "%d", i); + str = buffer; + strvect.push_back(move(str)); + } + return 0; } diff --git a/test/upgradable_mutex_test.cpp b/test/upgradable_mutex_test.cpp index 251c568..cb45248 100644 --- a/test/upgradable_mutex_test.cpp +++ b/test/upgradable_mutex_test.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include "util.hpp" int main () diff --git a/test/user_buffer_test.cpp b/test/user_buffer_test.cpp index c4275d4..e619d91 100644 --- a/test/user_buffer_test.cpp +++ b/test/user_buffer_test.cpp @@ -20,7 +20,7 @@ #include #include #include -#include "printcontainer.hpp" +#include "print_container.hpp" /******************************************************************************/ /* */ @@ -150,7 +150,7 @@ int main () } MyUserList otheruserlist(*userlist); - MyHeapList otherheaplist(*userlist); + MyHeapList otherheaplist(*heaplist); MyStdList otherstdlist(*stdlist); userlist->splice(userlist->begin(), otheruserlist); heaplist->splice(heaplist->begin(), otherheaplist); diff --git a/test/util.hpp b/test/util.hpp index 4a43427..44474ff 100644 --- a/test/util.hpp +++ b/test/util.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gazta�ga 2004-2006. Distributed under the Boost +// (C) Copyright Ion Gaztañaga 2004-2006. 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) // @@ -27,8 +27,9 @@ #include #include -#include #include +#include +#include #ifndef DEFAULT_EXECUTION_MONITOR_TYPE # define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition diff --git a/test/vector_test.cpp b/test/vector_test.cpp index c57653c..b160788 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -21,168 +21,239 @@ #include #include #include -#include +#include "allocator_v1.hpp" #include -#include "printcontainer.hpp" +#include +#include +#include "print_container.hpp" +#include "check_equal_containers.hpp" +#include "movable_int.hpp" #include #include "expand_bwd_test_allocator.hpp" #include "expand_bwd_test_template.hpp" - -//***************************************************************// -// // -// This example repeats the same operations with std::vector // -// and interprocess::vector using the node allocator // -// and compares the values of both containers // -// // -//***************************************************************// +#include "dummy_test_allocator.hpp" +#include using namespace boost::interprocess; -//Customize managed_shared_memory class - typedef basic_managed_shared_memory , - flat_map_index - > my_managed_shared_memory; - -//Alias allocator type -typedef allocator - shmem_allocator_t; - -typedef node_allocator - shmem_node_allocator_t; + simple_seq_fit, + flat_map_index + > managed_shared_memory_t; //Explicit instantiation to detect compilation errors -template class boost::interprocess::vector; -template class boost::interprocess::vector; -template class boost::interprocess::vector >; +template class boost::interprocess::vector >; -//Alias vector types -typedef vector MyShmVector; -typedef std::vector MyStdVector; - -//Function to check if both sets are equal -bool CheckEqual(MyShmVector *shmvector, MyStdVector *stdvector) +template +bool copyable_only(V1 *shmvector, V2 *stdvector, boost::false_type) { - if(shmvector->size() != stdvector->size()) - return false; - return std::equal(shmvector->begin(), shmvector->end(), stdvector->begin()); + return true; } - -int main () +//Function to check if both sets are equal +template +bool copyable_only(V1 *shmvector, V2 *stdvector, boost::true_type) { + typedef typename V1::value_type IntType; + std::size_t size = shmvector->size(); + stdvector->insert(stdvector->end(), 50, 1); + shmvector->insert(shmvector->end(), 50, 1); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + { + IntType move_me(1); + stdvector->insert(stdvector->begin()+size/2, 50, 1); + shmvector->insert(shmvector->begin()+size/2, 50, move(move_me)); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + } + { + IntType move_me(2); + shmvector->assign(shmvector->size()/2, move(move_me)); + stdvector->assign(stdvector->size()/2, 2); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + } + { + IntType move_me(3); + shmvector->assign(shmvector->size()*3-1, move(move_me)); + stdvector->assign(stdvector->size()*3-1, 3); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + } + return true; +} + +template class AllocatorType > +bool do_test() +{ + //Customize managed_shared_memory class + typedef basic_managed_shared_memory + , + flat_map_index + > my_managed_shared_memory; + + //Alias AllocatorType type + typedef AllocatorType + shmem_allocator_t; + + //Alias vector types + typedef vector MyShmVector; + typedef std::vector MyStdVector; const int Memsize = 65536; const char *const shMemName = "MySharedMemory"; const int max = 100; try{ //Compare several shared memory vector operations with std::vector + //Create shared memory + shared_memory_object::remove(shMemName); + my_managed_shared_memory segment(create_only, shMemName, Memsize); + + segment.reserve_named_objects(100); + + //Shared memory allocator must be always be initialized + //since it has no default constructor + MyShmVector *shmvector = segment.template construct("MyShmVector") + (segment.get_segment_manager()); + MyStdVector *stdvector = new MyStdVector; + + shmvector->resize(100); + stdvector->resize(100); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + shmvector->resize(200); + stdvector->resize(200); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + shmvector->resize(0); + stdvector->resize(0); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + for(int i = 0; i < max; ++i){ + IntType new_int(i); + shmvector->insert(shmvector->end(), move(new_int)); + stdvector->insert(stdvector->end(), i); + } + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + typename MyShmVector::iterator it; + typename MyShmVector::const_iterator cit = it; + + shmvector->erase(shmvector->begin()++); + stdvector->erase(stdvector->begin()++); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + shmvector->erase(shmvector->begin()); + stdvector->erase(stdvector->begin()); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + { - //Create shared memory - shared_memory_object::remove(shMemName); - my_managed_shared_memory segment(create_only, shMemName, Memsize); - - segment.reserve_named_objects(100); - - //Shared memory allocator must be always be initialized - //since it has no default constructor - MyShmVector *shmvector = segment.construct("MyShmVector") - (segment.get_segment_manager()); - - segment.get_type(shmvector); - segment.get_name(shmvector); - - MyStdVector *stdvector = new MyStdVector; - - int i, j; - for(i = 0; i < max; ++i){ - shmvector->insert(shmvector->end(), i); - stdvector->insert(stdvector->end(), i); + //Initialize values + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType new_int(-1); + aux_vect[i] = move(new_int); + } + int aux_vect2[50]; + for(int i = 0; i < 50; ++i){ + aux_vect2[i] = -1; } - if(!CheckEqual(shmvector, stdvector)) return 1; - MyShmVector::iterator it; - MyShmVector::const_iterator cit = it; + shmvector->insert(shmvector->end() + ,detail::make_move_iterator(&aux_vect[0]) + ,detail::make_move_iterator(aux_vect + 50)); + stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; - shmvector->erase(shmvector->begin()++); - stdvector->erase(stdvector->begin()++); - if(!CheckEqual(shmvector, stdvector)) return 1; - - shmvector->erase(shmvector->begin()); - stdvector->erase(stdvector->begin()); - if(!CheckEqual(shmvector, stdvector)) return 1; - - std::vector aux_vect; - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - aux_vect.assign(50, -1); - shmvector->insert(shmvector->end(), aux_vect.begin(), aux_vect.end()); - stdvector->insert(stdvector->end(), aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmvector, stdvector)) return 1; - #endif - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - for(i = 0, j = static_cast(shmvector->size()); i < j; ++i){ + for(int i = 0, j = static_cast(shmvector->size()); i < j; ++i){ shmvector->erase(shmvector->begin()); stdvector->erase(stdvector->begin()); } - if(!CheckEqual(shmvector, stdvector)) return 1; - #endif - - #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) - shmvector->insert(shmvector->begin(), aux_vect.begin(), aux_vect.end()); - shmvector->insert(shmvector->begin(), aux_vect.begin(), aux_vect.end()); - stdvector->insert(stdvector->begin(), aux_vect.begin(), aux_vect.end()); - stdvector->insert(stdvector->begin(), aux_vect.begin(), aux_vect.end()); - if(!CheckEqual(shmvector, stdvector)) return 1; - #endif - - std::size_t size = shmvector->size(); - stdvector->insert(stdvector->end(), 50, 1); - shmvector->insert(shmvector->end(), 50, 1); - if(!CheckEqual(shmvector, stdvector)) return 1; - - stdvector->insert(stdvector->begin()+size/2, 50, 1); - shmvector->insert(shmvector->begin()+size/2, 50, 1); - if(!CheckEqual(shmvector, stdvector)) return 1; - - shmvector->erase(shmvector->begin()); - stdvector->erase(stdvector->begin()); - - if(!CheckEqual(shmvector, stdvector)) return 1; - - for(i = 0; i < max; ++i){ - shmvector->insert(shmvector->begin(), i); - stdvector->insert(stdvector->begin(), i); - } - if(!CheckEqual(shmvector, stdvector)) return 1; - - stdvector->assign(stdvector->size()/2, 2); - shmvector->assign(shmvector->size()/2, 2); - if(!CheckEqual(shmvector, stdvector)) return 1; - - stdvector->assign(shmvector->capacity()-1, 3); - shmvector->assign(shmvector->capacity()-1, 3); - if(!CheckEqual(shmvector, stdvector)) return 1; - - delete stdvector; - segment.destroy("MyShmVector"); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; } - - //Now test all back insertion possibilities { - typedef test::expand_bwd_test_allocator allocator_type; - typedef vector vector_type; - test::test_all_expand_bwd(); + IntType aux_vect[50]; + for(int i = 0; i < 50; ++i){ + IntType new_int(-1); + aux_vect[i] = move(new_int); + } + int aux_vect2[50]; + for(int i = 0; i < 50; ++i){ + aux_vect2[i] = -1; + } + shmvector->insert(shmvector->begin() + ,detail::make_move_iterator(&aux_vect[0]) + ,detail::make_move_iterator(aux_vect + 50)); + stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; } + + shmvector->reserve(shmvector->size()*2); + stdvector->reserve(stdvector->size()*2); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + IntType push_back_this(1); + shmvector->push_back(move(push_back_this)); + stdvector->push_back(int(1)); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + if(!copyable_only(shmvector, stdvector + ,boost::integral_constant + ::value>())){ + return false; + } + + shmvector->erase(shmvector->begin()); + stdvector->erase(stdvector->begin()); + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + for(int i = 0; i < max; ++i){ + IntType insert_this(i); + shmvector->insert(shmvector->begin(), move(insert_this)); + stdvector->insert(stdvector->begin(), i); + } + if(!test::CheckEqualContainers(shmvector, stdvector)) return false; + + delete stdvector; + segment.template destroy("MyShmVector"); } catch(std::exception &ex){ std::cout << ex.what() << std::endl; - return 1; + return false; } std::cout << std::endl << "Test OK!" << std::endl; + return true; +} + +bool test_expand_bwd() +{ + //Now test all back insertion possibilities + typedef test::expand_bwd_test_allocator + allocator_type; + typedef vector + vector_type; + return test::test_all_expand_bwd(); +} + +int main() +{ + if(!do_test()) + return 1; + + if(!do_test()) + return 1; + + if(!do_test()) + return 1; + + if(!do_test()) + return 1; + + if(!test_expand_bwd()) + return 1; + return 0; } diff --git a/test/vectorstream_test.cpp b/test/vectorstream_test.cpp index ec6b91d..9bc433d 100644 --- a/test/vectorstream_test.cpp +++ b/test/vectorstream_test.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include