|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r49323 - in branches/release/libs: interprocess/doc interprocess/example interprocess/proj interprocess/proj/vc7ide interprocess/test intrusive/doc intrusive/example intrusive/proj/vc7ide intrusive/proj/vc7ide/_intrusivelib intrusive/proj/vc7ide/unordered_set intrusive/test
From: igaztanaga_at_[hidden]
Date: 2008-10-13 15:39:52
Author: igaztanaga
Date: 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
New Revision: 49323
URL: http://svn.boost.org/trac/boost/changeset/49323
Log:
Changes and fixes for Boost 1.37
Added:
branches/release/libs/interprocess/proj/to-do.txt
- copied unchanged from r49317, /trunk/libs/interprocess/proj/to-do.txt
branches/release/libs/interprocess/proj/vc7ide/named_construct_test.vcproj
- copied unchanged from r49317, /trunk/libs/interprocess/proj/vc7ide/named_construct_test.vcproj
branches/release/libs/interprocess/test/emplace_test.hpp
- copied unchanged from r49317, /trunk/libs/interprocess/test/emplace_test.hpp
branches/release/libs/interprocess/test/named_construct_test.cpp
- copied unchanged from r49317, /trunk/libs/interprocess/test/named_construct_test.cpp
branches/release/libs/intrusive/proj/vc7ide/to-do.txt
- copied unchanged from r49318, /trunk/libs/intrusive/proj/vc7ide/to-do.txt
Text files modified:
branches/release/libs/interprocess/doc/interprocess.qbk | 214 +++++++++++----------
branches/release/libs/interprocess/example/doc_contB.cpp | 2
branches/release/libs/interprocess/example/doc_ipc_messageA.cpp | 2
branches/release/libs/interprocess/example/doc_ipc_messageB.cpp | 2
branches/release/libs/interprocess/example/doc_managed_aligned_allocation.cpp | 6
branches/release/libs/interprocess/example/doc_managed_copy_on_write.cpp | 2
branches/release/libs/interprocess/example/doc_managed_external_buffer.cpp | 2
branches/release/libs/interprocess/example/doc_named_allocA.cpp | 2
branches/release/libs/interprocess/example/doc_named_allocB.cpp | 2
branches/release/libs/interprocess/example/doc_offset_ptr.cpp | 2
branches/release/libs/interprocess/example/doc_shared_memory2.cpp | 1
branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln | 10
branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj | 21 ++
branches/release/libs/interprocess/test/allocator_v1.hpp | 2
branches/release/libs/interprocess/test/cached_node_allocator_test.cpp | 2
branches/release/libs/interprocess/test/deque_test.cpp | 122 ++++++++++-
branches/release/libs/interprocess/test/expand_bwd_test_template.hpp | 10
branches/release/libs/interprocess/test/flat_tree_test.cpp | 38 +++
branches/release/libs/interprocess/test/intersegment_ptr_test.cpp | 15
branches/release/libs/interprocess/test/list_test.cpp | 19 +
branches/release/libs/interprocess/test/list_test.hpp | 1
branches/release/libs/interprocess/test/managed_mapped_file_test.cpp | 3
branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp | 18
branches/release/libs/interprocess/test/movable_int.hpp | 6
branches/release/libs/interprocess/test/mutex_test_template.hpp | 6
branches/release/libs/interprocess/test/node_allocator_test.cpp | 2
branches/release/libs/interprocess/test/private_node_allocator_test.cpp | 2
branches/release/libs/interprocess/test/semaphore_test_template.hpp | 6
branches/release/libs/interprocess/test/sharable_mutex_test_template.hpp | 40 ++--
branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp | 4
branches/release/libs/interprocess/test/shared_ptr_test.cpp | 2
branches/release/libs/interprocess/test/slist_test.cpp | 31 +++
branches/release/libs/interprocess/test/tree_test.cpp | 62 ++++++
branches/release/libs/interprocess/test/user_buffer_test.cpp | 2
branches/release/libs/interprocess/test/vector_test.cpp | 18 +
branches/release/libs/interprocess/test/vector_test.hpp | 37 ++-
branches/release/libs/interprocess/test/windows_shared_memory_mapping_test.cpp | 4
branches/release/libs/intrusive/doc/intrusive.qbk | 52 ++++-
branches/release/libs/intrusive/example/doc_window.cpp | 2
branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj | 3
branches/release/libs/intrusive/proj/vc7ide/unordered_set/unordered_set.vcproj | 5
branches/release/libs/intrusive/test/default_hook_test.cpp | 37 +++
branches/release/libs/intrusive/test/list_test.cpp | 310 ++++++++++++++++++++++++++++++-
branches/release/libs/intrusive/test/set_test.cpp | 1
branches/release/libs/intrusive/test/sg_multiset_test.cpp | 12 +
branches/release/libs/intrusive/test/sg_set_test.cpp | 12 +
branches/release/libs/intrusive/test/splay_multiset_test.cpp | 37 +++
branches/release/libs/intrusive/test/splay_set_test.cpp | 36 +++
branches/release/libs/intrusive/test/test_macros.hpp | 5
branches/release/libs/intrusive/test/unordered_multiset_test.cpp | 390 +++++++++++++++++++++++++++++++--------
branches/release/libs/intrusive/test/unordered_set_test.cpp | 297 ++++++++++++++++++++++++-----
51 files changed, 1528 insertions(+), 391 deletions(-)
Modified: branches/release/libs/interprocess/doc/interprocess.qbk
==============================================================================
--- branches/release/libs/interprocess/doc/interprocess.qbk (original)
+++ branches/release/libs/interprocess/doc/interprocess.qbk 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -146,7 +146,7 @@
[*Boost.Interprocess] allows creating complex objects in shared memory and memory
mapped files. For example, we can construct STL-like containers in shared memory.
-To do this, we just need to create a an special (managed) shared memory segment,
+To do this, we just need to create a special (managed) shared memory segment,
declare a [*Boost.Interprocess] allocator and construct the vector in shared memory
just if it was any other object. Just execute this first process:
@@ -207,7 +207,7 @@
shared memory or memory mapped files. Once the processes set up the
memory region, the processes can read/write the data like any
other memory segment without calling the operating system's kernel. This
- also requieres some kind of manual synchronization between processes.
+ also requires some kind of manual synchronization between processes.
[endsect]
@@ -264,7 +264,7 @@
Examples of this are shared memory, named mutexes and named semaphores (for example,
native windows CreateMutex/CreateSemaphore API family).
-The name used to identify a interprocess mechanism is not portable, even between
+The name used to identify an interprocess mechanism is not portable, even between
UNIX systems. For this reason, [*Boost.Interprocess] limits this name to a C++ variable
identifier or keyword:
@@ -281,7 +281,7 @@
Named [*Boost.Interprocess] resources (shared memory, memory mapped files,
named mutexes/conditions/semaphores) have kernel or filesystem persistency.
This means that even if all processes that have opened those resources
-end, the resource will still be accesible to be opened again and the resource
+end, the resource will still be accessible to be opened again and the resource
can only be destructed via an explicit to their static member `remove` function.
This behavior can be easily understood, since it's the same mechanism used
by functions controlling file opening/creation/erasure:
@@ -332,7 +332,7 @@
without calling operating system functions. However, we need some kind of
synchronization between processes that read and write shared memory.
-Consider what happens when a server process wants to send a html file to a client process
+Consider what happens when a server process wants to send an HTML file to a client process
that resides in the same machine using network mechanisms:
* The server must read the file to memory and pass it to the network functions, that
@@ -457,7 +457,7 @@
Once created or opened, a process just has to map the shared memory object in the process'
address space. The user can map the whole shared memory or just part of it. The
-mapping process is done using the the `mapped_region` class. The class represents
+mapping process is done using the `mapped_region` class. The class represents
a memory region that has been mapped from a shared memory or from other devices
that have also mapping capabilities (for example, files). A `mapped_region` can be
created from any `memory_mappable` object and as you might imagine, `shared_memory_object`
@@ -533,7 +533,7 @@
[section:removing Removing shared memory]
[classref boost::interprocess::shared_memory_object shared_memory_object]
-provides an static `remove` function to remove a shared memory objects.
+provides a static `remove` function to remove a shared memory objects.
This function [*can] fail if the shared memory objects does not exist or
it's opened by another process. Note that this function is similar to the
@@ -567,7 +567,7 @@
Creating a shared memory segment and mapping it can be a bit tedious when several
processes are involved. When processes are related via `fork()` operating system
-call in UNIX sytems a simpler method is available using anonymous shared memory.
+call in UNIX systems a simpler method is available using anonymous shared memory.
This feature has been implemented in UNIX systems mapping the device `\dev\zero` or
just using the `MAP_ANONYMOUS` in a POSIX conformant `mmap` system call.
@@ -576,7 +576,7 @@
function, which returns a `mapped_region` object holding an anonymous shared memory
segment that can be shared by related processes.
-Here's is an example:
+Here is an example:
[import ../example/doc_anonymous_shared_memory.cpp]
[doc_anonymous_shared_memory]
@@ -615,7 +615,7 @@
shared memory. Native windows shared memory has also another limitation: a process can
open and map the whole shared memory created by another process but it can't know
which is the size of that memory. This limitation is imposed by the Windows API so
-the user must somehow trasmit the size of the segment to processes opening the
+the user must somehow transmit the size of the segment to processes opening the
segment.
Let's repeat the same example presented for the portable shared memory object:
@@ -738,7 +738,7 @@
After creating a file mapping, a process just has to map the shared memory in the
process' address space. The user can map the whole shared memory or just part of it.
-The mapping process is done using the the `mapped_region` class. as we have said before
+The mapping process is done using the `mapped_region` class. as we have said before
The class represents a memory region that has been mapped from a shared memory or from other
devices that have also mapping capabilities:
@@ -770,7 +770,7 @@
If several processes map the same file, and a process modifies a memory range
from a mapped region that is also mapped by other process, the changes are
inmedially visible to other processes. However, the file contents on disk are
-not updated immediately, since that would hurt performance (writting to disk
+not updated immediately, since that would hurt performance (writing to disk
is several times slower than writing to memory). If the user wants to make sure
that file's contents have been updated, it can flush a range from the view to disk.
When the function returns, the data should have been written to disk:
@@ -799,7 +799,7 @@
Let's reproduce the same example described in the shared memory section, using
memory mapped files. A server process creates a shared
-memory segment, maps it and initializes all the bytes the a value. After that,
+memory segment, 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:
@@ -892,7 +892,7 @@
If fixed mapping address is used, ['offset] and ['address]
parameters should be multiples of that value.
-This value is, tipically, 4KB or 8KB for 32 bit operating systems.
+This value is, typically, 4KB or 8KB for 32 bit operating systems.
[c++]
@@ -929,7 +929,7 @@
The operating system will reserve a whole page that will not be reused by any
other mapping so we are going to waste [*(page size - 1)] bytes. If we want
-to use effiently operating system resources, we should create regions whose size
+to use efficiently operating system resources, we should create regions whose size
is a multiple of [*page size] bytes. If the user specifies the following two
mapped regions for a file with which has `2*page_size` bytes:
@@ -967,7 +967,7 @@
, page_size //Map the rest
);
-How can we obtain the [*page size]? The `mapped_region` class has an static
+How can we obtain the [*page size]? The `mapped_region` class has a static
function that returns that value:
[c++]
@@ -997,7 +997,7 @@
that region in different address in every process,
raw pointers are a problem since they are only valid for the
process that placed them there. To solve this, [*Boost.Interprocess] offers
-an special smart pointer that can be used instead of a raw pointer.
+a special smart pointer that can be used instead of a raw pointer.
So user classes containing raw pointers (or Boost smart pointers, that
internally own a raw pointer) can't be safely placed in a process shared
mapped region. These pointers must be replaced with offset pointers, and
@@ -1007,7 +1007,7 @@
Of course, a pointer placed in a mapped region shared between processes should
only point to an object of that mapped region. Otherwise, the pointer would
point to an address that it's only valid one process and other
-processes may crash when accesing to that address.
+processes may crash when accessing to that address.
[endsect]
@@ -1040,7 +1040,7 @@
This problem is very difficult to solve, since each process needs a
different virtual table pointer and the object that contains that pointer
-is shared accross many processes. Even if we map the mapped region in
+is shared across many processes. Even if we map the mapped region in
the same address in every process, the virtual table can be in a different
address in every process. To enable virtual functions for objects
shared between processes, deep compiler changes are needed and virtual
@@ -1099,7 +1099,7 @@
//This address can be different in each process
void *addr = region.get_address();
-This difficults the creation of complex objects in mapped regions: a C++
+This makes the creation of complex objects in mapped regions difficult: a C++
class instance placed in a mapped region might have a pointer pointing to
another object also placed in the mapped region. Since the pointer stores an
absolute address, that address is only valid for the process that placed
@@ -1107,9 +1107,9 @@
address.
To be able to simulate pointers in mapped regions, users must use [*offsets]
-(distance between objets) instead of absolute addresses. The offset between
+(distance between objects) instead of absolute addresses. The offset between
two objects in a mapped region is the same for any process that maps the
-mapped region, even if that region is placed in different base addreses.
+mapped region, even if that region is placed in different base addresses.
To facilitate the use of offsets, [*Boost.Interprocess] offers
[classref boost::interprocess::offset_ptr offset_ptr].
@@ -1119,7 +1119,7 @@
inspired in Boost Smart Pointers and this smart pointer
stores the offset (distance in bytes)
between the pointee's address and it's own `this` pointer.
-Imagine an structure in a common
+Imagine a structure in a common
32 bit processor:
[c++]
@@ -1209,7 +1209,7 @@
memory can't be effectively synchronized. This is the same problem that happens with
thread-synchronization mechanisms, where heap memory and global variables are
shared between threads, but the access to these resources needs to be synchronized
-tipically through mutex and condition variables. [*Boost.Threads] implements these
+typically through mutex and condition variables. [*Boost.Threads] implements these
synchronization utilities between threads inside the same process. [*Boost.Interprocess]
implements similar mechanisms to synchronize threads from different processes.
@@ -1223,7 +1223,7 @@
a file with using a `fstream` with the name ['filename] and another process opens
that file using another `fstream` with the same ['filename] argument.
[*Each process uses a different object to access to the resource, but both processes
- are using the the same underlying resource].
+ are using the same underlying resource].
* [*Anonymous utilities]: Since these utilities have no name, two processes must
share [*the same object] through shared memory or memory mapped files. This is
@@ -1245,8 +1245,8 @@
synchronization utilities.
The main interface difference between named and anonymous utilities are the constructors.
-Usually anonymous utilities have only one contructor, whereas the named utilities have
-several constructors whose first argument is an special type that requests creation,
+Usually anonymous utilities have only one constructor, whereas the named utilities have
+several constructors whose first argument is a special type that requests creation,
opening or opening or creation of the underlying resource:
[c++]
@@ -1403,7 +1403,7 @@
It's very important to unlock a mutex after the process has read or written the data.
This can be difficult when dealing with exceptions, so usually mutexes are used
with a scoped lock, a class that can guarantee that a mutex will always be unlocked
-even when an exception occurs. To use an scoped lock just include:
+even when an exception occurs. To use a scoped lock just include:
[c++]
@@ -1476,7 +1476,7 @@
[doc_anonymous_mutex_shared_data]
This is the process main process. Creates the shared memory, constructs
-the the cyclic buffer and start writing traces:
+the cyclic buffer and start writing traces:
[import ../example/doc_anonymous_mutexA.cpp]
[doc_anonymous_mutexA]
@@ -1516,11 +1516,11 @@
can do two things:
* [*wait]: The thread is blocked until some other thread notifies that it can
- continue because the condition that lead to waiting has dissapeared.
+ continue because the condition that lead to waiting has disapeared.
* [*notify]: The thread sends a signal to one blocked thread or to all blocked
threads to tell them that they the condition that provoked their wait has
- dissapeared.
+ disapeared.
Waiting in a condition variable is always associated with a mutex.
The mutex must be locked prior to waiting on the condition. When waiting
@@ -1649,7 +1649,7 @@
[section:semaphores_anonymous_example Anonymous semaphore example]
-We will implement a integer array in shared memory that will be used to trasfer data
+We will implement an integer array in shared memory that will be used to transfer data
from one process to another process. The first process will write some integers
to the array and the process will block if the array is full.
@@ -1662,7 +1662,7 @@
[doc_anonymous_semaphore_shared_data]
This is the process main process. Creates the shared memory, places there
-the interger array and starts integers one by one, blocking if the array
+the integer array and starts integers one by one, blocking if the array
is full:
[import ../example/doc_anonymous_semaphoreA.cpp]
@@ -1686,7 +1686,7 @@
[section:upgradable_whats_a_mutex What's An Upgradable Mutex?]
-An upgradable mutex is an special mutex that offers more locking possibilities than
+An upgradable mutex is a special mutex that offers more locking possibilities than
a normal mutex. Sometimes, we can distinguish between [*reading] the data and
[*modifying] the data. If just some threads need to modify the data, and a plain mutex
is used to protect the data from concurrent access, concurrency is pretty limited:
@@ -1937,7 +1937,7 @@
[*Precondition:] The thread must have upgradable ownership of the mutex.
[*Effects:] The thread atomically releases upgradable ownership and acquires exclusive
-ownership. This operation will block until all threads with sharable ownership releas it.
+ownership. This operation will block until all threads with sharable ownership release it.
[*Throws:] An exception derived from *interprocess_exception* on error.[blurb ['[*bool try_unlock_upgradable_and_lock()]]]
@@ -2176,9 +2176,9 @@
These operations can be managed more effectively using [*lock transfer operations].
A lock transfer operations explicitly indicates that a mutex owned by a lock is
-trasferred to another lock executing atomic unlocking plus locking operations.
+transferred to another lock executing atomic unlocking plus locking operations.
-[section:lock_trasfer_simple_transfer Simple Lock Transfer]
+[section:lock_trnasfer_simple_transfer Simple Lock Transfer]
Imagine that a thread modifies some data in the beginning but after that, it has to
just read it in a long time. The code can acquire the exclusive lock, modify the data
@@ -2239,19 +2239,19 @@
//Read data
- //The lock is automatically unlocked calling the appropiate unlock
+ //The lock is automatically unlocked calling the appropriate unlock
//function even in the presence of exceptions.
//If the mutex was not locked, no function is called.
As we can see, even if an exception is thrown at any moment, the mutex
-will be automatically unlocked calling the appropiate `unlock()` or
+will be automatically unlocked calling the appropriate `unlock()` or
`unlock_sharable()` method.
[endsect]
-[section:lock_trasfer_summary Lock Transfer Summary]
+[section:lock_transfer_summary Lock Transfer Summary]
-There are many lock trasfer operations that we can classify according to
+There are many lock transfer operations that we can classify according to
the operations presented in the upgradable mutex operations:
* [*Guaranteed to succeed and non-blocking:] Any transition from a more
@@ -2306,7 +2306,7 @@
[section:lock_transfer_summary_upgradable Transfers To Upgradable Lock]
-A transfer to an `upgradable_lock` is guaranteed to succeed only from an `scoped_lock`
+A transfer to an `upgradable_lock` is guaranteed to succeed only from a `scoped_lock`
since scoped locking is a more restrictive locking than an upgradable locking. This
operation is also non-blocking.
@@ -2352,7 +2352,7 @@
[endsect]
-[section:lock_trasfer_not_locked Transferring Unlocked Locks]
+[section:lock_transfer_not_locked Transferring Unlocked Locks]
In the previous examples, the mutex used in the transfer operation was previously
locked:
@@ -2373,7 +2373,7 @@
[c++]
- //These operations can left the mutex unlocked!
+ //These operations can leave the mutex unlocked!
{
//Try might fail
@@ -2400,7 +2400,7 @@
If the source mutex was not locked:
-* The target lock does not executes the atomic `unlock_xxx_and_lock_xxx` operation.
+* The target lock does not execute the atomic `unlock_xxx_and_lock_xxx` operation.
* The target lock is also unlocked.
* The source lock is released() and the ownership of the mutex is transferred to the target.
@@ -2418,7 +2418,7 @@
[endsect]
-[section:lock_trasfer_failure Transfer Failures]
+[section:lock_transfer_failure Transfer Failures]
When executing a lock transfer, the operation can fail:
@@ -2554,7 +2554,7 @@
[*Effects:]
The calling thread tries to acquire exclusive ownership of the file lock
without waiting. If no other thread has exclusive or sharable ownership of
-the file lock this succeeds.
+the file lock, this succeeds.
[*Returns:] If it can acquire exclusive ownership immediately returns true.
If it has to wait, returns false.
@@ -2595,7 +2595,7 @@
[*Effects:]
The calling thread tries to acquire sharable ownership of the file
lock without waiting. If no other thread has has exclusive ownership of
-the file lock this succeeds.
+the file lock, this succeeds.
[*Returns:] If it can acquire sharable ownership immediately returns true.
If it has to wait, returns false.
@@ -2851,7 +2851,7 @@
using boost::interprocess;
message_queue::remove("message_queue");
-The funtion can fail if the message queue is still being used by any process.
+The function can fail if the message queue is still being used by any process.
[endsect]
@@ -2897,7 +2897,7 @@
A mapped region is a fixed-length memory buffer and creating and destroying objects
of any type dynamically, requires a lot of work, since it would require programming
a memory management algorithm to allocate portions of that segment.
-Many times, we also want to associate a names to objects created in shared memory, so
+Many times, we also want to associate names to objects created in shared memory, so
all the processes can find the object using the name.
[*Boost.Interprocess] offers 4 managed memory segment classes:
@@ -2958,7 +2958,7 @@
* The Pointer type (`MemoryAlgorithm::void_pointer`) to be used
by the memory allocation algorithm or additional helper structures
- (like a map to mantain object/name associations). All STL compatible
+ (like a map to maintain object/name associations). All STL compatible
allocators and containers to be used with this managed memory segment
will use this pointer type. The pointer type
will define if the managed memory segment can be mapped between
@@ -3016,8 +3016,8 @@
,/*Default index type*/>
wmanaged_shared_memory;
-`managed_shared_memory` allocates objects in shared memory asociated with a c-string and
-`wmanaged_shared_memory` allocates objects in shared memory asociated with a wchar_t null
+`managed_shared_memory` allocates objects in shared memory associated with a c-string and
+`wmanaged_shared_memory` allocates objects in shared memory associated with a wchar_t null
terminated string. Both define the pointer type as `offset_ptr<void>` so they can be
used to map the shared memory at different base addresses in different processes.
@@ -3108,7 +3108,7 @@
//!! If anything fails, throws interprocess_exception
//
managed_shared_memory segment (open_or_create, "MySharedMemory", //Shared memory object name 65536); //Shared memory object size in bytes
-When the a `managed_shared_memory` object is destroyed, the shared memory
+When the `managed_shared_memory` object is destroyed, the shared memory
object is automatically unmapped, and all the resources are freed. To remove
the shared memory object from the system you must use the `shared_memory_object::remove`
function. Shared memory object removing might fail if any
@@ -3184,8 +3184,8 @@
flat_map_index
> wmanaged_mapped_file;
-`managed_mapped_file` allocates objects in a memory mapped files asociated with a c-string
-and `wmanaged_mapped_file` allocates objects in a memory mapped file asociated with a wchar_t null
+`managed_mapped_file` allocates objects in a memory mapped files associated with a c-string
+and `wmanaged_mapped_file` allocates objects in a memory mapped file associated with a wchar_t null
terminated string. Both define the pointer type as `offset_ptr<void>` so they can be
used to map the file at different base addresses in different processes.
@@ -3244,7 +3244,7 @@
//!! If anything fails, throws interprocess_exception
//
managed_mapped_file mfile (open_or_create, "MyMappedFile", //Mapped file name 65536); //Mapped file size
-When the a `managed_mapped_file` object is destroyed, the file is
+When the `managed_mapped_file` object is destroyed, the file is
automatically unmapped, and all the resources are freed. To remove
the file from the filesystem you can use standard C `std::remove`
or [*Boost.Filesystem]'s `remove()` functions. File removing might fail
@@ -3548,7 +3548,7 @@
* Length of the object: Returns the number of elements of the object (1 if it's
a single value, >=1 if it's an array).
-* The type of construction: Whether the object was construct using a named,
+* The type of construction: Whether the object was constructed using a named,
unique or anonymous construction.
Here is an example showing this functionality:
@@ -3676,7 +3676,7 @@
The following functions reserve memory to make the subsequent allocation of
named or unique objects more efficient. These functions are only useful for
pseudo-intrusive or non-node indexes (like `flat_map_index`,
-`iunordered_set_index`). These functions has no effect with the
+`iunordered_set_index`). These functions have no effect with the
default index (`iset_index`) or other indexes (`map_index`):
[c++]
@@ -3735,7 +3735,7 @@
Sometimes it's interesting to be able to allocate aligned fragments of memory
because of some hardware or software restrictions. Sometimes, having
-aligned memory is an feature that can be used to improve several
+aligned memory is a feature that can be used to improve several
memory algorithms.
This allocation is similar to the previously shown raw memory allocation but
@@ -3758,7 +3758,7 @@
request [*and] the possibilities of future aligned allocations. This information
is stored in the PayloadPerAllocation constant of managed memory segments.
-Here's is an small example showing how aligned allocation is used:
+Here is a small example showing how aligned allocation is used:
[import ../example/doc_managed_aligned_allocation.cpp]
[doc_managed_aligned_allocation]
@@ -3812,9 +3812,9 @@
referencing the first byte user can overwrite
in the memory buffer.
* The iterator category depends on the memory allocation algorithm,
- but it's a least a forward iterator.
+ but it's at least a forward iterator.
-Here's an small example showing all this functionality:
+Here is a small example showing all this functionality:
[import ../example/doc_managed_multiple_allocation.cpp]
[doc_managed_multiple_allocation]
@@ -3867,7 +3867,7 @@
buffer a bit bigger than the requested size. Thus, the programmer can maximize
the memory use using `allocation_command`.
-Here's the declaration of the function:
+Here is the declaration of the function:
[c++]
@@ -3992,12 +3992,12 @@
performing backwards expansion, if you have already constructed objects in the
old buffer, make sure to specify correctly the type.]
-Here is an small example that shows the use of `allocation_command`:
+Here is a small example that shows the use of `allocation_command`:
[import ../example/doc_managed_allocation_command.cpp]
[doc_managed_allocation_command]
-`allocation_commmand` is a very powerful function that can lead to important
+`allocation_command` is a very powerful function that can lead to important
performance gains. It's specially useful when programming vector-like data
structures where the programmer can minimize both the number of allocation
requests and the memory waste.
@@ -4016,7 +4016,7 @@
open a managed segment in copy on write mode and not modified pages from the managed
segment will be shared between all those processes, with considerable memory savings.
-Opening managed shared memory and mapped files with [*open_read_only] maps the the
+Opening managed shared memory and mapped files with [*open_read_only] maps the
underlying device in memory with [*read-only] attributes. This means that any attempt
to write that memory, either creating objects or locking any mutex might result in an
page-fault error (and thus, program termination) from the OS. Read-only mode opens
@@ -4034,7 +4034,7 @@
* Additionally, the `find<>` member function avoids using internal locks and can be
used to look for named and unique objects.
-Here's an example that shows the use of these two open modes:
+Here is an example that shows the use of these two open modes:
[import ../example/doc_managed_copy_on_write.cpp]
[doc_managed_copy_on_write]
@@ -4047,7 +4047,7 @@
[*Boost.Interprocess] offers managed shared memory between processes using
`managed_shared_memory` or `managed_mapped_file`. Two processes just map the same
-the memory mappable resoure and read from and write to that object.
+the memory mappable resource and read from and write to that object.
Many times, we don't want to use that shared memory approach and we prefer
to send serialized data through network, local socket or message queues. Serialization
@@ -4093,7 +4093,7 @@
[c++]
//Named object creation managed memory segment
- //All objects are constructed in a a user provided buffer
+ //All objects are constructed in a user provided buffer
template <
class CharType,
class MemoryAlgorithm,
@@ -4102,7 +4102,7 @@
class basic_managed_external_buffer;
//Named object creation managed memory segment
- //All objects are constructed in a a user provided buffer
+ //All objects are constructed in a user provided buffer
// Names are c-strings,
// Default memory management algorithm
// (rbtree_best_fit with no mutexes and relative pointers)
@@ -4114,7 +4114,7 @@
> managed_external_buffer;
//Named object creation managed memory segment
- //All objects are constructed in a a user provided buffer
+ //All objects are constructed in a user provided buffer
// Names are wide-strings,
// Default memory management algorithm
// (rbtree_best_fit with no mutexes and relative pointers)
@@ -4269,7 +4269,7 @@
[section:allocator_properties Properties of [*Boost.Interprocess] allocators]
-Container allocators are normally default-contructible because the are stateless.
+Container allocators are normally default-constructible because the are stateless.
`std::allocator` and [*Boost.Pool's] `boost::pool_allocator`/`boost::fast_pool_allocator`
are examples of default-constructible allocators.
@@ -4403,7 +4403,7 @@
Segregate storage node
allocators allocate large memory chunks from a general purpose memory
-allocator and divide that chunk into several nodes. No bookeeping information
+allocator and divide that chunk into several nodes. No bookkeeping information
is stored in the nodes to achieve minimal memory waste: free nodes are linked
using a pointer constructed in the memory of the node.
@@ -4642,7 +4642,7 @@
that won't be reused wasting memory from the segment.
Adaptive pool based allocators trade some space (the overhead can be as low as 1%)
-and performance (aceptable for many applications) with the ability to return free chunks
+and performance (acceptable for many applications) with the ability to return free chunks
of nodes to the memory segment, so that they can be used by any other container or managed
object construction. To know the details of the implementation of
of "adaptive pools" see the
@@ -4777,7 +4777,7 @@
[section:cached_adaptive_pool cached_adaptive_pool: Avoiding synchronization overhead]
Adaptive pools have also a cached version. In this allocator the allocator caches
-some nodes to avoid the synchronization and bookeeping overhead of the shared
+some nodes to avoid the synchronization and bookkeeping overhead of the shared
adaptive pool.
[classref boost::interprocess::cached_adaptive_pool cached_adaptive_pool]
allocates nodes from the common adaptive pool but caches some of them privately so that following
@@ -5065,7 +5065,7 @@
[section:unordered Boost unordered containers]
[*Boost.Unordered] containers are compatible with Interprocess, so programmers can store
-hash containers in shared memory and memory mapped files. Here's an small example storing
+hash containers in shared memory and memory mapped files. Here is a small example storing
`unordered_map` in shared memory:
[import ../example/doc_unordered_map.cpp]
@@ -5082,7 +5082,7 @@
an allocator in their constructors so this usually makes object insertion a bit more
complicated.
-Here's is an example that shows how to put a multi index container in shared memory:
+Here is an example that shows how to put a multi index container in shared memory:
[import ../example/doc_multi_index.cpp]
[doc_multi_index]
@@ -5433,7 +5433,7 @@
The virtual function limitation makes even impossible to achieve the same level of
functionality of Boost and TR1 with [*Boost.Interprocess] smart pointers.
-Interprocess ownership smart pointers are mainly "smart pointers contaning smart pointers",
+Interprocess ownership smart pointers are mainly "smart pointers containing smart pointers",
so we can specify the pointer type they contain.
[section:intrusive_ptr Intrusive pointer]
@@ -5463,7 +5463,7 @@
class intrusive_ptr;
So `boost::interprocess::intrusive_ptr<MyClass, void*>` is equivalent to
-`boost::instrusive_ptr<MyClass>`. But if we want to place the intrusive_ptr in
+`boost::intrusive_ptr<MyClass>`. But if we want to place the intrusive_ptr in
shared memory we must specify a relative pointer type like
`boost::interprocess::intrusive_ptr<MyClass, boost::interprocess::offset_ptr<void> >`
@@ -5511,7 +5511,7 @@
Unlike
[@http://www.boost.org/libs/smart_ptr/shared_ptr.htm boost::shared_ptr],
due to limitations of mapped segments [classref boost::interprocess::shared_ptr]
-can not take advantage of virtual functions to maintain the same shared pointer
+cannot take advantage of virtual functions to maintain the same shared pointer
type while providing user-defined allocators and deleters. The allocator
and the deleter are template parameters of the shared pointer.
@@ -5523,7 +5523,7 @@
[classref boost::interprocess::shared_ptr shared_ptr], just like
[*Boost.Interprocess] containers need to pass allocators in their constructors.
-Here's is the declaration of [classref boost::interprocess::shared_ptr shared_ptr]:
+Here is the declaration of [classref boost::interprocess::shared_ptr shared_ptr]:
[c++]
@@ -5567,7 +5567,7 @@
with an allocator that will allocate the reference count also in the managed
segment and a deleter that will erase the object from the segment.
-These utilities will use the a [*Boost.Interprocess] allocator
+These utilities will use a [*Boost.Interprocess] allocator
([classref boost::interprocess::allocator])
and deleter ([classref boost::interprocess::deleter]) to do their job.
The definition of the previous shared pointer
@@ -5766,7 +5766,7 @@
The *segment manager*, is an object also placed in the first bytes of the
managed memory segment (shared memory, memory mapped file), that offers more
-sofisticated services built above the [*memory algorithm]. How can [*both] the
+sophisticated services built above the [*memory algorithm]. How can [*both] the
segment manager and memory algorithm be placed in the beginning of the segment?
That's because the segment manager [*owns] the memory algorithm: The
truth is that the memory algorithm is [*embedded] in the segment manager:
@@ -5797,7 +5797,7 @@
* The first index is a map with a pointer to a c-string (the name of the named object)
as a key and a structure with information of the dynamically allocated object
- (the most importants being the address and the size of the object).
+ (the most important being the address and the size of the object).
* The second index is used to implement "unique instances"
and is basically the same as the first index,
@@ -5906,7 +5906,7 @@
Segregated storage pools are simple and follow the classic segregated storage algorithm.
-* The pool allocates chuncks of memory using the segment manager's raw memory
+* The pool allocates chunks of memory using the segment manager's raw memory
allocation functions.
* The chunk contains a pointer to form a singly linked list of chunks. The pool
will contain a pointer to the first chunk.
@@ -5932,7 +5932,7 @@
Adaptive pools are a variation of segregated lists but they have a more complicated
approach:
-* Instead of using raw allocation, the pool allocates [*aligned] chuncks of memory
+* Instead of using raw allocation, the pool allocates [*aligned] chunks of memory
using the segment manager. This is an [*essential] feature since a node can reach
its chunk information applying a simple mask to its address.
@@ -5958,7 +5958,7 @@
* Deallocation returns the node to the free node list of its chunk and updates
the "active" pool accordingly.
-* If the number of totally free chunks exceds the limit, chunks are returned
+* If the number of totally free chunks exceeds the limit, chunks are returned
to the segment manager.
* When the pool is destroyed, the list of chunks is traversed and memory is returned
@@ -6037,7 +6037,7 @@
[section:performance_named_allocation Performance of named allocations]
-[*Boost.Interprocess] allows the same paralelism as two threads writing to a common
+[*Boost.Interprocess] allows the same parallelism as two threads writing to a common
structure, except when the user creates/searches named/unique objects. The steps
when creating a named object are these:
@@ -6101,7 +6101,7 @@
If you see that the performance is not good enough you have these alternatives:
-* Maybe the problem is that the lock time is too big and it hurts paralelism.
+* Maybe the problem is that the lock time is too big and it hurts parallelism.
Try to reduce the number of named objects in the global index and if your
application serves several clients try to build a new managed memory segment
for each one instead of using a common one.
@@ -6146,12 +6146,12 @@
//!The pointer type to be used by the rest of Interprocess framework
typedef implementation_defined void_pointer;
- //!Constructor. "size" is the total size of the maanged memory segment,
+ //!Constructor. "size" is the total size of the managed memory segment,
//!"extra_hdr_bytes" indicates the extra bytes after the sizeof(my_algorithm)
//!that the allocator should not use at all.
my_algorithm (std::size_t size, std::size_t extra_hdr_bytes);
- //!Obtains the minimium size needed by the algorithm
+ //!Obtains the minimum size needed by the algorithm
static std::size_t get_min_size (std::size_t extra_hdr_bytes);
//!Allocates bytes, returns 0 if there is not more memory
@@ -6191,7 +6191,7 @@
then all [*Boost.Interprocess] framework will use relative pointers.
-The `mutex_family` is an structure containing typedefs
+The `mutex_family` is a structure containing typedefs
for different interprocess_mutex types to be used in the [*Boost.Interprocess]
framework. For example the defined
@@ -6236,7 +6236,7 @@
This function should be executed with the synchronization capabilities offered
by `typename mutex_family::mutex_type` interprocess_mutex. That means, that if we define
`typedef mutex_family mutex_family;` then this function should offer
- the same synchronization as if it was surrounded by a interprocess_mutex lock/unlock.
+ the same synchronization as if it was surrounded by an interprocess_mutex lock/unlock.
Normally, this is implemented using a member of type `mutex_family::mutex_type`, but
it could be done using atomic instructions or lock free algorithms.
@@ -6372,7 +6372,7 @@
[c++]
- //!The key of the the named allocation information index. Stores a to
+ //!The key of the named allocation information index. Stores a to
//!a null string and the length of the string to speed up sorting
template<...>
struct index_key
@@ -6448,7 +6448,7 @@
* [*boost::map_index] uses *boost::interprocess::map* as index type.
* [*boost::null_index] that uses an dummy index type if the user just needs
- anonymous allocations and want's to save some space and class instantations.
+ anonymous allocations and wants to save some space and class instantations.
Defining a new managed memory segment that uses the new index is easy. For
example, a new managed shared memory that uses the new index:
@@ -6541,6 +6541,20 @@
[section:release_notes Release Notes]
+[section:release_notes_boost_1_37_00 Boost 1.37 Release]
+
+* Containers can be used now in recursive types.
+* Added `BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION` macro option to force the use
+ of generic emulation code for process-shared synchronization primitives instead of
+ native POSIX functions.
+* Added placement insertion members to containers
+* `boost::posix_time::pos_inf` value is now handled portably for timed functions.
+* Update some function parameters from `iterator` to `const_iterator` in containers
+ to keep up with the draft of the next standard.
+* Documentation fixes.
+
+[endsect]
+
[section:release_notes_boost_1_36_00 Boost 1.36 Release]
* Added anonymous shared memory for UNIX systems.
@@ -6559,7 +6573,7 @@
[classref boost::interprocess::shared_ptr shared_ptr],
[classref boost::interprocess::weak_ptr weak_ptr] and
[classref boost::interprocess::unique_ptr unique_ptr]. Added explanations
- and examples of these smart pointers in the documenation.
+ and examples of these smart pointers in the documentation.
* Optimized vector:
* 1) Now works with raw pointers as much as possible when
@@ -6576,7 +6590,7 @@
that might define virtual functions with the same names as container
member functions. That would convert container functions in virtual functions
and might disallow some of them if the returned type does not lead to a covariant return.
- Allocators are now stored as base clases of internal structs.
+ Allocators are now stored as base classes of internal structs.
* Implemented [classref boost::interprocess::named_mutex named_mutex] and
[classref boost::interprocess::named_semaphore named_semaphore] with POSIX
@@ -6671,12 +6685,12 @@
if the element has been moved (which is the case of many movable types). This trick
was provided by Howard Hinnant.
-* Added security check to avoid interger overflow bug in allocators and
+* Added security check to avoid integer overflow bug in allocators and
named construction functions.
* Added alignment checks to forward and backwards expansion functions.
-* Fixed bug in atomic funtions for PPC.
+* Fixed bug in atomic functions for PPC.
* Fixed race-condition error when creating and opening a managed segment.
Modified: branches/release/libs/interprocess/example/doc_contB.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_contB.cpp (original)
+++ branches/release/libs/interprocess/example/doc_contB.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -19,7 +19,7 @@
{
using namespace boost::interprocess;
try{
- //An special shared memory where we can
+ //A special shared memory where we can
//construct objects associated with a name.
//Connect to the already created shared memory segment
//and initialize needed resources
Modified: branches/release/libs/interprocess/example/doc_ipc_messageA.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_ipc_messageA.cpp (original)
+++ branches/release/libs/interprocess/example/doc_ipc_messageA.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -16,7 +16,7 @@
{
using namespace boost::interprocess;
- //An special shared memory from which we are
+ //A special shared memory from which we are
//able to allocate raw memory buffers.
//First remove any old shared memory of the same name, create
//the shared memory segment and initialize needed resources
Modified: branches/release/libs/interprocess/example/doc_ipc_messageB.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_ipc_messageB.cpp (original)
+++ branches/release/libs/interprocess/example/doc_ipc_messageB.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -17,7 +17,7 @@
using namespace boost::interprocess;
try{
- //An special shared memory from which we are
+ //A special shared memory from which we are
//able to allocate raw memory buffers.
//Connect to the already created shared memory segment
//and initialize needed resources
Modified: branches/release/libs/interprocess/example/doc_managed_aligned_allocation.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_managed_aligned_allocation.cpp (original)
+++ branches/release/libs/interprocess/example/doc_managed_aligned_allocation.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -29,7 +29,7 @@
void *ptr = managed_shm.allocate_aligned(100, Alignment);
//Check alignment
- assert(((char*)ptr-(char*)0) % Alignment == 0);
+ assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
//Deallocate it
managed_shm.deallocate(ptr);
@@ -38,7 +38,7 @@
ptr = managed_shm.allocate_aligned(100, Alignment, std::nothrow);
//Check alignment
- assert(((char*)ptr-(char*)0) % Alignment == 0);
+ assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
//Deallocate it
managed_shm.deallocate(ptr);
@@ -53,7 +53,7 @@
(3*Alignment - managed_shared_memory::PayloadPerAllocation, Alignment);
//Check alignment
- assert(((char*)ptr-(char*)0) % Alignment == 0);
+ assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
//Deallocate it
managed_shm.deallocate(ptr);
Modified: branches/release/libs/interprocess/example/doc_managed_copy_on_write.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_managed_copy_on_write.cpp (original)
+++ branches/release/libs/interprocess/example/doc_managed_copy_on_write.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -49,7 +49,7 @@
std::fstream file("MyManagedFile2", std::ios_base::out | std::ios_base::binary);
if(!file)
throw int(0);
- file.write((const char *)managed_file_cow.get_address(), managed_file_cow.get_size());
+ file.write(static_cast<const char *>(managed_file_cow.get_address()), managed_file_cow.get_size());
}
//Now open the modified file and test changes
Modified: branches/release/libs/interprocess/example/doc_managed_external_buffer.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_managed_external_buffer.cpp (original)
+++ branches/release/libs/interprocess/example/doc_managed_external_buffer.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -30,7 +30,7 @@
//We optimize resources to create 100 named objects in the static buffer
objects_in_static_memory.reserve_named_objects(100);
- //Alias a integer node allocator type
+ //Alias an integer node allocator type
//This allocator will allocate memory inside the static buffer
typedef allocator<int, wmanaged_external_buffer::segment_manager>
allocator_t;
Modified: branches/release/libs/interprocess/example/doc_named_allocA.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_named_allocA.cpp (original)
+++ branches/release/libs/interprocess/example/doc_named_allocA.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -19,7 +19,7 @@
typedef std::pair<double, int> MyType;
try{
- //An special shared memory where we can
+ //A special shared memory where we can
//construct objects associated with a name.
//First remove any old shared memory of the same name, create
//the shared memory segment and initialize needed resources
Modified: branches/release/libs/interprocess/example/doc_named_allocB.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_named_allocB.cpp (original)
+++ branches/release/libs/interprocess/example/doc_named_allocB.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -21,7 +21,7 @@
typedef std::pair<double, int> MyType;
try{
- //An special shared memory where we can
+ //A special shared memory where we can
//construct objects associated with a name.
//Connect to the already created shared memory segment
//and initialize needed resources
Modified: branches/release/libs/interprocess/example/doc_offset_ptr.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_offset_ptr.cpp (original)
+++ branches/release/libs/interprocess/example/doc_offset_ptr.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -25,7 +25,7 @@
int main ()
{
//Destroy any previous shared memory with the name to be used.
- //Create an special shared memory from which we can
+ //Create a special shared memory from which we can
//allocate buffers of raw memory.
shared_memory_object::remove("MySharedMemory");
try{
Modified: branches/release/libs/interprocess/example/doc_shared_memory2.cpp
==============================================================================
--- branches/release/libs/interprocess/example/doc_shared_memory2.cpp (original)
+++ branches/release/libs/interprocess/example/doc_shared_memory2.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -17,6 +17,7 @@
int main ()
{
using namespace boost::interprocess;
+ shared_memory_object::remove("shared_memory");
try{
//Open already created shared memory object.
shared_memory_object shm (open_only, "shared_memory", read_only);
Modified: branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln
==============================================================================
--- branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln (original)
+++ branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -459,13 +459,15 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_construct_test", "named_construct_test.vcproj", "{5183C8CE-F2E1-3620-237A-B765C9896390}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.ActiveCfg = Debug|Win32
{5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.Build.0 = Debug|Win32
@@ -927,6 +929,10 @@
{5C19CF83-4FB7-8219-8F6D-3BA9D2715A22}.Debug.Build.0 = Debug|Win32
{5C19CF83-4FB7-8219-8F6D-3BA9D2715A22}.Release.ActiveCfg = Release|Win32
{5C19CF83-4FB7-8219-8F6D-3BA9D2715A22}.Release.Build.0 = Release|Win32
+ {5183C8CE-F2E1-3620-237A-B765C9896390}.Debug.ActiveCfg = Debug|Win32
+ {5183C8CE-F2E1-3620-237A-B765C9896390}.Debug.Build.0 = Debug|Win32
+ {5183C8CE-F2E1-3620-237A-B765C9896390}.Release.ActiveCfg = Release|Win32
+ {5183C8CE-F2E1-3620-237A-B765C9896390}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
Modified: branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj
==============================================================================
--- branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj (original)
+++ branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -362,6 +362,9 @@
Name="Detail"
Filter="">
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\advanced_insert_int.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\algorithms.hpp">
</File>
<File
@@ -392,12 +395,18 @@
RelativePath="..\..\..\..\boost\interprocess\detail\interprocess_tester.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\intersegment_ptr.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\iterators.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\detail\managed_memory_impl.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\managed_multi_shared_memory.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\managed_open_or_create_impl.hpp">
</File>
<File
@@ -416,6 +425,9 @@
RelativePath="..\..\..\..\boost\interprocess\detail\mpl.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\multi_segment_services.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\named_proxy.hpp">
</File>
<File
@@ -431,6 +443,9 @@
RelativePath="..\..\..\..\boost\interprocess\detail\posix_time_types_wrk.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\preprocessor.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\ptime_wrk.hpp">
</File>
<File
@@ -446,6 +461,9 @@
RelativePath="..\..\..\..\boost\interprocess\detail\utilities.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\variadic_templates_tools.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\version_type.hpp">
</File>
<File
@@ -527,6 +545,9 @@
RelativePath="..\..\test\dummy_test_allocator.hpp">
</File>
<File
+ RelativePath="..\..\test\emplace_test.hpp">
+ </File>
+ <File
RelativePath="..\..\test\expand_bwd_test_allocator.hpp">
</File>
<File
Modified: branches/release/libs/interprocess/test/allocator_v1.hpp
==============================================================================
--- branches/release/libs/interprocess/test/allocator_v1.hpp (original)
+++ branches/release/libs/interprocess/test/allocator_v1.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -110,7 +110,7 @@
//!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)
- { (void)hint; return pointer((value_type*)mp_mngr->allocate(count*sizeof(value_type))); }
+ { (void)hint; return pointer(static_cast<value_type*>(mp_mngr->allocate(count*sizeof(value_type)))); }
//!Deallocates memory previously allocated. Never throws
void deallocate(const pointer &ptr, size_type)
Modified: branches/release/libs/interprocess/test/cached_node_allocator_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/cached_node_allocator_test.cpp (original)
+++ branches/release/libs/interprocess/test/cached_node_allocator_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -21,7 +21,7 @@
using namespace boost::interprocess;
-//Alias a integer node allocator type
+//Alias an integer node allocator type
typedef cached_node_allocator
<int, managed_shared_memory::segment_manager>
cached_node_allocator_t;
Modified: branches/release/libs/interprocess/test/deque_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/deque_test.cpp (original)
+++ branches/release/libs/interprocess/test/deque_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -14,6 +14,7 @@
#include <deque>
#include <iostream>
#include <functional>
+#include <list>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/deque.hpp>
@@ -31,14 +32,15 @@
#include <boost/interprocess/detail/type_traits.hpp>
#include <string>
#include "get_process_id_name.hpp"
+#include "emplace_test.hpp"
-//***************************************************************//
+///////////////////////////////////////////////////////////////////
// //
// This example repeats the same operations with std::deque and //
// shmem_deque using the node allocator //
// and compares the values of both containers //
// //
-//***************************************************************//
+///////////////////////////////////////////////////////////////////
using namespace boost::interprocess;
@@ -63,23 +65,64 @@
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, detail::move_impl(move_me));
- 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, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
}
{
- IntType move_me(2);
- shmdeque->assign(shmdeque->size()/2, detail::move_impl(move_me));
- stddeque->assign(stddeque->size()/2, 2);
- if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ IntType move_me(2);
+ shmdeque->assign(shmdeque->size()/2, detail::move_impl(move_me));
+ stddeque->assign(stddeque->size()/2, 2);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ }
+ {
+ IntType move_me(1);
+ stddeque->clear();
+ shmdeque->clear();
+ stddeque->insert(stddeque->begin(), 50, 1);
+ shmdeque->insert(shmdeque->begin(), 50, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->begin()+20, 50, 1);
+ shmdeque->insert(shmdeque->begin()+20, 50, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->begin()+20, 20, 1);
+ shmdeque->insert(shmdeque->begin()+20, 20, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
}
+ {
+ IntType move_me(1);
+ stddeque->clear();
+ shmdeque->clear();
+ stddeque->insert(stddeque->end(), 50, 1);
+ shmdeque->insert(shmdeque->end(), 50, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->end()-20, 50, 1);
+ shmdeque->insert(shmdeque->end()-20, 50, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->end()-20, 20, 1);
+ shmdeque->insert(shmdeque->end()-20, 20, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ }
+
return true;
}
+//Test recursive structures
+class recursive_deque
+{
+public:
+ int id_;
+ deque<recursive_deque> deque_;
+};
+
template<class IntType, template<class T, class SegmentManager> class AllocatorType >
bool do_test()
{
+ //Test for recursive types
+ {
+ deque<recursive_deque> recursive_deque_deque;
+ }
//Customize managed_shared_memory class
typedef basic_managed_shared_memory
<char,
@@ -118,23 +161,43 @@
try{
//Compare several shared memory deque operations with std::deque
int i;
- for(i = 0; i < max; ++i){
+ for(i = 0; i < max*100; ++i){
IntType move_me(i);
shmdeque->insert(shmdeque->end(), detail::move_impl(move_me));
stddeque->insert(stddeque->end(), i);
}
- if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ shmdeque->clear();
+ stddeque->clear();
+
+ for(i = 0; i < max*100; ++i){
+ IntType move_me(i);
+ shmdeque->push_back(detail::move_impl(move_me));
+ stddeque->push_back(i);
+ }
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ shmdeque->clear();
+ stddeque->clear();
+
+ for(i = 0; i < max*100; ++i){
+ IntType move_me(i);
+ shmdeque->push_front(detail::move_impl(move_me));
+ stddeque->push_front(i);
+ }
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
typename MyShmDeque::iterator it;
typename MyShmDeque::const_iterator cit = it;
shmdeque->erase(shmdeque->begin()++);
stddeque->erase(stddeque->begin()++);
- if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
shmdeque->erase(shmdeque->begin());
stddeque->erase(stddeque->begin());
- if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
{
//Initialize values
@@ -185,21 +248,40 @@
shmdeque->erase(shmdeque->begin());
stddeque->erase(stddeque->begin());
- if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmdeque->insert(shmdeque->begin(), detail::move_impl(move_me));
stddeque->insert(stddeque->begin(), i);
}
- if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ //Test insertion from list
+ {
+ std::list<int> l(50, int(1));
+ shmdeque->insert(shmdeque->begin(), l.begin(), l.end());
+ stddeque->insert(stddeque->begin(), l.begin(), l.end());
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ shmdeque->assign(l.begin(), l.end());
+ stddeque->assign(l.begin(), l.end());
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ }
+
+ shmdeque->resize(100);
+ stddeque->resize(100);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+
+ shmdeque->resize(200);
+ stddeque->resize(200);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
segment.template destroy<MyShmDeque>("MyShmDeque");
delete stddeque;
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
- return 1;
+ return false;
}
catch(std::exception &ex){
std::cout << ex.what() << std::endl;
@@ -227,6 +309,12 @@
if(!do_test<int, test::allocator_v1>())
return 1;
+ const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
+
+ if(!boost::interprocess::test::test_emplace
+ < deque<test::EmplaceInt>, Options>())
+ return 1;
+
return 0;
}
Modified: branches/release/libs/interprocess/test/expand_bwd_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/expand_bwd_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/expand_bwd_test_template.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -148,7 +148,7 @@
}
expand_bwd_test_allocator<value_type> alloc
- ((value_type*)&memory[0], MemorySize, Offset[iteration]);
+ (&memory[0], MemorySize, Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
@@ -165,10 +165,10 @@
}
}
catch(...){
- delete []((non_volatile_value_type*)memory);
+ delete [](const_cast<non_volatile_value_type*>(memory));
throw;
}
- delete []((non_volatile_value_type*)memory);
+ delete [](const_cast<non_volatile_value_type*>(memory));
}
return true;
@@ -227,10 +227,10 @@
}
}
catch(...){
- delete []((typename boost::remove_volatile<value_type>::type*)memory);
+ delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
throw;
}
- delete []((typename boost::remove_volatile<value_type>::type*)memory);
+ delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
}
return true;
Modified: branches/release/libs/interprocess/test/flat_tree_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/flat_tree_test.cpp (original)
+++ branches/release/libs/interprocess/test/flat_tree_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -20,6 +20,7 @@
#include "movable_int.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
+#include "emplace_test.hpp"
/////////////////////////////////////////////////////////////////
//
@@ -30,7 +31,7 @@
/////////////////////////////////////////////////////////////////
using namespace boost::interprocess;
-
+/*
//Explicit instantiation to detect compilation errors
template class boost::interprocess::flat_set
<test::movable_and_copyable_int
@@ -55,7 +56,7 @@
,std::less<test::movable_and_copyable_int>
,test::dummy_test_allocator<std::pair<test::movable_and_copyable_int
,test::movable_and_copyable_int> > >;
-
+*/
//Customize managed_shared_memory class
typedef basic_managed_shared_memory
<char,
@@ -112,9 +113,29 @@
,std::less<test::movable_and_copyable_int>
,shmem_move_copy_pair_allocator_t> MyMoveCopyShmMultiMap;
+//Test recursive structures
+class recursive_flat_set
+{
+public:
+ int id_;
+ flat_set<recursive_flat_set> flat_set_;
+ friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b)
+ { return a.id_ < b.id_; }
+};
+
+class recursive_flat_map
+{
+public:
+ int id_;
+ flat_map<recursive_flat_map, recursive_flat_map> map_;
+ friend bool operator< (const recursive_flat_map &a, const recursive_flat_map &b)
+ { return a.id_ < b.id_; }
+};
+
int main()
{
using namespace boost::interprocess::test;
+
if (0 != set_test<my_managed_shared_memory
,MyShmSet
,MyStdSet
@@ -186,6 +207,19 @@
return 1;
}
+ #if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 3)
+ const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
+ const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
+
+ if(!boost::interprocess::test::test_emplace<flat_map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<flat_multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<flat_set<test::EmplaceInt>, SetOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<flat_multiset<test::EmplaceInt>, SetOptions>())
+ return 1;
+ #endif //!defined(__GNUC__)
return 0;
}
Modified: branches/release/libs/interprocess/test/intersegment_ptr_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/intersegment_ptr_test.cpp (original)
+++ branches/release/libs/interprocess/test/intersegment_ptr_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -205,14 +205,14 @@
if(sizeof(segment_data) > mapped_region::get_page_size())
return false;
- segment_data &seg_0_0 = *((segment_data *)reg_0_0.get_address());
- segment_data &seg_0_1 = *((segment_data *)reg_0_1.get_address());
- segment_data &seg_1_0 = *((segment_data *)reg_1_0.get_address());
- segment_data &seg_1_1 = *((segment_data *)reg_1_1.get_address());
+ segment_data &seg_0_0 = *static_cast<segment_data *>(reg_0_0.get_address());
+ segment_data &seg_0_1 = *static_cast<segment_data *>(reg_0_1.get_address());
+ segment_data &seg_1_0 = *static_cast<segment_data *>(reg_1_0.get_address());
+ segment_data &seg_1_1 = *static_cast<segment_data *>(reg_1_1.get_address());
//Some dummy multi_segment_services
- multi_segment_services *services0 = (multi_segment_services *)0;
- multi_segment_services *services1 = (multi_segment_services *)1;
+ multi_segment_services *services0 = static_cast<multi_segment_services *>(0);
+ multi_segment_services *services1 = reinterpret_cast<multi_segment_services *>(1);
const intersegment_ptr<int>::segment_group_id group_0_id =
intersegment_ptr<int>::new_segment_group(services0);
@@ -386,7 +386,7 @@
}
int main()
-{
+{/*
if(!test_types_and_convertions())
return 1;
if(!test_arithmetic())
@@ -398,6 +398,7 @@
if(!test_multi_segment_shared_memory())
return 1;
+*/
return 0;
}
Modified: branches/release/libs/interprocess/test/list_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/list_test.cpp (original)
+++ branches/release/libs/interprocess/test/list_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -16,6 +16,7 @@
#include "dummy_test_allocator.hpp"
#include "list_test.hpp"
#include "movable_int.hpp"
+#include "emplace_test.hpp"
using namespace boost::interprocess;
@@ -35,8 +36,21 @@
typedef allocator<test::movable_and_copyable_int, managed_shared_memory::segment_manager> ShmemCopyMoveAllocator;
typedef list<test::movable_and_copyable_int, ShmemCopyMoveAllocator> MyCopyMoveList;
+class recursive_list
+{
+public:
+ int id_;
+ list<recursive_list> list_;
+};
+
+void recursive_list_test()//Test for recursive types
+{
+ list<recursive_list> recursive_list_list;
+}
+
int main ()
{
+ recursive_list_test();
if(test::list_test<managed_shared_memory, MyList, true>())
return 1;
@@ -49,6 +63,11 @@
if(test::list_test<managed_shared_memory, MyCopyMoveList, true>())
return 1;
+ const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
+
+ if(!boost::interprocess::test::test_emplace<list<test::EmplaceInt>, Options>())
+ return 1;
+
return 0;
}
Modified: branches/release/libs/interprocess/test/list_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/list_test.hpp (original)
+++ branches/release/libs/interprocess/test/list_test.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -88,7 +88,6 @@
}
};
-
template<class ManagedSharedMemory
,class MyShmList
,bool DoublyLinked>
Modified: branches/release/libs/interprocess/test/managed_mapped_file_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/managed_mapped_file_test.cpp (original)
+++ branches/release/libs/interprocess/test/managed_mapped_file_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -20,7 +20,7 @@
int main ()
{
- const int FileSize = 65536;
+ const int FileSize = 65536*10;
const char *const FileName = test::get_process_id_name();
//STL compatible allocator object for memory-mapped file
@@ -42,6 +42,7 @@
//Let's allocate some memory
for(i = 0; i < max; ++i){
array[i] = mfile.allocate(i+1);
+ std::cout << i << ' ';
}
//Deallocate allocated memory
Modified: branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -108,7 +108,7 @@
std::size_t received_size;
if(a.template allocation_command<char>
( shrink_in_place | nothrow_allocation, i*2
- , i, received_size, (char*)buffers[i]).first){
+ , i, received_size, static_cast<char*>(buffers[i])).first){
if(received_size > std::size_t(i*2)){
return false;
}
@@ -160,7 +160,7 @@
while(a.template allocation_command<char>
( expand_fwd | nothrow_allocation, min_size
- , preferred_size, received_size, (char*)buffers[i]).first){
+ , preferred_size, received_size, static_cast<char*>(buffers[i])).first){
//Check received size is bigger than minimum
if(received_size < min_size){
return false;
@@ -215,7 +215,7 @@
std::size_t received_size;
if(a.template allocation_command<char>
( shrink_in_place | nothrow_allocation, received_sizes[i]
- , i, received_size, (char*)buffers[i]).first){
+ , i, received_size, static_cast<char*>(buffers[i])).first){
if(received_size > std::size_t(received_sizes[i])){
return false;
}
@@ -234,7 +234,7 @@
std::size_t request_size = received_sizes[i];
if(a.template allocation_command<char>
( expand_fwd | nothrow_allocation, request_size
- , request_size, received_size, (char*)buffers[i]).first){
+ , request_size, received_size, static_cast<char*>(buffers[i])).first){
if(received_size != received_sizes[i]){
return false;
}
@@ -299,7 +299,7 @@
while(a.template allocation_command<char>
( expand_fwd | nothrow_allocation, min_size
- , preferred_size, received_size, (char*)buffers[i]).first){
+ , preferred_size, received_size, static_cast<char*>(buffers[i])).first){
//Check received size is bigger than minimum
if(received_size < min_size){
return false;
@@ -312,8 +312,8 @@
}
//Now erase null values from the vector
- buffers.erase(std::remove(buffers.begin(), buffers.end(), (void*)0)
- ,buffers.end());
+ buffers.erase( std::remove(buffers.begin(), buffers.end(), static_cast<void*>(0))
+ , buffers.end());
//Deallocate it in non sequential order
for(int j = 0, max = (int)buffers.size()
@@ -369,7 +369,7 @@
std::size_t prf_size = (received_size + (i+1)*2);
std::pair<void*, bool> ret = a.raw_allocation_command
( expand_bwd | nothrow_allocation, min_size
- , prf_size, received_size, (char*)ptr, sizeof_object);
+ , prf_size, received_size, static_cast<char*>(ptr), sizeof_object);
if(!ret.first)
break;
//If we have memory, this must be a buffer reuse
@@ -511,7 +511,7 @@
//Test allocated memory is zero
for(int i = 0, max = buffers.size(); i < max; ++i){
for(int j = 0; j < i; ++j){
- if(((char*)buffers[i])[j]) return false;
+ if(static_cast<char*>(buffers[i])[j]) return false;
}
}
Modified: branches/release/libs/interprocess/test/movable_int.hpp
==============================================================================
--- branches/release/libs/interprocess/test/movable_int.hpp (original)
+++ branches/release/libs/interprocess/test/movable_int.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -52,6 +52,9 @@
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
#endif
+ movable_int & operator= (int i)
+ { this->m_int = i; return *this; }
+
bool operator ==(const movable_int &mi) const
{ return this->m_int == mi.m_int; }
@@ -123,6 +126,9 @@
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
#endif
+ movable_and_copyable_int & operator= (int i)
+ { this->m_int = i; return *this; }
+
bool operator ==(const movable_and_copyable_int &mi) const
{ return this->m_int == mi.m_int; }
Modified: branches/release/libs/interprocess/test/mutex_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/mutex_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/mutex_test_template.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -165,7 +165,7 @@
template<typename M>
void lock_and_sleep(void *arg, M &sm)
{
- data<M> *pdata = (data<M> *) arg;
+ data<M> *pdata = static_cast<data<M>*>(arg);
boost::interprocess::scoped_lock<M> l(sm);
if(pdata->m_secs){
boost::thread::sleep(xsecs(pdata->m_secs));
@@ -181,7 +181,7 @@
template<typename M>
void try_lock_and_sleep(void *arg, M &sm)
{
- data<M> *pdata = (data<M> *) arg;
+ data<M> *pdata = static_cast<data<M>*>(arg);
boost::interprocess::scoped_lock<M> l(sm, boost::interprocess::defer_lock);
if (l.try_lock()){
boost::thread::sleep(xsecs(2*BaseSeconds));
@@ -193,7 +193,7 @@
template<typename M>
void timed_lock_and_sleep(void *arg, M &sm)
{
- data<M> *pdata = (data<M> *) arg;
+ data<M> *pdata = static_cast<data<M>*>(arg);
boost::posix_time::ptime pt(delay(pdata->m_secs));
boost::interprocess::scoped_lock<M>
l (sm, boost::interprocess::defer_lock);
Modified: branches/release/libs/interprocess/test/node_allocator_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/node_allocator_test.cpp (original)
+++ branches/release/libs/interprocess/test/node_allocator_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -22,7 +22,7 @@
using namespace boost::interprocess;
//We will work with wide characters for shared memory objects
-//Alias a integer node allocator type
+//Alias an integer node allocator type
typedef node_allocator
<int, managed_shared_memory::segment_manager> shmem_node_allocator_t;
typedef detail::node_allocator_v1
Modified: branches/release/libs/interprocess/test/private_node_allocator_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/private_node_allocator_test.cpp (original)
+++ branches/release/libs/interprocess/test/private_node_allocator_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -22,7 +22,7 @@
using namespace boost::interprocess;
//We will work with wide characters for shared memory objects
-//Alias a integer node allocator type
+//Alias an integer node allocator type
typedef private_node_allocator
<int, managed_shared_memory::segment_manager> priv_node_allocator_t;
typedef detail::private_node_allocator_v1
Modified: branches/release/libs/interprocess/test/semaphore_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/semaphore_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/semaphore_test_template.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -146,7 +146,7 @@
template<typename P>
void wait_and_sleep(void *arg, P &sm)
{
- data<P> *pdata = (data<P> *) arg;
+ data<P> *pdata = static_cast<data<P>*>(arg);
boost::interprocess::scoped_lock<P> l(sm);
boost::thread::sleep(xsecs(3*BaseSeconds));
++shared_val;
@@ -156,7 +156,7 @@
template<typename P>
void try_wait_and_sleep(void *arg, P &sm)
{
- data<P> *pdata = (data<P> *) arg;
+ data<P> *pdata = static_cast<data<P>*>(arg);
boost::interprocess::scoped_lock<P> l(sm, boost::interprocess::defer_lock);
if (l.try_lock()){
boost::thread::sleep(xsecs(3*BaseSeconds));
@@ -168,7 +168,7 @@
template<typename P>
void timed_wait_and_sleep(void *arg, P &sm)
{
- data<P> *pdata = (data<P> *) arg;
+ data<P> *pdata = static_cast<data<P>*>(arg);
boost::posix_time::ptime pt(delay(pdata->m_secs));
boost::interprocess::scoped_lock<P>
l (sm, boost::interprocess::defer_lock);
Modified: branches/release/libs/interprocess/test/sharable_mutex_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/sharable_mutex_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/sharable_mutex_test_template.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -38,7 +38,7 @@
template<typename SM>
void plain_exclusive(void *arg, SM &sm)
{
- data<SM> *pdata = (data<SM> *) arg;
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::interprocess::scoped_lock<SM> l(sm);
boost::thread::sleep(xsecs(3*BaseSeconds));
shared_val += 10;
@@ -48,7 +48,7 @@
template<typename SM>
void plain_shared(void *arg, SM &sm)
{
- data<SM> *pdata = (data<SM> *) arg;
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::interprocess::sharable_lock<SM> l(sm);
if(pdata->m_secs){
boost::thread::sleep(xsecs(pdata->m_secs*BaseSeconds));
@@ -59,7 +59,7 @@
template<typename SM>
void try_exclusive(void *arg, SM &sm)
{
- data<SM> *pdata = (data<SM> *) arg;
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::interprocess::scoped_lock<SM> l(sm, boost::interprocess::defer_lock);
if (l.try_lock()){
boost::thread::sleep(xsecs(3*BaseSeconds));
@@ -71,7 +71,7 @@
template<typename SM>
void try_shared(void *arg, SM &sm)
{
- data<SM> *pdata = (data<SM> *) arg;
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::interprocess::sharable_lock<SM> l(sm, boost::interprocess::defer_lock);
if (l.try_lock()){
if(pdata->m_secs){
@@ -84,7 +84,7 @@
template<typename SM>
void timed_exclusive(void *arg, SM &sm)
{
- data<SM> *pdata = (data<SM> *) arg;
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::posix_time::ptime pt(delay(pdata->m_secs));
boost::interprocess::scoped_lock<SM>
l (sm, boost::interprocess::defer_lock);
@@ -98,7 +98,7 @@
template<typename SM>
void timed_shared(void *arg, SM &sm)
{
- data<SM> *pdata = (data<SM> *) arg;
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::posix_time::ptime pt(delay(pdata->m_secs));
boost::interprocess::sharable_lock<SM>
l(sm, boost::interprocess::defer_lock);
@@ -143,11 +143,11 @@
// Reader one launches, "clearly" after writer two, and "clearly"
// while writer 1 still holds the lock
boost::thread::sleep(xsecs(1*BaseSeconds));
- boost::thread tr1(thread_adapter<SM>(plain_shared,&s1, *pm3));
- boost::thread tr2(thread_adapter<SM>(plain_shared,&s2, *pm4));
+ boost::thread thr1(thread_adapter<SM>(plain_shared,&s1, *pm3));
+ boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, *pm4));
- tr2.join();
- tr1.join();
+ thr2.join();
+ thr1.join();
tw2.join();
tw1.join();
@@ -177,8 +177,8 @@
data<SM> e2(2);
//We launch 2 readers, that will block for 3*BaseTime seconds
- boost::thread tr1(thread_adapter<SM>(plain_shared,&s1,*pm1));
- boost::thread tr2(thread_adapter<SM>(plain_shared,&s2,*pm2));
+ boost::thread thr1(thread_adapter<SM>(plain_shared,&s1,*pm1));
+ boost::thread thr2(thread_adapter<SM>(plain_shared,&s2,*pm2));
//Make sure they try to hold the sharable lock
boost::thread::sleep(xsecs(1*BaseSeconds));
@@ -187,8 +187,8 @@
boost::thread tw1(thread_adapter<SM>(plain_exclusive,&e1,*pm3));
boost::thread tw2(thread_adapter<SM>(plain_exclusive,&e2,*pm4));
- tr2.join();
- tr1.join();
+ thr2.join();
+ thr1.join();
tw2.join();
tw1.join();
@@ -229,13 +229,13 @@
// Reader one launches, "clearly" after writer #1 holds the lock
// and before it releases the lock.
boost::thread::sleep(xsecs(1*BaseSeconds));
- boost::thread tr1(thread_adapter<SM>(try_shared,&s1,*pm2));
+ boost::thread thr1(thread_adapter<SM>(try_shared,&s1,*pm2));
// Writer two launches in the same timeframe.
boost::thread tw2(thread_adapter<SM>(try_exclusive,&e2,*pm3));
tw2.join();
- tr1.join();
+ thr1.join();
tw1.join();
assert(e1.m_value == 10);
@@ -281,12 +281,12 @@
// to get the lock. 2nd reader will wait 3*BaseSeconds seconds, and will get
// the lock.
- boost::thread tr1(thread_adapter<SM>(timed_shared,&s1,*pm3));
- boost::thread tr2(thread_adapter<SM>(timed_shared,&s2,*pm4));
+ boost::thread thr1(thread_adapter<SM>(timed_shared,&s1,*pm3));
+ boost::thread thr2(thread_adapter<SM>(timed_shared,&s2,*pm4));
tw1.join();
- tr1.join();
- tr2.join();
+ thr1.join();
+ thr2.join();
tw2.join();
assert(e1.m_value == 10);
Modified: branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp (original)
+++ branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -72,7 +72,7 @@
mapped_region region(mapping, read_write, 0, FileSize/2, 0);
mapped_region region2(mapping, read_write, FileSize/2, FileSize - FileSize/2, 0);
- unsigned char *checker = (unsigned char*)region.get_address();
+ unsigned char *checker = static_cast<unsigned char*>(region.get_address());
//Check pattern
for(std::size_t i = 0
;i < FileSize/2
@@ -83,7 +83,7 @@
}
//Check second half
- checker = (unsigned char *)region2.get_address();
+ checker = static_cast<unsigned char *>(region2.get_address());
//Check pattern
for(std::size_t i = FileSize/2
Modified: branches/release/libs/interprocess/test/shared_ptr_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/shared_ptr_test.cpp (original)
+++ branches/release/libs/interprocess/test/shared_ptr_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -587,7 +587,7 @@
BOOST_TEST( p2.use_count() == p.use_count() );
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
- p2.reset( p, (int*)0 );
+ p2.reset( p, static_cast<int*>(0) );
BOOST_TEST( p2.get() == 0 );
Modified: branches/release/libs/interprocess/test/slist_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/slist_test.cpp (original)
+++ branches/release/libs/interprocess/test/slist_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -16,6 +16,7 @@
#include "dummy_test_allocator.hpp"
#include "list_test.hpp"
#include "movable_int.hpp"
+#include "emplace_test.hpp"
using namespace boost::interprocess;
@@ -26,20 +27,50 @@
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
typedef slist<int, ShmemAllocator> MyList;
+typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
+typedef slist<volatile int, ShmemVolatileAllocator> MyVolatileList;
+
typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
typedef slist<test::movable_int, ShmemMoveAllocator> MyMoveList;
typedef allocator<test::movable_and_copyable_int, managed_shared_memory::segment_manager> ShmemCopyMoveAllocator;
typedef slist<test::movable_and_copyable_int, ShmemCopyMoveAllocator> MyCopyMoveList;
+class recursive_slist
+{
+public:
+ int id_;
+ slist<recursive_slist> slist_;
+};
+
+void recursive_slist_test()//Test for recursive types
+{
+ slist<recursive_slist> recursive_list_list;
+}
+
int main ()
{
+ recursive_slist_test();
+
if(test::list_test<managed_shared_memory, MyList, false>())
return 1;
if(test::list_test<managed_shared_memory, MyMoveList, false>())
return 1;
+ if(test::list_test<managed_shared_memory, MyCopyMoveList, false>())
+ return 1;
+
+ if(test::list_test<managed_shared_memory, MyVolatileList, false>())
+ return 1;
+
+ const test::EmplaceOptions Options = (test::EmplaceOptions)
+ (test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE | test::EMPLACE_AFTER);
+
+ if(!boost::interprocess::test::test_emplace
+ < slist<test::EmplaceInt>, Options>())
+ return 1;
+
return 0;
}
Modified: branches/release/libs/interprocess/test/tree_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/tree_test.cpp (original)
+++ branches/release/libs/interprocess/test/tree_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -22,6 +22,7 @@
#include "dummy_test_allocator.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
+#include "emplace_test.hpp"
///////////////////////////////////////////////////////////////////
// //
@@ -32,7 +33,7 @@
///////////////////////////////////////////////////////////////////
using namespace boost::interprocess;
-
+/*
//Explicit instantiation to detect compilation errors
template class boost::interprocess::set
<test::movable_and_copyable_int
@@ -57,7 +58,7 @@
,std::less<test::movable_and_copyable_int>
,test::dummy_test_allocator<std::pair<const test::movable_and_copyable_int
,test::movable_and_copyable_int> > >;
-
+*/
//Customize managed_shared_memory class
typedef basic_managed_shared_memory
<char,
@@ -66,7 +67,7 @@
> my_managed_shared_memory;
//We will work with narrow characters for shared memory objects
-//Alias a integer node allocator type
+//Alias an integer node allocator type
typedef allocator<int, my_managed_shared_memory::segment_manager>
shmem_allocator_t;
typedef allocator<std::pair<const int, int>, my_managed_shared_memory::segment_manager>
@@ -119,9 +120,54 @@
,test::movable_and_copyable_int
,std::less<test::movable_and_copyable_int>
,shmem_move_copy_node_pair_allocator_t> MyMoveCopyShmMultiMap;
+//Test recursive structures
+class recursive_set
+{
+public:
+ int id_;
+ set<recursive_set> set_;
+ friend bool operator< (const recursive_set &a, const recursive_set &b)
+ { return a.id_ < b.id_; }
+};
+
+class recursive_map
+{
+ public:
+ int id_;
+ map<recursive_map, recursive_map> map_;
+ friend bool operator< (const recursive_map &a, const recursive_map &b)
+ { return a.id_ < b.id_; }
+};
+
+//Test recursive structures
+class recursive_multiset
+{
+public:
+ int id_;
+ multiset<recursive_multiset> multiset_;
+ friend bool operator< (const recursive_multiset &a, const recursive_multiset &b)
+ { return a.id_ < b.id_; }
+};
+
+class recursive_multimap
+{
+public:
+ int id_;
+ multimap<recursive_multimap, recursive_multimap> multimap_;
+ friend bool operator< (const recursive_multimap &a, const recursive_multimap &b)
+ { return a.id_ < b.id_; }
+};
int main ()
{
+ //Recursive container instantiation
+ {
+ set<recursive_set> set_;
+ multiset<recursive_multiset> multiset_;
+ map<recursive_map, recursive_map> map_;
+ multimap<recursive_multimap, recursive_multimap> multimap_;
+ }
+
using namespace boost::interprocess::detail;
if(0 != test::set_test<my_managed_shared_memory
@@ -188,6 +234,16 @@
return 1;
}
+ const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
+ if(!boost::interprocess::test::test_emplace<set<test::EmplaceInt>, SetOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<multiset<test::EmplaceInt>, SetOptions>())
+ return 1;
+ const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
+ if(!boost::interprocess::test::test_emplace<map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
return 0;
}
Modified: branches/release/libs/interprocess/test/user_buffer_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/user_buffer_test.cpp (original)
+++ branches/release/libs/interprocess/test/user_buffer_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -198,7 +198,7 @@
std::size_t heap_list_size = heaplist->size();
//Copy heap buffer to another
- const char *insert_beg = detail::char_ptr_cast(heap_buffer.get_address());
+ const char *insert_beg = static_cast<char*>(heap_buffer.get_address());
const char *insert_end = insert_beg + heap_buffer.get_size();
std::vector<char> grow_copy (insert_beg, insert_end);
Modified: branches/release/libs/interprocess/test/vector_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/vector_test.cpp (original)
+++ branches/release/libs/interprocess/test/vector_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -76,8 +76,21 @@
return 0;
}
+class recursive_vector
+{
+ public:
+ int id_;
+ vector<recursive_vector> vector_;
+};
+
+void recursive_vector_test()//Test for recursive types
+{
+ vector<recursive_vector> recursive_vector_vector;
+}
+
int main()
{
+ recursive_vector_test();
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
typedef vector<int, ShmemAllocator> MyVector;
@@ -105,6 +118,11 @@
if(test_expand_bwd())
return 1;
+ const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
+ if(!boost::interprocess::test::test_emplace
+ < vector<test::EmplaceInt>, Options>())
+ return 1;
+
return 0;
}
Modified: branches/release/libs/interprocess/test/vector_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/vector_test.hpp (original)
+++ branches/release/libs/interprocess/test/vector_test.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -14,6 +14,7 @@
#include <vector>
#include <iostream>
#include <functional>
+#include <list>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/move_iterator.hpp>
@@ -24,6 +25,7 @@
#include <string>
#include <vector>
#include "get_process_id_name.hpp"
+#include "emplace_test.hpp"
namespace boost{
namespace interprocess{
@@ -46,22 +48,22 @@
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, detail::move_impl(move_me));
- 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, detail::move_impl(move_me));
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
}
{
- IntType move_me(2);
- shmvector->assign(shmvector->size()/2, detail::move_impl(move_me));
- stdvector->assign(stdvector->size()/2, 2);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
+ IntType move_me(2);
+ shmvector->assign(shmvector->size()/2, detail::move_impl(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, detail::move_impl(move_me));
- stdvector->assign(stdvector->size()*3-1, 3);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
+ IntType move_me(3);
+ shmvector->assign(shmvector->size()*3-1, detail::move_impl(move_me));
+ stdvector->assign(stdvector->size()*3-1, 3);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
}
return true;
}
@@ -192,6 +194,17 @@
}
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ //Test insertion from list
+ {
+ std::list<int> l(50, int(1));
+ shmvector->insert(shmvector->begin(), l.begin(), l.end());
+ stdvector->insert(stdvector->begin(), l.begin(), l.end());
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ shmvector->assign(l.begin(), l.end());
+ stdvector->assign(l.begin(), l.end());
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ }
+
delete stdvector;
segment.template destroy<MyShmVector>("MyShmVector");
segment.shrink_to_fit_indexes();
Modified: branches/release/libs/interprocess/test/windows_shared_memory_mapping_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/windows_shared_memory_mapping_test.cpp (original)
+++ branches/release/libs/interprocess/test/windows_shared_memory_mapping_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -68,7 +68,7 @@
mapped_region region (mapping, read_only, 0, FileSize/2, 0);
mapped_region region2(mapping, read_only, FileSize/2, FileSize - FileSize/2, 0);
- unsigned char *checker = (unsigned char*)region.get_address();
+ unsigned char *checker = static_cast<unsigned char*>(region.get_address());
//Check pattern
for(std::size_t i = 0
;i < FileSize/2
@@ -79,7 +79,7 @@
}
//Check second half
- checker = (unsigned char *)region2.get_address();
+ checker = static_cast<unsigned char *>(region2.get_address());
//Check pattern
for(std::size_t i = FileSize/2
Modified: branches/release/libs/intrusive/doc/intrusive.qbk
==============================================================================
--- branches/release/libs/intrusive/doc/intrusive.qbk (original)
+++ branches/release/libs/intrusive/doc/intrusive.qbk 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -596,7 +596,7 @@
be configured to use any type of pointer. This configuration information is also
transmitted to the containers, so all the internal pointers used by intrusive containers
configured with these hooks will be smart pointers. As an example,
- [*Boost.Interprocess] defines an mart pointer compatible with shared memory,
+ [*Boost.Interprocess] defines a smart pointer compatible with shared memory,
called `offset_ptr`. [*Boost.Intrusive] can be configured to use this smart pointer
to allow shared memory intrusive containers.
@@ -656,6 +656,15 @@
used in hooks' destructors to check that the hook is in a default state.
If any of these macros is not redefined, the assertion will default to `BOOST_ASSERT`.
+If `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT` or `BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT`
+is defined and the programmer needs to include a file to configure that assertion, it can define
+`BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE` or `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE`
+with the name of the file to include:
+
+[c++]
+
+ #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT MYASSERT
+ #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE <myassert.h>
[endsect]
@@ -1032,8 +1041,9 @@
* [*`optimize_size<bool Enable>`]: The hook will be optimized for size
instead of speed. The hook will embed the color bit of the red-black
tree node in the parent pointer if pointer alignment is even.
- Optimizing the size will reduce speed performance a bit since masking
- operations will be needed to access parent pointer and color attributes.
+ In some platforms, optimizing the size might reduce speed performance a bit
+ since masking operations will be needed to access parent pointer and color attributes,
+ in other platforms this option improves performance due to improved memory locality.
Default: `optimize_size<false>`.
[endsect]
@@ -1283,11 +1293,17 @@
(e.g. strings with a long common predicate) sometimes (specially when the
load factor is high or we have many equivalent elements in an
[classref boost::intrusive::unordered_multiset unordered_multiset] and
- no `optimize_multikey<>` is activatedin the hook)
+ no `optimize_multikey<>` is activated in the hook)
the equality function is a performance problem. Two equal values must have
equal hashes, so comparing the hash values of two elements before using the
comparison functor can speed up some implementations.
+* [*`incremental<bool Enabled>`]: Activates incremental hashing (also known as Linear Hashing).
+ This option implies `power_2_buckets<true>` and the container will require power of two buckets.
+ For more information on incremental hashing, see
+ [@http://en.wikipedia.org/wiki/Linear_hashing `Linear hash` on Wikipedia]
+ Default: `incremental<false>`
+
[endsect]
[section:unordered_set_unordered_multiset_example Example]
@@ -1558,8 +1574,9 @@
* [*`optimize_size<bool Enable>`]: The hook will be optimized for size
instead of speed. The hook will embed the balance bits of the AVL
tree node in the parent pointer if pointer alignment is multiple of 4.
- Optimizing the size will reduce speed performance a bit since masking
- operations will be needed to access parent pointer and balance factor attributes.
+ In some platforms, optimizing the size might reduce speed performance a bit
+ since masking operations will be needed to access parent pointer and balance factor attributes,
+ in other platforms this option improves performance due to improved memory locality.
Default: `optimize_size<false>`.
[endsect]
@@ -1890,7 +1907,7 @@
With multiple ordered and unordered associative containers
([classref boost::intrusive::multiset multiset] and
-[classref boost::intrusive::unordered_multiset unordered_multiset]) there's
+[classref boost::intrusive::unordered_multiset unordered_multiset]) there is
no need for these advanced insertion functions, since insertions are always succesful.
[endsect]
@@ -1982,7 +1999,7 @@
all the constructed elements are disposed using the disposer function object.
-Here's an example of `clone_from`:
+Here is an example of `clone_from`:
[import ../example/doc_clone_from.cpp]
[doc_clone_from]
@@ -2116,7 +2133,7 @@
be inserted container. Additionally, these hooks don't support `unlink()` and
`swap_nodes()` operations for the same reason.
-Here's an example that creates a class with two any hooks, and uses one to insert the
+Here is an example that creates a class with two any hooks, and uses one to insert the
class in a [classref slist] and the other one in a [classref list].
[import ../example/doc_any_hook.cpp]
@@ -2699,7 +2716,7 @@
Instead of using [*Boost.Intrusive] predefined hooks
a user might want to develop customized containers, for example, using nodes that are
optimized for a specific
-application or that are compatible with a a legacy ABI. A user might want
+application or that are compatible with a legacy ABI. A user might want
to have only two additional pointers in his class and insert the class in a doubly
linked list sometimes and in a singly linked list in other situations. You can't
achieve this using [*Boost.Intrusive] predefined hooks. Now, instead of using
@@ -3459,7 +3476,7 @@
[section:performance_results_conclusions Conclusions]
-Intrusive containers can offer performance benefits that can not be achieved with
+Intrusive containers can offer performance benefits that cannot be achieved with
equivalent non-intrusive containers. Memory locality improvements are noticeable
when the objects to be inserted are small. Minimizing memory allocation/deallocation calls is also
an important factor and intrusive containers make this simple if the user allocates
@@ -3471,6 +3488,17 @@
[section:release_notes Release Notes]
+[section:release_notes_boost_1_37_00 Boost 1.37 Release]
+
+* Intrusive now takes advantage of compilers with variadic templates.
+* `clone_from` functions now copy predicates and hash functions of associative containers.
+* Added incremental hashing to unordered containers via `incremental<>` option.
+* Update some function parameters from `iterator` to `const_iterator` in containers
+ to keep up with the draft of the next standard.
+* Added an option to specify include files for intrusive configurable assertion macros.
+
+[endsect]
+
[section:release_notes_boost_1_36_00 Boost 1.36 Release]
* Added `linear<>` and `cache_last<>` options to singly linked lists.
@@ -3512,7 +3540,7 @@
[endsect]
-[section:acknowledgments Acknowledgements]
+[section:acknowledgements Acknowledegements]
[*Olaf Krzikalla] would like to thank:
Modified: branches/release/libs/intrusive/example/doc_window.cpp
==============================================================================
--- branches/release/libs/intrusive/example/doc_window.cpp (original)
+++ branches/release/libs/intrusive/example/doc_window.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -21,7 +21,7 @@
//This is a container those value is an abstract class: you can't do this with std::list.
typedef list<Window> win_list;
- //An static intrusive list declaration
+ //A static intrusive list declaration
static win_list all_windows;
//Constructor. Includes this window in the list
Modified: branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj
==============================================================================
--- branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj (original)
+++ branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -267,6 +267,9 @@
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\utilities.hpp">
</File>
+ <File
+ RelativePath="..\..\..\..\..\boost\intrusive\detail\workaround.hpp">
+ </File>
</Filter>
</Filter>
<Filter
Modified: branches/release/libs/intrusive/proj/vc7ide/unordered_set/unordered_set.vcproj
==============================================================================
--- branches/release/libs/intrusive/proj/vc7ide/unordered_set/unordered_set.vcproj (original)
+++ branches/release/libs/intrusive/proj/vc7ide/unordered_set/unordered_set.vcproj 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="7.10"
Name="unordered_set"
- ProjectGUID="{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}"
+ ProjectGUID="{9101EE76-BB6C-2C91-F4B7-A27B94908F19}"
Keyword="Win32Proj">
<Platforms>
<Platform
@@ -21,6 +21,7 @@
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
@@ -116,7 +117,7 @@
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4F3C77F1-B78A-C745-4726-2D752AA322FF}">
+ UniqueIdentifier="{4F3C77F1-B78A-C745-4726-252AD75C322E}">
<File
RelativePath="..\..\..\test\unordered_set_test.cpp">
</File>
Modified: branches/release/libs/intrusive/test/default_hook_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/default_hook_test.cpp (original)
+++ branches/release/libs/intrusive/test/default_hook_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -13,6 +13,9 @@
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
#include "smart_ptr.hpp"
#include <vector>
@@ -28,6 +31,12 @@
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
, public unordered_set_base_hook
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+, public avl_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+, public splay_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+, public bs_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
{
int int_;
@@ -51,6 +60,9 @@
typedef slist<MyClass> Slist;
typedef set<MyClass> Set;
typedef unordered_set<MyClass> USet;
+typedef avl_set<MyClass> AvlSet;
+typedef splay_set<MyClass> SplaySet;
+typedef sg_set<MyClass> SgSet;
int main()
{
@@ -67,6 +79,9 @@
Slist my_slist;
Set my_set;
USet my_uset(USet::bucket_traits(buckets, 100));
+ AvlSet my_avlset;
+ SplaySet my_splayset;
+ SgSet my_sgset;
//Now insert them in the reverse order
//in the base hook intrusive list
@@ -75,6 +90,9 @@
my_slist.push_front(*it);
my_set.insert(*it);
my_uset.insert(*it);
+ my_avlset.insert(*it);
+ my_splayset.insert(*it);
+ my_sgset.insert(*it);
}
//Now test lists
@@ -82,13 +100,24 @@
List::const_iterator list_it(my_list.cbegin());
Slist::const_iterator slist_it(my_slist.cbegin());
Set::const_reverse_iterator set_rit(my_set.crbegin());
+ AvlSet::const_reverse_iterator avl_set_rit(my_avlset.crbegin());
+ SplaySet::const_reverse_iterator splay_set_rit(my_splayset.crbegin());
+ SgSet::const_reverse_iterator sg_set_rit(my_sgset.crbegin());
+
VectRit vect_it(values.rbegin()), vect_itend(values.rend());
//Test the objects inserted in the base hook list
- for(; vect_it != vect_itend; ++vect_it, ++list_it, ++slist_it, ++set_rit){
- if(&*list_it != &*vect_it) return 1;
- if(&*slist_it != &*vect_it) return 1;
- if(&*set_rit != &*vect_it) return 1;
+ for(; vect_it != vect_itend
+ ; ++vect_it, ++list_it
+ , ++slist_it, ++set_rit
+ , ++avl_set_rit, ++splay_set_rit
+ , ++sg_set_rit){
+ if(&*list_it != &*vect_it) return 1;
+ if(&*slist_it != &*vect_it) return 1;
+ if(&*set_rit != &*vect_it) return 1;
+ if(&*avl_set_rit != &*vect_it) return 1;
+ if(&*splay_set_rit != &*vect_it)return 1;
+ if(&*sg_set_rit != &*vect_it) return 1;
if(my_uset.find(*set_rit) == my_uset.cend()) return 1;
}
}
Modified: branches/release/libs/intrusive/test/list_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/list_test.cpp (original)
+++ branches/release/libs/intrusive/test/list_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -13,6 +13,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/list.hpp>
+
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp"
#include "smart_ptr.hpp"
@@ -446,13 +447,12 @@
>
>::type
>::test_all(data);
-/*
- test_list<stateful_value_traits
- < value_type
- , list_node_traits<VoidPointer>
- , safe_link>
- >::test_all(data);
-*/
+
+// test_list<stateful_value_traits
+// < value_type
+// , list_node_traits<VoidPointer>
+// , safe_link>
+// >::test_all(data);
test_list < typename detail::get_base_value_traits
< value_type
, typename value_type::list_auto_base_hook_t
@@ -467,13 +467,13 @@
>
>::type
>::test_all(data);
-/*
- test_list<stateful_value_traits
- < value_type
- , list_node_traits<VoidPointer>
- , auto_unlink>
- >::test_all(data);
-*/
+
+// test_list<stateful_value_traits
+// < value_type
+// , list_node_traits<VoidPointer>
+// , auto_unlink>
+// >::test_all(data);
+
return 0;
}
};
@@ -488,3 +488,285 @@
return boost::report_errors();
}
#include <boost/intrusive/detail/config_end.hpp>
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+#include <cstddef>
+
+
+////////////////////////////////////////////////////
+// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
+// be used to "unpack" into comma-separated values
+// in a function call.
+////////////////////////////////////////////////////
+
+template<int... Indexes>
+struct index_tuple{};
+
+template<std::size_t Num, typename Tuple = index_tuple<> >
+struct build_number_seq;
+
+template<std::size_t Num, int... Indexes>
+struct build_number_seq<Num, index_tuple<Indexes...> >
+ : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
+{};
+
+template<int... Indexes>
+struct build_number_seq<0, index_tuple<Indexes...> >
+{ typedef index_tuple<Indexes...> type; };
+
+template<class ...Types>
+struct typelist
+{};
+
+template<class T>
+struct invert_typelist;
+
+template<int I, typename Tuple>
+struct typelist_element;
+
+template<int I, typename Head, typename... Tail>
+struct typelist_element<I, typelist<Head, Tail...> >
+{
+ typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
+};
+
+template<typename Head, typename... Tail>
+struct typelist_element<0, typelist<Head, Tail...> >
+{
+ typedef Head type;
+};
+
+template<int ...Ints, class ...Types>
+typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
+ inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
+{
+ return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
+}
+
+
+template<class Typelist>
+struct sizeof_typelist;
+
+template<class ...Types>
+struct sizeof_typelist< typelist<Types...> >
+{
+ static const std::size_t value = sizeof...(Types);
+};
+
+//invert_typelist_impl
+template<class Typelist, class Indexes>
+struct invert_typelist_impl;
+
+
+template<class Typelist, int ...Ints>
+struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
+{
+ static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
+ typedef typelist
+ <typename typelist_element<last_idx - Ints, Typelist>::type...> type;
+};
+
+template<class Typelist, int Int>
+struct invert_typelist_impl< Typelist, index_tuple<Int> >
+{
+ typedef Typelist type;
+};
+
+template<class Typelist>
+struct invert_typelist_impl< Typelist, index_tuple<> >
+{
+ typedef Typelist type;
+};
+
+//invert_typelist
+template<class Typelist>
+struct invert_typelist;
+
+template<class ...Types>
+struct invert_typelist< typelist<Types...> >
+{
+ typedef typelist<Types...> typelist_t;
+ typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
+ typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
+};
+
+struct none
+{
+ template<class Base>
+ struct pack : Base
+ { };
+};
+
+//!This option setter specifies the type of
+//!a void pointer. This will instruct the hook
+//!to use this type of pointer instead of the
+//!default one
+template<class VoidPointer>
+struct void_pointer
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ typedef VoidPointer void_pointer;
+ };
+/// @endcond
+};
+
+//!This option setter specifies the type of
+//!the tag of a base hook. A type cannot have two
+//!base hooks of the same type, so a tag can be used
+//!to differentiate two base hooks with otherwise same type
+template<class Tag>
+struct tag
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ typedef Tag tag;
+ };
+/// @endcond
+};
+
+
+//!This option setter specifies if the hook
+//!should be optimized for size instead of for speed.
+template<bool Enabled>
+struct optimize_size
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool optimize_size = Enabled;
+ };
+/// @endcond
+};
+
+//!This option setter specifies if the list container should
+//!use a linear implementation instead of a circular one.
+template<bool Enabled>
+struct linear
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool linear = Enabled;
+ };
+/// @endcond
+};
+
+//!This option setter specifies if the list container should
+//!use a linear implementation instead of a circular one.
+template<bool Enabled>
+struct cache_last
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool cache_last = Enabled;
+ };
+/// @endcond
+};
+
+
+
+template<class Typelist>
+struct do_pack;
+
+template<>
+struct do_pack<typelist<> >;
+
+template<class Prev>
+struct do_pack<typelist<Prev> >
+{
+ typedef Prev type;
+};
+
+template<class Prev, class Last>
+struct do_pack<typelist<Prev, Last> >
+{
+ typedef typename Prev::template pack<Last> type;
+};
+
+template<class Prev, class ...Others>
+struct do_pack<typelist<Prev, Others...> >
+{
+ typedef typename Prev::template pack
+ <typename do_pack<typelist<Others...>>::type> type;
+};
+
+
+template<class ...Options>
+struct pack_options
+{
+ typedef typelist<Options...> typelist_t;
+ typedef typename invert_typelist<typelist_t>::type inverted_typelist;
+ typedef typename do_pack<inverted_typelist>::type type;
+};
+
+struct hook_defaults
+ : public pack_options
+ < none
+ , void_pointer<void*>
+ , tag<int>
+ , optimize_size<false>
+ , linear<false>
+ >::type
+{};
+
+
+#include <iostream>
+#include <typeinfo>
+
+struct S
+{};
+
+int main()
+{
+ {
+ typedef typelist<int, float, double> typelist_t;
+ typedef invert_typelist<typelist_t>::type inverted_typelist;
+ std::cout << "original: " << typeid(typelist_t).name() << std::endl;
+ std::cout << "inverted: " << typeid(inverted_typelist).name() << std::endl;
+ }
+ {
+ typedef typelist<int> typelist_t;
+ typedef invert_typelist<typelist_t>::type inverted_typelist;
+ std::cout << "original: " << typeid(typelist_t).name() << std::endl;
+ std::cout << "inverted: " << typeid(inverted_typelist).name() << std::endl;
+ }
+ {
+ typedef typelist<> typelist_t;
+ typedef invert_typelist<typelist_t>::type inverted_typelist;
+ std::cout << "original: " << typeid(typelist_t).name() << std::endl;
+ std::cout << "inverted: " << typeid(inverted_typelist).name() << std::endl;
+ }
+ {
+ typedef pack_options<S, none>::type options_t;
+ std::cout << "options_t " << typeid(options_t).name() << std::endl;
+ }
+ {
+ typedef pack_options<S, none, none>::type options_t;
+ std::cout << "options_t " << typeid(options_t).name() << std::endl;
+ }
+
+ hook_defaults h;
+ return 1;
+}
+*/
\ No newline at end of file
Modified: branches/release/libs/intrusive/test/set_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/set_test.cpp (original)
+++ branches/release/libs/intrusive/test/set_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -108,7 +108,6 @@
int main( int, char* [] )
{
-
test_main_template<void*, false>()();
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
test_main_template<void*, true>()();
Modified: branches/release/libs/intrusive/test/sg_multiset_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/sg_multiset_test.cpp (original)
+++ branches/release/libs/intrusive/test/sg_multiset_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -18,8 +18,18 @@
namespace boost { namespace intrusive { namespace test {
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_rebalance<boost::intrusive::sg_multiset<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::sg_multiset<T,
+ #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+> >
{
static const bool value = true;
};
Modified: branches/release/libs/intrusive/test/sg_set_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/sg_set_test.cpp (original)
+++ branches/release/libs/intrusive/test/sg_set_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -17,8 +17,18 @@
namespace boost { namespace intrusive { namespace test {
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_rebalance<boost::intrusive::sg_set<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::sg_set<T,
+ #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+> >
{
static const bool value = true;
};
Modified: branches/release/libs/intrusive/test/splay_multiset_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/splay_multiset_test.cpp (original)
+++ branches/release/libs/intrusive/test/splay_multiset_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -19,20 +19,51 @@
namespace boost { namespace intrusive { namespace test {
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_const_overloads<boost::intrusive::splay_multiset<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_const_overloads<boost::intrusive::splay_multiset<
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+T, O1, O2, O3, O4
+#else
+T, Options...
+#endif
+>
+>
{
static const bool value = false;
};
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_splay<boost::intrusive::splay_multiset<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_splay<boost::intrusive::splay_multiset<T,
+ #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+> >
{
static const bool value = true;
};
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_rebalance<boost::intrusive::splay_multiset<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::splay_multiset<T,
+ #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+> >
{
static const bool value = true;
};
Modified: branches/release/libs/intrusive/test/splay_set_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/splay_set_test.cpp (original)
+++ branches/release/libs/intrusive/test/splay_set_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -17,20 +17,50 @@
namespace boost { namespace intrusive { namespace test {
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_const_overloads<boost::intrusive::splay_set<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_const_overloads<boost::intrusive::splay_set<T,
+ #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+> >
{
static const bool value = false;
};
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_splay<boost::intrusive::splay_set<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_splay<boost::intrusive::splay_set<T,
+ #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+> >
{
static const bool value = true;
};
+#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4>
-struct has_rebalance<boost::intrusive::splay_set<T, O1, O2, O3, O4> >
+#else
+template<class T, class ...Options>
+#endif
+struct has_rebalance<boost::intrusive::splay_set<T,
+ #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+> >
{
static const bool value = true;
};
Modified: branches/release/libs/intrusive/test/test_macros.hpp
==============================================================================
--- branches/release/libs/intrusive/test/test_macros.hpp (original)
+++ branches/release/libs/intrusive/test/test_macros.hpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -15,10 +15,7 @@
#define TEST_INTRUSIVE_SEQUENCE( INTVALUES, ITERATOR )\
{ \
- const int init_values_size = sizeof(INTVALUES)/sizeof(INTVALUES[0]); \
- std::vector<int> expected; \
- expected.assign(&INTVALUES[0], &INTVALUES[0] + init_values_size); \
- BOOST_TEST (std::equal(expected.begin(), expected.end(), ITERATOR) ); \
+ BOOST_TEST (std::equal(&INTVALUES[0], &INTVALUES[0] + sizeof(INTVALUES)/sizeof(INTVALUES[0]), ITERATOR) ); \
}
#define TEST_INTRUSIVE_SEQUENCE_EXPECTED( EXPECTEDVECTOR, ITERATOR )\
Modified: branches/release/libs/intrusive/test/unordered_multiset_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/unordered_multiset_test.cpp (original)
+++ branches/release/libs/intrusive/test/unordered_multiset_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -25,9 +25,9 @@
using namespace boost::intrusive;
-static const std::size_t BucketSize = 11;
+static const std::size_t BucketSize = 8;
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
struct test_unordered_multiset
{
typedef typename ValueTraits::value_type value_type;
@@ -35,14 +35,16 @@
static void test_sort(std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
- static void test_rehash(std::vector<value_type>& values);
+ static void test_rehash(std::vector<value_type>& values, detail::true_);
+ static void test_rehash(std::vector<value_type>& values, detail::false_);
static void test_find(std::vector<value_type>& values);
static void test_impl();
static void test_clone(std::vector<value_type>& values);
};
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_all (std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_all (std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_multiset
@@ -51,6 +53,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
{
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
@@ -71,15 +74,16 @@
test_sort(values);
test_insert(values);
test_swap(values);
- test_rehash(values);
+ test_rehash(values, detail::bool_<Incremental>());
test_find(values);
test_impl();
test_clone(values);
}
//test case due to an error in tree implementation:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_impl()
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+ ::test_impl()
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_multiset
@@ -88,6 +92,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
@@ -110,8 +115,9 @@
}
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_sort(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+ ::test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_multiset
@@ -120,21 +126,29 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
typename unordered_multiset_type::bucket_type buckets [BucketSize];
unordered_multiset_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
- { int init_values [] = { 1, 2, 2, 3, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ if(Incremental){
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
+ else{
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
testset1.clear();
BOOST_TEST (testset1.empty());
}
-
+
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_insert(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+ ::test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_multiset
@@ -143,54 +157,100 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
typedef typename unordered_multiset_type::iterator iterator;
- {
- typename unordered_multiset_type::bucket_type buckets [BucketSize];
- unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
-
- testset.insert(&values[0] + 2, &values[0] + 5);
-
- const unordered_multiset_type& const_testset = testset;
- { int init_values [] = { 1, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
-
- typename unordered_multiset_type::iterator i = testset.begin();
- BOOST_TEST (i->value_ == 1);
-
- i = testset.insert (values[0]);
- BOOST_TEST (&*i == &values[0]);
-
- i = testset.iterator_to (values[2]);
- BOOST_TEST (&*i == &values[2]);
- testset.erase(i);
-
- { int init_values [] = { 1, 3, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
- testset.clear();
- testset.insert(&values[0], &values[0] + values.size());
+ typename unordered_multiset_type::bucket_type buckets [BucketSize];
+ unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
- { int init_values [] = { 1, 2, 2, 3, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ testset.insert(&values[0] + 2, &values[0] + 5);
- BOOST_TEST (testset.erase(1) == 1);
- BOOST_TEST (testset.erase(2) == 2);
- BOOST_TEST (testset.erase(3) == 1);
- BOOST_TEST (testset.erase(4) == 1);
- BOOST_TEST (testset.erase(5) == 1);
- BOOST_TEST (testset.empty() == true);
+ const unordered_multiset_type& const_testset = testset;
- //Now with a single bucket
- typename unordered_multiset_type::bucket_type single_bucket[1];
- unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
- testset2.insert(&values[0], &values[0] + values.size());
- BOOST_TEST (testset2.erase(5) == 1);
- BOOST_TEST (testset2.erase(2) == 2);
- BOOST_TEST (testset2.erase(1) == 1);
- BOOST_TEST (testset2.erase(4) == 1);
- BOOST_TEST (testset2.erase(3) == 1);
- BOOST_TEST (testset2.empty() == true);
+ if(Incremental){
+ {
+ { int init_values [] = { 4, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+ typename unordered_multiset_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 4);
+
+ i = testset.insert (values[0]);
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+ testset.erase(i);
+
+ { int init_values [] = { 5, 1, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ testset.clear();
+ testset.insert(&values[0], &values[0] + values.size());
+
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+ BOOST_TEST (testset.erase(1) == 1);
+ BOOST_TEST (testset.erase(2) == 2);
+ BOOST_TEST (testset.erase(3) == 1);
+ BOOST_TEST (testset.erase(4) == 1);
+ BOOST_TEST (testset.erase(5) == 1);
+ BOOST_TEST (testset.empty() == true);
+
+ //Now with a single bucket
+ typename unordered_multiset_type::bucket_type single_bucket[1];
+ unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
+ testset2.insert(&values[0], &values[0] + values.size());
+ BOOST_TEST (testset2.erase(5) == 1);
+ BOOST_TEST (testset2.erase(2) == 2);
+ BOOST_TEST (testset2.erase(1) == 1);
+ BOOST_TEST (testset2.erase(4) == 1);
+ BOOST_TEST (testset2.erase(3) == 1);
+ BOOST_TEST (testset2.empty() == true);
+ }
+ }
+ else{
+ {
+ { int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+ typename unordered_multiset_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 1);
+
+ i = testset.insert (values[0]);
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+ testset.erase(i);
+
+ { int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ testset.clear();
+ testset.insert(&values[0], &values[0] + values.size());
+
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+ BOOST_TEST (testset.erase(1) == 1);
+ BOOST_TEST (testset.erase(2) == 2);
+ BOOST_TEST (testset.erase(3) == 1);
+ BOOST_TEST (testset.erase(4) == 1);
+ BOOST_TEST (testset.erase(5) == 1);
+ BOOST_TEST (testset.empty() == true);
+
+ //Now with a single bucket
+ typename unordered_multiset_type::bucket_type single_bucket[1];
+ unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
+ testset2.insert(&values[0], &values[0] + values.size());
+ BOOST_TEST (testset2.erase(5) == 1);
+ BOOST_TEST (testset2.erase(2) == 2);
+ BOOST_TEST (testset2.erase(1) == 1);
+ BOOST_TEST (testset2.erase(4) == 1);
+ BOOST_TEST (testset2.erase(3) == 1);
+ BOOST_TEST (testset2.empty() == true);
+ }
}
{
//Now erase just one per loop
@@ -270,11 +330,12 @@
}
}
}
-}
+}
//test: insert (seq-version), swap, erase (seq-version), size:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_swap(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_multiset
@@ -283,17 +344,30 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
typename unordered_multiset_type::bucket_type buckets [BucketSize];
- {
- typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
- unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
- unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
- testset2.insert (&values[0] + 2, &values[0] + 6);
- testset1.swap (testset2);
+ typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
+ unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
+ unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
+
+ testset2.insert (&values[0] + 2, &values[0] + 6);
+ testset1.swap (testset2);
+ if(Incremental){
+ { int init_values [] = { 4, 5, 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ { int init_values [] = { 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+ testset1.erase (testset1.iterator_to(values[4]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ // BOOST_TEST (&testset1.front() == &values[3]);
+ BOOST_TEST (&*testset1.begin() == &values[2]);
+ }
+ else{
{ int init_values [] = { 1, 2, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
@@ -306,9 +380,141 @@
}
}
+
+
//test: rehash:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
+
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+ ::test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::true_)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
+ , compare_hash<CompareHash>
+ , incremental<Incremental>
+ > unordered_multiset_type;
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+ //Build a uset
+ typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
+ typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
+ unordered_multiset_type testset1(&values[0], &values[0] + values.size(), bucket_traits(buckets1, BucketSize));
+ //Test current state
+ BOOST_TEST(testset1.split_count() == BucketSize/2);
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Incremental rehash step
+ BOOST_TEST (testset1.incremental_rehash() == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+ { int init_values [] = { 5, 1, 2, 2, 3, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Rest of incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket != BucketSize; ++split_bucket){
+ BOOST_TEST (testset1.incremental_rehash() == true);
+ BOOST_TEST(testset1.split_count() == (split_bucket+1));
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
+ //This incremental rehash should fail because we've reached the end of the bucket array
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+ //
+ //This incremental rehash should fail because the new size is not twice the original
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should success because the new size is twice the original
+ //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should also success because the new size is half the original
+ //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+ //
+ //This incremental rehash should fail because the new size is not twice the original
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should success because the new size is twice the original
+ //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should also success because the new size is half the original
+ //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //Full shrink rehash
+ testset1.rehash(bucket_traits(buckets1, 4));
+ BOOST_TEST (testset1.size() == values.size());
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Full shrink rehash again
+ testset1.rehash(bucket_traits(buckets1, 2));
+ BOOST_TEST (testset1.size() == values.size());
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 2, 2, 4, 3, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Full growing rehash
+ testset1.rehash(bucket_traits(buckets1, BucketSize));
+ BOOST_TEST (testset1.size() == values.size());
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Incremental rehash shrinking
+ //First incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket > 6; --split_bucket){
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (split_bucket-1));
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
+ //Incremental rehash step
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+ { int init_values [] = { 5, 1, 2, 2, 3, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Incremental rehash step 2
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2));
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //This incremental rehash should fail because we've reached the half of the bucket array
+ BOOST_TEST(testset1.incremental_rehash(false) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize/2);
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+}
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
+ ::test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::false_)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_multiset
@@ -317,6 +523,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
@@ -325,36 +532,37 @@
typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
unordered_multiset_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
- BOOST_TEST (testset1.size() == 6);
+ BOOST_TEST (testset1.size() == values.size());
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
testset1.rehash(bucket_traits(buckets2, 2));
- BOOST_TEST (testset1.size() == 6);
+ BOOST_TEST (testset1.size() == values.size());
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
- BOOST_TEST (testset1.size() == 6);
+ BOOST_TEST (testset1.size() == values.size());
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
//Now rehash reducing the buckets
testset1.rehash(bucket_traits(buckets3, 2));
- BOOST_TEST (testset1.size() == 6);
+ BOOST_TEST (testset1.size() == values.size());
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
//Now rehash increasing the buckets
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
- BOOST_TEST (testset1.size() == 6);
+ BOOST_TEST (testset1.size() == values.size());
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
}
//test: find, equal_range (lower_bound, upper_bound):
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_find(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_find(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_multiset
@@ -363,6 +571,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
@@ -387,8 +596,8 @@
}
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
::test_clone(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
@@ -398,6 +607,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_multiset_type;
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
{
@@ -442,7 +652,7 @@
unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize*2));
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
- //Ordering is not guarantee in the cloning so insert data in a set and test
+ //Ordering is not guaranteed in the cloning so insert data in a set and test
std::multiset<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::multiset<typename ValueTraits::value_type>
@@ -453,7 +663,7 @@
}
}
-template<class VoidPointer, bool constant_time_size>
+template<class VoidPointer, bool constant_time_size, bool Incremental>
class test_main_template
{
public:
@@ -471,6 +681,7 @@
>::type
, true
, false
+ , Incremental
>::test_all(data);
test_unordered_multiset < typename detail::get_member_value_traits
@@ -482,14 +693,15 @@
>::type
, false
, false
+ , Incremental
>::test_all(data);
return 0;
}
};
-template<class VoidPointer>
-class test_main_template<VoidPointer, false>
+template<class VoidPointer, bool Incremental>
+class test_main_template<VoidPointer, false, Incremental>
{
public:
int operator()()
@@ -506,6 +718,7 @@
>::type
, true
, false
+ , Incremental
>::test_all(data);
test_unordered_multiset < typename detail::get_member_value_traits
@@ -517,6 +730,7 @@
>::type
, false
, false
+ , Incremental
>::test_all(data);
test_unordered_multiset < typename detail::get_base_value_traits
@@ -525,6 +739,7 @@
>::type
, true
, true
+ , Incremental
>::test_all(data);
test_unordered_multiset < typename detail::get_member_value_traits
@@ -536,6 +751,7 @@
>::type
, false
, true
+ , Incremental
>::test_all(data);
return 0;
}
@@ -543,10 +759,14 @@
int main( int, char* [] )
{
- test_main_template<void*, false>()();
- test_main_template<smart_ptr<void>, false>()();
- test_main_template<void*, true>()();
- test_main_template<smart_ptr<void>, true>()();
+ test_main_template<void*, false, true>()();
+ test_main_template<smart_ptr<void>, false, true>()();
+ test_main_template<void*, true, true>()();
+ test_main_template<smart_ptr<void>, true, true>()();
+ test_main_template<void*, false, false>()();
+ test_main_template<smart_ptr<void>, false, false>()();
+ test_main_template<void*, true, true>()();
+ test_main_template<smart_ptr<void>, true, false>()();
return boost::report_errors();
}
Modified: branches/release/libs/intrusive/test/unordered_set_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/unordered_set_test.cpp (original)
+++ branches/release/libs/intrusive/test/unordered_set_test.cpp 2008-10-13 15:39:47 EDT (Mon, 13 Oct 2008)
@@ -24,9 +24,9 @@
using namespace boost::intrusive;
-static const std::size_t BucketSize = 11;
+static const std::size_t BucketSize = 8;
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
struct test_unordered_set
{
typedef typename ValueTraits::value_type value_type;
@@ -34,14 +34,16 @@
static void test_sort(std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
- static void test_rehash(std::vector<value_type>& values);
+ static void test_rehash(std::vector<value_type>& values, detail::true_);
+ static void test_rehash(std::vector<value_type>& values, detail::false_);
static void test_find(std::vector<value_type>& values);
static void test_impl();
static void test_clone(std::vector<value_type>& values);
};
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_all(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_all(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_set
@@ -50,6 +52,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
{
@@ -70,15 +73,15 @@
test_sort(values);
test_insert(values);
test_swap(values);
- test_rehash(values);
+ test_rehash(values, detail::bool_<Incremental>());
test_find(values);
test_impl();
test_clone(values);
}
//test case due to an error in tree implementation:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_impl()
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::test_impl()
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_set
@@ -87,6 +90,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
@@ -107,8 +111,9 @@
}
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_sort(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_set
@@ -117,23 +122,31 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
typename unordered_set_type::bucket_type buckets [BucketSize];
unordered_set_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
-
BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));
- { int init_values [] = { 1, 2, 3, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ if(Incremental){
+ { int init_values [] = { 4, 5, 1, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
+ else{
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
testset1.clear();
BOOST_TEST (testset1.empty());
}
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_insert(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_set
@@ -142,6 +155,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
@@ -150,27 +164,47 @@
testset.insert(&values[0] + 2, &values[0] + 5);
const unordered_set_type& const_testset = testset;
- { int init_values [] = { 1, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ if(Incremental)
+ {
+ { int init_values [] = { 4, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ typename unordered_set_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 4);
+
+ i = testset.insert(values[0]).first;
+ BOOST_TEST (&*i == &values[0]);
- typename unordered_set_type::iterator i = testset.begin();
- BOOST_TEST (i->value_ == 1);
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
- i = testset.insert(values[0]).first;
- BOOST_TEST (&*i == &values[0]);
+ testset.erase (i);
- i = testset.iterator_to (values[2]);
- BOOST_TEST (&*i == &values[2]);
+ { int init_values [] = { 5, 1, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ }
+ else{
+ { int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ typename unordered_set_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 1);
+
+ i = testset.insert(values[0]).first;
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
- testset.erase (i);
+ testset.erase (i);
- { int init_values [] = { 1, 3, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ { int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ }
}
//test: insert (seq-version), swap, erase (seq-version), size:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_swap(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_set
@@ -179,6 +213,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
@@ -190,20 +225,30 @@
testset2.insert (&values[0] + 2, &values[0] + 6);
testset1.swap (testset2);
- { int init_values [] = { 1, 2, 4, 5 };
+ if(Incremental){
+ { int init_values [] = { 4, 5, 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ { int init_values [] = { 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+ testset1.erase (testset1.iterator_to(values[4]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ BOOST_TEST (&*testset1.begin() == &values[2]);
+ }
+ else{
+ { int init_values [] = { 1, 2, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
- { int init_values [] = { 2, 3 };
+ { int init_values [] = { 2, 3 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
-
- testset1.erase (testset1.iterator_to(values[5]), testset1.end());
- BOOST_TEST (testset1.size() == 1);
- // BOOST_TEST (&testset1.front() == &values[3]);
- BOOST_TEST (&*testset1.begin() == &values[3]);
+ testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ BOOST_TEST (&*testset1.begin() == &values[3]);
+ }
}
//test: rehash:
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::true_)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_set
@@ -212,6 +257,137 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
+ > unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
+ //Build a uset
+ typename unordered_set_type::bucket_type buckets1 [BucketSize];
+ typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
+ unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
+ //Test current state
+ BOOST_TEST(testset1.split_count() == BucketSize/2);
+ { int init_values [] = { 4, 5, 1, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Incremental rehash step
+ BOOST_TEST (testset1.incremental_rehash() == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+ { int init_values [] = { 5, 1, 2, 3, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Rest of incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket != BucketSize; ++split_bucket){
+ BOOST_TEST (testset1.incremental_rehash() == true);
+ BOOST_TEST(testset1.split_count() == (split_bucket+1));
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
+ //This incremental rehash should fail because we've reached the end of the bucket array
+ BOOST_TEST(testset1.incremental_rehash() == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+ //
+ //This incremental rehash should fail because the new size is not twice the original
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should success because the new size is twice the original
+ //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should also success because the new size is half the original
+ //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+ //
+ //This incremental rehash should fail because the new size is not twice the original
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should success because the new size is twice the original
+ //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //This incremental rehash should also success because the new size is half the original
+ //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ //Full shrink rehash
+ testset1.rehash(bucket_traits(buckets1, 4));
+ BOOST_TEST (testset1.size() == values.size()-1);
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 4, 5, 1, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Full shrink rehash again
+ testset1.rehash(bucket_traits(buckets1, 2));
+ BOOST_TEST (testset1.size() == values.size()-1);
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 2, 4, 3, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Full growing rehash
+ testset1.rehash(bucket_traits(buckets1, BucketSize));
+ BOOST_TEST (testset1.size() == values.size()-1);
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Incremental rehash shrinking
+ //First incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket > 6; --split_bucket){
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (split_bucket-1));
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ }
+ //Incremental rehash step
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+ { int init_values [] = { 5, 1, 2, 3, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //Incremental rehash step 2
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2));
+ { int init_values [] = { 4, 5, 1, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ //This incremental rehash should fail because we've reached the half of the bucket array
+ BOOST_TEST(testset1.incremental_rehash(false) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize/2);
+ { int init_values [] = { 4, 5, 1, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+}
+
+//test: rehash:
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::false_)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
+ , compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
@@ -220,37 +396,38 @@
typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
- BOOST_TEST (testset1.size() == 5);
+ BOOST_TEST (testset1.size() == values.size()-1);
{ int init_values [] = { 1, 2, 3, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
testset1.rehash(bucket_traits(buckets2, 2));
- BOOST_TEST (testset1.size() == 5);
+ BOOST_TEST (testset1.size() == values.size()-1);
{ int init_values [] = { 4, 2, 5, 3, 1 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
- BOOST_TEST (testset1.size() == 5);
+ BOOST_TEST (testset1.size() == values.size()-1);
{ int init_values [] = { 1, 2, 3, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
//Now rehash reducing the buckets
testset1.rehash(bucket_traits(buckets3, 2));
- BOOST_TEST (testset1.size() == 5);
+ BOOST_TEST (testset1.size() == values.size()-1);
{ int init_values [] = { 4, 2, 5, 3, 1 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
//Now rehash increasing the buckets
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
- BOOST_TEST (testset1.size() == 5);
+ BOOST_TEST (testset1.size() == values.size()-1);
{ int init_values [] = { 1, 2, 3, 4, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
}
//test: find, equal_range (lower_bound, upper_bound):
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_find(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
+ test_find(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
typedef unordered_set
@@ -259,6 +436,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
@@ -281,8 +459,8 @@
BOOST_TEST (testset.find (cmp_val) == testset.end());
}
-template<class ValueTraits, bool CacheBegin, bool CompareHash>
-void test_unordered_set<ValueTraits, CacheBegin, CompareHash>
+template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
+void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>
::test_clone(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type value_type;
@@ -292,6 +470,7 @@
, constant_time_size<value_type::constant_time_size>
, cache_begin<CacheBegin>
, compare_hash<CompareHash>
+ , incremental<Incremental>
> unordered_set_type;
typedef typename unordered_set_type::bucket_traits bucket_traits;
{
@@ -319,7 +498,7 @@
unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
- //Ordering is not guarantee in the cloning so insert data in a set and test
+ //Ordering is not guaranteed in the cloning so insert data in a set and test
std::set<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::set<typename ValueTraits::value_type>
@@ -347,7 +526,7 @@
}
}
-template<class VoidPointer, bool constant_time_size>
+template<class VoidPointer, bool constant_time_size, bool incremental>
class test_main_template
{
public:
@@ -365,6 +544,7 @@
>::type
, true
, false
+ , incremental
>::test_all(data);
test_unordered_set < typename detail::get_member_value_traits
< value_type
@@ -375,14 +555,15 @@
>::type
, false
, false
+ , incremental
>::test_all(data);
return 0;
}
};
-template<class VoidPointer>
-class test_main_template<VoidPointer, false>
+template<class VoidPointer, bool incremental>
+class test_main_template<VoidPointer, false, incremental>
{
public:
int operator()()
@@ -399,6 +580,7 @@
>::type
, true
, false
+ , incremental
>::test_all(data);
test_unordered_set < typename detail::get_member_value_traits
@@ -410,6 +592,7 @@
>::type
, false
, false
+ , incremental
>::test_all(data);
test_unordered_set < typename detail::get_base_value_traits
@@ -418,6 +601,7 @@
>::type
, true
, true
+ , incremental
>::test_all(data);
test_unordered_set < typename detail::get_member_value_traits
@@ -429,6 +613,7 @@
>::type
, false
, true
+ , incremental
>::test_all(data);
return 0;
}
@@ -436,10 +621,14 @@
int main( int, char* [] )
{
- test_main_template<void*, false>()();
- test_main_template<smart_ptr<void>, false>()();
- test_main_template<void*, true>()();
- test_main_template<smart_ptr<void>, true>()();
+ test_main_template<void*, false, true>()();
+ test_main_template<smart_ptr<void>, false, true>()();
+ test_main_template<void*, true, true>()();
+ test_main_template<smart_ptr<void>, true, true>()();
+ test_main_template<void*, false, false>()();
+ test_main_template<smart_ptr<void>, false, false>()();
+ test_main_template<void*, true, true>()();
+ test_main_template<smart_ptr<void>, true, false>()();
return boost::report_errors();
}
#include <boost/intrusive/detail/config_end.hpp>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk