mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
no message
[SVN r37976]
This commit is contained in:
@@ -36,7 +36,7 @@ doxygen interprocess_doxygen
|
||||
|
||||
xml interprocess_xml : interprocess.qbk ;
|
||||
|
||||
boostbook standalone
|
||||
boostbook interprocess
|
||||
:
|
||||
interprocess_xml
|
||||
interprocess_doxygen
|
||||
|
||||
@@ -29,7 +29,7 @@ and synchronization mechanisms and offers a wide range of them:
|
||||
[*Boost.Interprocess] also offers higher-level interprocess mechanisms to allocate
|
||||
dynamically portions of a shared memory or a memory mapped file (in general,
|
||||
to allocate portions of a fixed size memory segment). Using these mechanisms,
|
||||
[*Boost.Interprocess] offers the tools to construct C++ objects, including
|
||||
[*Boost.Interprocess] offers useful tools to construct C++ objects, including
|
||||
STL-like containers, in shared memory and memory mapped files:
|
||||
|
||||
* Dynamic creation of anonymous and named objects in a shared memory or memory
|
||||
@@ -38,6 +38,29 @@ STL-like containers, in shared memory and memory mapped files:
|
||||
* STL-like allocators ready for shared memory/memory-mapped files implementing
|
||||
several memory allocation patterns (like pooling).
|
||||
|
||||
[section:introduction_building_interprocess Building Boost.Interprocess]
|
||||
|
||||
There is no need to compile anything to use [*Boost.Interprocess], since it's
|
||||
a header only library. Just include your Boost header directory in your
|
||||
compiler include path.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:tested_compilers Tested compilers]
|
||||
|
||||
[*Boost.Interprocess] has been tested in the following compilers/platforms:
|
||||
|
||||
* Visual 7.1/WinXP
|
||||
* Visual 8.0/WinXP
|
||||
* GCC 4.1.1/MinGW
|
||||
* GCC 3.4.4/Cygwin
|
||||
* Intel 9.1/WinXP
|
||||
* GCC 4.1.2/Linux
|
||||
* Codewarrior 9.4/WinXP
|
||||
* GCC 3.4.3 Solaris 11
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:quick_guide Quick Guide for the Impatient]
|
||||
@@ -117,14 +140,10 @@ STL algorithms:
|
||||
|
||||
[section:qg_interprocess_map Creating maps in shared memory]
|
||||
|
||||
Just like a vector, [*Boost.Interprocess] allows creating maps in shared memory and memory
|
||||
mapped files. [*Boost.Interprocess]'s map is
|
||||
The construction of map is a bit tricky, because
|
||||
|
||||
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,
|
||||
declare a [*Boost.Interprocess] allocator and construct the vector in shared memory
|
||||
just if it was any other object. Just execute this first process:
|
||||
Just like a vector, [*Boost.Interprocess] allows creating maps in
|
||||
shared memory and memory mapped files. The only difference is that
|
||||
like standard associative containers, [*Boost.Interprocess]'s map needs
|
||||
also the comparison functor when an allocator is passed in the constructor:
|
||||
|
||||
[import ../example/doc_map.cpp]
|
||||
[doc_map]
|
||||
@@ -962,11 +981,11 @@ opening or opening or creation of the underlying resource:
|
||||
NamedUtility(create_only, ...)
|
||||
|
||||
//Open the synchronization utility. If it does not previously
|
||||
//exist, throws an error.
|
||||
//exist, it's created.
|
||||
NamedUtility(open_or_create, ...)
|
||||
|
||||
//Open the synchronization utility. If it does not previously
|
||||
//exist, create it.
|
||||
//exist, throws an error.
|
||||
NamedUtility(open_only, ...)
|
||||
|
||||
On the other hand the anonymous synchronization utility can only
|
||||
@@ -1083,7 +1102,7 @@ Boost.Interprocess offers the following mutex types:
|
||||
|
||||
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
||||
|
||||
* [classref boost::interprocess::interprocess_mutex]: A recursive,
|
||||
* [classref boost::interprocess::interprocess_recursive_mutex]: A recursive,
|
||||
anonymous mutex that can be placed in shared memory or memory mapped files.
|
||||
|
||||
[c++]
|
||||
@@ -3422,6 +3441,95 @@ memory segment using `get_segment_manager` member:
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:managed_memory_segment_additional_features Additional functions]
|
||||
|
||||
Managed memory segments offer additional functions:
|
||||
|
||||
Obtain the size of the memory segment:
|
||||
|
||||
[c++]
|
||||
|
||||
managed_shm.get_size();
|
||||
|
||||
Obtain the number of free bytes of the segment:
|
||||
|
||||
[c++]
|
||||
|
||||
managed_shm.get_free_memory();
|
||||
|
||||
Clear to zero the free memory:
|
||||
|
||||
[c++]
|
||||
|
||||
managed_shm.zero_free_memory();
|
||||
|
||||
Returns true if all memory has been deallocated, false otherwise:
|
||||
|
||||
[c++]
|
||||
|
||||
managed_shm.all_memory_deallocated();
|
||||
|
||||
Tests internal structures of the managed segment and returns true
|
||||
if no errors are detected:
|
||||
|
||||
[c++]
|
||||
|
||||
managed_shm.check_sanity();
|
||||
|
||||
Reserves memory to make the subsequent allocation of named or unique objects more
|
||||
efficient. This function is only useful for pseudo-intrusive or non-node indexes (like
|
||||
`flat_map_index`, `iunordered_set_index`). This function has no effect with the
|
||||
default index (`iset_index`) or other indexes (`map_index`):
|
||||
|
||||
[c++]
|
||||
|
||||
managed_shm.reserve_named_objects(1000);
|
||||
managed_shm.reserve_unique_objects(1000);
|
||||
|
||||
Returns the number of named and unique objects allocated in the segment:
|
||||
|
||||
[c++]
|
||||
|
||||
managed_shm.get_num_named_objects();
|
||||
managed_shm.get_num_unique_objects();
|
||||
|
||||
Returns constant iterators to the range of named and unique objects stored in the
|
||||
managed segment. [*Caution:] These functions are for debugging purposes
|
||||
and they are [*not] thread-safe. If any other process creates or destroys
|
||||
named/unique objects while a process iterates the named/unique objects the
|
||||
results are undefined. Iterators are invalidated after each named/unique object
|
||||
creation/erasure:
|
||||
|
||||
[c++]
|
||||
|
||||
typedef managed_shared_memory::const_named_iterator const_named_it;
|
||||
const_named_it named_beg = managed_shm.named_begin();
|
||||
const_named_it named_end = managed_shm.named_end();
|
||||
|
||||
typedef managed_shared_memory::const_unique_iterator const_unique_it;
|
||||
const_unique_it unique_beg = managed_shm.unique_begin();
|
||||
const_unique_it unique_end = managed_shm.unique_end();
|
||||
|
||||
for(; named_beg != named_end; ++named_beg){
|
||||
//A pointer to the name of the named object
|
||||
const managed_shared_memory::char_type *name = named_beg->name();
|
||||
//The length of the name
|
||||
std::size_t name_len = named_beg->name_length();
|
||||
//A constant void pointer to the named object
|
||||
const void *value = named_beg->value();
|
||||
}
|
||||
|
||||
for(; unique_beg != unique_end; ++unique_beg){
|
||||
//The typeid(T).name() of the unique object
|
||||
const char *typeid_name = unique_beg->name();
|
||||
//The length of the name
|
||||
std::size_t name_len = unique_beg->name_length();
|
||||
//A constant void pointer to the unique object
|
||||
const void *value = unique_beg->value();
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:allocator_introduction Introduction to Interprocess allocators]
|
||||
@@ -5462,40 +5570,6 @@ pointer family as `segment_manager::void_pointer` typedef. This means that if `s
|
||||
reason for this is that allocators are members of containers, and if we want to put
|
||||
the container in a managed memory segment, the allocator should be ready for that.
|
||||
|
||||
If the user wants to optimize further allocator usage in [*Boost.Interprocess] node
|
||||
containers, he can change the common allocator::construct function from:
|
||||
|
||||
[c++]
|
||||
|
||||
void construct(pointer ptr, const value_type &value);
|
||||
|
||||
to this one:
|
||||
|
||||
[c++]
|
||||
|
||||
template<class Convertible>
|
||||
void construct(pointer ptr, const Convertible &value)
|
||||
|
||||
and define a specialization of `boost::interprocess::has_convertible_construct<...>`
|
||||
defined in `<boost/interprocess/detail/utilities.hpp>` file:
|
||||
|
||||
[c++]
|
||||
|
||||
namespace boost{ namespace interprocess{
|
||||
|
||||
template<class T, class SegmentManager>
|
||||
struct has_convertible_construct
|
||||
<my_allocator<T, SegmentManager> >
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
}} //namespace boost{ namespace interprocess{
|
||||
|
||||
Using this optimization, [*Boost.Interprocess] node containers will just store one allocator instance
|
||||
instead of 2, because nodes could be constructed from the value type directly.
|
||||
[*Boost.Interprocess] STL-like allocators implement this optimization.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:custom_indexes Building custom indexes]
|
||||
@@ -5863,7 +5937,7 @@ thank them:
|
||||
* Thanks to [*Francis Andre] and [*Anders Hybertz] for their ideas and suggestions.
|
||||
Many of them are not implemented yet but I hope to include them when library gets some stability.
|
||||
|
||||
* Thanks to [*Steve LoBasso], [*Glenn Schrader], [*Hiang Swee Chiang],
|
||||
* Thanks to [*Matt Doyle], [*Steve LoBasso], [*Glenn Schrader], [*Hiang Swee Chiang],
|
||||
[*Phil Endecott], [*Rene Rivera],
|
||||
[*Harold Pirtle], [*Paul Ryan],
|
||||
[*Shumin Wu], [*Michal Wozniak], [*Peter Johnson],
|
||||
@@ -5935,6 +6009,20 @@ limitations under the License.
|
||||
|
||||
[section:changes Changes...]
|
||||
|
||||
[section:changes_interprocess_2007_06_11 Changes in Interprocess 2007-06-11...]
|
||||
|
||||
* Added iteration of named and unique objects in a segment manager.
|
||||
* Fixed leak in [classref boost::interprocess::vector vector].
|
||||
* Added support for Solaris.
|
||||
* Optimized [classref boost::interprocess::segment_manager] to avoid
|
||||
code bloat associated with templated instantiations.
|
||||
* Removed the use of allocator::construct/destroy from containers.
|
||||
* Correction of typos and documentation errors.
|
||||
* Fixed bug for UNIX: No slash ('/') was being added as the first character
|
||||
for shared memory names, leading to errors in some UNIX systems.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:changes_interprocess_2007_05_03 Changes in Interprocess 2007-05-03...]
|
||||
|
||||
* Fixed bug in VC-8.0: Broken function inlining in core offset_ptr functions.
|
||||
|
||||
@@ -22,6 +22,7 @@ rule test_all
|
||||
for local fileb in [ glob *.cpp ]
|
||||
{
|
||||
all_rules += [ link $(fileb) /boost/thread//boost_thread
|
||||
# all_rules += [ compile $(fileb)
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
//[doc_cont
|
||||
#include <boost/interprocess/containers/vector.hpp>
|
||||
#include <boost/interprocess/allocators/allocator.hpp>
|
||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||
|
||||
int main ()
|
||||
|
||||
@@ -34,7 +34,7 @@ int main ()
|
||||
//so the allocator must allocate that pair.
|
||||
typedef int KeyType;
|
||||
typedef float MappedType;
|
||||
typedef std::pair<int, float> ValueType;
|
||||
typedef std::pair<const int, float> ValueType;
|
||||
|
||||
//Alias an STL compatible allocator of for the map.
|
||||
//This allocator will allow to place containers
|
||||
@@ -61,7 +61,7 @@ int main ()
|
||||
|
||||
//Insert data in the map
|
||||
for(int i = 0; i < 100; ++i){
|
||||
mymap->insert(std::pair<int, float>(i, (float)i));
|
||||
mymap->insert(std::pair<const int, float>(i, (float)i));
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
|
||||
@@ -56,6 +56,8 @@ int main ()
|
||||
for(int i = 0; i < 2; ++i){
|
||||
//Create an object in shared memory
|
||||
my_class * my_object = shmem.construct<my_class>("my_object")();
|
||||
my_class * my_object2 = shmem.construct<my_class>(anonymous_instance)();
|
||||
shmem.destroy_ptr(my_object2);
|
||||
|
||||
//Since the next shared memory allocation can throw
|
||||
//assign it to a scoped_ptr so that if an exception occurs
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//[doc_vectorstream
|
||||
#include <boost/interprocess/containers/vector.hpp>
|
||||
#include <boost/interprocess/containers/string.hpp>
|
||||
#include <boost/interprocess/allocators/allocator.hpp>
|
||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||
#include <boost/interprocess/streams/vectorstream.hpp>
|
||||
#include <iterator>
|
||||
|
||||
@@ -301,18 +301,6 @@ bool operator!=(const adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
|
||||
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
|
||||
|
||||
|
||||
/// @cond
|
||||
/*!This specialization indicates that the construct function allows
|
||||
convertible types to construct the value type. This allows
|
||||
storing less allocator instances in containers.*/
|
||||
template<class T, class S, std::size_t NodesPerChunk, std::size_t F>
|
||||
struct has_convertible_construct
|
||||
<boost::interprocess::adaptive_pool<T, S, NodesPerChunk, F> >
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
@@ -140,21 +140,6 @@ class allocator
|
||||
void deallocate(const pointer &ptr, size_type)
|
||||
{ mp_mngr->deallocate(detail::get_pointer(ptr)); }
|
||||
|
||||
/*!Construct object, calling constructor.
|
||||
Throws if T(const Convertible &) throws*/
|
||||
template<class Convertible>
|
||||
void construct(const pointer &ptr, const Convertible &value)
|
||||
{ new(detail::get_pointer(ptr)) value_type(value); }
|
||||
|
||||
/*!Default construct an object.
|
||||
Throws if T's default constructor throws*/
|
||||
void construct(const pointer &ptr)
|
||||
{ new(detail::get_pointer(ptr)) value_type; }
|
||||
|
||||
/*!Destroys object. Throws if object's destructor throws*/
|
||||
void destroy(const pointer &ptr)
|
||||
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
|
||||
|
||||
/*!Returns the number of elements that could be allocated. Never throws*/
|
||||
size_type max_size() const
|
||||
{ return mp_mngr->get_size()/sizeof(value_type); }
|
||||
@@ -229,21 +214,13 @@ bool operator!=(const allocator<T, SegmentManager> &alloc1,
|
||||
const allocator<T, SegmentManager> &alloc2)
|
||||
{ return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
|
||||
|
||||
/// @cond
|
||||
/*!This specialization indicates that the construct function allows
|
||||
convertible types to construct the value type. This allows
|
||||
storing less allocator instances in containers.*/
|
||||
template<class T, class SegmentManager>
|
||||
struct has_convertible_construct
|
||||
<boost::interprocess::allocator<T, SegmentManager> >
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
} //namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class T>
|
||||
struct has_trivial_destructor;
|
||||
|
||||
template<class T, class SegmentManager>
|
||||
struct has_trivial_destructor
|
||||
<boost::interprocess::allocator <T, SegmentManager> >
|
||||
|
||||
@@ -390,18 +390,6 @@ bool operator!=(const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc1,
|
||||
const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc2)
|
||||
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
|
||||
|
||||
/// @cond
|
||||
/*!This specialization indicates that the construct function allows
|
||||
convertible types to construct the value type. This allows
|
||||
storing less allocator instances in containers.*/
|
||||
template<class T, class SegmentManager, std::size_t NodesPerChunk, std::size_t M>
|
||||
struct has_convertible_construct
|
||||
<boost::interprocess::cached_adaptive_pool<T, SegmentManager, NodesPerChunk, M> >
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
} //namespace interprocess {
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
@@ -388,18 +388,6 @@ bool operator!=(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
|
||||
const cached_node_allocator<T, S, NodesPerChunk> &alloc2)
|
||||
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
|
||||
|
||||
/// @cond
|
||||
/*!This specialization indicates that the construct function allows
|
||||
convertible types to construct the value type. This allows
|
||||
storing less allocator instances in containers.*/
|
||||
template<class T, class SegmentManager, std::size_t NodesPerChunk>
|
||||
struct has_convertible_construct
|
||||
<boost::interprocess::cached_node_allocator<T, SegmentManager, NodesPerChunk> >
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -273,7 +273,6 @@ class private_node_pool
|
||||
//If there are no free nodes we allocate a new block
|
||||
if (m_freelist.empty())
|
||||
priv_alloc_chunk();
|
||||
|
||||
//We take the first free node
|
||||
node_t *n = (node_t*)&m_freelist.front();
|
||||
m_freelist.pop_front();
|
||||
@@ -303,9 +302,8 @@ class private_node_pool
|
||||
|
||||
//We initialize all Nodes in Node Block to insert
|
||||
//them in the free Node list
|
||||
for(std::size_t i = 0; i < NumAlloc; ++i){
|
||||
m_freelist.push_front(*(node_t*)pNode );
|
||||
pNode += RealNodeSize;
|
||||
for(std::size_t i = 0; i < NumAlloc; ++i, pNode += RealNodeSize){
|
||||
m_freelist.push_front(*new (pNode) node_t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -298,19 +298,6 @@ bool operator!=(const node_allocator<T, S, NodesPerChunk> &alloc1,
|
||||
const node_allocator<T, S, NodesPerChunk> &alloc2)
|
||||
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
|
||||
|
||||
|
||||
/// @cond
|
||||
/*!This specialization indicates that the construct function allows
|
||||
convertible types to construct the value type. This allows
|
||||
storing less allocator instances in containers.*/
|
||||
template<class T, class S, std::size_t NodesPerChunk>
|
||||
struct has_convertible_construct
|
||||
<boost::interprocess::node_allocator<T, S, NodesPerChunk> >
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -235,16 +235,6 @@ bool operator!=(const private_adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
|
||||
return &alloc1 != &alloc2;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
//!This specialization indicates that the construct function allows
|
||||
//!convertible types to construct the value type. This allows
|
||||
//!storing less allocator instances in containers.
|
||||
template<class T, class S, std::size_t NodesPerChunk, std::size_t F>
|
||||
struct has_convertible_construct
|
||||
<boost::interprocess::private_adaptive_pool<T, S, NodesPerChunk, F> >
|
||||
{ enum { value = true }; };
|
||||
/// @endcond
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -236,18 +236,6 @@ bool operator!=(const private_node_allocator<T, S, NodesPerChunk> &alloc1,
|
||||
return &alloc1 != &alloc2;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
//!This specialization indicates that the construct function allows
|
||||
//!convertible types to construct the value type. This allows
|
||||
//!storing less allocator instances in containers.
|
||||
template<class T, class S, std::size_t NodesPerChunk>
|
||||
struct has_convertible_construct
|
||||
<boost::interprocess::private_node_allocator<T, S, NodesPerChunk> >
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/iterators.hpp>
|
||||
#include <boost/interprocess/detail/algorithms.hpp>
|
||||
#include <boost/interprocess/detail/min_max.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
@@ -64,7 +68,6 @@
|
||||
#include <boost/interprocess/detail/move_iterator.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -84,10 +87,8 @@ inline std::size_t deque_buf_size(std::size_t size)
|
||||
// exception safety easier.
|
||||
template <class T, class Alloc>
|
||||
class deque_base
|
||||
: public boost::detail::allocator::
|
||||
rebind_to<Alloc, T >::type,
|
||||
public boost::detail::allocator::
|
||||
rebind_to<Alloc, typename Alloc::pointer>::type
|
||||
: public Alloc::template rebind<T>::other,
|
||||
public Alloc::template rebind<typename Alloc::pointer>::other
|
||||
{
|
||||
public:
|
||||
typedef typename Alloc::value_type val_alloc_val;
|
||||
@@ -96,16 +97,15 @@ class deque_base
|
||||
typedef typename Alloc::reference val_alloc_ref;
|
||||
typedef typename Alloc::const_reference val_alloc_cref;
|
||||
typedef typename Alloc::value_type val_alloc_diff;
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<Alloc, val_alloc_ptr>::type ptr_alloc;
|
||||
typedef typename Alloc::template rebind
|
||||
<typename Alloc::pointer>::other ptr_alloc;
|
||||
typedef typename ptr_alloc::value_type ptr_alloc_val;
|
||||
typedef typename ptr_alloc::pointer ptr_alloc_ptr;
|
||||
typedef typename ptr_alloc::const_pointer ptr_alloc_cptr;
|
||||
typedef typename ptr_alloc::reference ptr_alloc_ref;
|
||||
typedef typename ptr_alloc::const_reference ptr_alloc_cref;
|
||||
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<Alloc, T >::type allocator_type;
|
||||
typedef typename Alloc::template
|
||||
rebind<T>::other allocator_type;
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{ return *this; }
|
||||
@@ -113,8 +113,8 @@ class deque_base
|
||||
protected:
|
||||
enum { trivial_dctr_after_move = boost::has_trivial_destructor<val_alloc_val>::value };
|
||||
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<Alloc, typename Alloc::pointer>::type map_allocator_type;
|
||||
typedef typename Alloc::template
|
||||
rebind<typename Alloc::pointer>::other map_allocator_type;
|
||||
|
||||
val_alloc_ptr priv_allocate_node()
|
||||
{ return this->allocator_type::allocate(deque_buf_size(sizeof(T))); }
|
||||
@@ -372,6 +372,7 @@ class deque_base
|
||||
: allocator_type(a), map_allocator_type(a),
|
||||
m_map(0), m_map_size(0), m_start(), m_finish() {}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
deque_base(const detail::moved_object<deque_base> &md)
|
||||
: allocator_type(md.get()), map_allocator_type(md.get()),
|
||||
m_map(md.get().m_map), m_map_size(md.get().m_map_size),
|
||||
@@ -382,6 +383,18 @@ class deque_base
|
||||
m_start = iterator();
|
||||
m_finish = iterator();
|
||||
}
|
||||
#else
|
||||
deque_base(deque_base &&md)
|
||||
: allocator_type(md), map_allocator_type(md),
|
||||
m_map(md.m_map), m_map_size(md.m_map_size),
|
||||
m_start(md.m_start), m_finish(md.m_finish)
|
||||
{
|
||||
m_map = 0;
|
||||
m_map_size = 0;
|
||||
m_start = iterator();
|
||||
m_finish = iterator();
|
||||
}
|
||||
#endif
|
||||
|
||||
~deque_base()
|
||||
{
|
||||
@@ -464,8 +477,8 @@ class deque : protected deque_base<T, Alloc>
|
||||
typedef typename Alloc::const_pointer val_alloc_cptr;
|
||||
typedef typename Alloc::reference val_alloc_ref;
|
||||
typedef typename Alloc::const_reference val_alloc_cref;
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<Alloc, val_alloc_ptr>::type ptr_alloc;
|
||||
typedef typename Alloc::template
|
||||
rebind<val_alloc_ptr>::other ptr_alloc;
|
||||
typedef typename ptr_alloc::value_type ptr_alloc_val;
|
||||
typedef typename ptr_alloc::pointer ptr_alloc_ptr;
|
||||
typedef typename ptr_alloc::const_pointer ptr_alloc_cptr;
|
||||
@@ -581,9 +594,15 @@ class deque : protected deque_base<T, Alloc>
|
||||
deque(const deque& x) : Base(x.get_allocator(), x.size())
|
||||
{ std::uninitialized_copy(x.begin(), x.end(), this->m_start); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
deque(const detail::moved_object<deque> &mx)
|
||||
: Base(move((Base&)mx.get()))
|
||||
{}
|
||||
#else
|
||||
deque(deque &&mx)
|
||||
: Base(move((Base&)mx))
|
||||
{}
|
||||
#endif
|
||||
|
||||
deque(size_type n, const value_type& value,
|
||||
const allocator_type& a = allocator_type()) : Base(a, n)
|
||||
@@ -599,7 +618,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InpIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_initialize_dispatch(first, last, Result());
|
||||
}
|
||||
|
||||
@@ -621,8 +640,13 @@ class deque : protected deque_base<T, Alloc>
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
deque& operator= (const detail::moved_object<deque> &mx)
|
||||
{ this->clear(); this->swap(mx.get()); return *this; }
|
||||
#else
|
||||
deque& operator= (deque &&mx)
|
||||
{ this->clear(); this->swap(mx); return *this; }
|
||||
#endif
|
||||
|
||||
void swap(deque& x)
|
||||
{
|
||||
@@ -632,8 +656,13 @@ class deque : protected deque_base<T, Alloc>
|
||||
std::swap(this->m_map_size, x.m_map_size);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<deque> &mx)
|
||||
{ this->swap(mx.get()); }
|
||||
#else
|
||||
void swap(deque &&mx)
|
||||
{ this->swap(mx); }
|
||||
#endif
|
||||
|
||||
void assign(size_type n, const T& val) {
|
||||
this->priv_fill_assign(n, val);
|
||||
@@ -643,55 +672,79 @@ class deque : protected deque_base<T, Alloc>
|
||||
void assign(InpIt first, InpIt last) {
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InpIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_assign_dispatch(first, last, Result());
|
||||
}
|
||||
|
||||
void push_back(const value_type& t)
|
||||
{
|
||||
if (this->m_finish.m_cur != this->m_finish.m_last - 1) {
|
||||
this->allocator_type::construct(this->m_finish.m_cur, t);
|
||||
new(detail::get_pointer(this->m_finish.m_cur))value_type(t);
|
||||
++this->m_finish.m_cur;
|
||||
}
|
||||
else
|
||||
this->priv_push_back_aux(t);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void push_back(const detail::moved_object<value_type> &mt)
|
||||
{
|
||||
if (this->m_finish.m_cur != this->m_finish.m_last - 1) {
|
||||
this->allocator_type::construct(this->m_finish.m_cur, mt);
|
||||
new(detail::get_pointer(this->m_finish.m_cur))value_type(mt);
|
||||
++this->m_finish.m_cur;
|
||||
}
|
||||
else
|
||||
this->priv_push_back_aux(mt);
|
||||
}
|
||||
#else
|
||||
void push_back(value_type &&mt)
|
||||
{
|
||||
if (this->m_finish.m_cur != this->m_finish.m_last - 1) {
|
||||
new(detail::get_pointer(this->m_finish.m_cur))value_type(move(mt));
|
||||
++this->m_finish.m_cur;
|
||||
}
|
||||
else
|
||||
this->priv_push_back_aux(move(mt));
|
||||
}
|
||||
#endif
|
||||
|
||||
void push_front(const value_type& t)
|
||||
{
|
||||
if (this->m_start.m_cur != this->m_start.m_first) {
|
||||
this->allocator_type::construct(this->m_start.m_cur - 1, t);
|
||||
new(detail::get_pointer(this->m_start.m_cur)- 1)value_type(t);
|
||||
--this->m_start.m_cur;
|
||||
}
|
||||
else
|
||||
this->priv_push_front_aux(t);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void push_front(const detail::moved_object<value_type> &mt)
|
||||
{
|
||||
if (this->m_start.m_cur != this->m_start.m_first) {
|
||||
this->allocator_type::construct(this->m_start.m_cur - 1, mt);
|
||||
new(detail::get_pointer(this->m_start.m_cur)- 1)value_type(mt);
|
||||
--this->m_start.m_cur;
|
||||
}
|
||||
else
|
||||
this->priv_push_front_aux(mt);
|
||||
}
|
||||
#else
|
||||
void push_front(value_type &&mt)
|
||||
{
|
||||
if (this->m_start.m_cur != this->m_start.m_first) {
|
||||
new(detail::get_pointer(this->m_start.m_cur)- 1)value_type(move(mt));
|
||||
--this->m_start.m_cur;
|
||||
}
|
||||
else
|
||||
this->priv_push_front_aux(move(mt));
|
||||
}
|
||||
#endif
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
if (this->m_finish.m_cur != this->m_finish.m_first) {
|
||||
--this->m_finish.m_cur;
|
||||
static_cast<allocator_type*>(this)->destroy(this->m_finish.m_cur);
|
||||
detail::get_pointer(this->m_finish.m_cur)->~value_type();
|
||||
}
|
||||
else
|
||||
this->priv_pop_back_aux();
|
||||
@@ -700,7 +753,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
void pop_front()
|
||||
{
|
||||
if (this->m_start.m_cur != this->m_start.m_last - 1) {
|
||||
static_cast<allocator_type*>(this)->destroy(this->m_start.m_cur);
|
||||
detail::get_pointer(this->m_start.m_cur)->~value_type();
|
||||
++this->m_start.m_cur;
|
||||
}
|
||||
else
|
||||
@@ -724,6 +777,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<value_type> &mx)
|
||||
{
|
||||
if (position.m_cur == this->m_start.m_cur) {
|
||||
@@ -740,6 +794,24 @@ class deque : protected deque_base<T, Alloc>
|
||||
return this->priv_insert_aux(position, mx);
|
||||
}
|
||||
}
|
||||
#else
|
||||
iterator insert(iterator position, value_type &&mx)
|
||||
{
|
||||
if (position.m_cur == this->m_start.m_cur) {
|
||||
this->push_front(move(mx));
|
||||
return this->m_start;
|
||||
}
|
||||
else if (position.m_cur == this->m_finish.m_cur) {
|
||||
this->push_back(move(mx));
|
||||
iterator tmp = this->m_finish;
|
||||
--tmp;
|
||||
return tmp;
|
||||
}
|
||||
else {
|
||||
return this->priv_insert_aux(position, move(mx));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void insert(iterator pos, size_type n, const value_type& x)
|
||||
{ this->priv_fill_insert(pos, n, x); }
|
||||
@@ -750,7 +822,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InpIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_insert_dispatch(pos, first, last, Result());
|
||||
}
|
||||
|
||||
@@ -873,7 +945,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
if (pos.m_cur == this->m_start.m_cur) {
|
||||
iterator new_start = this->priv_reserve_elements_at_front(n);
|
||||
BOOST_TRY{
|
||||
std::uninitialized_copy(first, last, new_start);
|
||||
boost::interprocess::uninitialized_copy(first, last, new_start);
|
||||
this->m_start = new_start;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
@@ -885,7 +957,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
else if (pos.m_cur == this->m_finish.m_cur) {
|
||||
iterator new_finish = this->priv_reserve_elements_at_back(n);
|
||||
BOOST_TRY{
|
||||
std::uninitialized_copy(first, last, this->m_finish);
|
||||
boost::interprocess::uninitialized_copy(first, last, this->m_finish);
|
||||
this->m_finish = new_finish;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
@@ -914,31 +986,37 @@ class deque : protected deque_base<T, Alloc>
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void priv_initialize_dispatch(Integer n, Integer x, boost::mpl::true_)
|
||||
void priv_initialize_dispatch(Integer n, Integer x, true_)
|
||||
{
|
||||
this->priv_initialize_map(n);
|
||||
this->priv_fill_initialize(x);
|
||||
}
|
||||
|
||||
template <class InpIt>
|
||||
void priv_initialize_dispatch(InpIt first, InpIt last, boost::mpl::false_)
|
||||
void priv_initialize_dispatch(InpIt first, InpIt last, false_)
|
||||
{
|
||||
typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
|
||||
this->priv_range_initialize(first, last, ItCat());
|
||||
}
|
||||
|
||||
void priv_destroy_range(iterator p, iterator p2)
|
||||
{ for(;p != p2; ++p) static_cast<allocator_type*>(this)->destroy(&*p); }
|
||||
{
|
||||
for(;p != p2; ++p)
|
||||
detail::get_pointer(&*p)->~value_type();
|
||||
}
|
||||
|
||||
void priv_destroy_range(pointer p, pointer p2)
|
||||
{ for(;p != p2; ++p) static_cast<allocator_type*>(this)->destroy(p); }
|
||||
{
|
||||
for(;p != p2; ++p)
|
||||
detail::get_pointer(&*p)->~value_type();
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void priv_assign_dispatch(Integer n, Integer val, boost::mpl::true_)
|
||||
void priv_assign_dispatch(Integer n, Integer val, true_)
|
||||
{ this->priv_fill_assign((size_type) n, (T) val); }
|
||||
|
||||
template <class InpIt>
|
||||
void priv_assign_dispatch(InpIt first, InpIt last, boost::mpl::false_)
|
||||
void priv_assign_dispatch(InpIt first, InpIt last, false_)
|
||||
{
|
||||
typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
|
||||
this->priv_assign_aux(first, last, ItCat());
|
||||
@@ -973,7 +1051,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
|
||||
template <class Integer>
|
||||
void priv_insert_dispatch(iterator pos, Integer n, Integer x,
|
||||
boost::mpl::true_)
|
||||
true_)
|
||||
{
|
||||
this->priv_fill_insert(pos, (size_type) n, (value_type) x);
|
||||
}
|
||||
@@ -981,7 +1059,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
template <class InpIt>
|
||||
void priv_insert_dispatch(iterator pos,
|
||||
InpIt first, InpIt last,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
|
||||
this->insert(pos, first, last, ItCat());
|
||||
@@ -994,6 +1072,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
return iterator(this->begin() + n);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator priv_insert_aux(iterator pos, const detail::moved_object<value_type> &mx)
|
||||
{
|
||||
typedef repeat_iterator<T, difference_type> r_iterator;
|
||||
@@ -1005,6 +1084,19 @@ class deque : protected deque_base<T, Alloc>
|
||||
,move_it(r_iterator()));
|
||||
return iterator(this->begin() + n);
|
||||
}
|
||||
#else
|
||||
iterator priv_insert_aux(iterator pos, value_type &&mx)
|
||||
{
|
||||
typedef repeat_iterator<T, difference_type> r_iterator;
|
||||
typedef detail::move_iterator<r_iterator> move_it;
|
||||
//Just call more general insert(pos, size, value) and return iterator
|
||||
size_type n = pos - begin();
|
||||
this->insert(pos
|
||||
,move_it(r_iterator(mx, 1))
|
||||
,move_it(r_iterator()));
|
||||
return iterator(this->begin() + n);
|
||||
}
|
||||
#endif
|
||||
|
||||
void priv_insert_aux(iterator pos, size_type n, const value_type& x)
|
||||
{
|
||||
@@ -1024,7 +1116,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
BOOST_TRY {
|
||||
if (elemsbefore >= difference_type(n)) {
|
||||
iterator start_n = this->m_start + difference_type(n);
|
||||
std::uninitialized_copy(detail::make_move_iterator(this->m_start), detail::make_move_iterator(start_n), new_start);
|
||||
boost::interprocess::uninitialized_copy(detail::make_move_iterator(this->m_start), detail::make_move_iterator(start_n), new_start);
|
||||
this->m_start = new_start;
|
||||
std::copy(detail::make_move_iterator(start_n), detail::make_move_iterator(pos), old_start);
|
||||
std::copy(first, last, pos - difference_type(n));
|
||||
@@ -1053,7 +1145,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
BOOST_TRY {
|
||||
if (elemsafter > difference_type(n)) {
|
||||
iterator finish_n = this->m_finish - difference_type(n);
|
||||
std::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->m_finish), this->m_finish);
|
||||
boost::interprocess::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->m_finish), this->m_finish);
|
||||
this->m_finish = new_finish;
|
||||
std::copy_backward(detail::make_move_iterator(pos), detail::make_move_iterator(finish_n), old_finish);
|
||||
std::copy(first, last, pos);
|
||||
@@ -1087,9 +1179,9 @@ class deque : protected deque_base<T, Alloc>
|
||||
index_pointer cur;
|
||||
BOOST_TRY {
|
||||
for (cur = this->m_start.m_node; cur < this->m_finish.m_node; ++cur){
|
||||
std::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value);
|
||||
boost::interprocess::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value);
|
||||
}
|
||||
std::uninitialized_fill(this->m_finish.m_first, this->m_finish.m_cur, value);
|
||||
boost::interprocess::uninitialized_fill(this->m_finish.m_first, this->m_finish.m_cur, value);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->priv_destroy_range(this->m_start, iterator(*cur, cur));
|
||||
@@ -1127,10 +1219,10 @@ class deque : protected deque_base<T, Alloc>
|
||||
++cur_node) {
|
||||
FwdIt mid = first;
|
||||
std::advance(mid, this->s_buffer_size());
|
||||
std::uninitialized_copy(first, mid, *cur_node);
|
||||
boost::interprocess::uninitialized_copy(first, mid, *cur_node);
|
||||
first = mid;
|
||||
}
|
||||
std::uninitialized_copy(first, last, this->m_finish.m_first);
|
||||
boost::interprocess::uninitialized_copy(first, last, this->m_finish.m_first);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->priv_destroy_range(this->m_start, iterator(*cur_node, cur_node));
|
||||
@@ -1145,7 +1237,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
this->priv_reserve_map_at_back();
|
||||
*(this->m_finish.m_node + 1) = this->priv_allocate_node();
|
||||
BOOST_TRY {
|
||||
this->allocator_type::construct(this->m_finish.m_cur, t);
|
||||
new(detail::get_pointer(this->m_finish.m_cur))value_type(t);
|
||||
this->m_finish.priv_set_node(this->m_finish.m_node + 1);
|
||||
this->m_finish.m_cur = this->m_finish.m_first;
|
||||
}
|
||||
@@ -1157,12 +1249,13 @@ class deque : protected deque_base<T, Alloc>
|
||||
}
|
||||
|
||||
// Called only if this->m_finish.m_cur == this->m_finish.m_last - 1.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void priv_push_back_aux(const detail::moved_object<value_type> &mt)
|
||||
{
|
||||
this->priv_reserve_map_at_back();
|
||||
*(this->m_finish.m_node + 1) = this->priv_allocate_node();
|
||||
BOOST_TRY {
|
||||
this->allocator_type::construct(this->m_finish.m_cur, mt);
|
||||
new(detail::get_pointer(this->m_finish.m_cur))value_type(mt);
|
||||
this->m_finish.priv_set_node(this->m_finish.m_node + 1);
|
||||
this->m_finish.m_cur = this->m_finish.m_first;
|
||||
}
|
||||
@@ -1172,6 +1265,23 @@ class deque : protected deque_base<T, Alloc>
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
#else
|
||||
void priv_push_back_aux(value_type &&mt)
|
||||
{
|
||||
this->priv_reserve_map_at_back();
|
||||
*(this->m_finish.m_node + 1) = this->priv_allocate_node();
|
||||
BOOST_TRY {
|
||||
new(detail::get_pointer(this->m_finish.m_cur))value_type(move(mt));
|
||||
this->m_finish.priv_set_node(this->m_finish.m_node + 1);
|
||||
this->m_finish.m_cur = this->m_finish.m_first;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->priv_deallocate_node(*(this->m_finish.m_node + 1));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
#endif
|
||||
|
||||
// Called only if this->m_start.m_cur == this->m_start.m_first.
|
||||
void priv_push_front_aux(const value_type& t)
|
||||
@@ -1181,7 +1291,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
BOOST_TRY {
|
||||
this->m_start.priv_set_node(this->m_start.m_node - 1);
|
||||
this->m_start.m_cur = this->m_start.m_last - 1;
|
||||
this->allocator_type::construct(this->m_start.m_cur, t);
|
||||
new(detail::get_pointer(this->m_start.m_cur))value_type(t);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
++this->m_start;
|
||||
@@ -1191,6 +1301,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void priv_push_front_aux(const detail::moved_object<value_type> &mt)
|
||||
{
|
||||
this->priv_reserve_map_at_front();
|
||||
@@ -1198,7 +1309,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
BOOST_TRY {
|
||||
this->m_start.priv_set_node(this->m_start.m_node - 1);
|
||||
this->m_start.m_cur = this->m_start.m_last - 1;
|
||||
this->allocator_type::construct(this->m_start.m_cur, mt);
|
||||
new(detail::get_pointer(this->m_start.m_cur))value_type(mt);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
++this->m_start;
|
||||
@@ -1206,7 +1317,25 @@ class deque : protected deque_base<T, Alloc>
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
}
|
||||
#else
|
||||
void priv_push_front_aux(value_type &&mt)
|
||||
{
|
||||
this->priv_reserve_map_at_front();
|
||||
*(this->m_start.m_node - 1) = this->priv_allocate_node();
|
||||
BOOST_TRY {
|
||||
this->m_start.priv_set_node(this->m_start.m_node - 1);
|
||||
this->m_start.m_cur = this->m_start.m_last - 1;
|
||||
new(detail::get_pointer(this->m_start.m_cur))value_type(move(mt));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
++this->m_start;
|
||||
this->priv_deallocate_node(*(this->m_start.m_node - 1));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
#endif
|
||||
|
||||
// Called only if this->m_finish.m_cur == this->m_finish.m_first.
|
||||
void priv_pop_back_aux()
|
||||
@@ -1214,7 +1343,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
this->priv_deallocate_node(this->m_finish.m_first);
|
||||
this->m_finish.priv_set_node(this->m_finish.m_node - 1);
|
||||
this->m_finish.m_cur = this->m_finish.m_last - 1;
|
||||
static_cast<allocator_type*>(this)->destroy(this->m_finish.m_cur);
|
||||
detail::get_pointer(this->m_finish.m_cur)->~value_type();
|
||||
}
|
||||
|
||||
// Called only if this->m_start.m_cur == this->m_start.m_last - 1. Note that
|
||||
@@ -1223,7 +1352,7 @@ class deque : protected deque_base<T, Alloc>
|
||||
// must have at least two nodes.
|
||||
void priv_pop_front_aux()
|
||||
{
|
||||
static_cast<allocator_type*>(this)->destroy(this->m_start.m_cur);
|
||||
detail::get_pointer(this->m_start.m_cur)->~value_type();
|
||||
this->priv_deallocate_node(this->m_start.m_first);
|
||||
this->m_start.priv_set_node(this->m_start.m_node + 1);
|
||||
this->m_start.m_cur = this->m_start.m_first;
|
||||
@@ -1336,13 +1465,13 @@ class deque : protected deque_base<T, Alloc>
|
||||
iterator first2, iterator last2,
|
||||
const T& x)
|
||||
{
|
||||
iterator mid2 = std::uninitialized_copy(first1, last1, first2);
|
||||
iterator mid2 = boost::interprocess::uninitialized_copy(first1, last1, first2);
|
||||
BOOST_TRY {
|
||||
std::uninitialized_fill(mid2, last2, x);
|
||||
boost::interprocess::uninitialized_fill(mid2, last2, x);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for(;first2 != mid2; ++first2){
|
||||
static_cast<allocator_type*>(this)->destroy(&*first2);
|
||||
detail::get_pointer(&*first2)->~value_type();
|
||||
}
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
@@ -1355,13 +1484,13 @@ class deque : protected deque_base<T, Alloc>
|
||||
const T& x,
|
||||
iterator first, iterator last)
|
||||
{
|
||||
std::uninitialized_fill(result, mid, x);
|
||||
boost::interprocess::uninitialized_fill(result, mid, x);
|
||||
BOOST_TRY {
|
||||
return std::uninitialized_copy(first, last, mid);
|
||||
return boost::interprocess::uninitialized_copy(first, last, mid);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for(;result != mid; ++result){
|
||||
static_cast<allocator_type*>(this)->destroy(&*result);
|
||||
detail::get_pointer(&*result)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
@@ -1377,13 +1506,13 @@ class deque : protected deque_base<T, Alloc>
|
||||
InpIt2 first2, InpIt2 last2,
|
||||
FwdIt result)
|
||||
{
|
||||
FwdIt mid = std::uninitialized_copy(first1, last1, result);
|
||||
FwdIt mid = boost::interprocess::uninitialized_copy(first1, last1, result);
|
||||
BOOST_TRY {
|
||||
return std::uninitialized_copy(first2, last2, mid);
|
||||
return boost::interprocess::uninitialized_copy(first2, last2, mid);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for(;result != mid; ++result){
|
||||
static_cast<allocator_type*>(this)->destroy(&*result);
|
||||
detail::get_pointer(&*result)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
#include <boost/interprocess/containers/vector.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
@@ -134,9 +133,15 @@ class flat_tree
|
||||
: m_data(x.m_data, x.m_data.m_vect)
|
||||
{ }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_tree(const detail::moved_object<flat_tree> &x)
|
||||
: m_data(move(x.get().m_data))
|
||||
{ }
|
||||
#else
|
||||
flat_tree(flat_tree &&x)
|
||||
: m_data(move(x.m_data))
|
||||
{ }
|
||||
#endif
|
||||
|
||||
~flat_tree()
|
||||
{ }
|
||||
@@ -144,8 +149,13 @@ class flat_tree
|
||||
flat_tree& operator=(const flat_tree& x)
|
||||
{ flat_tree(x).swap(*this); return *this; }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_tree& operator=(const detail::moved_object<flat_tree>& mx)
|
||||
{ m_data = move(mx.get().m_data); return *this; }
|
||||
#else
|
||||
flat_tree& operator=(flat_tree &&mx)
|
||||
{ m_data = move(mx.m_data); return *this; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
// accessors:
|
||||
@@ -198,10 +208,15 @@ class flat_tree
|
||||
myvect.swap(othervect);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<flat_tree>& other)
|
||||
{ this->swap(other.get()); }
|
||||
#else
|
||||
void swap(flat_tree &&other)
|
||||
{ this->swap(other); }
|
||||
#endif
|
||||
|
||||
public:
|
||||
public:
|
||||
// insert/erase
|
||||
std::pair<iterator,bool> insert_unique(const value_type& val)
|
||||
{
|
||||
@@ -213,6 +228,7 @@ class flat_tree
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
std::pair<iterator,bool> insert_unique(const detail::moved_object<value_type>& mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
@@ -222,6 +238,18 @@ class flat_tree
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
std::pair<iterator,bool> insert_unique(value_type && mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(mval, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, move(mval));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
iterator insert_equal(const value_type& val)
|
||||
{
|
||||
@@ -230,12 +258,21 @@ class flat_tree
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert_equal(const detail::moved_object<value_type>& mval)
|
||||
{
|
||||
iterator i = this->upper_bound(KeyOfValue()(mval.get()));
|
||||
i = this->m_data.m_vect.insert(i, mval);
|
||||
return i;
|
||||
}
|
||||
#else
|
||||
iterator insert_equal(value_type && mval)
|
||||
{
|
||||
iterator i = this->upper_bound(KeyOfValue()(mval));
|
||||
i = this->m_data.m_vect.insert(i, move(mval));
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert_unique(const_iterator pos, const value_type& val)
|
||||
{
|
||||
@@ -247,6 +284,7 @@ class flat_tree
|
||||
return ret.first;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert_unique(const_iterator pos, const detail::moved_object<value_type>& mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
@@ -256,6 +294,17 @@ class flat_tree
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
#else
|
||||
iterator insert_unique(const_iterator pos, value_type&&mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, move(mval));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert_equal(const_iterator pos, const value_type& val)
|
||||
{
|
||||
@@ -264,12 +313,21 @@ class flat_tree
|
||||
return priv_insert_commit(data, val);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert_equal(const_iterator pos, const detail::moved_object<value_type>& mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
priv_insert_equal_prepare(pos, mval.get(), data);
|
||||
return priv_insert_commit(data, mval);
|
||||
}
|
||||
#else
|
||||
iterator insert_equal(const_iterator pos, value_type && mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
priv_insert_equal_prepare(pos, mval, data);
|
||||
return priv_insert_commit(data, move(mval));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(InIt first, InIt last)
|
||||
@@ -468,10 +526,17 @@ class flat_tree
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
iterator priv_insert_commit
|
||||
(insert_commit_data &commit_data, const Convertible &convertible)
|
||||
{ return this->m_data.m_vect.insert(commit_data.position, convertible); }
|
||||
#else
|
||||
template<class Convertible>
|
||||
iterator priv_insert_commit
|
||||
(insert_commit_data &commit_data, Convertible &&convertible)
|
||||
{ return this->m_data.m_vect.insert(commit_data.position, forward<Convertible>(convertible)); }
|
||||
#endif
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_lower_bound(RanIt first, RanIt last,
|
||||
|
||||
@@ -47,16 +47,11 @@
|
||||
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/interprocess/detail/generic_cast.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/intrusive/rbtree.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
@@ -70,10 +65,7 @@ struct value_compare_impl
|
||||
typedef Value value_type;
|
||||
typedef KeyCompare key_compare;
|
||||
typedef KeyOfValue key_of_value;
|
||||
class dummy;
|
||||
|
||||
typedef typename boost::mpl::if_c
|
||||
<is_same<Key, Value>::value, dummy, Key>::type key_type;
|
||||
typedef Key key_type;
|
||||
|
||||
value_compare_impl(key_compare kcomp)
|
||||
: key_compare(kcomp)
|
||||
@@ -85,14 +77,9 @@ struct value_compare_impl
|
||||
key_compare &key_comp()
|
||||
{ return static_cast<key_compare &>(*this); }
|
||||
|
||||
bool operator()(const value_type &a, const value_type &b) const
|
||||
template<class A, class B>
|
||||
bool operator()(const A &a, const B &b) const
|
||||
{ return key_compare::operator()(KeyOfValue()(a), KeyOfValue()(b)); }
|
||||
|
||||
bool operator()(const key_type &a, const value_type &b) const
|
||||
{ return key_compare::operator()(a, KeyOfValue()(b)); }
|
||||
|
||||
bool operator()(const value_type &a, const key_type &b) const
|
||||
{ return key_compare::operator()(KeyOfValue()(a), b); }
|
||||
};
|
||||
|
||||
template <class T, class VoidPointer>
|
||||
@@ -109,9 +96,15 @@ struct rbtree_node
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
rbtree_node(const Convertible &conv)
|
||||
: m_data(conv){}
|
||||
#else
|
||||
template<class Convertible>
|
||||
rbtree_node(Convertible &&conv)
|
||||
: m_data(forward<Convertible>(conv)){}
|
||||
#endif
|
||||
|
||||
rbtree_node &operator=(const rbtree_node &other)
|
||||
{ do_assign(other.m_data); return *this; }
|
||||
@@ -133,21 +126,20 @@ struct rbtree_node
|
||||
|
||||
template<class A, class ValueCompare>
|
||||
struct rbtree_alloc
|
||||
: public boost::detail::allocator::
|
||||
rebind_to<A, rbtree_node
|
||||
<typename A::value_type, typename boost::detail::allocator::
|
||||
rebind_to<A, void>::type::pointer>
|
||||
>::type
|
||||
: public A::template rebind<rbtree_node
|
||||
< typename A::value_type
|
||||
, typename detail::pointer_to_other<typename A::pointer, void>::type>
|
||||
>::other
|
||||
{
|
||||
typedef rbtree_alloc<A, ValueCompare> self_t;
|
||||
typedef typename A::value_type value_type;
|
||||
typedef rbtree_node
|
||||
<value_type, typename boost::detail::allocator::
|
||||
rebind_to<A, void>::type::pointer> Node;
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<A, void>::type::pointer VoidPointer;
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<A, Node>::type NodeAlloc;
|
||||
<typename A::value_type
|
||||
,typename detail::pointer_to_other
|
||||
<typename A::pointer, void>::type> Node;
|
||||
typedef typename A::template rebind<Node>::other NodeAlloc;
|
||||
typedef typename detail::pointer_to_other
|
||||
<typename A::pointer, void>::type VoidPointer;
|
||||
typedef A ValAlloc;
|
||||
typedef typename NodeAlloc::pointer NodePtr;
|
||||
typedef detail::scoped_deallocator<NodeAlloc> Deallocator;
|
||||
@@ -180,28 +172,34 @@ struct rbtree_alloc
|
||||
,boost::intrusive::safe_link
|
||||
,typename A::size_type> Irbtree;
|
||||
|
||||
enum {
|
||||
node_has_trivial_destructor =
|
||||
boost::has_trivial_destructor<NodePtr>::value &&
|
||||
boost::has_trivial_destructor<value_type>::value
|
||||
};
|
||||
|
||||
rbtree_alloc(const ValAlloc &a, const ValueCompare &c)
|
||||
: NodeAlloc(a), m_irbtree(node_compare(c))
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
rbtree_alloc(const detail::moved_object<ValAlloc> &a, const ValueCompare &c)
|
||||
: NodeAlloc(a.get()), m_irbtree(node_compare(c))
|
||||
{}
|
||||
#else
|
||||
rbtree_alloc(ValAlloc &&a, const ValueCompare &c)
|
||||
: NodeAlloc(a), m_irbtree(node_compare(c))
|
||||
{}
|
||||
#endif
|
||||
|
||||
rbtree_alloc(const rbtree_alloc &other, const ValueCompare &c)
|
||||
: NodeAlloc(other), m_irbtree(node_compare(c))
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
rbtree_alloc
|
||||
(const detail::moved_object<rbtree_alloc> &other, const ValueCompare &c)
|
||||
: NodeAlloc(move((NodeAlloc&)other.get())), m_irbtree(node_compare(c))
|
||||
{ this->swap(other.get()); }
|
||||
#else
|
||||
rbtree_alloc(rbtree_alloc &&other, const ValueCompare &c)
|
||||
: NodeAlloc(move((NodeAlloc&)other)), m_irbtree(node_compare(c))
|
||||
{ this->swap(other); }
|
||||
#endif
|
||||
|
||||
~rbtree_alloc()
|
||||
{}
|
||||
@@ -209,10 +207,17 @@ struct rbtree_alloc
|
||||
typename NodeAlloc::size_type max_size() const
|
||||
{ return NodeAlloc::max_size(); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
static void construct(const NodePtr &ptr, const Convertible &value)
|
||||
{ new(detail::get_pointer(ptr)) Node(value); }
|
||||
#else
|
||||
template<class Convertible>
|
||||
static void construct(const NodePtr &ptr, Convertible &&value)
|
||||
{ new(detail::get_pointer(ptr)) Node(forward<Convertible>(value)); }
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible1, class Convertible2>
|
||||
static void construct(const NodePtr &ptr,
|
||||
const detail::moved_object<std::pair<Convertible1, Convertible2> > &value)
|
||||
@@ -225,25 +230,49 @@ struct rbtree_alloc
|
||||
|
||||
new((void*)detail::get_pointer(ptr)) hack_node_t(value);
|
||||
}
|
||||
#else
|
||||
template<class Convertible1, class Convertible2>
|
||||
static void construct(const NodePtr &ptr,
|
||||
std::pair<Convertible1, Convertible2> &&value)
|
||||
{
|
||||
//std::pair is not movable so we define our own type and overwrite it
|
||||
typedef detail::pair<typename Node::value_type::first_type
|
||||
,typename Node::value_type::second_type> hack_pair_t;
|
||||
|
||||
typedef rbtree_node<hack_pair_t, VoidPointer> hack_node_t;
|
||||
|
||||
new((void*)detail::get_pointer(ptr)) hack_node_t(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void destroy(const NodePtr &ptr)
|
||||
{ detail::get_pointer(ptr)->~Node(); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
NodePtr create_node(const Convertible& x)
|
||||
{
|
||||
NodePtr p = NodeAlloc::allocate(1);
|
||||
scoped_ptr<Node, Deallocator>node_deallocator(p, *this);
|
||||
Deallocator node_deallocator(p, *this);
|
||||
self_t::construct(p, x);
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
#else
|
||||
template<class Convertible>
|
||||
NodePtr create_node(Convertible &&x)
|
||||
{
|
||||
NodePtr p = NodeAlloc::allocate(1);
|
||||
Deallocator node_deallocator(p, *this);
|
||||
self_t::construct(p, forward<Convertible>(x));
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
#endif
|
||||
|
||||
void destroy_node(NodePtr node)
|
||||
{
|
||||
if(!node_has_trivial_destructor){
|
||||
self_t::destroy(node);
|
||||
}
|
||||
self_t::destroy(node);
|
||||
NodeAlloc::deallocate(node, 1);
|
||||
}
|
||||
|
||||
@@ -511,9 +540,15 @@ class rbtree
|
||||
(x.m_irbtree, typename AllocHolder::cloner(*this), Destroyer(*this));
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
rbtree(const detail::moved_object<rbtree>& x)
|
||||
: AllocHolder(x.get(), x.get().key_comp())
|
||||
{ this->swap(x.get()); }
|
||||
#else
|
||||
rbtree(rbtree &&x)
|
||||
: AllocHolder(x, x.key_comp())
|
||||
{ this->swap(x); }
|
||||
#endif
|
||||
|
||||
~rbtree()
|
||||
{ this->clear(); }
|
||||
@@ -540,8 +575,13 @@ class rbtree
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
rbtree& operator=(const detail::moved_object<rbtree>& mx)
|
||||
{ this->clear(); this->swap(mx.get()); return *this; }
|
||||
#else
|
||||
rbtree& operator=(rbtree &&mx)
|
||||
{ this->clear(); this->swap(mx); return *this; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
// accessors:
|
||||
@@ -590,8 +630,13 @@ class rbtree
|
||||
void swap(ThisType& x)
|
||||
{ AllocHolder::swap(x); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<rbtree>& mt)
|
||||
{ this->swap(mt.get()); }
|
||||
#else
|
||||
void swap(rbtree &&mt)
|
||||
{ this->swap(mt); }
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -621,6 +666,7 @@ class rbtree
|
||||
return iterator(it);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class MovableConvertible>
|
||||
iterator insert_unique_commit
|
||||
(const detail::moved_object<MovableConvertible>& mv, insert_commit_data &data)
|
||||
@@ -629,6 +675,16 @@ class rbtree
|
||||
iiterator it(this->m_irbtree.insert_unique_commit(*tmp, data));
|
||||
return iterator(it);
|
||||
}
|
||||
#else
|
||||
template<class MovableConvertible>
|
||||
iterator insert_unique_commit
|
||||
(MovableConvertible && mv, insert_commit_data &data)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(forward<MovableConvertible>(mv));
|
||||
iiterator it(this->m_irbtree.insert_unique_commit(*tmp, data));
|
||||
return iterator(it);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::pair<iterator,bool> insert_unique(const value_type& v)
|
||||
{
|
||||
@@ -641,6 +697,7 @@ class rbtree
|
||||
(this->insert_unique_commit(v, data), true);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class MovableConvertible>
|
||||
std::pair<iterator,bool> insert_unique
|
||||
(const detail::moved_object<MovableConvertible>& mv)
|
||||
@@ -653,6 +710,19 @@ class rbtree
|
||||
return std::pair<iterator,bool>
|
||||
(this->insert_unique_commit(mv, data), true);
|
||||
}
|
||||
#else
|
||||
template<class MovableConvertible>
|
||||
std::pair<iterator,bool> insert_unique(MovableConvertible &&mv)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(KeyOfValue()(mv), data);
|
||||
if(!ret.second)
|
||||
return ret;
|
||||
return std::pair<iterator,bool>
|
||||
(this->insert_unique_commit(forward<MovableConvertible>(mv), data), true);
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert_unique(const_iterator hint, const value_type& v)
|
||||
{
|
||||
@@ -664,6 +734,7 @@ class rbtree
|
||||
return this->insert_unique_commit(v, data);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class MovableConvertible>
|
||||
iterator insert_unique
|
||||
(const_iterator hint, const detail::moved_object<MovableConvertible> &mv)
|
||||
@@ -675,6 +746,19 @@ class rbtree
|
||||
return ret.first;
|
||||
return this->insert_unique_commit(mv, data);
|
||||
}
|
||||
#else
|
||||
template<class MovableConvertible>
|
||||
iterator insert_unique
|
||||
(const_iterator hint, MovableConvertible &&mv)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(hint, KeyOfValue()(mv), data);
|
||||
if(!ret.second)
|
||||
return ret.first;
|
||||
return this->insert_unique_commit(forward<MovableConvertible>(mv), data);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class InputIterator>
|
||||
void insert_unique(InputIterator first, InputIterator last)
|
||||
@@ -698,12 +782,21 @@ class rbtree
|
||||
return iterator(this->m_irbtree.insert_equal_upper_bound(*p));
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(const detail::moved_object<MovableConvertible> &mv)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(mv));
|
||||
return iterator(this->m_irbtree.insert_equal_upper_bound(*p));
|
||||
}
|
||||
#else
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(MovableConvertible &&mv)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(forward<MovableConvertible>(mv)));
|
||||
return iterator(this->m_irbtree.insert_equal_upper_bound(*p));
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert_equal(const_iterator hint, const value_type& v)
|
||||
{
|
||||
@@ -711,12 +804,21 @@ class rbtree
|
||||
return iterator(this->m_irbtree.insert_equal(hint.get(), *p));
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(const_iterator hint, const detail::moved_object<MovableConvertible> &mv)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(mv));
|
||||
return iterator(this->m_irbtree.insert_equal(hint.get(), *p));
|
||||
}
|
||||
#else
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(const_iterator hint, MovableConvertible &&mv)
|
||||
{
|
||||
NodePtr p(AllocHolder::create_node(move(mv)));
|
||||
return iterator(this->m_irbtree.insert_equal(hint.get(), *p));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class InputIterator>
|
||||
void insert_equal(InputIterator first, InputIterator last)
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/interprocess/containers/detail/flat_tree.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
|
||||
namespace boost { namespace interprocess {
|
||||
@@ -72,15 +72,15 @@ class flat_map
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef detail::flat_tree<Key,
|
||||
detail::pair<Key, T>,
|
||||
detail::select1st< detail::pair<Key, T> >,
|
||||
select1st< detail::pair<Key, T> >,
|
||||
Pred,
|
||||
typename boost::detail::allocator::
|
||||
rebind_to<Alloc, detail::pair<Key, T> >::type> impl_tree_t;
|
||||
typename Alloc::template
|
||||
rebind<detail::pair<Key, T> >::other> impl_tree_t;
|
||||
|
||||
//This is the tree that we should store if pair was movable
|
||||
typedef detail::flat_tree<Key,
|
||||
std::pair<Key, T>,
|
||||
detail::select1st< std::pair<Key, T> >,
|
||||
select1st< std::pair<Key, T> >,
|
||||
Pred,
|
||||
Alloc> tree_t;
|
||||
|
||||
@@ -98,15 +98,21 @@ class flat_map
|
||||
typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
|
||||
typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
|
||||
typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
typedef detail::moved_object<impl_value_type> impl_moved_value_type;
|
||||
/*
|
||||
template<class D, class S>
|
||||
static D &force(S &s)
|
||||
{ return *(reinterpret_cast<D*>(&s)); }
|
||||
*/
|
||||
#else
|
||||
typedef impl_value_type&& impl_moved_value_type;
|
||||
#endif
|
||||
|
||||
template<class D, class S>
|
||||
static D &force(const S &s)
|
||||
{ return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class D, class S>
|
||||
static D &&force(S &&s)
|
||||
{ return reinterpret_cast<D&&>(s); }
|
||||
#endif
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
@@ -158,9 +164,15 @@ class flat_map
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_map(const detail::moved_object<flat_map<Key,T,Pred,Alloc> >& x)
|
||||
: m_flat_tree(move(x.get().m_flat_tree)) {}
|
||||
|
||||
#else
|
||||
flat_map(flat_map<Key,T,Pred,Alloc> && x)
|
||||
: m_flat_tree(move(x.m_flat_tree)) {}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
@@ -173,8 +185,13 @@ class flat_map
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_map<Key,T,Pred,Alloc>& operator=(const detail::moved_object<flat_map<Key, T, Pred, Alloc> >& mx)
|
||||
{ m_flat_tree = move(mx.get().m_flat_tree); return *this; }
|
||||
#else
|
||||
flat_map<Key,T,Pred,Alloc>& operator=(flat_map<Key, T, Pred, Alloc> && mx)
|
||||
{ m_flat_tree = move(mx.m_flat_tree); return *this; }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
@@ -289,6 +306,13 @@ class flat_map
|
||||
size_type max_size() const
|
||||
{ return m_flat_tree.max_size(); }
|
||||
|
||||
//! Effects: If there is no key equivalent to x in the flat_map, inserts
|
||||
//! value_type(move(x), T()) into the flat_map (the key is move-constructed)
|
||||
//!
|
||||
//! Returns: A reference to the mapped_type corresponding to x in *this.
|
||||
//!
|
||||
//! Complexity: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
//! Effects: If there is no key equivalent to x in the flat_map, inserts
|
||||
//! value_type(x, T()) into the flat_map.
|
||||
//!
|
||||
@@ -304,12 +328,6 @@ class flat_map
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
//! Effects: If there is no key equivalent to x in the flat_map, inserts
|
||||
//! value_type(move(x), T()) into the flat_map (the key is move-constructed)
|
||||
//!
|
||||
//! Returns: A reference to the mapped_type corresponding to x in *this.
|
||||
//!
|
||||
//! Complexity: Logarithmic.
|
||||
T &operator[](const detail::moved_object<key_type>& mk)
|
||||
{
|
||||
key_type &k = mk.get();
|
||||
@@ -319,6 +337,23 @@ class flat_map
|
||||
i = insert(i, value_type(k, move(T())));
|
||||
return (*i).second;
|
||||
}
|
||||
#else
|
||||
//! Effects: If there is no key equivalent to x in the flat_map, inserts
|
||||
//! value_type(x, T()) into the flat_map.
|
||||
//!
|
||||
//! Returns: A reference to the mapped_type corresponding to x in *this.
|
||||
//!
|
||||
//! Complexity: Logarithmic.
|
||||
T &operator[](key_type &&mk)
|
||||
{
|
||||
key_type &k = mk;
|
||||
iterator i = lower_bound(k);
|
||||
// i->first is greater than or equivalent to k.
|
||||
if (i == end() || key_comp()(k, (*i).first))
|
||||
i = insert(i, value_type(forward<key_type>(k), move(T())));
|
||||
return (*i).second;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Swaps the contents of *this and x.
|
||||
//! If this->allocator_type() != x.allocator_type() allocators are also swapped.
|
||||
@@ -335,8 +370,13 @@ class flat_map
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<flat_map<Key,T,Pred,Alloc> >& x)
|
||||
{ m_flat_tree.swap(x.get().m_flat_tree); }
|
||||
#else
|
||||
void swap(flat_map<Key,T,Pred,Alloc> && x)
|
||||
{ m_flat_tree.swap(x.m_flat_tree); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
|
||||
//! with key equivalent to the key of x.
|
||||
@@ -364,9 +404,15 @@ class flat_map
|
||||
//! to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
|
||||
{ return force<std::pair<iterator,bool> >(
|
||||
m_flat_tree.insert_unique(force<impl_moved_value_type>(x))); }
|
||||
#else
|
||||
std::pair<iterator,bool> insert(value_type &&x)
|
||||
{ return force<std::pair<iterator,bool> >(
|
||||
m_flat_tree.insert_unique(force<impl_moved_value_type>(move(x)))); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
|
||||
//! no element in the container with key equivalent to the key of x.
|
||||
@@ -392,9 +438,15 @@ class flat_map
|
||||
//! right before p) plus insertion linear to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<value_type>& x)
|
||||
{ return force<iterator>(
|
||||
m_flat_tree.insert_unique(force<impl_iterator>(position), force<impl_moved_value_type>(x))); }
|
||||
#else
|
||||
iterator insert(iterator position, value_type &&x)
|
||||
{ return force<iterator>(
|
||||
m_flat_tree.insert_unique(force<impl_iterator>(position), force<impl_moved_value_type>(move(x)))); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -571,6 +623,7 @@ inline bool operator>=(const flat_map<Key,T,Pred,Alloc>& x,
|
||||
const flat_map<Key,T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(flat_map<Key,T,Pred,Alloc>& x,
|
||||
flat_map<Key,T,Pred,Alloc>& y)
|
||||
@@ -585,6 +638,12 @@ template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(flat_map<Key,T,Pred,Alloc>& x,
|
||||
const detail::moved_object<flat_map<Key,T,Pred,Alloc> >& y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(flat_map<Key,T,Pred,Alloc>&&x,
|
||||
flat_map<Key,T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
//!This class is movable
|
||||
@@ -641,14 +700,14 @@ class flat_multimap
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef detail::flat_tree<Key,
|
||||
detail::pair<Key, T>,
|
||||
detail::select1st< detail::pair<Key, T> >,
|
||||
select1st< detail::pair<Key, T> >,
|
||||
Pred,
|
||||
typename boost::detail::allocator::
|
||||
rebind_to<Alloc, detail::pair<Key, T> >::type> impl_tree_t;
|
||||
typename Alloc::template
|
||||
rebind<detail::pair<Key, T> >::other> impl_tree_t;
|
||||
|
||||
typedef detail::flat_tree<Key,
|
||||
std::pair<Key, T>,
|
||||
detail::select1st< std::pair<Key, T> >,
|
||||
select1st< std::pair<Key, T> >,
|
||||
Pred,
|
||||
Alloc> tree_t;
|
||||
// tree_t m_flat_tree; // flat tree representing flat_multimap
|
||||
@@ -665,15 +724,21 @@ class flat_multimap
|
||||
typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
|
||||
typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
|
||||
typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
typedef detail::moved_object<impl_value_type> impl_moved_value_type;
|
||||
/*
|
||||
template<class D, class S>
|
||||
static D &force(S &s)
|
||||
{ return *(reinterpret_cast<D*>(&s)); }
|
||||
*/
|
||||
#else
|
||||
typedef impl_value_type&& impl_moved_value_type;
|
||||
#endif
|
||||
|
||||
template<class D, class S>
|
||||
static D &force(const S &s)
|
||||
{ return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class D, class S>
|
||||
static D &&force(S &&s)
|
||||
{ return reinterpret_cast<D&&>(s); }
|
||||
#endif
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
@@ -726,8 +791,13 @@ class flat_multimap
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_multimap(const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> >& x)
|
||||
: m_flat_tree(move(x.get().m_flat_tree)) { }
|
||||
#else
|
||||
flat_multimap(flat_multimap<Key,T,Pred,Alloc> && x)
|
||||
: m_flat_tree(move(x.m_flat_tree)) { }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -739,9 +809,15 @@ class flat_multimap
|
||||
//! <b>Effects</b>: this->swap(x.get()).
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_multimap<Key,T,Pred,Alloc>&
|
||||
operator=(const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> >& mx)
|
||||
{ m_flat_tree = move(mx.get().m_flat_tree); return *this; }
|
||||
#else
|
||||
flat_multimap<Key,T,Pred,Alloc>&
|
||||
operator=(flat_multimap<Key,T,Pred,Alloc> && mx)
|
||||
{ m_flat_tree = move(mx.m_flat_tree); return *this; }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
@@ -871,8 +947,13 @@ class flat_multimap
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> >& x)
|
||||
{ m_flat_tree.swap(x.get().m_flat_tree); }
|
||||
#else
|
||||
void swap(flat_multimap<Key,T,Pred,Alloc> && x)
|
||||
{ m_flat_tree.swap(x.m_flat_tree); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
|
||||
//! newly inserted element.
|
||||
@@ -891,8 +972,13 @@ class flat_multimap
|
||||
//! to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(const detail::moved_object<value_type>& x)
|
||||
{ return force<iterator>(m_flat_tree.insert_equal(force<impl_moved_value_type>(x))); }
|
||||
#else
|
||||
iterator insert(value_type &&x)
|
||||
{ return force<iterator>(m_flat_tree.insert_equal(force<impl_moved_value_type>(move(x)))); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container.
|
||||
//! p is a hint pointing to where the insert should start to search.
|
||||
@@ -919,8 +1005,13 @@ class flat_multimap
|
||||
//! to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<value_type>& x)
|
||||
{ return force<iterator>(m_flat_tree.insert_equal(force<impl_iterator>(position), force<impl_moved_value_type>(x))); }
|
||||
#else
|
||||
iterator insert(iterator position, value_type &&x)
|
||||
{ return force<iterator>(m_flat_tree.insert_equal(force<impl_iterator>(position), force<impl_moved_value_type>(move(x)))); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -1098,6 +1189,7 @@ inline bool operator>=(const flat_multimap<Key,T,Pred,Alloc>& x,
|
||||
const flat_multimap<Key,T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(flat_multimap<Key,T,Pred,Alloc>& x,
|
||||
flat_multimap<Key,T,Pred,Alloc>& y)
|
||||
@@ -1113,6 +1205,12 @@ template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(flat_multimap<Key,T,Pred,Alloc>& x,
|
||||
const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > & y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(flat_multimap<Key,T,Pred,Alloc>&&x,
|
||||
flat_multimap<Key,T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
//!This class is movable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <boost/interprocess/containers/detail/flat_tree.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
|
||||
|
||||
@@ -60,7 +61,7 @@ class flat_set
|
||||
/// @cond
|
||||
private:
|
||||
typedef detail::flat_tree<T, T,
|
||||
detail::identity<T>, Pred, Alloc> tree_t;
|
||||
identity<T>, Pred, Alloc> tree_t;
|
||||
tree_t m_flat_tree; // flat tree representing flat_set
|
||||
/// @endcond
|
||||
|
||||
@@ -114,8 +115,13 @@ class flat_set
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_set(const detail::moved_object<flat_set<T,Pred,Alloc> >& mx)
|
||||
: m_flat_tree(move(mx.get().m_flat_tree)) {}
|
||||
#else
|
||||
flat_set(flat_set<T,Pred,Alloc> && mx)
|
||||
: m_flat_tree(move(mx.m_flat_tree)) {}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -126,9 +132,16 @@ class flat_set
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_set<T,Pred,Alloc>& operator=(const detail::moved_object<flat_set<T, Pred, Alloc> > &mx)
|
||||
{ m_flat_tree = move(mx.get().m_flat_tree); return *this; }
|
||||
|
||||
#else
|
||||
flat_set<T,Pred,Alloc>& operator=(flat_set<T, Pred, Alloc> &&mx)
|
||||
{ m_flat_tree = move(mx.m_flat_tree); return *this; }
|
||||
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
//!
|
||||
@@ -257,8 +270,13 @@ class flat_set
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object <flat_set<T,Pred,Alloc> >& mx)
|
||||
{ this->swap(mx.get()); }
|
||||
#else
|
||||
void swap(flat_set<T,Pred,Alloc> && mx)
|
||||
{ this->swap(mx); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
|
||||
//! with key equivalent to the key of x.
|
||||
@@ -285,8 +303,13 @@ class flat_set
|
||||
//! to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
|
||||
{ return m_flat_tree.insert_unique(x); }
|
||||
#else
|
||||
std::pair<iterator,bool> insert(value_type && x)
|
||||
{ return m_flat_tree.insert_unique(move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
|
||||
//! no element in the container with key equivalent to the key of x.
|
||||
@@ -311,8 +334,13 @@ class flat_set
|
||||
//! right before p) plus insertion linear to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<value_type>& x)
|
||||
{ return m_flat_tree.insert_unique(position, x); }
|
||||
#else
|
||||
iterator insert(iterator position, value_type && x)
|
||||
{ return m_flat_tree.insert_unique(position, move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -490,6 +518,7 @@ inline bool operator>=(const flat_set<T,Pred,Alloc>& x,
|
||||
const flat_set<T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(flat_set<T,Pred,Alloc>& x,
|
||||
flat_set<T,Pred,Alloc>& y)
|
||||
@@ -504,6 +533,12 @@ template <class T, class Pred, class Alloc>
|
||||
inline void swap(flat_set<T,Pred,Alloc>& x,
|
||||
const detail::moved_object<flat_set<T,Pred,Alloc> >& y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(flat_set<T,Pred,Alloc>&&x,
|
||||
flat_set<T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
@@ -543,7 +578,7 @@ class flat_multiset
|
||||
/// @cond
|
||||
private:
|
||||
typedef detail::flat_tree<T, T,
|
||||
detail::identity<T>, Pred, Alloc> tree_t;
|
||||
identity<T>, Pred, Alloc> tree_t;
|
||||
tree_t m_flat_tree; // flat tree representing flat_multiset
|
||||
/// @endcond
|
||||
|
||||
@@ -580,14 +615,24 @@ class flat_multiset
|
||||
flat_multiset(const flat_multiset<T,Pred,Alloc>& x)
|
||||
: m_flat_tree(x.m_flat_tree) {}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_multiset(const detail::moved_object<flat_multiset<T,Pred,Alloc> >& x)
|
||||
: m_flat_tree(move(x.get().m_flat_tree)) {}
|
||||
#else
|
||||
flat_multiset(flat_multiset<T,Pred,Alloc> && x)
|
||||
: m_flat_tree(move(x.m_flat_tree)) {}
|
||||
#endif
|
||||
|
||||
flat_multiset<T,Pred,Alloc>& operator=(const flat_multiset<T,Pred,Alloc>& x)
|
||||
{ m_flat_tree = x.m_flat_tree; return *this; }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
flat_multiset<T,Pred,Alloc>& operator=(const detail::moved_object<flat_multiset<T,Pred,Alloc> >& mx)
|
||||
{ m_flat_tree = move(mx.get().m_flat_tree); return *this; }
|
||||
#else
|
||||
flat_multiset<T,Pred,Alloc>& operator=(flat_multiset<T,Pred,Alloc> && mx)
|
||||
{ m_flat_tree = move(mx.m_flat_tree); return *this; }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
@@ -717,8 +762,13 @@ class flat_multiset
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<flat_multiset<T,Pred,Alloc> >& mx)
|
||||
{ this->swap(mx.get()); }
|
||||
#else
|
||||
void swap(flat_multiset<T,Pred,Alloc> && mx)
|
||||
{ this->swap(mx); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
|
||||
//! newly inserted element.
|
||||
@@ -737,8 +787,13 @@ class flat_multiset
|
||||
//! to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(const detail::moved_object<value_type>& x)
|
||||
{ return m_flat_tree.insert_equal(x); }
|
||||
#else
|
||||
iterator insert(value_type && x)
|
||||
{ return m_flat_tree.insert_equal(move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container.
|
||||
//! p is a hint pointing to where the insert should start to search.
|
||||
@@ -763,8 +818,13 @@ class flat_multiset
|
||||
//! right before p) plus insertion linear to the elements with bigger keys than x.
|
||||
//!
|
||||
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<value_type>& x)
|
||||
{ return m_flat_tree.insert_equal(position, x); }
|
||||
#else
|
||||
iterator insert(iterator position, value_type && x)
|
||||
{ return m_flat_tree.insert_equal(position, move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -942,6 +1002,7 @@ inline bool operator>=(const flat_multiset<T,Pred,Alloc>& x,
|
||||
const flat_multiset<T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(flat_multiset<T,Pred,Alloc>& x,
|
||||
flat_multiset<T,Pred,Alloc>& y)
|
||||
@@ -956,6 +1017,12 @@ template <class T, class Pred, class Alloc>
|
||||
inline void swap(flat_multiset<T,Pred,Alloc>& x,
|
||||
const detail::moved_object<flat_multiset<T,Pred,Alloc> >& y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(flat_multiset<T,Pred,Alloc>&&x,
|
||||
flat_multiset<T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
|
||||
@@ -55,17 +55,10 @@
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
@@ -91,54 +84,66 @@ struct list_node
|
||||
, boost::intrusive::safe_link
|
||||
, VoidPointer> IlistData;
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
list_node(const Convertible &conv)
|
||||
: m_data(conv)
|
||||
{}
|
||||
#else
|
||||
template<class Convertible>
|
||||
list_node(Convertible &&conv)
|
||||
: m_data(forward<Convertible>(conv))
|
||||
{}
|
||||
#endif
|
||||
|
||||
T m_data;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct list_alloc
|
||||
: public boost::detail::allocator::
|
||||
rebind_to<A, list_node
|
||||
<typename A::value_type, typename boost::detail::allocator::
|
||||
rebind_to<A, void>::type::pointer>
|
||||
>::type
|
||||
: public A::template rebind<list_node
|
||||
< typename A::value_type
|
||||
, typename detail::pointer_to_other<typename A::pointer, void>::type>
|
||||
>::other
|
||||
{
|
||||
typedef list_alloc<A> self_t;
|
||||
typedef typename A::value_type value_type;
|
||||
typedef list_node
|
||||
<value_type, typename boost::detail::allocator::
|
||||
rebind_to<A, void>::type::pointer> Node;
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<A, Node>::type NodeAlloc;
|
||||
<typename A::value_type
|
||||
,typename detail::pointer_to_other
|
||||
<typename A::pointer, void>::type> Node;
|
||||
typedef typename A::template rebind<Node>::other NodeAlloc;
|
||||
typedef A ValAlloc;
|
||||
typedef typename NodeAlloc::pointer NodePtr;
|
||||
typedef detail::scoped_deallocator<NodeAlloc> Deallocator;
|
||||
|
||||
enum {
|
||||
node_has_trivial_destructor =
|
||||
boost::has_trivial_destructor<NodePtr>::value &&
|
||||
boost::has_trivial_destructor<value_type>::value
|
||||
};
|
||||
|
||||
list_alloc(const ValAlloc &a)
|
||||
: NodeAlloc(a)
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
list_alloc(const detail::moved_object<ValAlloc> &a)
|
||||
: NodeAlloc(a.get())
|
||||
{}
|
||||
#else
|
||||
list_alloc(ValAlloc &&a)
|
||||
: NodeAlloc(a)
|
||||
{}
|
||||
#endif
|
||||
|
||||
list_alloc(const list_alloc &other)
|
||||
: NodeAlloc(other)
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
list_alloc(const detail::moved_object<list_alloc> &other)
|
||||
: NodeAlloc(move((NodeAlloc&)other.get()))
|
||||
{ this->swap(other.get()); }
|
||||
#else
|
||||
list_alloc(list_alloc &&other)
|
||||
: NodeAlloc(move((NodeAlloc&)other))
|
||||
{ this->swap(other); }
|
||||
#endif
|
||||
|
||||
~list_alloc()
|
||||
{}
|
||||
@@ -146,28 +151,44 @@ struct list_alloc
|
||||
typename NodeAlloc::size_type max_size() const
|
||||
{ return NodeAlloc::max_size(); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
static void construct(const NodePtr &ptr, const Convertible &value)
|
||||
{ new(detail::get_pointer(ptr)) Node(value); }
|
||||
#else
|
||||
template<class Convertible>
|
||||
static void construct(const NodePtr &ptr, Convertible &&value)
|
||||
{ new(detail::get_pointer(ptr)) Node(forward<Convertible>(value)); }
|
||||
#endif
|
||||
|
||||
static void destroy(const NodePtr &ptr)
|
||||
{ detail::get_pointer(ptr)->~Node(); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
NodePtr create_node(const Convertible& x)
|
||||
{
|
||||
NodePtr p = NodeAlloc::allocate(1);
|
||||
scoped_ptr<Node, Deallocator>node_deallocator(p, *this);
|
||||
Deallocator node_deallocator(p, *this);
|
||||
self_t::construct(p, x);
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
#else
|
||||
template<class Convertible>
|
||||
NodePtr create_node(Convertible &&x)
|
||||
{
|
||||
NodePtr p = NodeAlloc::allocate(1);
|
||||
Deallocator node_deallocator(p, *this);
|
||||
self_t::construct(p, forward<Convertible>(x));
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
#endif
|
||||
|
||||
void destroy_node(NodePtr node)
|
||||
{
|
||||
if(!node_has_trivial_destructor){
|
||||
self_t::destroy(node);
|
||||
}
|
||||
self_t::destroy(node);
|
||||
NodeAlloc::deallocate(node, 1);
|
||||
}
|
||||
|
||||
@@ -433,9 +454,15 @@ class list
|
||||
//! <b>Throws</b>: If allocator_type's default constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
list(const detail::moved_object<list> &x)
|
||||
: AllocHolder(move((AllocHolder&)x.get()))
|
||||
{}
|
||||
#else
|
||||
list(list &&x)
|
||||
: AllocHolder(move((AllocHolder&)x))
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
||||
//! and inserts a copy of the range [first, last) in the list.
|
||||
@@ -581,8 +608,13 @@ class list
|
||||
//! <b>Throws</b>: If memory allocation throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void push_front(const detail::moved_object<T>& x)
|
||||
{ this->insert(this->begin(), x); }
|
||||
#else
|
||||
void push_front(T &&x)
|
||||
{ this->insert(this->begin(), move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Removes the last element from the list.
|
||||
//!
|
||||
@@ -597,8 +629,13 @@ class list
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void push_back (const detail::moved_object<T>& x)
|
||||
{ this->insert(this->end(), x); }
|
||||
#else
|
||||
void push_back (T &&x)
|
||||
{ this->insert(this->end(), move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Removes the first element from the list.
|
||||
//!
|
||||
@@ -758,12 +795,21 @@ class list
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
ThisType& operator=(const detail::moved_object<ThisType>& mx)
|
||||
{
|
||||
this->clear();
|
||||
this->swap(mx.get());
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
ThisType& operator=(ThisType &&mx)
|
||||
{
|
||||
this->clear();
|
||||
this->swap(mx);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: p must be a valid iterator of *this.
|
||||
//!
|
||||
@@ -787,7 +833,7 @@ class list
|
||||
void insert(iterator p, InpIt first, InpIt last)
|
||||
{
|
||||
const bool aux_boolean = boost::is_integral<InpIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_insert_dispatch(p, first, last, Result());
|
||||
}
|
||||
|
||||
@@ -811,11 +857,19 @@ class list
|
||||
//! <b>Throws</b>: If memory allocation throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator p, const detail::moved_object<T>& x)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(x);
|
||||
return iterator(this->m_ilist.insert(p.get(), *tmp));
|
||||
}
|
||||
#else
|
||||
iterator insert(iterator p, T &&x)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(move(x));
|
||||
return iterator(this->m_ilist.insert(p.get(), *tmp));
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: p must be a valid iterator of *this.
|
||||
//!
|
||||
@@ -855,7 +909,7 @@ class list
|
||||
void assign(InpIt first, InpIt last)
|
||||
{
|
||||
const bool aux_boolean = boost::is_integral<InpIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_assign_dispatch(first, last, Result());
|
||||
}
|
||||
|
||||
@@ -1143,7 +1197,7 @@ class list
|
||||
template <class InputIter>
|
||||
void priv_insert_dispatch(iterator p,
|
||||
InputIter first, InputIter last,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
for ( ; first != last; ++first){
|
||||
this->insert(p, *first);
|
||||
@@ -1151,7 +1205,7 @@ class list
|
||||
}
|
||||
|
||||
template<class Integer>
|
||||
void priv_insert_dispatch(iterator p, Integer n, Integer x, boost::mpl::true_)
|
||||
void priv_insert_dispatch(iterator p, Integer n, Integer x, true_)
|
||||
{ this->priv_fill_insert(p, n, x); }
|
||||
|
||||
void priv_fill_assign(size_type n, const T& val)
|
||||
@@ -1167,12 +1221,12 @@ class list
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void priv_assign_dispatch(Integer n, Integer val, boost::mpl::true_)
|
||||
void priv_assign_dispatch(Integer n, Integer val, true_)
|
||||
{ this->priv_fill_assign((size_type) n, (T) val); }
|
||||
|
||||
template <class InputIter>
|
||||
void priv_assign_dispatch(InputIter first2, InputIter last2,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
iterator first1 = this->begin();
|
||||
iterator last1 = this->end();
|
||||
@@ -1248,6 +1302,7 @@ inline bool operator>=(const list<T,A>& x, const list<T,A>& y)
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T, class A>
|
||||
inline void swap(list<T, A>& x, list<T, A>& y)
|
||||
{
|
||||
@@ -1265,6 +1320,14 @@ inline void swap(list<T, A>& x, const detail::moved_object<list<T, A> >& y)
|
||||
{
|
||||
x.swap(y.get());
|
||||
}
|
||||
#else
|
||||
template <class T, class A>
|
||||
inline void swap(list<T, A> &&x, list<T, A> &&y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gazta<EFBFBD>ga 2005-2007. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <boost/interprocess/containers/detail/tree.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
|
||||
namespace boost { namespace interprocess {
|
||||
@@ -89,7 +90,7 @@ class map
|
||||
private:
|
||||
typedef detail::rbtree<Key,
|
||||
std::pair<const Key, T>,
|
||||
detail::select1st< std::pair<const Key, T> >,
|
||||
select1st< std::pair<const Key, T> >,
|
||||
Pred,
|
||||
Alloc> tree_t;
|
||||
tree_t m_tree; // red-black tree representing map
|
||||
@@ -161,9 +162,15 @@ class map
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
map(const detail::moved_object<map<Key,T,Pred,Alloc> >& x)
|
||||
: m_tree(move(x.get().m_tree))
|
||||
{}
|
||||
#else
|
||||
map(map<Key,T,Pred,Alloc> &&x)
|
||||
: m_tree(move(x.m_tree))
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -174,8 +181,13 @@ class map
|
||||
//! <b>Effects</b>: this->swap(x.get()).
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
map<Key,T,Pred,Alloc>& operator=(const detail::moved_object<map<Key,T,Pred,Alloc> >& x)
|
||||
{ m_tree = move(x.get().m_tree); return *this; }
|
||||
#else
|
||||
map<Key,T,Pred,Alloc>& operator=(map<Key,T,Pred,Alloc> &&x)
|
||||
{ m_tree = move(x.m_tree); return *this; }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
@@ -314,6 +326,7 @@ class map
|
||||
//! Returns: A reference to the mapped_type corresponding to x in *this.
|
||||
//!
|
||||
//! Complexity: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
T& operator[](const detail::moved_object<key_type>& mk)
|
||||
{
|
||||
key_type &k = mk.get();
|
||||
@@ -326,6 +339,21 @@ class map
|
||||
}
|
||||
return (*i).second;
|
||||
}
|
||||
#else
|
||||
T& operator[](key_type &&mk)
|
||||
{
|
||||
key_type &k = mk;
|
||||
//we can optimize this
|
||||
iterator i = lower_bound(k);
|
||||
// i->first is greater than or equivalent to k.
|
||||
if (i == end() || key_comp()(k, (*i).first)){
|
||||
value_type val(move(k), move(T()));
|
||||
i = insert(i, move(val));
|
||||
}
|
||||
return (*i).second;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
//! Effects: If there is no key equivalent to x in the map, inserts
|
||||
//! value_type(move(x), T()) into the map (the key is move-constructed)
|
||||
@@ -370,8 +398,13 @@ class map
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<map<Key,T,Pred,Alloc> >& x)
|
||||
{ m_tree.swap(x.get().m_tree); }
|
||||
#else
|
||||
void swap(map<Key,T,Pred,Alloc> &&x)
|
||||
{ m_tree.swap(x.m_tree); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
|
||||
//! with key equivalent to the key of x.
|
||||
@@ -403,8 +436,13 @@ class map
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
std::pair<iterator,bool> insert(const detail::moved_object<std::pair<key_type, mapped_type> > &x)
|
||||
{ return m_tree.insert_unique(x); }
|
||||
#else
|
||||
std::pair<iterator,bool> insert(std::pair<key_type, mapped_type> &&x)
|
||||
{ return m_tree.insert_unique(move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Move constructs a new value from x if and only if there is
|
||||
//! no element in the container with key equivalent to the key of x.
|
||||
@@ -414,8 +452,13 @@ class map
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
|
||||
{ return m_tree.insert_unique(x); }
|
||||
#else
|
||||
std::pair<iterator,bool> insert(value_type &&x)
|
||||
{ return m_tree.insert_unique(move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
|
||||
//! no element in the container with key equivalent to the key of x.
|
||||
@@ -438,8 +481,13 @@ class map
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<std::pair<key_type, mapped_type> > &x)
|
||||
{ return m_tree.insert_unique(position, x); }
|
||||
#else
|
||||
iterator insert(iterator position, std::pair<key_type, mapped_type> &&x)
|
||||
{ return m_tree.insert_unique(position, move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container.
|
||||
//! p is a hint pointing to where the insert should start to search.
|
||||
@@ -456,8 +504,13 @@ class map
|
||||
//! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<value_type>& x)
|
||||
{ return m_tree.insert_unique(position, x); }
|
||||
#else
|
||||
iterator insert(iterator position, value_type &&x)
|
||||
{ return m_tree.insert_unique(position, move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -603,6 +656,7 @@ inline bool operator>=(const map<Key,T,Pred,Alloc>& x,
|
||||
const map<Key,T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(map<Key,T,Pred,Alloc>& x,
|
||||
map<Key,T,Pred,Alloc>& y)
|
||||
@@ -617,6 +671,15 @@ template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(map<Key,T,Pred,Alloc>& x,
|
||||
const detail::moved_object<map<Key,T,Pred,Alloc> >& y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(map<Key,T,Pred,Alloc>&&x,
|
||||
map<Key,T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
@@ -667,7 +730,7 @@ class multimap
|
||||
private:
|
||||
typedef detail::rbtree<Key,
|
||||
std::pair<const Key, T>,
|
||||
detail::select1st< std::pair<const Key, T> >,
|
||||
select1st< std::pair<const Key, T> >,
|
||||
Pred,
|
||||
Alloc> tree_t;
|
||||
tree_t m_tree; // red-black tree representing map
|
||||
@@ -740,9 +803,15 @@ class multimap
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
multimap(const detail::moved_object<multimap<Key,T,Pred,Alloc> >& x)
|
||||
: m_tree(move(x.get().m_tree))
|
||||
{}
|
||||
#else
|
||||
multimap(multimap<Key,T,Pred,Alloc> && x)
|
||||
: m_tree(move(x.m_tree))
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -754,9 +823,15 @@ class multimap
|
||||
//! <b>Effects</b>: this->swap(x.get()).
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
multimap<Key,T,Pred,Alloc>&
|
||||
operator=(const detail::moved_object<multimap<Key,T,Pred,Alloc> >& x)
|
||||
{ m_tree = move(x.get().m_tree); return *this; }
|
||||
#else
|
||||
multimap<Key,T,Pred,Alloc>&
|
||||
operator=(multimap<Key,T,Pred,Alloc> && x)
|
||||
{ m_tree = move(x.m_tree); return *this; }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
@@ -886,8 +961,13 @@ class multimap
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<multimap<Key,T,Pred,Alloc> >& x)
|
||||
{ m_tree.swap(x.get().m_tree); }
|
||||
#else
|
||||
void swap(multimap<Key,T,Pred,Alloc> && x)
|
||||
{ m_tree.swap(x.m_tree); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
|
||||
//! newly inserted element.
|
||||
@@ -907,8 +987,13 @@ class multimap
|
||||
//! the iterator pointing to the newly inserted element.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(const detail::moved_object<std::pair<key_type, mapped_type> >& x)
|
||||
{ return m_tree.insert_equal(x); }
|
||||
#else
|
||||
iterator insert(std::pair<key_type, mapped_type> && x)
|
||||
{ return m_tree.insert_equal(move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container.
|
||||
//! p is a hint pointing to where the insert should start to search.
|
||||
@@ -940,8 +1025,13 @@ class multimap
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<std::pair<key_type, mapped_type> >& x)
|
||||
{ return m_tree.insert_equal(position, x); }
|
||||
#else
|
||||
iterator insert(iterator position, std::pair<key_type, mapped_type> && x)
|
||||
{ return m_tree.insert_equal(position, move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -1088,6 +1178,8 @@ inline bool operator>=(const multimap<Key,T,Pred,Alloc>& x,
|
||||
const multimap<Key,T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(multimap<Key,T,Pred,Alloc>& x,
|
||||
multimap<Key,T,Pred,Alloc>& y)
|
||||
@@ -1102,6 +1194,12 @@ template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(multimap<Key,T,Pred,Alloc>& x,
|
||||
const detail::moved_object<multimap<Key,T,Pred,Alloc> >& y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class Key, class T, class Pred, class Alloc>
|
||||
inline void swap(multimap<Key,T,Pred,Alloc>&&x,
|
||||
multimap<Key,T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
template <class T, class P, class A>
|
||||
|
||||
@@ -49,15 +49,17 @@
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/containers/detail/tree.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
@@ -84,7 +86,7 @@ class set
|
||||
/// @cond
|
||||
private:
|
||||
typedef detail::rbtree<T, T,
|
||||
detail::identity<T>, Pred, Alloc> tree_t;
|
||||
identity<T>, Pred, Alloc> tree_t;
|
||||
tree_t m_tree; // red-black tree representing set
|
||||
/// @endcond
|
||||
|
||||
@@ -138,9 +140,15 @@ class set
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
set(const detail::moved_object<set<T,Pred,Alloc> >& x)
|
||||
: m_tree(move(x.get().m_tree))
|
||||
{}
|
||||
#else
|
||||
set(set<T,Pred,Alloc> &&x)
|
||||
: m_tree(move(x.m_tree))
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -151,8 +159,13 @@ class set
|
||||
//! <b>Effects</b>: this->swap(x.get()).
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
set<T,Pred,Alloc>& operator=(const detail::moved_object<set<T, Pred, Alloc> >& x)
|
||||
{ m_tree = move(x.get().m_tree); return *this; }
|
||||
#else
|
||||
set<T,Pred,Alloc>& operator=(set<T, Pred, Alloc> &&x)
|
||||
{ m_tree = move(x.m_tree); return *this; }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
@@ -282,8 +295,13 @@ class set
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<set<T,Pred,Alloc> >& x)
|
||||
{ m_tree.swap(x.get().m_tree); }
|
||||
#else
|
||||
void swap(set<T,Pred,Alloc> &&x)
|
||||
{ m_tree.swap(x.m_tree); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
|
||||
//! with key equivalent to the key of x.
|
||||
@@ -304,8 +322,13 @@ class set
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
|
||||
{ return m_tree.insert_unique(x); }
|
||||
#else
|
||||
std::pair<iterator,bool> insert(value_type &&x)
|
||||
{ return m_tree.insert_unique(move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
|
||||
//! no element in the container with key equivalent to the key of x.
|
||||
@@ -325,8 +348,13 @@ class set
|
||||
//! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(const_iterator p, const detail::moved_object<value_type>& x)
|
||||
{ return m_tree.insert_unique(p, x); }
|
||||
#else
|
||||
iterator insert(const_iterator p, value_type &&x)
|
||||
{ return m_tree.insert_unique(p, move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -473,6 +501,7 @@ inline bool operator>=(const set<T,Pred,Alloc>& x,
|
||||
const set<T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(set<T,Pred,Alloc>& x,
|
||||
set<T,Pred,Alloc>& y)
|
||||
@@ -488,6 +517,13 @@ inline void swap(detail::moved_object<set<T,Pred,Alloc> >& y,
|
||||
set<T,Pred,Alloc>& x)
|
||||
{ y.swap(x.get()); }
|
||||
|
||||
#else
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(set<T,Pred,Alloc>&&x,
|
||||
set<T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
template <class T, class P, class A>
|
||||
@@ -530,7 +566,7 @@ class multiset
|
||||
/// @cond
|
||||
private:
|
||||
typedef detail::rbtree<T, T,
|
||||
detail::identity<T>, Pred, Alloc> tree_t;
|
||||
identity<T>, Pred, Alloc> tree_t;
|
||||
tree_t m_tree; // red-black tree representing multiset
|
||||
/// @endcond
|
||||
|
||||
@@ -585,9 +621,15 @@ class multiset
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
multiset(const detail::moved_object<multiset<T,Pred,Alloc> >& x)
|
||||
: m_tree(move(x.get().m_tree))
|
||||
{}
|
||||
#else
|
||||
multiset(multiset<T,Pred,Alloc> &&x)
|
||||
: m_tree(move(x.m_tree))
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
@@ -598,8 +640,13 @@ class multiset
|
||||
//! <b>Effects</b>: this->swap(x.get()).
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
multiset<T,Pred,Alloc>& operator=(const detail::moved_object<multiset<T,Pred,Alloc> >& x)
|
||||
{ m_tree = move(x.get().m_tree); return *this; }
|
||||
#else
|
||||
multiset<T,Pred,Alloc>& operator=(multiset<T,Pred,Alloc> &&x)
|
||||
{ m_tree = move(x.m_tree); return *this; }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
//! of which a was constructed.
|
||||
@@ -729,8 +776,13 @@ class multiset
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<multiset<T,Pred,Alloc> >& x)
|
||||
{ m_tree.swap(x.get().m_tree); }
|
||||
#else
|
||||
void swap(multiset<T,Pred,Alloc> && x)
|
||||
{ m_tree.swap(x.m_tree); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
|
||||
//! newly inserted element.
|
||||
@@ -746,8 +798,13 @@ class multiset
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(const detail::moved_object<value_type>& x)
|
||||
{ return m_tree.insert_equal(x); }
|
||||
#else
|
||||
iterator insert(value_type && x)
|
||||
{ return m_tree.insert_equal(move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container.
|
||||
//! p is a hint pointing to where the insert should start to search.
|
||||
@@ -768,8 +825,13 @@ class multiset
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(const_iterator p, const detail::moved_object<value_type>& x)
|
||||
{ return m_tree.insert_equal(p, x); }
|
||||
#else
|
||||
iterator insert(const_iterator p, value_type && x)
|
||||
{ return m_tree.insert_equal(p, move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: i, j are not iterators into *this.
|
||||
//!
|
||||
@@ -916,6 +978,7 @@ inline bool operator>=(const multiset<T,Pred,Alloc>& x,
|
||||
const multiset<T,Pred,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(multiset<T,Pred,Alloc>& x,
|
||||
multiset<T,Pred,Alloc>& y)
|
||||
@@ -930,6 +993,12 @@ template <class T, class Pred, class Alloc>
|
||||
inline void swap(detail::moved_object<multiset<T,Pred,Alloc> >& y,
|
||||
multiset<T,Pred,Alloc>& x)
|
||||
{ y.swap(x.get()); }
|
||||
#else
|
||||
template <class T, class Pred, class Alloc>
|
||||
inline void swap(multiset<T,Pred,Alloc>&&x,
|
||||
multiset<T,Pred,Alloc>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
|
||||
@@ -54,12 +54,12 @@
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
@@ -83,54 +83,65 @@ struct slist_node
|
||||
, boost::intrusive::safe_link
|
||||
, VoidPointer> IslistData;
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
slist_node(const Convertible &value)
|
||||
: m_data(value){}
|
||||
#else
|
||||
template<class Convertible>
|
||||
slist_node(Convertible &&value)
|
||||
: m_data(forward<Convertible>(value)){}
|
||||
#endif
|
||||
|
||||
T m_data;
|
||||
};
|
||||
|
||||
template<class A>
|
||||
struct slist_alloc
|
||||
: public boost::detail::allocator::
|
||||
rebind_to<A, slist_node
|
||||
<typename A::value_type, typename boost::detail::allocator::
|
||||
rebind_to<A, void>::type::pointer>
|
||||
>::type
|
||||
: public A::template rebind<slist_node
|
||||
< typename A::value_type
|
||||
, typename detail::pointer_to_other<typename A::pointer, void>::type>
|
||||
>::other
|
||||
{
|
||||
typedef slist_alloc<A> self_t;
|
||||
typedef typename A::value_type value_type;
|
||||
typedef slist_node
|
||||
<value_type, typename boost::detail::allocator::
|
||||
rebind_to<A, void>::type::pointer> Node;
|
||||
typedef typename boost::detail::allocator::
|
||||
rebind_to<A, Node>::type NodeAlloc;
|
||||
<typename A::value_type
|
||||
,typename detail::pointer_to_other
|
||||
<typename A::pointer, void>::type> Node;
|
||||
typedef typename A::template rebind<Node>::other NodeAlloc;
|
||||
typedef A ValAlloc;
|
||||
typedef typename A::size_type SizeType;
|
||||
typedef typename NodeAlloc::pointer NodePtr;
|
||||
typedef detail::scoped_deallocator<NodeAlloc> Deallocator;
|
||||
|
||||
enum {
|
||||
node_has_trivial_destructor =
|
||||
boost::has_trivial_destructor<NodePtr>::value &&
|
||||
boost::has_trivial_destructor<value_type>::value
|
||||
};
|
||||
|
||||
slist_alloc(const ValAlloc &a)
|
||||
: NodeAlloc(a)
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
slist_alloc(const detail::moved_object<ValAlloc> &a)
|
||||
: NodeAlloc(a.get())
|
||||
{}
|
||||
#else
|
||||
slist_alloc(ValAlloc&&a)
|
||||
: NodeAlloc(a)
|
||||
{}
|
||||
#endif
|
||||
|
||||
slist_alloc(const slist_alloc &other)
|
||||
: NodeAlloc(other)
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
slist_alloc(const detail::moved_object<slist_alloc> &other)
|
||||
: NodeAlloc(move((NodeAlloc&)other.get()))
|
||||
{ this->swap(other.get()); }
|
||||
#else
|
||||
slist_alloc(slist_alloc &&other)
|
||||
: NodeAlloc(move((NodeAlloc&)other))
|
||||
{ this->swap(other); }
|
||||
#endif
|
||||
|
||||
~slist_alloc()
|
||||
{}
|
||||
@@ -138,28 +149,44 @@ struct slist_alloc
|
||||
typename NodeAlloc::size_type max_size() const
|
||||
{ return NodeAlloc::max_size(); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
static void construct(const NodePtr &ptr, const Convertible &value)
|
||||
{ new(detail::get_pointer(ptr)) Node(value); }
|
||||
#else
|
||||
template<class Convertible>
|
||||
static void construct(const NodePtr &ptr, Convertible &&value)
|
||||
{ new(detail::get_pointer(ptr)) Node(forward<Convertible>(value)); }
|
||||
#endif
|
||||
|
||||
static void destroy(const NodePtr &ptr)
|
||||
{ detail::get_pointer(ptr)->~Node(); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template<class Convertible>
|
||||
NodePtr create_node(const Convertible& x)
|
||||
{
|
||||
NodePtr p = NodeAlloc::allocate(1);
|
||||
scoped_ptr<Node, Deallocator>node_deallocator(p, *this);
|
||||
Deallocator node_deallocator(p, *this);
|
||||
self_t::construct(p, x);
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
#else
|
||||
template<class Convertible>
|
||||
NodePtr create_node(Convertible &&x)
|
||||
{
|
||||
NodePtr p = NodeAlloc::allocate(1);
|
||||
Deallocator node_deallocator(p, *this);
|
||||
self_t::construct(p, forward<Convertible>(x));
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
#endif
|
||||
|
||||
void destroy_node(NodePtr node)
|
||||
{
|
||||
if(!node_has_trivial_destructor){
|
||||
self_t::destroy(node);
|
||||
}
|
||||
self_t::destroy(node);
|
||||
NodeAlloc::deallocate(node, 1);
|
||||
}
|
||||
|
||||
@@ -428,9 +455,15 @@ class slist
|
||||
//! <b>Throws</b>: If allocator_type's default constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
slist(const detail::moved_object<slist> &x)
|
||||
: AllocHolder(move((AllocHolder&)x.get()))
|
||||
{}
|
||||
#else
|
||||
slist(slist &&x)
|
||||
: AllocHolder(move((AllocHolder&)x))
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Makes *this contain the same elements as x.
|
||||
//!
|
||||
@@ -456,6 +489,7 @@ class slist
|
||||
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in x.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
slist& operator= (const detail::moved_object<slist>& mx)
|
||||
{
|
||||
if (&mx.get() != this){
|
||||
@@ -464,6 +498,16 @@ class slist
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
slist& operator= (slist && mx)
|
||||
{
|
||||
if (&mx != this){
|
||||
this->clear();
|
||||
this->swap(mx);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Destroys the list. All stored values are destroyed
|
||||
//! and used memory is deallocated.
|
||||
@@ -502,7 +546,7 @@ class slist
|
||||
void assign(InpIt first, InpIt last)
|
||||
{
|
||||
const bool aux_boolean = boost::is_integral<InpIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->assign_dispatch(first, last, Result());
|
||||
}
|
||||
|
||||
@@ -629,8 +673,13 @@ class slist
|
||||
//! <b>Throws</b>: If memory allocation throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void push_front(const detail::moved_object<T>& x)
|
||||
{ this->m_islist.push_front(*this->create_node(x)); }
|
||||
#else
|
||||
void push_front(T && x)
|
||||
{ this->m_islist.push_front(*this->create_node(move(x))); }
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Removes the first element from the list.
|
||||
//!
|
||||
@@ -689,8 +738,13 @@ class slist
|
||||
//!
|
||||
//! <b>Note</b>: Does not affect the validity of iterators and references of
|
||||
//! previous values.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert_after(iterator prev_pos, const detail::moved_object<value_type>& x)
|
||||
{ return iterator(this->m_islist.insert_after(prev_pos.get(), *this->create_node(x))); }
|
||||
#else
|
||||
iterator insert_after(iterator prev_pos, value_type && x)
|
||||
{ return iterator(this->m_islist.insert_after(prev_pos.get(), *this->create_node(move(x)))); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: prev_pos must be a valid iterator of *this.
|
||||
//!
|
||||
@@ -738,8 +792,13 @@ class slist
|
||||
//! <b>Throws</b>: If memory allocation throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the elements before p.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator p, const detail::moved_object<value_type>& x)
|
||||
{ return insert_after(previous(p), x); }
|
||||
#else
|
||||
iterator insert(iterator p, value_type && x)
|
||||
{ return insert_after(previous(p), move(x)); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: p must be a valid iterator of *this.
|
||||
//!
|
||||
@@ -1223,12 +1282,12 @@ class slist
|
||||
}
|
||||
|
||||
template <class Int>
|
||||
void assign_dispatch(Int n, Int val, boost::mpl::true_)
|
||||
void assign_dispatch(Int n, Int val, true_)
|
||||
{ this->fill_assign((size_type) n, (T)val); }
|
||||
|
||||
template <class InpIt>
|
||||
void assign_dispatch(InpIt first, InpIt last,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
iterator end_n(end());
|
||||
iterator prev(before_begin());
|
||||
@@ -1258,16 +1317,16 @@ class slist
|
||||
void insert_after_range(iterator prev_pos, InIter first, InIter last)
|
||||
{
|
||||
const bool aux_boolean = boost::is_integral<InIter>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->insert_after_range(prev_pos, first, last, Result());
|
||||
}
|
||||
|
||||
template <class Int>
|
||||
void insert_after_range(iterator prev_pos, Int n, Int x, boost::mpl::true_)
|
||||
void insert_after_range(iterator prev_pos, Int n, Int x, true_)
|
||||
{ this->priv_insert_after_fill(prev_pos, n, x); }
|
||||
|
||||
template <class InIter>
|
||||
void insert_after_range(iterator prev_pos, InIter first, InIter last, boost::mpl::false_)
|
||||
void insert_after_range(iterator prev_pos, InIter first, InIter last, false_)
|
||||
{
|
||||
typename Islist::iterator intrusive_it(prev_pos.get());
|
||||
while (first != last){
|
||||
@@ -1349,6 +1408,7 @@ inline bool
|
||||
operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2)
|
||||
{ return !(sL1 < sL2); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T, class A>
|
||||
inline void swap(slist<T,A>& x, slist<T,A>& y)
|
||||
{ x.swap(y); }
|
||||
@@ -1360,6 +1420,11 @@ inline void swap(const detail::moved_object<slist<T,A> >& x, slist<T,A>& y)
|
||||
template <class T, class A>
|
||||
inline void swap(slist<T,A>& x, const detail::moved_object<slist<T,A> >& y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class T, class A>
|
||||
inline void swap(slist<T,A>&&x, slist<T,A>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
|
||||
@@ -30,15 +30,18 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/algorithms.hpp>
|
||||
#include <boost/interprocess/detail/min_max.hpp>
|
||||
#include <boost/interprocess/detail/iterators.hpp>
|
||||
#include <boost/interprocess/detail/version_type.hpp>
|
||||
#include <boost/interprocess/allocators/allocation_type.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
@@ -95,12 +98,21 @@ class basic_string_base
|
||||
this->allocate_initial_block(n);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_string_base(const detail::moved_object<basic_string_base<A> >& b)
|
||||
: allocator_type(static_cast<allocator_type&>(b.get()))
|
||||
{
|
||||
init();
|
||||
this->swap(b.get());
|
||||
}
|
||||
#else
|
||||
basic_string_base(basic_string_base<A> && b)
|
||||
: allocator_type(static_cast<allocator_type&>(b))
|
||||
{
|
||||
init();
|
||||
this->swap(b);
|
||||
}
|
||||
#endif
|
||||
|
||||
~basic_string_base()
|
||||
{
|
||||
@@ -279,13 +291,16 @@ class basic_string_base
|
||||
}
|
||||
|
||||
void construct(pointer p, const value_type &value = value_type())
|
||||
{ allocator_type::construct(p, value); }
|
||||
{ new(detail::get_pointer(p)) value_type(value); }
|
||||
|
||||
void destroy(pointer p, size_type n)
|
||||
{ for(; n--; ++p) allocator_type::destroy(p); }
|
||||
{
|
||||
for(; n--; ++p)
|
||||
detail::get_pointer(p)->~value_type();
|
||||
}
|
||||
|
||||
void destroy(pointer p)
|
||||
{ allocator_type::destroy(p); }
|
||||
{ detail::get_pointer(p)->~value_type(); }
|
||||
|
||||
void allocate_initial_block(std::size_t n)
|
||||
{
|
||||
@@ -521,9 +536,15 @@ class basic_string
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_string(const detail::moved_object<basic_string>& s)
|
||||
: base_t(move((base_t&)s.get()))
|
||||
{}
|
||||
#else
|
||||
basic_string(basic_string && s)
|
||||
: base_t(move((base_t&)s))
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and is initialized by a specific number of characters of the s string.
|
||||
@@ -571,7 +592,7 @@ class basic_string
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InputIterator>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_initialize_dispatch(f, l, Result());
|
||||
}
|
||||
|
||||
@@ -600,6 +621,7 @@ class basic_string
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_string& operator=(const detail::moved_object<basic_string>& ms)
|
||||
{
|
||||
basic_string &s = ms.get();
|
||||
@@ -608,6 +630,16 @@ class basic_string
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
basic_string& operator=(basic_string && ms)
|
||||
{
|
||||
basic_string &s = ms;
|
||||
if (&s != this){
|
||||
this->swap(s);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Assignment from a null-terminated c-string.
|
||||
basic_string& operator=(const CharT* s)
|
||||
@@ -759,7 +791,7 @@ class basic_string
|
||||
size_type new_length = 0;
|
||||
|
||||
new_length += priv_uninitialized_copy
|
||||
(this->priv_addr(), this->priv_addr() + this->priv_size(), new_start, this->get_alloc());
|
||||
(this->priv_addr(), this->priv_addr() + this->priv_size(), new_start);
|
||||
this->priv_construct_null(new_start + new_length);
|
||||
this->deallocate_block();
|
||||
this->is_short(false);
|
||||
@@ -917,8 +949,13 @@ class basic_string
|
||||
{ return this->operator=(s); }
|
||||
|
||||
//! <b>Effects</b>: Moves the resources from ms *this.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_string& assign(const detail::moved_object<basic_string>& ms)
|
||||
{ return this->operator=(ms);}
|
||||
#else
|
||||
basic_string& assign(basic_string && ms)
|
||||
{ return this->operator=(ms);}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Assigns the range [pos, pos + n) from s to *this.
|
||||
basic_string& assign(const basic_string& s,
|
||||
@@ -947,7 +984,7 @@ class basic_string
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InputIter>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
return this->priv_assign_dispatch(first, last, Result());
|
||||
}
|
||||
|
||||
@@ -1048,7 +1085,7 @@ class basic_string
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InputIter>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_insert_dispatch(p, first, last, Result());
|
||||
}
|
||||
|
||||
@@ -1191,7 +1228,7 @@ class basic_string
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<iterator>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
return this->priv_replace_dispatch(first, last, f, l, Result());
|
||||
}
|
||||
|
||||
@@ -1210,8 +1247,13 @@ class basic_string
|
||||
{ base_t::swap(s); }
|
||||
|
||||
//! <b>Effects</b>: Swaps the contents of two strings.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<basic_string>& ms)
|
||||
{ this->swap(ms.get()); }
|
||||
#else
|
||||
void swap(basic_string && ms)
|
||||
{ this->swap(ms); }
|
||||
#endif
|
||||
|
||||
//! <b>Returns</b>: Returns a pointer to a null-terminated array of characters
|
||||
//! representing the string's contents. For any string s it is guaranteed
|
||||
@@ -1564,7 +1606,7 @@ class basic_string
|
||||
{
|
||||
difference_type n = std::distance(f, l);
|
||||
this->allocate_initial_block(max_value<difference_type>(n+1, InternalBufferChars));
|
||||
priv_uninitialized_copy(f, l, this->priv_addr(), this->get_alloc());
|
||||
priv_uninitialized_copy(f, l, this->priv_addr());
|
||||
this->priv_size(n);
|
||||
this->priv_terminate_string();
|
||||
}
|
||||
@@ -1577,21 +1619,20 @@ class basic_string
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void priv_initialize_dispatch(Integer n, Integer x, boost::mpl::true_)
|
||||
void priv_initialize_dispatch(Integer n, Integer x, true_)
|
||||
{
|
||||
this->allocate_initial_block(max_value<difference_type>(n+1, InternalBufferChars));
|
||||
priv_uninitialized_fill_n(this->priv_addr(), n, x, this->get_alloc());
|
||||
priv_uninitialized_fill_n(this->priv_addr(), n, x);
|
||||
this->priv_size(n);
|
||||
this->priv_terminate_string();
|
||||
}
|
||||
|
||||
template <class InputIter>
|
||||
void priv_initialize_dispatch(InputIter f, InputIter l, boost::mpl::false_)
|
||||
void priv_initialize_dispatch(InputIter f, InputIter l, false_)
|
||||
{ this->priv_range_initialize(f, l); }
|
||||
|
||||
template<class FwdIt, class Count, class Alloc> inline
|
||||
void priv_uninitialized_fill_n(FwdIt first, Count count,
|
||||
const CharT val, Alloc& al)
|
||||
template<class FwdIt, class Count> inline
|
||||
void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
|
||||
{
|
||||
//Save initial position
|
||||
FwdIt init = first;
|
||||
@@ -1599,22 +1640,21 @@ class basic_string
|
||||
BOOST_TRY{
|
||||
//Construct objects
|
||||
for (; count--; ++first){
|
||||
al.construct(first, val);
|
||||
this->construct(first, val);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; init != first; ++init){
|
||||
al.destroy(init);
|
||||
this->destroy(init);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template<class InpIt, class FwdIt, class Alloc> inline
|
||||
size_type priv_uninitialized_copy(InpIt first, InpIt last,
|
||||
FwdIt dest, Alloc& al)
|
||||
template<class InpIt, class FwdIt> inline
|
||||
size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest)
|
||||
{
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
@@ -1623,13 +1663,13 @@ class basic_string
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; first != last; ++dest, ++first, ++constructed){
|
||||
al.construct(dest, *first);
|
||||
this->construct(dest, *first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; constructed--; ++dest_init){
|
||||
al.destroy(dest_init);
|
||||
this->destroy(dest_init);
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -1638,12 +1678,12 @@ class basic_string
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
basic_string& priv_assign_dispatch(Integer n, Integer x, boost::mpl::true_)
|
||||
basic_string& priv_assign_dispatch(Integer n, Integer x, true_)
|
||||
{ return this->assign((size_type) n, (CharT) x); }
|
||||
|
||||
template <class InputIter>
|
||||
basic_string& priv_assign_dispatch(InputIter f, InputIter l,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
size_type cur = 0;
|
||||
CharT *ptr = detail::get_pointer(this->priv_addr());
|
||||
@@ -1707,8 +1747,7 @@ class basic_string
|
||||
if (elems_after >= n) {
|
||||
pointer pointer_past_last = this->priv_addr() + this->priv_size() + 1;
|
||||
priv_uninitialized_copy(this->priv_addr() + (this->priv_size() - n + 1),
|
||||
pointer_past_last,
|
||||
pointer_past_last, *this);
|
||||
pointer_past_last, pointer_past_last);
|
||||
|
||||
this->priv_size(this->priv_size()+n);
|
||||
Traits::move(detail::get_pointer(position + n),
|
||||
@@ -1720,11 +1759,11 @@ class basic_string
|
||||
ForwardIter mid = first;
|
||||
std::advance(mid, elems_after + 1);
|
||||
|
||||
priv_uninitialized_copy(mid, last, this->priv_addr() + this->priv_size() + 1, *this);
|
||||
priv_uninitialized_copy(mid, last, this->priv_addr() + this->priv_size() + 1);
|
||||
this->priv_size(this->priv_size() + (n - elems_after));
|
||||
priv_uninitialized_copy
|
||||
(position, this->priv_addr() + old_length + 1,
|
||||
this->priv_addr() + this->priv_size(), *this);
|
||||
this->priv_addr() + this->priv_size());
|
||||
this->priv_size(this->priv_size() + elems_after);
|
||||
this->priv_copy(first, mid, position);
|
||||
}
|
||||
@@ -1736,12 +1775,12 @@ class basic_string
|
||||
size_type new_length = 0;
|
||||
//This can't throw, since characters are POD
|
||||
new_length += priv_uninitialized_copy
|
||||
(this->priv_addr(), position, new_start, *this);
|
||||
(this->priv_addr(), position, new_start);
|
||||
new_length += priv_uninitialized_copy
|
||||
(first, last, new_start + new_length, *this);
|
||||
(first, last, new_start + new_length);
|
||||
new_length += priv_uninitialized_copy
|
||||
(position, this->priv_addr() + this->priv_size(),
|
||||
new_start + new_length, *this);
|
||||
new_start + new_length);
|
||||
this->priv_construct_null(new_start + new_length);
|
||||
|
||||
this->deallocate_block();
|
||||
@@ -1762,7 +1801,7 @@ class basic_string
|
||||
Traits::move(newbuf, oldbuf, before);
|
||||
Traits::move(newbuf + before + n, pos, old_size - before);
|
||||
//Now initialize the new data
|
||||
priv_uninitialized_copy(first, last, new_start + before, *this);
|
||||
priv_uninitialized_copy(first, last, new_start + before);
|
||||
this->priv_construct_null(new_start + (old_size + n));
|
||||
this->is_short(false);
|
||||
this->priv_addr(new_start);
|
||||
@@ -1775,12 +1814,12 @@ class basic_string
|
||||
|
||||
template <class Integer>
|
||||
void priv_insert_dispatch(iterator p, Integer n, Integer x,
|
||||
boost::mpl::true_)
|
||||
true_)
|
||||
{ insert(p, (size_type) n, (CharT) x); }
|
||||
|
||||
template <class InputIter>
|
||||
void priv_insert_dispatch(iterator p, InputIter first, InputIter last,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
typedef typename std::iterator_traits<InputIter>::iterator_category Category;
|
||||
priv_insert(p, first, last, Category());
|
||||
@@ -1799,13 +1838,13 @@ class basic_string
|
||||
template <class Integer>
|
||||
basic_string& priv_replace_dispatch(iterator first, iterator last,
|
||||
Integer n, Integer x,
|
||||
boost::mpl::true_)
|
||||
true_)
|
||||
{ return this->replace(first, last, (size_type) n, (CharT) x); }
|
||||
|
||||
template <class InputIter>
|
||||
basic_string& priv_replace_dispatch(iterator first, iterator last,
|
||||
InputIter f, InputIter l,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
typedef typename std::iterator_traits<InputIter>::iterator_category Category;
|
||||
return this->priv_replace(first, last, f, l, Category());
|
||||
@@ -1872,6 +1911,7 @@ operator+(const basic_string<CharT,Traits,A>& x,
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline detail::moved_object<basic_string<CharT,Traits,A> >
|
||||
operator+(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
|
||||
@@ -1880,15 +1920,36 @@ operator+(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
|
||||
mx.get() += y;
|
||||
return mx;
|
||||
}
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
basic_string<CharT,Traits,A> &&
|
||||
operator+(basic_string<CharT,Traits,A> && mx,
|
||||
const basic_string<CharT,Traits,A>& y)
|
||||
{
|
||||
mx += y;
|
||||
return move(mx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline detail::moved_object<basic_string<CharT,Traits,A> >
|
||||
operator+(const basic_string<CharT,Traits,A>& x,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& my)
|
||||
{
|
||||
my.get() += x;
|
||||
return my;
|
||||
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
|
||||
return my.get().replace(size_type(0), size_type(0), x);
|
||||
}
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
inline basic_string<CharT,Traits,A> &&
|
||||
operator+(const basic_string<CharT,Traits,A>& x,
|
||||
basic_string<CharT,Traits,A> && my)
|
||||
{
|
||||
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
|
||||
return my.replace(size_type(0), size_type(0), x);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class CharT, class Traits, class A>
|
||||
inline basic_string<CharT,Traits,A>
|
||||
@@ -1904,6 +1965,26 @@ operator+(const CharT* s, const basic_string<CharT,Traits,A>& y)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline detail::moved_object<basic_string<CharT,Traits,A> >
|
||||
operator+(const CharT* s,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& my)
|
||||
{
|
||||
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
|
||||
return my.get().replace(size_type(0), size_type(0), s);
|
||||
}
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
inline basic_string<CharT,Traits,A> &&
|
||||
operator+(const CharT* s,
|
||||
basic_string<CharT,Traits,A> && my)
|
||||
{
|
||||
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
|
||||
return move(my.get().replace(size_type(0), size_type(0), s));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class CharT, class Traits, class A>
|
||||
inline basic_string<CharT,Traits,A>
|
||||
operator+(CharT c, const basic_string<CharT,Traits,A>& y)
|
||||
@@ -1917,6 +1998,26 @@ operator+(CharT c, const basic_string<CharT,Traits,A>& y)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline detail::moved_object<basic_string<CharT,Traits,A> >
|
||||
operator+(CharT c,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& my)
|
||||
{
|
||||
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
|
||||
return my.get().replace(size_type(0), size_type(0), &c, &c + 1);
|
||||
}
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
inline basic_string<CharT,Traits,A> &&
|
||||
operator+(CharT c,
|
||||
basic_string<CharT,Traits,A> && my)
|
||||
{
|
||||
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
|
||||
return my.replace(size_type(0), size_type(0), &c, &c + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class CharT, class Traits, class A>
|
||||
inline basic_string<CharT,Traits,A>
|
||||
operator+(const basic_string<CharT,Traits,A>& x, const CharT* s)
|
||||
@@ -1931,6 +2032,26 @@ operator+(const basic_string<CharT,Traits,A>& x, const CharT* s)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline detail::moved_object<basic_string<CharT,Traits,A> >
|
||||
operator+(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
|
||||
const CharT* s)
|
||||
{
|
||||
mx.get() += s;
|
||||
return mx;
|
||||
}
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
basic_string<CharT,Traits,A> &&
|
||||
operator+(basic_string<CharT,Traits,A> && mx,
|
||||
const CharT* s)
|
||||
{
|
||||
mx += s;
|
||||
return move(mx);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class CharT, class Traits, class A>
|
||||
inline basic_string<CharT,Traits,A>
|
||||
operator+(const basic_string<CharT,Traits,A>& x, const CharT c)
|
||||
@@ -1944,6 +2065,25 @@ operator+(const basic_string<CharT,Traits,A>& x, const CharT c)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline detail::moved_object<basic_string<CharT,Traits,A> >
|
||||
operator+(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
|
||||
const CharT c)
|
||||
{
|
||||
mx.get() += c;
|
||||
return mx;
|
||||
}
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
basic_string<CharT,Traits,A> &&
|
||||
operator+(basic_string<CharT,Traits,A> && mx, const CharT c)
|
||||
{
|
||||
mx += c;
|
||||
return move(mx);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Operator== and operator!=
|
||||
|
||||
template <class CharT, class Traits, class A>
|
||||
@@ -2076,7 +2216,7 @@ operator>=(const basic_string<CharT,Traits,A>& x, const CharT* s)
|
||||
{ return !(x < s); }
|
||||
|
||||
// Swap.
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline void swap(basic_string<CharT,Traits,A>& x,
|
||||
basic_string<CharT,Traits,A>& y)
|
||||
@@ -2091,7 +2231,12 @@ template <class CharT, class Traits, class A>
|
||||
inline void swap(basic_string<CharT,Traits,A>& x,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& my)
|
||||
{ x.swap(my.get()); }
|
||||
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
inline void swap(basic_string<CharT,Traits,A> && x,
|
||||
basic_string<CharT,Traits,A> &&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
// I/O.
|
||||
@@ -2118,7 +2263,11 @@ interprocess_string_fill(std::basic_ostream<CharT, Traits>& os,
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os,
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
const basic_string<CharT,Traits,A>& s)
|
||||
#else
|
||||
const basic_string<CharT,Traits,A>&&s)
|
||||
#endif
|
||||
{
|
||||
typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
|
||||
bool ok = false;
|
||||
@@ -2150,16 +2299,23 @@ operator<<(std::basic_ostream<CharT, Traits>& os,
|
||||
return os;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& ms)
|
||||
{ return os << ms.get(); }
|
||||
#endif
|
||||
|
||||
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is,
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_string<CharT,Traits,A>& s)
|
||||
#else
|
||||
basic_string<CharT,Traits,A>&&s)
|
||||
#endif
|
||||
{
|
||||
typename std::basic_istream<CharT, Traits>::sentry sentry(is);
|
||||
|
||||
@@ -2204,16 +2360,22 @@ operator>>(std::basic_istream<CharT, Traits>& is,
|
||||
return is;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& ms)
|
||||
{ return is >> ms.get(); }
|
||||
#endif
|
||||
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
getline(std::istream& is,
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_string<CharT,Traits,A>& s,
|
||||
#else
|
||||
basic_string<CharT,Traits,A>&&s,
|
||||
#endif
|
||||
CharT delim)
|
||||
{
|
||||
std::size_t nread = 0;
|
||||
@@ -2245,6 +2407,16 @@ getline(std::istream& is,
|
||||
return is;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
getline(std::istream& is,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& ms,
|
||||
CharT delim)
|
||||
{ return getline(is, ms.get(), delim); }
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class CharT, class Traits, class A>
|
||||
inline std::basic_istream<CharT, Traits>&
|
||||
getline(std::basic_istream<CharT, Traits>& is,
|
||||
@@ -2256,15 +2428,15 @@ getline(std::basic_istream<CharT, Traits>& is,
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
getline(std::istream& is,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& ms,
|
||||
CharT delim)
|
||||
{ return getline(is, ms.get(), delim); }
|
||||
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& ms)
|
||||
{ return getline(is, ms.get()); }
|
||||
#else
|
||||
template <class CharT, class Traits, class A>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
getline(std::istream& is,
|
||||
const detail::moved_object<basic_string<CharT,Traits,A> >& ms)
|
||||
{ return getline(is, ms.get()); }
|
||||
basic_string<CharT,Traits,A> && ms)
|
||||
{ return getline(is, ms); }
|
||||
#endif
|
||||
|
||||
template <class Ch, class A>
|
||||
inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, A> const& v)
|
||||
|
||||
@@ -45,27 +45,31 @@
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/interprocess/detail/move_iterator.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/interprocess/detail/version_type.hpp>
|
||||
#include <boost/interprocess/allocators/allocation_type.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/type_traits/is_scalar.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/version_type.hpp>
|
||||
#include <boost/interprocess/allocators/allocation_type.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/iterators.hpp>
|
||||
#include <boost/interprocess/detail/algorithms.hpp>
|
||||
#include <boost/interprocess/detail/min_max.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/detail/move_iterator.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
@@ -81,7 +85,9 @@ struct vector_alloc_holder
|
||||
typedef typename A::size_type size_type;
|
||||
typedef typename A::value_type value_type;
|
||||
|
||||
enum { trivial_dctr_after_move = has_trivial_destructor_after_move<value_type>::value };
|
||||
enum { trivial_dctr_after_move =
|
||||
has_trivial_destructor_after_move<value_type>::value ||
|
||||
boost::has_trivial_destructor<value_type>::value };
|
||||
|
||||
//Constructor, does not throw
|
||||
vector_alloc_holder(const A &a)
|
||||
@@ -94,9 +100,15 @@ struct vector_alloc_holder
|
||||
{}
|
||||
|
||||
//Constructor, does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
vector_alloc_holder(const detail::moved_object<vector_alloc_holder<A> > &h)
|
||||
: A(move((A&)h.get())), m_start(0), m_size(0), m_capacity(0)
|
||||
{}
|
||||
#else
|
||||
vector_alloc_holder(vector_alloc_holder<A> &&h)
|
||||
: A(move((A&)h)), m_start(0), m_size(0), m_capacity(0)
|
||||
{}
|
||||
#endif
|
||||
|
||||
//Destructor
|
||||
~vector_alloc_holder()
|
||||
@@ -165,13 +177,13 @@ struct vector_alloc_holder
|
||||
void destroy(pointer p)
|
||||
{
|
||||
if(!has_trivial_destructor<value_type>::value)
|
||||
A::destroy(p);
|
||||
detail::get_pointer(p)->~value_type();
|
||||
}
|
||||
|
||||
void destroy_n(pointer p, size_type n)
|
||||
{
|
||||
if(!has_trivial_destructor<value_type>::value)
|
||||
for(; n--; ++p) this->destroy(p);
|
||||
for(; n--; ++p) detail::get_pointer(p)->~value_type();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -409,6 +421,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
vector(const detail::moved_object<vector<T, A> >& mx)
|
||||
: base_t(move((base_t&)mx.get()))
|
||||
{
|
||||
@@ -420,6 +433,19 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
x.m_size = 0;
|
||||
x.m_capacity = 0;
|
||||
}
|
||||
#else
|
||||
vector(vector<T, A> && mx)
|
||||
: base_t(move((base_t&)mx))
|
||||
{
|
||||
vector<T, A> &x = mx;
|
||||
this->m_start = x.m_start;
|
||||
this->m_size = x.m_size;
|
||||
this->m_capacity = x.m_capacity;
|
||||
x.m_start = 0;
|
||||
x.m_size = 0;
|
||||
x.m_capacity = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
|
||||
//! and inserts a copy of the range [first, last) in the vector.
|
||||
@@ -651,15 +677,16 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//There is not enough memory, allocate a new
|
||||
//buffer or expand the old one.
|
||||
bool same_buffer_start;
|
||||
size_type real_cap;
|
||||
std::pair<pointer, bool> ret =
|
||||
this->allocation_command
|
||||
(allocate_new | expand_fwd | expand_bwd,
|
||||
new_cap, new_cap, new_cap, this->m_start);
|
||||
new_cap, new_cap, real_cap, this->m_start);
|
||||
|
||||
//Check for forward expansion
|
||||
same_buffer_start = ret.second && this->m_start == ret.first;
|
||||
if(same_buffer_start){
|
||||
this->m_capacity = new_cap;
|
||||
this->m_capacity = real_cap;
|
||||
}
|
||||
|
||||
//If there is no forward expansion, move objects
|
||||
@@ -669,12 +696,12 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//Backwards (and possibly forward) expansion
|
||||
if(ret.second){
|
||||
this->priv_range_insert_expand_backwards
|
||||
(ret.first, new_cap, this->m_start, dummy_it, dummy_it, 0);
|
||||
(ret.first, real_cap, this->m_start, dummy_it, dummy_it, 0);
|
||||
}
|
||||
//New buffer
|
||||
else{
|
||||
this->priv_range_insert_new_allocation
|
||||
(ret.first, new_cap, this->m_start, dummy_it, dummy_it);
|
||||
(ret.first, real_cap, this->m_start, dummy_it, dummy_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -704,6 +731,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
vector<T, A>& operator=(const detail::moved_object<vector<T, A> >& mx)
|
||||
{
|
||||
vector<T, A> &x = mx.get();
|
||||
@@ -715,6 +743,19 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
vector<T, A>& operator=(vector<T, A> && mx)
|
||||
{
|
||||
vector<T, A> &x = mx;
|
||||
|
||||
if (&x != this){
|
||||
this->swap(x);
|
||||
x.clear();
|
||||
//? base_t::prot_deallocate();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Assigns the n copies of val to *this.
|
||||
//!
|
||||
@@ -735,7 +776,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_assign_dispatch(first, last, Result());
|
||||
}
|
||||
|
||||
@@ -749,7 +790,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
{
|
||||
if (this->m_size < this->m_capacity){
|
||||
//There is more memory, just construct a new object at the end
|
||||
this->construct(this->m_start + this->m_size, x);
|
||||
new(detail::get_pointer(this->m_start) + this->m_size)value_type(x);
|
||||
++this->m_size;
|
||||
}
|
||||
else{
|
||||
@@ -763,18 +804,32 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//! <b>Throws</b>: If memory allocation throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void push_back(const detail::moved_object<T> & mx)
|
||||
{
|
||||
if (this->m_size < this->m_capacity){
|
||||
//There is more memory, just construct a new object at the end
|
||||
this->construct(this->m_start + this->m_size, mx);
|
||||
new(detail::get_pointer(this->m_start + this->m_size))value_type(mx);
|
||||
++this->m_size;
|
||||
}
|
||||
else{
|
||||
this->insert(this->end(), mx);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
void push_back(T && mx)
|
||||
{
|
||||
if (this->m_size < this->m_capacity){
|
||||
//There is more memory, just construct a new object at the end
|
||||
new(detail::get_pointer(this->m_start + this->m_size))value_type(move(mx));
|
||||
++this->m_size;
|
||||
}
|
||||
else{
|
||||
this->insert(this->end(), move(mx));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Swaps the contents of *this and x.
|
||||
//! If this->allocator_type() != x.allocator_type()
|
||||
//! allocators are also swapped.
|
||||
@@ -802,11 +857,19 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<vector<T, A> >& mx)
|
||||
{
|
||||
vector<T, A> &x = mx.get();
|
||||
this->swap(x);
|
||||
}
|
||||
#else
|
||||
void swap(vector<T, A> && mx)
|
||||
{
|
||||
vector<T, A> &x = mx;
|
||||
this->swap(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: position must be a valid iterator of *this.
|
||||
//!
|
||||
@@ -832,6 +895,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//!
|
||||
//! <b>Complexity</b>: If position is begin() or end(), amortized constant time
|
||||
//! Linear time otherwise.
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
iterator insert(iterator position, const detail::moved_object<T> &mx)
|
||||
{
|
||||
typedef repeat_iterator<T, difference_type> r_iterator;
|
||||
@@ -843,6 +907,19 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
,move_it(r_iterator()));
|
||||
return iterator(this->m_start + n);
|
||||
}
|
||||
#else
|
||||
iterator insert(iterator position, T &&mx)
|
||||
{
|
||||
typedef repeat_iterator<T, difference_type> r_iterator;
|
||||
typedef detail::move_iterator<r_iterator> move_it;
|
||||
//Just call more general insert(pos, size, value) and return iterator
|
||||
size_type n = position - begin();
|
||||
this->insert(position
|
||||
,move_it(r_iterator(mx, 1))
|
||||
,move_it(r_iterator()));
|
||||
return iterator(this->m_start + n);
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: pos must be a valid iterator of *this.
|
||||
//!
|
||||
@@ -857,7 +934,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
const bool aux_boolean = boost::is_integral<InIt>::value;
|
||||
typedef boost::mpl::bool_<aux_boolean> Result;
|
||||
typedef bool_<aux_boolean> Result;
|
||||
this->priv_insert_dispatch(pos, first, last, Result());
|
||||
}
|
||||
|
||||
@@ -999,7 +1076,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
size_type remaining = this->m_capacity - this->m_size;
|
||||
bool same_buffer_start;
|
||||
std::pair<pointer, bool> ret;
|
||||
size_type new_cap;
|
||||
size_type real_cap = this->m_capacity;
|
||||
|
||||
//Check if we already have room
|
||||
if (n <= remaining){
|
||||
@@ -1008,15 +1085,15 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
else{
|
||||
//There is not enough memory, allocate a new
|
||||
//buffer or expand the old one.
|
||||
new_cap = this->next_capacity(n);
|
||||
size_type new_cap = this->next_capacity(n);
|
||||
ret = this->allocation_command
|
||||
(allocate_new | expand_fwd | expand_bwd,
|
||||
this->m_size + n, new_cap, new_cap, this->m_start);
|
||||
this->m_size + n, new_cap, real_cap, this->m_start);
|
||||
|
||||
//Check for forward expansion
|
||||
same_buffer_start = ret.second && this->m_start == ret.first;
|
||||
if(same_buffer_start){
|
||||
this->m_capacity = new_cap;
|
||||
this->m_capacity = real_cap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,12 +1105,12 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//Backwards (and possibly forward) expansion
|
||||
else if(ret.second){
|
||||
this->priv_range_insert_expand_backwards
|
||||
(ret.first, new_cap, pos, first, last, n);
|
||||
(ret.first, real_cap, pos, first, last, n);
|
||||
}
|
||||
//New buffer
|
||||
else{
|
||||
this->priv_range_insert_new_allocation
|
||||
(ret.first, new_cap, pos, first, last);
|
||||
(ret.first, real_cap, pos, first, last);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1050,8 +1127,8 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
if (elems_after > n){
|
||||
//New elements can be just copied.
|
||||
//Move to uninitialized memory last objects
|
||||
n_uninitialized_copy(move_it(old_finish - n), move_it(old_finish),
|
||||
old_finish, static_cast<A&>(*this));
|
||||
boost::interprocess::n_uninitialized_copy
|
||||
(move_it(old_finish - n), move_it(old_finish), old_finish);
|
||||
this->m_size += n;
|
||||
//Copy previous to last objects to the initialized end
|
||||
std::copy_backward(move_it(pos), move_it(old_finish - n), old_finish);
|
||||
@@ -1063,11 +1140,11 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//to the beginning of the unallocated zone the last new elements.
|
||||
FwdIt mid = first;
|
||||
std::advance(mid, elems_after);
|
||||
n_uninitialized_copy(mid, last, old_finish, static_cast<A&>(*this));
|
||||
boost::interprocess::n_uninitialized_copy(mid, last, old_finish);
|
||||
this->m_size += n - elems_after;
|
||||
//Copy old [pos, end()) elements to the uninitialized memory
|
||||
n_uninitialized_copy(move_it(pos), move_it(old_finish),
|
||||
this->m_start + this->m_size, static_cast<A&>(*this));
|
||||
boost::interprocess::n_uninitialized_copy
|
||||
(move_it(pos), move_it(old_finish), this->m_start + this->m_size);
|
||||
this->m_size += elems_after;
|
||||
//Copy first new elements in pos
|
||||
std::copy(first, mid, pos);
|
||||
@@ -1080,20 +1157,20 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
{
|
||||
typedef detail::move_iterator<pointer> move_it;
|
||||
//Anti-exception rollback
|
||||
scoped_ptr<T, dealloc_t> scoped_alloc(new_start, dealloc_t(*this, new_cap));
|
||||
dealloc_t scoped_alloc(new_start, *this, new_cap);
|
||||
pointer new_finish = new_start;
|
||||
BOOST_TRY{
|
||||
//Initialize with [begin(), pos) old buffer
|
||||
//the start of the new buffer
|
||||
new_finish += n_uninitialized_copy
|
||||
(move_it(this->m_start), move_it(pos), new_start, static_cast<A&>(*this));
|
||||
new_finish += boost::interprocess::n_uninitialized_copy
|
||||
(move_it(this->m_start), move_it(pos), new_start);
|
||||
//Initialize new objects, starting from previous point
|
||||
new_finish += n_uninitialized_copy
|
||||
(first, last, new_finish, static_cast<A&>(*this));
|
||||
new_finish += boost::interprocess::n_uninitialized_copy
|
||||
(first, last, new_finish);
|
||||
//Initialize from the rest of the old buffer,
|
||||
//starting from previous point
|
||||
new_finish += n_uninitialized_copy
|
||||
(move_it(pos), move_it(this->m_start + this->m_size), new_finish, static_cast<A&>(*this));
|
||||
new_finish += boost::interprocess::n_uninitialized_copy
|
||||
(move_it(pos), move_it(this->m_start + this->m_size), new_finish);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->destroy_n(new_start, new_finish - new_start);
|
||||
@@ -1101,10 +1178,13 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
scoped_alloc.release();
|
||||
//Destroy and deallocate old elements except if we have
|
||||
//moved them and they have has_trivial_destructor_after_move
|
||||
if(!base_t::trivial_dctr_after_move)
|
||||
this->priv_destroy_and_deallocate();
|
||||
//Destroy and deallocate old elements
|
||||
//If there is allocated memory, destroy and deallocate
|
||||
if(this->m_start != 0){
|
||||
if(!base_t::trivial_dctr_after_move)
|
||||
this->destroy_n(this->m_start, this->m_size);
|
||||
this->deallocate(this->m_start, this->m_capacity);
|
||||
}
|
||||
this->m_start = new_start;
|
||||
this->m_size = new_finish - new_start;
|
||||
this->m_capacity = new_cap;
|
||||
@@ -1115,8 +1195,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
(pointer new_start, size_type new_capacity,
|
||||
pointer pos, FwdIt first, FwdIt last, size_type n)
|
||||
{
|
||||
typedef detail::scoped_destructor_n
|
||||
<allocator_type> ValueArrayDestructor;
|
||||
typedef detail::scoped_destructor_n<pointer> ValueArrayDestructor;
|
||||
typedef detail::move_iterator<pointer> move_it;
|
||||
//Backup old data
|
||||
pointer old_start = this->m_start;
|
||||
@@ -1134,9 +1213,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
|
||||
//If anything goes wrong, this object will destroy
|
||||
//all the old objects to fulfill previous vector state
|
||||
scoped_ptr<value_type, ValueArrayDestructor>
|
||||
old_values_destroyer
|
||||
(old_start, ValueArrayDestructor(static_cast<A&>(*this),old_size));
|
||||
ValueArrayDestructor old_values_destroyer(old_start, old_size);
|
||||
|
||||
//Check if s_before is so big that even copying the old data + new data
|
||||
//there is a gap between the new data and the old data
|
||||
@@ -1153,15 +1230,12 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//
|
||||
//Copy first old values before pos, after that the
|
||||
//new objects
|
||||
uninitialized_copy_copy
|
||||
(move_it(old_start), move_it(pos), first, last, new_start, static_cast<A&>(*this));
|
||||
scoped_ptr<value_type, ValueArrayDestructor>
|
||||
new_values_destroyer(new_start
|
||||
,ValueArrayDestructor(static_cast<A&>(*this)
|
||||
,elemsbefore));
|
||||
boost::interprocess::uninitialized_copy_copy
|
||||
(move_it(old_start), move_it(pos), first, last, new_start);
|
||||
ValueArrayDestructor new_values_destroyer(new_start, elemsbefore);
|
||||
//Now initialize the rest of memory with the last old values
|
||||
uninitialized_copy(move_it(pos), move_it(old_finish)
|
||||
,new_start + elemsbefore + n, static_cast<A&>(*this));
|
||||
boost::interprocess::uninitialized_copy(move_it(pos), move_it(old_finish)
|
||||
,new_start + elemsbefore + n);
|
||||
//All new elements correctly constructed, avoid new element destruction
|
||||
new_values_destroyer.release();
|
||||
this->m_size = old_size + n;
|
||||
@@ -1185,17 +1259,14 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//
|
||||
//Copy first old values before pos, after that the
|
||||
//new objects
|
||||
uninitialized_copy_copy
|
||||
(move_it(old_start), move_it(pos), first, last, new_start, static_cast<A&>(*this));
|
||||
scoped_ptr<value_type, ValueArrayDestructor>
|
||||
new_values_destroyer(new_start
|
||||
,ValueArrayDestructor(static_cast<A&>(*this)
|
||||
,elemsbefore));
|
||||
boost::interprocess::uninitialized_copy_copy
|
||||
(move_it(old_start), move_it(pos), first, last, new_start);
|
||||
ValueArrayDestructor new_values_destroyer(new_start, elemsbefore);
|
||||
size_type raw_gap = s_before - (elemsbefore + n);
|
||||
//Now initialize the rest of s_before memory with the
|
||||
//first of elements after new values
|
||||
uninitialized_copy(move_it(pos), move_it(pos + raw_gap)
|
||||
,new_start + elemsbefore + n, static_cast<A&>(*this));
|
||||
boost::interprocess::uninitialized_copy
|
||||
(move_it(pos), move_it(pos + raw_gap), new_start + elemsbefore + n);
|
||||
//All new elements correctly constructed, avoid new element destruction
|
||||
new_values_destroyer.release();
|
||||
//All new elements correctly constructed, avoid old element destruction
|
||||
@@ -1269,7 +1340,8 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//
|
||||
//Copy the first part of old_begin to raw_mem
|
||||
pointer start_n = old_start + difference_type(s_before);
|
||||
uninitialized_copy(move_it(old_start), move_it(start_n), new_start, static_cast<A&>(*this));
|
||||
boost::interprocess::uninitialized_copy
|
||||
(move_it(old_start), move_it(start_n), new_start);
|
||||
//The buffer is all constructed until old_end,
|
||||
//release destroyer and update size
|
||||
old_values_destroyer.release();
|
||||
@@ -1319,8 +1391,8 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
FwdIt mid = first;
|
||||
size_type n_new_init = difference_type(s_before) - elemsbefore;
|
||||
std::advance(mid, n_new_init);
|
||||
uninitialized_copy_copy
|
||||
(move_it(old_start), move_it(pos), first, mid, new_start, static_cast<A&>(*this));
|
||||
boost::interprocess::uninitialized_copy_copy
|
||||
(move_it(old_start), move_it(pos), first, mid, new_start);
|
||||
//The buffer is all constructed until old_end,
|
||||
//release destroyer and update size
|
||||
old_values_destroyer.release();
|
||||
@@ -1388,8 +1460,8 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//
|
||||
//First copy the part of old_end raw_mem
|
||||
pointer finish_n = old_finish - difference_type(n_after);
|
||||
uninitialized_copy(move_it(finish_n), move_it(old_finish)
|
||||
,old_finish, static_cast<A&>(*this));
|
||||
boost::interprocess::uninitialized_copy
|
||||
(move_it(finish_n), move_it(old_finish), old_finish);
|
||||
this->m_size += n_after;
|
||||
//Displace the rest of old_end to the new position
|
||||
std::copy_backward(move_it(pos), move_it(finish_n), old_finish);
|
||||
@@ -1412,9 +1484,8 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
FwdIt mid = first;
|
||||
std::advance(mid, elemsafter);
|
||||
//First initialize data in raw memory
|
||||
uninitialized_copy_copy
|
||||
(mid, last, move_it(pos), move_it(old_finish),
|
||||
old_finish, static_cast<A&>(*this));
|
||||
boost::interprocess::uninitialized_copy_copy
|
||||
(mid, last, move_it(pos), move_it(old_finish), old_finish);
|
||||
this->m_size += n_after;
|
||||
//Now copy the part of new_end over constructed elements
|
||||
std::copy(first, mid, pos);
|
||||
@@ -1461,20 +1532,20 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
size_type remaining = this->m_capacity - this->m_size;
|
||||
bool same_buffer_start;
|
||||
std::pair<pointer, bool> ret;
|
||||
size_type new_cap;
|
||||
size_type real_cap = this->m_capacity;
|
||||
|
||||
if (n <= remaining){
|
||||
same_buffer_start = true;
|
||||
}
|
||||
else{
|
||||
//There is not enough memory, allocate a new buffer
|
||||
new_cap = this->next_capacity(n);
|
||||
size_type new_cap = this->next_capacity(n);
|
||||
ret = this->allocation_command
|
||||
(allocate_new | expand_fwd | expand_bwd,
|
||||
this->size() + n, new_cap, new_cap, this->m_start);
|
||||
this->size() + n, new_cap, real_cap, this->m_start);
|
||||
same_buffer_start = ret.second && this->m_start == ret.first;
|
||||
if(same_buffer_start){
|
||||
this->m_capacity = new_cap;
|
||||
this->m_capacity = real_cap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1494,43 +1565,42 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
std::advance(mid, this->size());
|
||||
std::copy(first, mid, this->m_start);
|
||||
//Initialize the remaining new elements in the uninitialized memory
|
||||
n_uninitialized_copy(mid, last, this->m_start + this->m_size, static_cast<A&>(*this));
|
||||
boost::interprocess::n_uninitialized_copy
|
||||
(mid, last, this->m_start + this->m_size);
|
||||
this->m_size = n;
|
||||
}
|
||||
}
|
||||
else if(!ret.second){
|
||||
scoped_ptr<T, dealloc_t> scoped_alloc(ret.first, dealloc_t(*this, new_cap));
|
||||
n_uninitialized_copy(first, last, ret.first, static_cast<A&>(*this));
|
||||
dealloc_t scoped_alloc(ret.first, *this, real_cap);
|
||||
boost::interprocess::n_uninitialized_copy(first, last, ret.first);
|
||||
scoped_alloc.release();
|
||||
//Destroy and deallocate old buffer
|
||||
this->priv_destroy_and_deallocate();
|
||||
if(this->m_start != 0){
|
||||
this->destroy_n(this->m_start, this->m_size);
|
||||
this->deallocate(this->m_start, this->m_capacity);
|
||||
}
|
||||
this->m_start = ret.first;
|
||||
this->m_size = n;
|
||||
this->m_capacity = new_cap;
|
||||
this->m_capacity = real_cap;
|
||||
}
|
||||
else{
|
||||
//Backwards expansion
|
||||
//If anything goes wrong, this object will destroy
|
||||
//all old objects
|
||||
typedef detail::scoped_destructor_n
|
||||
<allocator_type> ValueArrayDestructor;
|
||||
typedef detail::scoped_destructor_n<pointer> ValueArrayDestructor;
|
||||
pointer old_start = this->m_start;
|
||||
size_type old_size = this->m_size;
|
||||
scoped_ptr<value_type, ValueArrayDestructor>
|
||||
old_values_destroyer(old_start
|
||||
,ValueArrayDestructor(static_cast<A&>(*this)
|
||||
,old_size));
|
||||
ValueArrayDestructor old_values_destroyer(old_start, old_size);
|
||||
//If something goes wrong size will be 0
|
||||
//but holding the whole buffer
|
||||
this->m_size = 0;
|
||||
this->m_start = ret.first;
|
||||
this->m_capacity = new_cap;
|
||||
this->m_capacity = real_cap;
|
||||
|
||||
//Backup old buffer data
|
||||
size_type old_offset = old_start - ret.first;
|
||||
size_type first_count = min_value(n, old_offset);
|
||||
FwdIt mid = n_uninitialized_copy_n
|
||||
(first, first_count, ret.first, static_cast<A&>(*this));
|
||||
FwdIt mid = boost::interprocess::n_uninitialized_copy_n(first, first_count, ret.first);
|
||||
|
||||
if(old_offset > n){
|
||||
//All old elements will be destroyed by "old_values_destroyer"
|
||||
@@ -1549,8 +1619,8 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
//Check if we still have to append elements in the
|
||||
//uninitialized end
|
||||
if(second_count == old_size){
|
||||
n_uninitialized_copy_n(mid, n - first_count - second_count
|
||||
, old_start + old_size, static_cast<A&>(*this));
|
||||
boost::interprocess::n_uninitialized_copy_n
|
||||
(mid, n - first_count - second_count, old_start + old_size);
|
||||
}
|
||||
else{
|
||||
//We have to destroy some old values
|
||||
@@ -1564,12 +1634,12 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void priv_assign_dispatch(Integer n, Integer val, boost::mpl::true_)
|
||||
void priv_assign_dispatch(Integer n, Integer val, true_)
|
||||
{ this->assign((size_type) n, (T) val); }
|
||||
|
||||
template <class InIt>
|
||||
void priv_assign_dispatch(InIt first, InIt last,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
typedef typename
|
||||
@@ -1579,12 +1649,12 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
|
||||
template <class Integer>
|
||||
void priv_insert_dispatch( iterator pos, Integer n,
|
||||
Integer val, boost::mpl::true_)
|
||||
Integer val, true_)
|
||||
{ this->insert(pos, (size_type)n, (T)val); }
|
||||
|
||||
template <class InIt>
|
||||
void priv_insert_dispatch(iterator pos, InIt first,
|
||||
InIt last, boost::mpl::false_)
|
||||
InIt last, false_)
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
typedef typename
|
||||
@@ -1593,7 +1663,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void priv_initialize_aux(Integer n, Integer value, boost::mpl::true_)
|
||||
void priv_initialize_aux(Integer n, Integer value, true_)
|
||||
{
|
||||
this->priv_range_initialize(cvalue_iterator(value, n),
|
||||
cvalue_iterator(),
|
||||
@@ -1602,7 +1672,7 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
|
||||
template <class InIt>
|
||||
void priv_initialize_aux(InIt first, InIt last,
|
||||
boost::mpl::false_)
|
||||
false_)
|
||||
{
|
||||
//Dispatch depending on integer/iterator
|
||||
typedef typename
|
||||
@@ -1610,23 +1680,14 @@ class vector : private detail::vector_alloc_holder<A>
|
||||
this->priv_range_initialize(first, last, ItCat());
|
||||
}
|
||||
|
||||
void priv_destroy_and_deallocate()
|
||||
{
|
||||
//If there is allocated memory, destroy and deallocate
|
||||
if(this->m_start != 0){
|
||||
this->destroy_n(this->m_start, this->m_size);
|
||||
this->deallocate(this->m_start, this->m_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
template <class FwdIt>
|
||||
pointer priv_reserve_and_copy(size_type n, size_type &cap
|
||||
,FwdIt first, FwdIt last)
|
||||
{
|
||||
//Allocate n element buffer and initialize from range
|
||||
pointer result = this->allocation_command(allocate_new, n, n, cap).first;
|
||||
scoped_ptr<T, dealloc_t> scoped_alloc(result, dealloc_t(*this, cap));
|
||||
n_uninitialized_copy(first, last, result, static_cast<A&>(*this));
|
||||
dealloc_t scoped_alloc(result, *this, cap);
|
||||
boost::interprocess::n_uninitialized_copy(first, last, result);
|
||||
scoped_alloc.release();
|
||||
return result;
|
||||
}
|
||||
@@ -1666,6 +1727,7 @@ operator<(const vector<T, A>& x, const vector<T, A>& y)
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T, class A>
|
||||
inline void swap(vector<T, A>& x, vector<T, A>& y)
|
||||
{ x.swap(y); }
|
||||
@@ -1677,6 +1739,11 @@ inline void swap(const detail::moved_object<vector<T, A> >& x, vector<T, A>& y)
|
||||
template <class T, class A>
|
||||
inline void swap(vector<T, A> &x, const detail::moved_object<vector<T, A> >& y)
|
||||
{ x.swap(y.get()); }
|
||||
#else
|
||||
template <class T, class A>
|
||||
inline void swap(vector<T, A>&&x, vector<T, A>&&y)
|
||||
{ x.swap(y); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
/*!This class is movable*/
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
|
||||
#define BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/in_place_interface.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
#include <string> //char_traits
|
||||
#include <new> //std::nothrow
|
||||
#include <utility> //std::pair
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
/*!\file
|
||||
Describes the object placed in a memory segment that provides
|
||||
named object allocation capabilities for single-segment and
|
||||
multi-segment allocations.
|
||||
*/
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
|
||||
template<class MemoryAlgorithm>
|
||||
class mem_algo_deallocator
|
||||
{
|
||||
void * m_ptr;
|
||||
MemoryAlgorithm & m_algo;
|
||||
|
||||
public:
|
||||
mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo)
|
||||
: m_ptr(ptr), m_algo(algo)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
|
||||
~mem_algo_deallocator()
|
||||
{ if(m_ptr) m_algo.deallocate(m_ptr); }
|
||||
};
|
||||
|
||||
//!An integer that describes the type of the
|
||||
//!instance constructed in memory
|
||||
enum instance_type { anonymous_type, named_type, unique_type, max_allocation_type };
|
||||
|
||||
/// @cond
|
||||
struct block_header
|
||||
{
|
||||
std::size_t m_value_bytes;
|
||||
unsigned short m_num_char;
|
||||
unsigned char m_value_alignment;
|
||||
unsigned char m_alloc_type_sizeof_char;
|
||||
|
||||
block_header(std::size_t value_bytes
|
||||
,std::size_t value_alignment
|
||||
,std::size_t allocation_type
|
||||
,std::size_t sizeof_char
|
||||
,std::size_t num_char
|
||||
)
|
||||
: m_value_bytes(value_bytes)
|
||||
, m_num_char(num_char)
|
||||
, m_value_alignment(value_alignment)
|
||||
, m_alloc_type_sizeof_char
|
||||
( ((unsigned char)allocation_type << 5u) |
|
||||
((unsigned char)sizeof_char & 0x1F) )
|
||||
{};
|
||||
|
||||
|
||||
template<class T>
|
||||
block_header &operator= (const T& )
|
||||
{ return *this; }
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
if(allocation_type() != detail::anonymous_type){
|
||||
return name_offset() + (m_num_char+1)*sizeof_char();
|
||||
}
|
||||
else{
|
||||
return value_offset() + m_value_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
std::size_t total_size_with_header() const
|
||||
{
|
||||
return get_rounded_size
|
||||
( sizeof(Header)
|
||||
, boost::alignment_of<block_header>::value)
|
||||
+ total_size();
|
||||
}
|
||||
|
||||
std::size_t allocation_type() const
|
||||
{ return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; }
|
||||
|
||||
std::size_t sizeof_char() const
|
||||
{ return m_alloc_type_sizeof_char & (unsigned char)0x1F; }
|
||||
|
||||
template<class CharType>
|
||||
CharType *name() const
|
||||
{
|
||||
return reinterpret_cast<CharType*>
|
||||
(detail::char_ptr_cast(this) + name_offset());
|
||||
}
|
||||
|
||||
std::size_t name_length() const
|
||||
{ return m_num_char; }
|
||||
|
||||
std::size_t name_offset() const
|
||||
{
|
||||
return value_offset() + get_rounded_size(m_value_bytes, sizeof_char());
|
||||
}
|
||||
|
||||
void *value() const
|
||||
{
|
||||
return detail::char_ptr_cast(this) + value_offset();
|
||||
}
|
||||
|
||||
std::size_t value_offset() const
|
||||
{
|
||||
return get_rounded_size(sizeof(block_header), m_value_alignment);
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
bool less(const block_header &b) const
|
||||
{
|
||||
return m_num_char < b.m_num_char ||
|
||||
(m_num_char < b.m_num_char &&
|
||||
std::char_traits<CharType>::compare
|
||||
(name<CharType>(), b.name<CharType>(), m_num_char) < 0);
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
bool equal(const block_header &b) const
|
||||
{
|
||||
return m_num_char == b.m_num_char &&
|
||||
std::char_traits<CharType>::compare
|
||||
(name<CharType>(), b.name<CharType>(), m_num_char) == 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static block_header *block_header_from_value(T *value)
|
||||
{ return block_header_from_value(value, sizeof(T), boost::alignment_of<T>::value); }
|
||||
|
||||
static block_header *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
|
||||
{
|
||||
block_header * hdr =
|
||||
reinterpret_cast<block_header*>(detail::char_ptr_cast(value) -
|
||||
get_rounded_size(sizeof(block_header), algn));
|
||||
(void)sz;
|
||||
//Some sanity checks
|
||||
assert(hdr->m_value_alignment == algn);
|
||||
assert(hdr->m_value_bytes % sz == 0);
|
||||
return hdr;
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
static block_header *from_first_header(Header *header)
|
||||
{
|
||||
block_header * hdr =
|
||||
reinterpret_cast<block_header*>(detail::char_ptr_cast(header) +
|
||||
get_rounded_size(sizeof(Header), boost::alignment_of<block_header>::value));
|
||||
//Some sanity checks
|
||||
return hdr;
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
static Header *to_first_header(block_header *bheader)
|
||||
{
|
||||
Header * hdr =
|
||||
reinterpret_cast<Header*>(detail::char_ptr_cast(bheader) -
|
||||
get_rounded_size(sizeof(Header), boost::alignment_of<block_header>::value));
|
||||
//Some sanity checks
|
||||
return hdr;
|
||||
}
|
||||
};
|
||||
|
||||
inline void array_construct(void *mem, std::size_t num, detail::in_place_interface &table)
|
||||
{
|
||||
//Try constructors
|
||||
std::size_t constructed = 0;
|
||||
BOOST_TRY{
|
||||
table.construct_n(mem, num, constructed);
|
||||
}
|
||||
//If there is an exception call destructors and erase index node
|
||||
BOOST_CATCH(...){
|
||||
std::size_t destroyed = 0;
|
||||
table.destroy_n(mem, constructed, destroyed);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template<class MemoryAlgorithm>
|
||||
class basic_segment_manager
|
||||
: private MemoryAlgorithm
|
||||
{
|
||||
public:
|
||||
typedef typename MemoryAlgorithm::void_pointer void_pointer;
|
||||
typedef typename MemoryAlgorithm::mutex_family mutex_family;
|
||||
|
||||
MemoryAlgorithm &memory_algorithm()
|
||||
{ return *this; }
|
||||
|
||||
const MemoryAlgorithm &memory_algorithm() const
|
||||
{ return *this; }
|
||||
|
||||
enum { PayloadPerAllocation = MemoryAlgorithm::PayloadPerAllocation };
|
||||
|
||||
basic_segment_manager(std::size_t size, std::size_t reserved_bytes)
|
||||
: MemoryAlgorithm(size, reserved_bytes)
|
||||
{
|
||||
assert((sizeof(basic_segment_manager<MemoryAlgorithm>) == sizeof(MemoryAlgorithm)));
|
||||
}
|
||||
|
||||
//!Returns the size of the memory segment
|
||||
std::size_t get_size() const
|
||||
{ return MemoryAlgorithm::get_size(); }
|
||||
|
||||
//!Returns the number of unallocated bytes of the memory segment
|
||||
std::size_t get_free_memory() const
|
||||
{ return MemoryAlgorithm::get_free_memory(); }
|
||||
|
||||
//!Obtains the minimum size needed by the segment manager
|
||||
static std::size_t get_min_size (std::size_t size)
|
||||
{ return MemoryAlgorithm::get_min_size(size); }
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Never throws
|
||||
void * allocate (std::size_t nbytes, std::nothrow_t)
|
||||
{ return MemoryAlgorithm::allocate(nbytes); }
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Throws bad_alloc when fails
|
||||
void * allocate(std::size_t nbytes)
|
||||
{
|
||||
void * ret = MemoryAlgorithm::allocate(nbytes);
|
||||
if(!ret)
|
||||
throw bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Never throws
|
||||
void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t)
|
||||
{ return MemoryAlgorithm::allocate_aligned(nbytes, alignment); }
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Throws bad_alloc when fails
|
||||
void * allocate_aligned(std::size_t nbytes, std::size_t alignment)
|
||||
{
|
||||
void * ret = MemoryAlgorithm::allocate_aligned(nbytes, alignment);
|
||||
if(!ret)
|
||||
throw bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::pair<void *, bool>
|
||||
allocation_command (allocation_type command, std::size_t limit_size,
|
||||
std::size_t preferred_size,std::size_t &received_size,
|
||||
void *reuse_ptr = 0, std::size_t backwards_multiple = 1)
|
||||
{
|
||||
std::pair<void *, bool> ret = MemoryAlgorithm::allocation_command
|
||||
( command | nothrow_allocation, limit_size, preferred_size, received_size
|
||||
, reuse_ptr, backwards_multiple);
|
||||
if(!(command & nothrow_allocation) && !ret.first)
|
||||
throw bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Deallocates the bytes allocated with allocate/allocate_at_least()
|
||||
//!pointed by addr
|
||||
void deallocate (void *addr)
|
||||
{ MemoryAlgorithm::deallocate(addr); }
|
||||
|
||||
//!Increases managed memory in extra_size bytes more. This only works
|
||||
//!with single-segment management*
|
||||
void grow(std::size_t extra_size)
|
||||
{ MemoryAlgorithm::grow(extra_size); }
|
||||
|
||||
//!Returns the result of "all_memory_deallocated()" function
|
||||
//!of the used memory algorithm
|
||||
bool all_memory_deallocated()
|
||||
{ return MemoryAlgorithm::all_memory_deallocated(); }
|
||||
|
||||
//!Returns the result of "check_sanity()" function
|
||||
//!of the used memory algorithm
|
||||
bool check_sanity()
|
||||
{ return MemoryAlgorithm::check_sanity(); }
|
||||
|
||||
//!Writes to zero free memory (memory not yet allocated) of the memory algorithm
|
||||
void zero_free_memory()
|
||||
{ MemoryAlgorithm::zero_free_memory(); }
|
||||
|
||||
/// @cond
|
||||
protected:
|
||||
void * prot_anonymous_construct
|
||||
(std::size_t num, bool dothrow, detail::in_place_interface &table)
|
||||
{
|
||||
typedef detail::block_header block_header_t;
|
||||
block_header_t block_info ( table.size*num
|
||||
, table.alignment
|
||||
, detail::anonymous_type
|
||||
, 1
|
||||
, 0);
|
||||
|
||||
//Allocate memory
|
||||
void *ptr_struct = this->allocate(block_info.total_size(), std::nothrow_t());
|
||||
|
||||
//Check if there is enough memory
|
||||
if(!ptr_struct){
|
||||
if(dothrow){
|
||||
throw bad_alloc();
|
||||
}
|
||||
else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Build scoped ptr to avoid leaks with constructor exception
|
||||
detail::mem_algo_deallocator<MemoryAlgorithm> mem(ptr_struct, *this);
|
||||
|
||||
//Now construct the header
|
||||
block_header_t * hdr = new(ptr_struct) block_header_t(block_info);
|
||||
void *ptr = hdr->value();
|
||||
|
||||
//Now call constructors
|
||||
detail::array_construct(ptr, num, table);
|
||||
|
||||
//All constructors successful, we don't want erase memory
|
||||
mem.release();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//!Calls the destructor and makes an anonymous deallocate
|
||||
bool prot_anonymous_destroy(const void *object, detail::in_place_interface &table)
|
||||
{
|
||||
if(!object)
|
||||
return false;
|
||||
|
||||
//Get control data from associated with this object
|
||||
typedef detail::block_header block_header_t;
|
||||
block_header_t *ctrl_data = block_header_t::block_header_from_value(object, table.size, table.alignment);
|
||||
|
||||
//-------------------------------
|
||||
//boost::interprocess::scoped_lock<rmutex> guard(m_header);
|
||||
//-------------------------------
|
||||
|
||||
if(ctrl_data->allocation_type() != detail::anonymous_type){
|
||||
//This is not an anonymous object, the pointer is wrong!
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Call destructors and free memory
|
||||
//Build scoped ptr to avoid leaks with destructor exception
|
||||
std::size_t destroyed = 0;
|
||||
table.destroy_n((void*)object, ctrl_data->m_value_bytes/table.size, destroyed);
|
||||
this->deallocate(ctrl_data);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
}} //namespace boost { namespace interprocess
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
|
||||
|
||||
229
include/boost/interprocess/detail/algorithms.hpp
Normal file
229
include/boost/interprocess/detail/algorithms.hpp
Normal file
@@ -0,0 +1,229 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
template<class FwdIt, class T>
|
||||
void uninitialized_fill(FwdIt first, FwdIt last, const T& val)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
//Save initial position
|
||||
FwdIt init = first;
|
||||
|
||||
BOOST_TRY{
|
||||
//Construct objects
|
||||
for (; first != last; ++first){
|
||||
new(detail::get_pointer(&*first))value_type(val);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; init != first; ++init){
|
||||
detail::get_pointer(&*init)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template<class FwdIt, class Count, class T>
|
||||
void uninitialized_fill_n(FwdIt first, Count count,
|
||||
const T& val)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
//Save initial position
|
||||
FwdIt init = first;
|
||||
|
||||
BOOST_TRY{
|
||||
//Construct objects
|
||||
for (; count--; ++first){
|
||||
new(detail::get_pointer(&*first))value_type(val);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; init != first; ++init){
|
||||
detail::get_pointer(&*init)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template<class InIt, class OutIt>
|
||||
InIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
|
||||
{
|
||||
for (; length--; ++dest, ++first)
|
||||
*dest = *first;
|
||||
return first;
|
||||
}
|
||||
|
||||
template<class InIt, class FwdIt>
|
||||
typename std::iterator_traits<InIt>::difference_type
|
||||
n_uninitialized_copy(InIt first, InIt last, FwdIt dest)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
typename std::iterator_traits<InIt>::difference_type constructed = 0;
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; first != last; ++dest, ++first, ++constructed){
|
||||
new(detail::get_pointer(&*dest))value_type(*first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; dest_init != dest; ++dest_init){
|
||||
detail::get_pointer(&*dest_init)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return (constructed);
|
||||
}
|
||||
|
||||
template<class InIt, class FwdIt> inline
|
||||
FwdIt uninitialized_copy(InIt first, InIt last, FwdIt dest)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
typename std::iterator_traits<InIt>::difference_type constructed = 0;
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; first != last; ++dest, ++first, ++constructed){
|
||||
new(detail::get_pointer(&*dest))value_type(*first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; dest_init != dest; ++dest_init){
|
||||
detail::get_pointer(&*dest_init)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return (dest);
|
||||
}
|
||||
|
||||
template<class InIt, class FwdIt> inline
|
||||
InIt n_uninitialized_copy_n
|
||||
(InIt first,
|
||||
typename std::iterator_traits<InIt>::difference_type count,
|
||||
FwdIt dest)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
typename std::iterator_traits<InIt>::difference_type new_count = count+1;
|
||||
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; --new_count; ++dest, ++first){
|
||||
new(detail::get_pointer(&*dest))value_type(*first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
new_count = count - new_count;
|
||||
for (; new_count--; ++dest_init){
|
||||
detail::get_pointer(&*dest_init)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return first;
|
||||
}
|
||||
|
||||
// uninitialized_copy_copy
|
||||
// Copies [first1, last1) into [result, result + (last1 - first1)), and
|
||||
// copies [first2, last2) into
|
||||
// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
|
||||
template <class InpIt1, class InpIt2, class FwdIt>
|
||||
FwdIt uninitialized_copy_copy(InpIt1 first1, InpIt1 last1,
|
||||
InpIt2 first2, InpIt2 last2,
|
||||
FwdIt result)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
FwdIt mid = boost::interprocess::uninitialized_copy(first1, last1, result);
|
||||
BOOST_TRY {
|
||||
return boost::interprocess::uninitialized_copy(first2, last2, mid);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for(;result != mid; ++result){
|
||||
detail::get_pointer(&*result)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
// uninitialized_copy_n_copy_n
|
||||
// Copies [first1, first1 + n1) into [result, result + n1), and
|
||||
// copies [first2, first2 + n2) into
|
||||
// [result + n1, result + n1 + n2).
|
||||
template <class InpIt1, class InpIt2, class FwdIt>
|
||||
InpIt2 uninitialized_copy_n_copy_n
|
||||
(InpIt1 first1,
|
||||
typename std::iterator_traits<InpIt1>::difference_type n1,
|
||||
InpIt2 first2,
|
||||
typename std::iterator_traits<InpIt2>::difference_type n2,
|
||||
FwdIt result)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
typename std::iterator_traits<InpIt1>::difference_type c1 = n1+1;
|
||||
typename std::iterator_traits<InpIt2>::difference_type c2 = n2+1;
|
||||
FwdIt dest_init = result;
|
||||
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; --c1; ++result, ++first1){
|
||||
new(detail::get_pointer(&*result))value_type(*first1);
|
||||
}
|
||||
for (; --c2; ++result, ++first2){
|
||||
new(detail::get_pointer(&*result))value_type(*first2);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
typename std::iterator_traits<FwdIt>::
|
||||
difference_type c = (n1 - c1) + (n2 - c2);
|
||||
for (; c--; ++dest_init){
|
||||
detail::get_pointer(&*dest_init)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return first2;
|
||||
}
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP
|
||||
|
||||
@@ -179,8 +179,8 @@ static boost::uint32_t inline intel_atomic_add32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{
|
||||
asm volatile ("lock; xaddl %0,%1"
|
||||
: "=r"(val), "=m"(*mem) /* outputs */
|
||||
: "0"(val), "m"(*mem) /* inputs */
|
||||
: "=r"(val), "=m"(*mem) // outputs
|
||||
: "0"(val), "m"(*mem) // inputs
|
||||
: "memory", "cc");
|
||||
return val;
|
||||
}
|
||||
@@ -368,16 +368,24 @@ inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint3
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ atomic_xchg32(mem, val); }
|
||||
|
||||
#elif (defined(SOLARIS2) && SOLARIS2 >= 10)
|
||||
} //namespace detail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
#elif (defined(sun) || defined(__sun))
|
||||
|
||||
#include <atomic.h>
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
||||
//! "mem": pointer to the object
|
||||
//! "val": amount to add
|
||||
//! Returns the old value pointed to by mem
|
||||
inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ return atomic_add_32_nv(mem, val) - val; }
|
||||
{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), (int32_t)val) - val; }
|
||||
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
||||
//! If they are the same swap the value with "with"
|
||||
@@ -387,25 +395,25 @@ inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32
|
||||
//! Returns the old value of *mem
|
||||
inline boost::uint32_t atomic_cas32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
|
||||
{ return atomic_cas_32(mem, cmp, with); }
|
||||
{ return atomic_cas_32(reinterpret_cast<volatile ::uint32_t*>(mem), cmp, with); }
|
||||
|
||||
//! Atomically subtract 'val' from an apr_uint32_t
|
||||
//! "mem": pointer to the object
|
||||
//! "val": amount to subtract
|
||||
inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ return atomic_add_32(mem, (-val)); }
|
||||
{ return atomic_add_32(reinterpret_cast<volatile ::uint32_t*>(mem), -val); }
|
||||
|
||||
//! Atomically increment an apr_uint32_t by 1
|
||||
//! "mem": pointer to the object
|
||||
//! Returns the old value pointed to by mem
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
|
||||
{ return atomic_add_32_nv(mem, 1) - 1; }
|
||||
{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), 1) - 1; }
|
||||
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
||||
//! "mem": pointer to the atomic value
|
||||
//! Returns false if the value becomes zero on decrement, otherwise true
|
||||
inline bool atomic_dec32(volatile boost::uint32_t *mem)
|
||||
{ return atomic_add_32_nv(mem, -1) != 0; }
|
||||
{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), -1) != 0; }
|
||||
|
||||
//! Atomically read an boost::uint32_t from memory
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
|
||||
@@ -416,7 +424,7 @@ inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
|
||||
//! "val": what to swap it with
|
||||
//! Returns the old value of *mem
|
||||
inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ return atomic_swap_32(mem, val); }
|
||||
{ return atomic_swap_32(reinterpret_cast<volatile ::uint32_t*>(mem), val); }
|
||||
|
||||
//! Atomically set an boost::uint32_t in memory
|
||||
//! "mem": pointer to the object
|
||||
|
||||
389
include/boost/interprocess/detail/basic_segment_manager.hpp
Normal file
389
include/boost/interprocess/detail/basic_segment_manager.hpp
Normal file
@@ -0,0 +1,389 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
|
||||
#define BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/in_place_interface.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
#include <string> //char_traits
|
||||
#include <new> //std::nothrow
|
||||
#include <utility> //std::pair
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
/*!\file
|
||||
Describes the object placed in a memory segment that provides
|
||||
named object allocation capabilities for single-segment and
|
||||
multi-segment allocations.
|
||||
*/
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
|
||||
template<class MemoryAlgorithm>
|
||||
class mem_algo_deallocator
|
||||
{
|
||||
void * m_ptr;
|
||||
MemoryAlgorithm & m_algo;
|
||||
|
||||
public:
|
||||
mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo)
|
||||
: m_ptr(ptr), m_algo(algo)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
|
||||
~mem_algo_deallocator()
|
||||
{ if(m_ptr) m_algo.deallocate(m_ptr); }
|
||||
};
|
||||
|
||||
//!An integer that describes the type of the
|
||||
//!instance constructed in memory
|
||||
enum instance_type { anonymous_type, named_type, unique_type, max_allocation_type };
|
||||
|
||||
/// @cond
|
||||
struct block_header
|
||||
{
|
||||
std::size_t m_value_bytes;
|
||||
unsigned short m_num_char;
|
||||
unsigned char m_value_alignment;
|
||||
unsigned char m_alloc_type_sizeof_char;
|
||||
|
||||
block_header(std::size_t value_bytes
|
||||
,std::size_t value_alignment
|
||||
,std::size_t allocation_type
|
||||
,std::size_t sizeof_char
|
||||
,std::size_t num_char
|
||||
)
|
||||
: m_value_bytes(value_bytes)
|
||||
, m_num_char(num_char)
|
||||
, m_value_alignment(value_alignment)
|
||||
, m_alloc_type_sizeof_char
|
||||
( ((unsigned char)allocation_type << 5u) |
|
||||
((unsigned char)sizeof_char & 0x1F) )
|
||||
{};
|
||||
|
||||
|
||||
template<class T>
|
||||
block_header &operator= (const T& )
|
||||
{ return *this; }
|
||||
|
||||
std::size_t total_size() const
|
||||
{
|
||||
if(allocation_type() != detail::anonymous_type){
|
||||
return name_offset() + (m_num_char+1)*sizeof_char();
|
||||
}
|
||||
else{
|
||||
return value_offset() + m_value_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
std::size_t total_size_with_header() const
|
||||
{
|
||||
return get_rounded_size
|
||||
( sizeof(Header)
|
||||
, boost::alignment_of<block_header>::value)
|
||||
+ total_size();
|
||||
}
|
||||
|
||||
std::size_t allocation_type() const
|
||||
{ return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; }
|
||||
|
||||
std::size_t sizeof_char() const
|
||||
{ return m_alloc_type_sizeof_char & (unsigned char)0x1F; }
|
||||
|
||||
template<class CharType>
|
||||
CharType *name() const
|
||||
{
|
||||
return reinterpret_cast<CharType*>
|
||||
(detail::char_ptr_cast(this) + name_offset());
|
||||
}
|
||||
|
||||
std::size_t name_length() const
|
||||
{ return m_num_char; }
|
||||
|
||||
std::size_t name_offset() const
|
||||
{
|
||||
return value_offset() + get_rounded_size(m_value_bytes, sizeof_char());
|
||||
}
|
||||
|
||||
void *value() const
|
||||
{
|
||||
return detail::char_ptr_cast(this) + value_offset();
|
||||
}
|
||||
|
||||
std::size_t value_offset() const
|
||||
{
|
||||
return get_rounded_size(sizeof(block_header), m_value_alignment);
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
bool less(const block_header &b) const
|
||||
{
|
||||
return m_num_char < b.m_num_char ||
|
||||
(m_num_char < b.m_num_char &&
|
||||
std::char_traits<CharType>::compare
|
||||
(name<CharType>(), b.name<CharType>(), m_num_char) < 0);
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
bool equal(const block_header &b) const
|
||||
{
|
||||
return m_num_char == b.m_num_char &&
|
||||
std::char_traits<CharType>::compare
|
||||
(name<CharType>(), b.name<CharType>(), m_num_char) == 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static block_header *block_header_from_value(T *value)
|
||||
{ return block_header_from_value(value, sizeof(T), boost::alignment_of<T>::value); }
|
||||
|
||||
static block_header *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
|
||||
{
|
||||
block_header * hdr =
|
||||
reinterpret_cast<block_header*>(detail::char_ptr_cast(value) -
|
||||
get_rounded_size(sizeof(block_header), algn));
|
||||
(void)sz;
|
||||
//Some sanity checks
|
||||
assert(hdr->m_value_alignment == algn);
|
||||
assert(hdr->m_value_bytes % sz == 0);
|
||||
return hdr;
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
static block_header *from_first_header(Header *header)
|
||||
{
|
||||
block_header * hdr =
|
||||
reinterpret_cast<block_header*>(detail::char_ptr_cast(header) +
|
||||
get_rounded_size(sizeof(Header), boost::alignment_of<block_header>::value));
|
||||
//Some sanity checks
|
||||
return hdr;
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
static Header *to_first_header(block_header *bheader)
|
||||
{
|
||||
Header * hdr =
|
||||
reinterpret_cast<Header*>(detail::char_ptr_cast(bheader) -
|
||||
get_rounded_size(sizeof(Header), boost::alignment_of<block_header>::value));
|
||||
//Some sanity checks
|
||||
return hdr;
|
||||
}
|
||||
};
|
||||
|
||||
inline void array_construct(void *mem, std::size_t num, detail::in_place_interface &table)
|
||||
{
|
||||
//Try constructors
|
||||
std::size_t constructed = 0;
|
||||
BOOST_TRY{
|
||||
table.construct_n(mem, num, constructed);
|
||||
}
|
||||
//If there is an exception call destructors and erase index node
|
||||
BOOST_CATCH(...){
|
||||
std::size_t destroyed = 0;
|
||||
table.destroy_n(mem, constructed, destroyed);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template<class MemoryAlgorithm>
|
||||
class basic_segment_manager
|
||||
: private MemoryAlgorithm
|
||||
{
|
||||
public:
|
||||
typedef typename MemoryAlgorithm::void_pointer void_pointer;
|
||||
typedef typename MemoryAlgorithm::mutex_family mutex_family;
|
||||
|
||||
MemoryAlgorithm &memory_algorithm()
|
||||
{ return *this; }
|
||||
|
||||
const MemoryAlgorithm &memory_algorithm() const
|
||||
{ return *this; }
|
||||
|
||||
enum { PayloadPerAllocation = MemoryAlgorithm::PayloadPerAllocation };
|
||||
|
||||
basic_segment_manager(std::size_t size, std::size_t reserved_bytes)
|
||||
: MemoryAlgorithm(size, reserved_bytes)
|
||||
{
|
||||
assert((sizeof(basic_segment_manager<MemoryAlgorithm>) == sizeof(MemoryAlgorithm)));
|
||||
}
|
||||
|
||||
//!Returns the size of the memory segment
|
||||
std::size_t get_size() const
|
||||
{ return MemoryAlgorithm::get_size(); }
|
||||
|
||||
//!Returns the number of unallocated bytes of the memory segment
|
||||
std::size_t get_free_memory() const
|
||||
{ return MemoryAlgorithm::get_free_memory(); }
|
||||
|
||||
//!Obtains the minimum size needed by the segment manager
|
||||
static std::size_t get_min_size (std::size_t size)
|
||||
{ return MemoryAlgorithm::get_min_size(size); }
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Never throws
|
||||
void * allocate (std::size_t nbytes, std::nothrow_t)
|
||||
{ return MemoryAlgorithm::allocate(nbytes); }
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Throws bad_alloc when fails
|
||||
void * allocate(std::size_t nbytes)
|
||||
{
|
||||
void * ret = MemoryAlgorithm::allocate(nbytes);
|
||||
if(!ret)
|
||||
throw bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Never throws
|
||||
void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t)
|
||||
{ return MemoryAlgorithm::allocate_aligned(nbytes, alignment); }
|
||||
|
||||
//!Allocates nbytes bytes. This function is only used in
|
||||
//!single-segment management. Throws bad_alloc when fails
|
||||
void * allocate_aligned(std::size_t nbytes, std::size_t alignment)
|
||||
{
|
||||
void * ret = MemoryAlgorithm::allocate_aligned(nbytes, alignment);
|
||||
if(!ret)
|
||||
throw bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::pair<void *, bool>
|
||||
allocation_command (allocation_type command, std::size_t limit_size,
|
||||
std::size_t preferred_size,std::size_t &received_size,
|
||||
void *reuse_ptr = 0, std::size_t backwards_multiple = 1)
|
||||
{
|
||||
std::pair<void *, bool> ret = MemoryAlgorithm::allocation_command
|
||||
( command | nothrow_allocation, limit_size, preferred_size, received_size
|
||||
, reuse_ptr, backwards_multiple);
|
||||
if(!(command & nothrow_allocation) && !ret.first)
|
||||
throw bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//!Deallocates the bytes allocated with allocate/allocate_at_least()
|
||||
//!pointed by addr
|
||||
void deallocate (void *addr)
|
||||
{ MemoryAlgorithm::deallocate(addr); }
|
||||
|
||||
//!Increases managed memory in extra_size bytes more. This only works
|
||||
//!with single-segment management*
|
||||
void grow(std::size_t extra_size)
|
||||
{ MemoryAlgorithm::grow(extra_size); }
|
||||
|
||||
//!Returns the result of "all_memory_deallocated()" function
|
||||
//!of the used memory algorithm
|
||||
bool all_memory_deallocated()
|
||||
{ return MemoryAlgorithm::all_memory_deallocated(); }
|
||||
|
||||
//!Returns the result of "check_sanity()" function
|
||||
//!of the used memory algorithm
|
||||
bool check_sanity()
|
||||
{ return MemoryAlgorithm::check_sanity(); }
|
||||
|
||||
//!Writes to zero free memory (memory not yet allocated) of the memory algorithm
|
||||
void zero_free_memory()
|
||||
{ MemoryAlgorithm::zero_free_memory(); }
|
||||
|
||||
/// @cond
|
||||
protected:
|
||||
void * prot_anonymous_construct
|
||||
(std::size_t num, bool dothrow, detail::in_place_interface &table)
|
||||
{
|
||||
typedef detail::block_header block_header_t;
|
||||
block_header_t block_info ( table.size*num
|
||||
, table.alignment
|
||||
, detail::anonymous_type
|
||||
, 1
|
||||
, 0);
|
||||
|
||||
//Allocate memory
|
||||
void *ptr_struct = this->allocate(block_info.total_size(), std::nothrow_t());
|
||||
|
||||
//Check if there is enough memory
|
||||
if(!ptr_struct){
|
||||
if(dothrow){
|
||||
throw bad_alloc();
|
||||
}
|
||||
else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Build scoped ptr to avoid leaks with constructor exception
|
||||
detail::mem_algo_deallocator<MemoryAlgorithm> mem(ptr_struct, *this);
|
||||
|
||||
//Now construct the header
|
||||
block_header_t * hdr = new(ptr_struct) block_header_t(block_info);
|
||||
void *ptr = hdr->value();
|
||||
|
||||
//Now call constructors
|
||||
detail::array_construct(ptr, num, table);
|
||||
|
||||
//All constructors successful, we don't want erase memory
|
||||
mem.release();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//!Calls the destructor and makes an anonymous deallocate
|
||||
bool prot_anonymous_destroy(const void *object, detail::in_place_interface &table)
|
||||
{
|
||||
if(!object)
|
||||
return false;
|
||||
|
||||
//Get control data from associated with this object
|
||||
typedef detail::block_header block_header_t;
|
||||
block_header_t *ctrl_data = block_header_t::block_header_from_value(object, table.size, table.alignment);
|
||||
|
||||
//-------------------------------
|
||||
//boost::interprocess::scoped_lock<rmutex> guard(m_header);
|
||||
//-------------------------------
|
||||
|
||||
if(ctrl_data->allocation_type() != detail::anonymous_type){
|
||||
//This is not an anonymous object, the pointer is wrong!
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Call destructors and free memory
|
||||
//Build scoped ptr to avoid leaks with destructor exception
|
||||
std::size_t destroyed = 0;
|
||||
table.destroy_n((void*)object, ctrl_data->m_value_bytes/table.size, destroyed);
|
||||
this->deallocate(ctrl_data);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
}} //namespace boost { namespace interprocess
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
|
||||
|
||||
@@ -32,9 +32,3 @@
|
||||
#pragma warning (disable : 4146)
|
||||
#pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data
|
||||
#endif
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# pragma warn -8026 // shut up warning "cannot inline function because ..."
|
||||
# pragma warn -8027 // shut up warning "cannot inline function because ..."
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
#if defined _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# pragma warn .8026
|
||||
# pragma warn .8027
|
||||
#endif
|
||||
|
||||
@@ -47,13 +47,19 @@ class file_wrapper
|
||||
/*!Moves the ownership of "moved"'s shared memory object to *this.
|
||||
After the call, "moved" does not represent any shared memory object.
|
||||
Does not throw*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
file_wrapper
|
||||
(detail::moved_object<file_wrapper> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
file_wrapper(file_wrapper &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
/*!Moves the ownership of "moved"'s shared memory to *this.
|
||||
After the call, "moved" does not represent any shared memory.
|
||||
Does not throw*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
file_wrapper &operator=
|
||||
(detail::moved_object<file_wrapper> &moved)
|
||||
{
|
||||
@@ -61,6 +67,14 @@ class file_wrapper
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
file_wrapper &operator=(file_wrapper &&moved)
|
||||
{
|
||||
file_wrapper tmp(move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Swaps to shared_memory_objects. Does not throw*/
|
||||
void swap(file_wrapper &other);
|
||||
|
||||
75
include/boost/interprocess/detail/in_place_interface.hpp
Normal file
75
include/boost/interprocess/detail/in_place_interface.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP
|
||||
#define BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <typeinfo> //typeid
|
||||
|
||||
/*!\file
|
||||
Describes an abstract interface for placement construction and destruction.
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
|
||||
struct in_place_interface
|
||||
{
|
||||
in_place_interface(std::size_t alignm, std::size_t sz, const char *tname)
|
||||
: alignment(alignm), size(sz), type_name(tname)
|
||||
{}
|
||||
|
||||
std::size_t alignment;
|
||||
std::size_t size;
|
||||
const char *type_name;
|
||||
|
||||
virtual void construct(void *mem) = 0;
|
||||
virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed) = 0;
|
||||
virtual void destroy(void *mem) = 0;
|
||||
virtual void destroy_n(void *mem, std::size_t num, std::size_t &destroyed) = 0;
|
||||
virtual ~in_place_interface(){}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct placement_destroy : public in_place_interface
|
||||
{
|
||||
placement_destroy()
|
||||
: in_place_interface(boost::alignment_of<T>::value, sizeof(T), typeid(T).name())
|
||||
{}
|
||||
|
||||
virtual void destroy(void *mem)
|
||||
{ static_cast<T*>(mem)->~T(); }
|
||||
|
||||
virtual void destroy_n(void *mem, std::size_t num, std::size_t &destroyed)
|
||||
{
|
||||
T* memory = static_cast<T*>(mem);
|
||||
for(destroyed = 0; destroyed < num; ++destroyed)
|
||||
(memory++)->~T();
|
||||
}
|
||||
|
||||
virtual void construct(void *) {}
|
||||
virtual void construct_n(void *, std::size_t, std::size_t &) {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} //namespace boost { namespace interprocess { namespace detail {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP
|
||||
138
include/boost/interprocess/detail/iterators.hpp
Normal file
138
include/boost/interprocess/detail/iterators.hpp
Normal file
@@ -0,0 +1,138 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class constant_iterator
|
||||
: public boost::iterator_facade
|
||||
< constant_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, const T &
|
||||
, Difference>
|
||||
{
|
||||
typedef boost::iterator_facade
|
||||
< constant_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, const T &
|
||||
, Difference> super_t;
|
||||
|
||||
typedef constant_iterator<T, Difference> this_type;
|
||||
//Give access to private core functions
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
public:
|
||||
explicit constant_iterator(const T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
constant_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
private:
|
||||
const T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class repeat_iterator
|
||||
: public boost::iterator_facade
|
||||
< repeat_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, T &
|
||||
, Difference>
|
||||
{
|
||||
typedef boost::iterator_facade
|
||||
< repeat_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, T &
|
||||
, Difference> super_t;
|
||||
|
||||
typedef repeat_iterator<T, Difference> this_type;
|
||||
//Give access to private core functions
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
public:
|
||||
explicit repeat_iterator(T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
repeat_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
private:
|
||||
T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP
|
||||
|
||||
@@ -84,10 +84,15 @@ class basic_managed_memory_impl
|
||||
public:
|
||||
typedef typename segment_manager_type
|
||||
<CharType, MemoryAlgorithm, IndexType>::type segment_manager;
|
||||
typedef typename MemoryAlgorithm::void_pointer void_pointer;
|
||||
typedef CharType char_type;
|
||||
typedef MemoryAlgorithm memory_algorithm;
|
||||
typedef typename MemoryAlgorithm::mutex_family mutex_family;
|
||||
typedef CharType char_t;
|
||||
typedef std::ptrdiff_t handle_t;
|
||||
typedef typename segment_manager::
|
||||
named_index_t::const_iterator const_named_iterator;
|
||||
typedef typename segment_manager::
|
||||
unique_index_t::const_iterator const_unique_iterator;
|
||||
|
||||
enum { PayloadPerAllocation = segment_manager::PayloadPerAllocation };
|
||||
|
||||
@@ -208,6 +213,26 @@ class basic_managed_memory_impl
|
||||
std::size_t get_size () const
|
||||
{ return mp_header->get_size(); }
|
||||
|
||||
//!Returns the number of free bytes of the memory
|
||||
//!segment
|
||||
std::size_t get_free_memory() const
|
||||
{ return mp_header->get_free_memory(); }
|
||||
|
||||
//!Returns the result of "all_memory_deallocated()" function
|
||||
//!of the used memory algorithm
|
||||
bool all_memory_deallocated()
|
||||
{ return mp_header->all_memory_deallocated(); }
|
||||
|
||||
//!Returns the result of "check_sanity()" function
|
||||
//!of the used memory algorithm
|
||||
bool check_sanity()
|
||||
{ return mp_header->check_sanity(); }
|
||||
|
||||
//!Writes to zero free memory (memory not yet allocated) of
|
||||
//!the memory algorithm
|
||||
void zero_free_memory()
|
||||
{ mp_header->zero_free_memory(); }
|
||||
|
||||
//!Transforms an absolute address into an offset from base address.
|
||||
//!The address must belong to the memory segment. Never throws.
|
||||
handle_t get_handle_from_address (const void *ptr) const
|
||||
@@ -280,7 +305,7 @@ class basic_managed_memory_impl
|
||||
//!array was being constructed, destructors of created objects are called
|
||||
//!before freeing the memory.
|
||||
template <class T>
|
||||
typename segment_manager::template construct_proxy<T, true>::type
|
||||
typename segment_manager::template construct_proxy<T>::type
|
||||
construct(char_ptr_holder_t name)
|
||||
{ return mp_header->construct<T>(name); }
|
||||
|
||||
@@ -301,7 +326,7 @@ class basic_managed_memory_impl
|
||||
//!array was being constructed, destructors of created objects are called
|
||||
//!before freeing the memory.
|
||||
template <class T>
|
||||
typename segment_manager::template find_construct_proxy<T, true>::type
|
||||
typename segment_manager::template construct_proxy<T>::type
|
||||
find_or_construct(char_ptr_holder_t name)
|
||||
{ return mp_header->find_or_construct<T>(name); }
|
||||
|
||||
@@ -322,7 +347,7 @@ class basic_managed_memory_impl
|
||||
//!array was being constructed, destructors of created objects are called
|
||||
//!before freeing the memory.
|
||||
template <class T>
|
||||
typename segment_manager::template construct_proxy<T, false>::type
|
||||
typename segment_manager::template construct_proxy<T>::type
|
||||
construct(char_ptr_holder_t name, std::nothrow_t nothrow)
|
||||
{ return mp_header->construct<T>(name, nothrow); }
|
||||
|
||||
@@ -343,7 +368,7 @@ class basic_managed_memory_impl
|
||||
//!array was being constructed, destructors of created objects are called
|
||||
//!before freeing the memory.
|
||||
template <class T>
|
||||
typename segment_manager::template find_construct_proxy<T, false>::type
|
||||
typename segment_manager::template construct_proxy<T>::type
|
||||
find_or_construct(char_ptr_holder_t name, std::nothrow_t nothrow)
|
||||
{ return mp_header->find_or_construct<T>(name, nothrow); }
|
||||
|
||||
@@ -364,7 +389,7 @@ class basic_managed_memory_impl
|
||||
//!Memory is freed automatically if T's constructor throws and
|
||||
//!destructors of created objects are called before freeing the memory.
|
||||
template <class T>
|
||||
typename segment_manager::template construct_iter_proxy<T, true>::type
|
||||
typename segment_manager::template construct_iter_proxy<T>::type
|
||||
construct_it(char_ptr_holder_t name)
|
||||
{ return mp_header->construct_it<T>(name); }
|
||||
|
||||
@@ -387,7 +412,7 @@ class basic_managed_memory_impl
|
||||
//!Memory is freed automatically if T's constructor throws and
|
||||
//!destructors of created objects are called before freeing the memory.
|
||||
template <class T>
|
||||
typename segment_manager::template find_construct_iter_proxy<T, true>::type
|
||||
typename segment_manager::template construct_iter_proxy<T>::type
|
||||
find_or_construct_it(char_ptr_holder_t name)
|
||||
{ return mp_header->find_or_construct_it<T>(name); }
|
||||
|
||||
@@ -408,7 +433,7 @@ class basic_managed_memory_impl
|
||||
//!Memory is freed automatically if T's constructor throws and
|
||||
//!destructors of created objects are called before freeing the memory.*/
|
||||
template <class T>
|
||||
typename segment_manager::template construct_iter_proxy<T, false>::type
|
||||
typename segment_manager::template construct_iter_proxy<T>::type
|
||||
construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
|
||||
{ return mp_header->construct_it<T>(name, nothrow); }
|
||||
|
||||
@@ -431,7 +456,7 @@ class basic_managed_memory_impl
|
||||
//!Memory is freed automatically if T's constructor throws and
|
||||
//!destructors of created objects are called before freeing the memory.*/
|
||||
template <class T>
|
||||
typename segment_manager::template find_construct_iter_proxy<T, false>::type
|
||||
typename segment_manager::template construct_iter_proxy<T>::type
|
||||
find_or_construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
|
||||
{ return mp_header->find_or_construct_it<T>(name, nothrow); }
|
||||
|
||||
@@ -525,7 +550,7 @@ class basic_managed_memory_impl
|
||||
//!Returns is the the name of an object created with construct/find_or_construct
|
||||
//!functions. Does not throw
|
||||
template<class T>
|
||||
InstanceType get_type(const T *ptr)
|
||||
detail::instance_type get_type(const T *ptr)
|
||||
{ return mp_header->get_type(ptr); }
|
||||
|
||||
//!Preallocates needed index resources to optimize the
|
||||
@@ -566,28 +591,16 @@ class basic_managed_memory_impl
|
||||
(std::streamsize)get_size()).good();
|
||||
}
|
||||
|
||||
typename segment_manager::named_index_t::iterator named_begin()
|
||||
const_named_iterator named_begin() const
|
||||
{ return mp_header->named_begin(); }
|
||||
|
||||
typename segment_manager::named_index_t::iterator named_begin() const
|
||||
{ return mp_header->named_begin(); }
|
||||
|
||||
typename segment_manager::named_index_t::iterator named_end()
|
||||
const_named_iterator named_end() const
|
||||
{ return mp_header->named_end(); }
|
||||
|
||||
typename segment_manager::named_index_t::iterator named_end() const
|
||||
{ return mp_header->named_end(); }
|
||||
|
||||
typename segment_manager::unique_index_t::iterator unique_begin()
|
||||
const_unique_iterator unique_begin() const
|
||||
{ return mp_header->unique_begin(); }
|
||||
|
||||
typename segment_manager::unique_index_t::iterator unique_begin() const
|
||||
{ return mp_header->unique_begin(); }
|
||||
|
||||
typename segment_manager::unique_index_t::iterator unique_end()
|
||||
{ return mp_header->unique_end(); }
|
||||
|
||||
typename segment_manager::unique_index_t::iterator unique_end() const
|
||||
const_unique_iterator unique_end() const
|
||||
{ return mp_header->unique_end(); }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include <boost/interprocess/detail/creation_tags.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
@@ -147,10 +147,17 @@ class managed_open_or_create_impl
|
||||
, construct_func);
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
managed_open_or_create_impl
|
||||
(detail::moved_object<managed_open_or_create_impl> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
managed_open_or_create_impl
|
||||
(managed_open_or_create_impl &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
managed_open_or_create_impl &operator=
|
||||
(detail::moved_object<managed_open_or_create_impl> &moved)
|
||||
{
|
||||
@@ -158,6 +165,15 @@ class managed_open_or_create_impl
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
managed_open_or_create_impl &operator=
|
||||
(managed_open_or_create_impl &&moved)
|
||||
{
|
||||
managed_open_or_create_impl tmp(move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
~managed_open_or_create_impl()
|
||||
{}
|
||||
@@ -184,11 +200,11 @@ class managed_open_or_create_impl
|
||||
|
||||
//These are templatized to allow explicit instantiations
|
||||
template<bool dummy>
|
||||
static void write_whole_device(DeviceAbstraction &, std::size_t, boost::mpl::false_)
|
||||
static void write_whole_device(DeviceAbstraction &, std::size_t, false_)
|
||||
{} //Empty
|
||||
|
||||
template<bool dummy>
|
||||
static void write_whole_device(DeviceAbstraction &dev, std::size_t size, boost::mpl::true_)
|
||||
static void write_whole_device(DeviceAbstraction &dev, std::size_t size, true_)
|
||||
{
|
||||
file_handle_t hnd = detail::file_handle_from_mapping_handle(dev.get_mapping_handle());
|
||||
|
||||
@@ -208,7 +224,7 @@ class managed_open_or_create_impl
|
||||
;remaining -= write_size){
|
||||
const std::size_t DataSize = 512;
|
||||
static char data [DataSize];
|
||||
write_size = min_value(DataSize, remaining);
|
||||
write_size = DataSize < remaining ? DataSize : remaining;
|
||||
if(!detail::write_file(hnd, data, write_size)){
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
@@ -218,23 +234,23 @@ class managed_open_or_create_impl
|
||||
|
||||
//These are templatized to allow explicit instantiations
|
||||
template<bool dummy>
|
||||
static void truncate_device(DeviceAbstraction &, std::size_t, boost::mpl::false_)
|
||||
static void truncate_device(DeviceAbstraction &, std::size_t, false_)
|
||||
{} //Empty
|
||||
|
||||
template<bool dummy>
|
||||
static void truncate_device(DeviceAbstraction &dev, std::size_t size, boost::mpl::true_)
|
||||
static void truncate_device(DeviceAbstraction &dev, std::size_t size, true_)
|
||||
{ dev.truncate(size); }
|
||||
|
||||
//These are templatized to allow explicit instantiations
|
||||
template<bool dummy>
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t size, boost::mpl::false_)
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t size, false_)
|
||||
{
|
||||
DeviceAbstraction tmp(create_only, name, read_write, size);
|
||||
tmp.swap(dev);
|
||||
}
|
||||
|
||||
template<bool dummy>
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t, boost::mpl::true_)
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t, true_)
|
||||
{
|
||||
DeviceAbstraction tmp(create_only, name, read_write);
|
||||
tmp.swap(dev);
|
||||
@@ -246,7 +262,7 @@ class managed_open_or_create_impl
|
||||
mode_t mode, const void *addr,
|
||||
ConstructFunc construct_func)
|
||||
{
|
||||
typedef boost::mpl::bool_<FileBased> file_like_t;
|
||||
typedef bool_<FileBased> file_like_t;
|
||||
(void)mode;
|
||||
error_info err;
|
||||
bool created = false;
|
||||
|
||||
40
include/boost/interprocess/detail/min_max.hpp
Normal file
40
include/boost/interprocess/detail/min_max.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_MIN_MAX_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_MIN_MAX_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
template<class T>
|
||||
const T &max_value(const T &a, const T &b)
|
||||
{ return a > b ? a : b; }
|
||||
|
||||
template<class T>
|
||||
const T &min_value(const T &a, const T &b)
|
||||
{ return a < b ? a : b; }
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_MIN_MAX_HPP
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
/*!\file
|
||||
Describes a function and a type to emulate move semantics.
|
||||
@@ -32,6 +31,15 @@ struct is_movable
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
|
||||
/*!An object that represents a moved object.*/
|
||||
@@ -54,11 +62,7 @@ template <typename T>
|
||||
struct move_type
|
||||
{
|
||||
public: // metafunction result
|
||||
typedef typename mpl::if_<
|
||||
is_movable<T>
|
||||
, moved_object<T>
|
||||
, T&
|
||||
>::type type;
|
||||
typedef typename if_<is_movable<T>, moved_object<T>, T&>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -87,14 +91,15 @@ struct return_type
|
||||
{
|
||||
public: // metafunction result
|
||||
|
||||
typedef typename boost::mpl::if_
|
||||
<is_movable<T>
|
||||
, move_return<T>
|
||||
, T
|
||||
>::type type;
|
||||
typedef typename if_<is_movable<T>, move_return<T>, T>::type type;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
/*!A function that converts an object to a moved object so that
|
||||
it can match a function taking a detail::moved_object object.*/
|
||||
@@ -109,6 +114,29 @@ typename detail::move_type<Object>::type move
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#else //#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
template <class T>
|
||||
inline typename boost::remove_reference<T>::type&&
|
||||
move(T&& t)
|
||||
{ return t; }
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
T&&
|
||||
forward(typename identity<T>::type&& t)
|
||||
{ return t; }
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_MOVE_HPP
|
||||
|
||||
@@ -25,7 +25,11 @@ class move_iterator
|
||||
public:
|
||||
typedef typename boost::remove_reference<It>::type iterator_type;
|
||||
typedef typename std::iterator_traits<iterator_type>::value_type value_type;
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
typedef typename move_type<value_type>::type reference;
|
||||
#else
|
||||
typedef value_type && reference;
|
||||
#endif
|
||||
typedef typename std::iterator_traits<iterator_type>::pointer pointer;
|
||||
typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
|
||||
@@ -49,7 +53,11 @@ class move_iterator
|
||||
{ return m_it; }
|
||||
|
||||
reference operator*() const
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
{ return move(*m_it); }
|
||||
#else
|
||||
{ return *m_it; }
|
||||
#endif
|
||||
|
||||
pointer operator->() const
|
||||
{ return m_it; }
|
||||
|
||||
88
include/boost/interprocess/detail/mpl.hpp
Normal file
88
include/boost/interprocess/detail/mpl.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_MPL_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_MPL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
template< bool C_ >
|
||||
struct bool_
|
||||
{
|
||||
static const bool value = C_;
|
||||
};
|
||||
|
||||
typedef bool_<true> true_;
|
||||
typedef bool_<false> false_;
|
||||
|
||||
template<
|
||||
bool C
|
||||
, typename T1
|
||||
, typename T2
|
||||
>
|
||||
struct if_c
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename T1
|
||||
, typename T2
|
||||
>
|
||||
struct if_c<false,T1,T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
>
|
||||
struct if_
|
||||
{
|
||||
typedef typename if_c<0 != T1::value, T2, T3>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <class Pair>
|
||||
struct select1st
|
||||
: public std::unary_function<Pair, typename Pair::first_type>
|
||||
{
|
||||
const typename Pair::first_type& operator()(const Pair& x) const
|
||||
{ return x.first; }
|
||||
|
||||
const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
|
||||
{ return x; }
|
||||
};
|
||||
|
||||
// identity is an extension: it is not part of the standard.
|
||||
template <class T>
|
||||
struct identity
|
||||
: public std::unary_function<T,T>
|
||||
{
|
||||
const T& operator()(const T& x) const
|
||||
{ return x; }
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_MPL_HPP
|
||||
|
||||
@@ -19,50 +19,43 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <new>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/interprocess/detail/in_place_interface.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
|
||||
/*!\file
|
||||
Describes a proxy class that implements named allocation syntax.
|
||||
*/
|
||||
|
||||
namespace boost { namespace interprocess {
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
|
||||
/*!Function object that makes placement new without arguments*/
|
||||
template<class T>
|
||||
struct Ctor0Arg
|
||||
struct Ctor0Arg : public placement_destroy<T>
|
||||
{
|
||||
typedef Ctor0Arg self_t;
|
||||
typedef T target_t;
|
||||
enum { is_trivial = boost::has_trivial_constructor<T>::value };
|
||||
|
||||
Ctor0Arg(){}
|
||||
|
||||
self_t& operator++() { return *this; }
|
||||
self_t operator++(int) { return *this; }
|
||||
static inline void construct(T *mem, boost::mpl::false_)
|
||||
{ new(mem)T; }
|
||||
static inline void construct(T *mem, boost::mpl::true_)
|
||||
{}
|
||||
void operator()(T *mem) const
|
||||
|
||||
virtual void construct(void *mem)
|
||||
{ new(mem)T; }
|
||||
|
||||
virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)
|
||||
{
|
||||
typedef boost::mpl::bool_<is_trivial> Result;
|
||||
Ctor0Arg<T>::construct(mem, Result());
|
||||
T* memory = static_cast<T*>(mem);
|
||||
for(constructed = 0; constructed < num; ++constructed)
|
||||
new(memory++)T;
|
||||
}
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
private:
|
||||
char dummy_; // BCB would by default use 8 B for empty structure
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS
|
||||
@@ -75,17 +68,16 @@ struct Ctor0Arg
|
||||
// template<class T, bool param_or_it, class P1, class P2>
|
||||
// struct Ctor2Arg
|
||||
// {
|
||||
// enum { is_trivial = false };
|
||||
// typedef Ctor2Arg self_t;
|
||||
//
|
||||
// void do_increment(boost::mpl::false_)
|
||||
// void do_increment(false_)
|
||||
// { ++m_p1; ++m_p2; }
|
||||
//
|
||||
// void do_increment(boost::mpl::true_){}
|
||||
// void do_increment(true_){}
|
||||
//
|
||||
// self_t& operator++()
|
||||
// {
|
||||
// typedef boost::mpl::bool_<param_or_it> Result;
|
||||
// typedef bool_<param_or_it> Result;
|
||||
// this->do_increment(Result());
|
||||
// return *this;
|
||||
// }
|
||||
@@ -95,8 +87,21 @@ struct Ctor0Arg
|
||||
// Ctor2Arg(const P1 &p1, const P2 &p2)
|
||||
// : p1((P1 &)p_1), p2((P2 &)p_2) {}
|
||||
//
|
||||
// void operator()(T* mem) const
|
||||
// { new (mem) T(m_p1, m_p2); }
|
||||
// virtual void construct(void *mem)
|
||||
// { new(object)T(m_p1, m_p2); }
|
||||
//
|
||||
// virtual void construct_n(void *mem
|
||||
// , std::size_t num
|
||||
// , std::size_t &constructed)
|
||||
// {
|
||||
// T* memory = static_cast<T*>(mem);
|
||||
// for(constructed = 0; constructed < num; ++constructed){
|
||||
// new(memory++)T(m_p1, m_p2);
|
||||
// typedef bool_<param_or_it> Result;
|
||||
// this->do_increment(Result());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private:
|
||||
// P1 &m_p1; P2 &m_p2;
|
||||
// };
|
||||
@@ -122,24 +127,27 @@ struct Ctor0Arg
|
||||
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
|
||||
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_DEREFERENCE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<class T, bool param_or_it, BOOST_PP_ENUM_PARAMS(n, class P) >\
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
|
||||
: public placement_destroy<T> \
|
||||
{ \
|
||||
enum { is_trivial = false }; \
|
||||
typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t; \
|
||||
typedef T target_t; \
|
||||
\
|
||||
void do_increment(boost::mpl::false_) \
|
||||
void do_increment(false_) \
|
||||
{ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); } \
|
||||
\
|
||||
void do_increment(boost::mpl::true_){} \
|
||||
void do_increment(true_){} \
|
||||
\
|
||||
self_t& operator++() \
|
||||
{ \
|
||||
typedef boost::mpl::bool_<param_or_it> Result; \
|
||||
typedef bool_<param_or_it> Result; \
|
||||
this->do_increment(Result()); \
|
||||
return *this; \
|
||||
} \
|
||||
@@ -150,14 +158,27 @@ struct Ctor0Arg
|
||||
( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _) ) \
|
||||
: BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {} \
|
||||
\
|
||||
void operator()(T* mem) const \
|
||||
{ new (mem) T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
|
||||
virtual void construct(void *mem) \
|
||||
{ new(mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
|
||||
\
|
||||
private: \
|
||||
virtual void construct_n(void *mem \
|
||||
, std::size_t num \
|
||||
, std::size_t &constructed) \
|
||||
{ \
|
||||
T* memory = static_cast<T*>(mem); \
|
||||
for(constructed = 0; constructed < num; ++constructed){ \
|
||||
new(memory++)T(BOOST_PP_ENUM_PARAMS(n, m_p)); \
|
||||
typedef bool_<param_or_it> Result; \
|
||||
this->do_increment(Result()); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
@@ -166,32 +187,34 @@ struct Ctor0Arg
|
||||
#undef BOOST_INTERPROCESS_AUX_PARAM_DEFINE
|
||||
#undef BOOST_INTERPROCESS_AUX_PARAM_INC
|
||||
|
||||
/*!Describes a proxy class that implements named allocation syntax.
|
||||
*/
|
||||
//!Describes a proxy class that implements named
|
||||
//!allocation syntax.
|
||||
template
|
||||
< class CharType //char type for the name (char, wchar_t...)
|
||||
< class SegmentManager //segment manager to construct the object
|
||||
, class T //type of object to build
|
||||
, class NamedAlloc //class to allocate and construct the object
|
||||
, bool find //if true, we try to find the object before creating
|
||||
, bool dothrow //if true, we throw an exception, otherwise, return 0
|
||||
, bool param_or_it //passing parameters are normal object or iterators?
|
||||
>
|
||||
class named_proxy
|
||||
{
|
||||
const CharType * mp_name;
|
||||
NamedAlloc * mp_alloc;
|
||||
typedef typename SegmentManager::char_type char_type;
|
||||
const char_type * mp_name;
|
||||
SegmentManager * mp_mngr;
|
||||
mutable std::size_t m_num;
|
||||
const bool m_find;
|
||||
const bool m_dothrow;
|
||||
|
||||
public:
|
||||
named_proxy(const CharType *name, NamedAlloc *alloc)
|
||||
: mp_name(name), mp_alloc(alloc), m_num(1){}
|
||||
public:
|
||||
named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
|
||||
: mp_name(name), mp_mngr(mngr), m_num(1)
|
||||
, m_find(find), m_dothrow(dothrow)
|
||||
{}
|
||||
|
||||
/*!makes a named allocation and calls the default constructor*/
|
||||
T *operator()() const
|
||||
{
|
||||
Ctor0Arg<T> ctor_obj;
|
||||
return mp_alloc->template
|
||||
generic_construct<T>(mp_name, m_num, find, dothrow, ctor_obj);
|
||||
return mp_mngr->template
|
||||
generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
|
||||
}
|
||||
/**/
|
||||
|
||||
@@ -212,8 +235,8 @@ class named_proxy
|
||||
<T, param_or_it, BOOST_PP_ENUM (n, BOOST_INTERPROCESS_AUX_TYPE_LIST, _)> \
|
||||
ctor_obj_t; \
|
||||
ctor_obj_t ctor_obj (BOOST_PP_ENUM_PARAMS(n, p)); \
|
||||
return mp_alloc->template generic_construct<T> \
|
||||
(mp_name, m_num, find, dothrow, ctor_obj); \
|
||||
return mp_mngr->template generic_construct<T> \
|
||||
(mp_name, m_num, m_find, m_dothrow, ctor_obj); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
@@ -234,8 +257,8 @@ class named_proxy
|
||||
// ctor_obj_t;
|
||||
// ctor_obj_t ctor_obj(p1, p2);
|
||||
//
|
||||
// return mp_alloc->template generic_construct<T>
|
||||
// (mp_name, m_num, find, dothrow, ctor_obj);
|
||||
// return mp_mngr->template generic_construct<T>
|
||||
// (mp_name, m_num, m_find, m_dothrow, ctor_obj);
|
||||
// }
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
73
include/boost/interprocess/detail/pointer_type.hpp
Normal file
73
include/boost/interprocess/detail/pointer_type.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2007.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_POINTER_TYPE_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_POINTER_TYPE_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
|
||||
struct two {char _[2];};
|
||||
|
||||
namespace pointer_type_imp {
|
||||
|
||||
template <class U> static two test(...);
|
||||
template <class U> static char test(typename U::pointer* = 0);
|
||||
|
||||
} //namespace pointer_type_imp {
|
||||
|
||||
template <class T>
|
||||
struct has_pointer_type
|
||||
{
|
||||
static const bool value = sizeof(pointer_type_imp::test<T>(0)) == 1;
|
||||
};
|
||||
|
||||
namespace pointer_type_imp {
|
||||
|
||||
template <class T, class D, bool = has_pointer_type<D>::value>
|
||||
struct pointer_type
|
||||
{
|
||||
typedef typename D::pointer type;
|
||||
};
|
||||
|
||||
template <class T, class D>
|
||||
struct pointer_type<T, D, false>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
} //namespace pointer_type_imp {
|
||||
|
||||
template <class T, class D>
|
||||
struct pointer_type
|
||||
{
|
||||
typedef typename pointer_type_imp::pointer_type<T,
|
||||
typename boost::remove_reference<D>::type>::type type;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_POINTER_TYPE_HPP
|
||||
|
||||
@@ -22,37 +22,42 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/type_traits/has_nothrow_destructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <boost/interprocess/detail/min_max.hpp>
|
||||
//#include <functional>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
|
||||
namespace boost { namespace interprocess {
|
||||
|
||||
template<class T>
|
||||
class offset_ptr;
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
|
||||
/*!Overload for smart pointers to avoid ADL problems with get_pointer*/
|
||||
template<class Ptr>
|
||||
inline typename Ptr::value_type *get_pointer(const Ptr &ptr)
|
||||
{ using boost::get_pointer; return get_pointer(ptr); }
|
||||
template<class SmartPtr>
|
||||
struct smart_ptr_type
|
||||
{
|
||||
typedef typename SmartPtr::value_type value_type;
|
||||
typedef value_type *pointer;
|
||||
static pointer get (const SmartPtr &smartptr)
|
||||
{ return smartptr.get();}
|
||||
};
|
||||
|
||||
/*!Overload for raw pointers to avoid ADL problems with get_pointer*/
|
||||
template<class T>
|
||||
inline T *get_pointer(T *ptr)
|
||||
{ return ptr; }
|
||||
struct smart_ptr_type<T*>
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef value_type *pointer;
|
||||
static pointer get (pointer ptr)
|
||||
{ return ptr;}
|
||||
};
|
||||
|
||||
/*!To avoid ADL problems with swap*/
|
||||
//!Overload for smart pointers to avoid ADL problems with get_pointer
|
||||
template<class Ptr>
|
||||
inline typename smart_ptr_type<Ptr>::pointer
|
||||
get_pointer(const Ptr &ptr)
|
||||
{ return smart_ptr_type<Ptr>::get(ptr); }
|
||||
|
||||
//!To avoid ADL problems with swap
|
||||
template <class T>
|
||||
inline void do_swap(T& x, T& y)
|
||||
{
|
||||
@@ -60,31 +65,30 @@ inline void do_swap(T& x, T& y)
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
/*!A deleter for scoped_ptr that deallocates the memory
|
||||
allocated for an object using a STL allocator.*/
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_deallocator
|
||||
struct scoped_ptr_deallocator
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
|
||||
Allocator& m_alloc;
|
||||
|
||||
scoped_deallocator(Allocator& a)
|
||||
scoped_ptr_deallocator(Allocator& a)
|
||||
: m_alloc(a) {}
|
||||
|
||||
void operator()(pointer ptr)
|
||||
{ if (ptr) m_alloc.deallocate(ptr, 1); }
|
||||
|
||||
};
|
||||
|
||||
/*!A deleter for scoped_ptr that deallocates the memory
|
||||
allocated for an array of objects using a STL allocator.*/
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an array of objects using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_array_deallocator
|
||||
struct scoped_ptr_array_deallocator
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
|
||||
scoped_array_deallocator(Allocator& a, std::size_t length)
|
||||
scoped_ptr_array_deallocator(Allocator& a, std::size_t length)
|
||||
: m_alloc(a), m_length(length) {}
|
||||
|
||||
void operator()(pointer &ptr)
|
||||
@@ -95,46 +99,78 @@ struct scoped_array_deallocator
|
||||
std::size_t m_length;
|
||||
};
|
||||
|
||||
/*!A deleter for scoped_ptr that destroys
|
||||
an object using a STL allocator.*/
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_destructor
|
||||
struct scoped_deallocator
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
|
||||
Allocator& m_alloc;
|
||||
pointer m_ptr;
|
||||
Allocator& m_alloc;
|
||||
|
||||
scoped_destructor(Allocator& a)
|
||||
: m_alloc(a){}
|
||||
scoped_deallocator(pointer p, Allocator& a)
|
||||
: m_ptr(p), m_alloc(a) {}
|
||||
|
||||
void operator()(pointer &ptr)
|
||||
{ m_alloc.destroy(ptr); }
|
||||
~scoped_deallocator()
|
||||
{ if (m_ptr) m_alloc.deallocate(m_ptr, 1); }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
};
|
||||
|
||||
/*!A deleter for scoped_ptr that destroys
|
||||
an object using a STL allocator.*/
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an array of objects using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_destructor_n
|
||||
struct scoped_array_deallocator
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
|
||||
Allocator& m_alloc;
|
||||
size_type m_n;
|
||||
scoped_array_deallocator(pointer p, Allocator& a, std::size_t length)
|
||||
: m_ptr(p), m_alloc(a), m_length(length) {}
|
||||
|
||||
scoped_destructor_n(Allocator& a, size_type n)
|
||||
: m_alloc(a), m_n(n){}
|
||||
~scoped_array_deallocator()
|
||||
{ if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
|
||||
|
||||
void operator()(pointer ptr)
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
|
||||
private:
|
||||
pointer m_ptr;
|
||||
Allocator& m_alloc;
|
||||
std::size_t m_length;
|
||||
};
|
||||
|
||||
//!A deleter for scoped_ptr that destroys
|
||||
//!an object using a STL allocator.
|
||||
template <class Pointer>
|
||||
struct scoped_destructor_n
|
||||
{
|
||||
typedef Pointer pointer;
|
||||
|
||||
pointer m_p;
|
||||
std::size_t m_n;
|
||||
|
||||
scoped_destructor_n(pointer p, std::size_t n)
|
||||
: m_p(p), m_n(n){}
|
||||
|
||||
void release()
|
||||
{ m_p = 0; }
|
||||
|
||||
~scoped_destructor_n()
|
||||
{
|
||||
for(size_type i = 0; i < m_n; ++i, ++ptr)
|
||||
m_alloc.destroy(ptr);
|
||||
if(!m_p) return;
|
||||
typedef typename std::iterator_traits<Pointer>::value_type value_type;
|
||||
value_type *raw_ptr = detail::get_pointer(m_p);
|
||||
for(std::size_t i = 0; i < m_n; ++i, ++raw_ptr)
|
||||
raw_ptr->~value_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_destroyer
|
||||
{
|
||||
typedef typename A::value_type value_type;
|
||||
private:
|
||||
A & a_;
|
||||
|
||||
@@ -143,9 +179,9 @@ class allocator_destroyer
|
||||
: a_(a)
|
||||
{}
|
||||
|
||||
void operator()(typename A::pointer p)
|
||||
void operator()(const typename A::pointer &p)
|
||||
{
|
||||
a_.destroy(p);
|
||||
detail::get_pointer(p)->~value_type();
|
||||
a_.deallocate(p, 1);
|
||||
}
|
||||
};
|
||||
@@ -164,23 +200,6 @@ inline char* char_ptr_cast()
|
||||
return (char*)(0);
|
||||
}
|
||||
|
||||
template <class Pair>
|
||||
struct select1st
|
||||
: public std::unary_function<Pair, typename Pair::first_type>
|
||||
{
|
||||
const typename Pair::first_type& operator()(const Pair& x) const
|
||||
{ return x.first; }
|
||||
};
|
||||
|
||||
// identity is an extension: it is not part of the standard.
|
||||
template <class T>
|
||||
struct identity
|
||||
: public std::unary_function<T,T>
|
||||
{
|
||||
const T& operator()(const T& x) const
|
||||
{ return x; }
|
||||
};
|
||||
|
||||
//Rounds "orig_size" by excess to round_to bytes
|
||||
inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to)
|
||||
{
|
||||
@@ -191,7 +210,6 @@ inline std::size_t get_truncated_size(std::size_t orig_size, std::size_t multipl
|
||||
{
|
||||
return orig_size/multiple*multiple;
|
||||
}
|
||||
|
||||
|
||||
template <std::size_t OrigSize, std::size_t RoundTo>
|
||||
struct ct_rounded_size
|
||||
@@ -259,46 +277,8 @@ struct pointer_to_other< T*, U >
|
||||
typedef U* type;
|
||||
};
|
||||
|
||||
//Anti-exception node eraser
|
||||
template<class Cont>
|
||||
class value_eraser
|
||||
{
|
||||
public:
|
||||
value_eraser(Cont & cont, typename Cont::iterator it)
|
||||
: m_cont(cont), m_index_it(it), m_erase(true){}
|
||||
~value_eraser()
|
||||
{
|
||||
if(boost::has_nothrow_destructor<typename Cont::value_type>::value){
|
||||
if(m_erase) m_cont.erase(m_index_it);
|
||||
}
|
||||
else{
|
||||
//value_eraser is used in exceptions, so we
|
||||
//disable double-exception danger
|
||||
BOOST_TRY{ if(m_erase) m_cont.erase(m_index_it); }
|
||||
BOOST_CATCH(...){}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
}
|
||||
void release() { m_erase = false; }
|
||||
|
||||
private:
|
||||
Cont &m_cont;
|
||||
typename Cont::iterator m_index_it;
|
||||
bool m_erase;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
|
||||
/*!Trait class to detect if an allocator has
|
||||
a templatized construct function. If this is the case
|
||||
in node containers we only need just one allocator
|
||||
instead of three*/
|
||||
template <class Allocator>
|
||||
struct has_convertible_construct
|
||||
{
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
/*!Trait class to detect if an index is a node
|
||||
index. This allows more efficient operations
|
||||
when deallocating named objects.*/
|
||||
@@ -351,295 +331,15 @@ class deleter
|
||||
{ mp_deleter->destroy_ptr(detail::get_pointer(p)); }
|
||||
};
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class constant_iterator
|
||||
: public boost::iterator_facade
|
||||
< constant_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, const T &
|
||||
, Difference>
|
||||
{
|
||||
typedef boost::iterator_facade
|
||||
< constant_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, const T &
|
||||
, Difference> super_t;
|
||||
|
||||
typedef constant_iterator<T, Difference> this_type;
|
||||
//Give access to private core functions
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
public:
|
||||
explicit constant_iterator(const T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
constant_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
private:
|
||||
const T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class repeat_iterator
|
||||
: public boost::iterator_facade
|
||||
< repeat_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, T &
|
||||
, Difference>
|
||||
{
|
||||
typedef boost::iterator_facade
|
||||
< repeat_iterator<T, Difference>
|
||||
, T
|
||||
, boost::random_access_traversal_tag
|
||||
, T &
|
||||
, Difference> super_t;
|
||||
|
||||
typedef repeat_iterator<T, Difference> this_type;
|
||||
//Give access to private core functions
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
public:
|
||||
explicit repeat_iterator(T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
repeat_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
private:
|
||||
T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template<class FwdIt, class Count, class T, class Alloc> inline
|
||||
void uninitialized_fill_n(FwdIt first, Count count,
|
||||
const T& val, Alloc& al)
|
||||
{
|
||||
//Save initial position
|
||||
FwdIt init = first;
|
||||
|
||||
BOOST_TRY{
|
||||
//Construct objects
|
||||
for (; count--; ++first){
|
||||
al.construct(first, val);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; init != first; ++init){
|
||||
al.destroy(init);
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template<class InIt, class OutIt>
|
||||
InIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
|
||||
{
|
||||
for (; length--; ++dest, ++first)
|
||||
*dest = *first;
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
template<class InIt, class FwdIt, class Alloc> inline
|
||||
typename std::iterator_traits<InIt>::difference_type
|
||||
n_uninitialized_copy(InIt first, InIt last,
|
||||
FwdIt dest, Alloc& al)
|
||||
{
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
typename std::iterator_traits<InIt>::difference_type constructed = 0;
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; first != last; ++dest, ++first, ++constructed){
|
||||
al.construct(dest, *first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; dest_init != dest; ++dest_init){
|
||||
al.destroy(dest_init);
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return (constructed);
|
||||
}
|
||||
|
||||
template<class InIt, class FwdIt, class Alloc> inline
|
||||
FwdIt uninitialized_copy(InIt first, InIt last,
|
||||
FwdIt dest, Alloc& al)
|
||||
{
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
typename std::iterator_traits<InIt>::difference_type constructed = 0;
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; first != last; ++dest, ++first, ++constructed){
|
||||
al.construct(dest, *first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
for (; dest_init != dest; ++dest_init){
|
||||
al.destroy(dest_init);
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return (dest);
|
||||
}
|
||||
|
||||
template<class InIt, class FwdIt, class Alloc> inline
|
||||
InIt n_uninitialized_copy_n
|
||||
(InIt first,
|
||||
typename std::iterator_traits<InIt>::difference_type count,
|
||||
FwdIt dest, Alloc& al)
|
||||
{
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
typename std::iterator_traits<InIt>::difference_type new_count = count+1;
|
||||
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; --new_count; ++dest, ++first){
|
||||
al.construct(dest, *first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
new_count = count - new_count;
|
||||
for (; new_count--; ++dest_init){
|
||||
al.destroy(dest_init);
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return first;
|
||||
}
|
||||
|
||||
// uninitialized_copy_copy
|
||||
// Copies [first1, last1) into [result, result + (last1 - first1)), and
|
||||
// copies [first2, last2) into
|
||||
// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
|
||||
template <class InpIt1, class InpIt2, class FwdIt, class Alloc>
|
||||
FwdIt uninitialized_copy_copy(InpIt1 first1, InpIt1 last1,
|
||||
InpIt2 first2, InpIt2 last2,
|
||||
FwdIt result, Alloc &alloc)
|
||||
{
|
||||
FwdIt mid = uninitialized_copy(first1, last1, result, alloc);
|
||||
BOOST_TRY {
|
||||
return uninitialized_copy(first2, last2, mid, alloc);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for(;result != mid; ++result){
|
||||
alloc.destroy(&*result);
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
// uninitialized_copy_n_copy_n
|
||||
// Copies [first1, first1 + n1) into [result, result + n1), and
|
||||
// copies [first2, first2 + n2) into
|
||||
// [result + n1, result + n1 + n2).
|
||||
template <class InpIt1, class InpIt2, class FwdIt, class Alloc>
|
||||
InpIt2 uninitialized_copy_n_copy_n
|
||||
(InpIt1 first1,
|
||||
typename std::iterator_traits<InpIt1>::difference_type n1,
|
||||
InpIt2 first2,
|
||||
typename std::iterator_traits<InpIt2>::difference_type n2,
|
||||
FwdIt result,
|
||||
Alloc &alloc)
|
||||
{
|
||||
typename std::iterator_traits<InpIt1>::difference_type c1 = n1+1;
|
||||
typename std::iterator_traits<InpIt2>::difference_type c2 = n2+1;
|
||||
FwdIt dest_init = result;
|
||||
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; --c1; ++result, ++first1){
|
||||
alloc.construct(result, *first1);
|
||||
}
|
||||
for (; --c2; ++result, ++first2){
|
||||
alloc.construct(result, *first2);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
typename std::iterator_traits<FwdIt>::
|
||||
difference_type c = (n1 - c1) + (n2 - c2);
|
||||
for (; c--; ++dest_init){
|
||||
alloc.destroy(dest_init);
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return first2;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T &max_value(const T &a, const T &b)
|
||||
{ return a > b ? a : b; }
|
||||
|
||||
template<class T>
|
||||
const T &min_value(const T &a, const T &b)
|
||||
{ return a < b ? a : b; }
|
||||
|
||||
template <class SizeType>
|
||||
SizeType
|
||||
get_next_capacity(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{/*
|
||||
if (n > max_size - capacity)
|
||||
throw std::length_error("get_next_capacity");
|
||||
*/
|
||||
{
|
||||
// if (n > max_size - capacity)
|
||||
// throw std::length_error("get_next_capacity");
|
||||
|
||||
const SizeType m3 = max_size/3;
|
||||
|
||||
if (capacity < m3)
|
||||
@@ -653,44 +353,6 @@ SizeType
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct two {char _[2];};
|
||||
|
||||
namespace pointer_type_imp {
|
||||
|
||||
template <class U> static two test(...);
|
||||
template <class U> static char test(typename U::pointer* = 0);
|
||||
|
||||
} //namespace pointer_type_imp {
|
||||
|
||||
template <class T>
|
||||
struct has_pointer_type
|
||||
{
|
||||
static const bool value = sizeof(pointer_type_imp::test<T>(0)) == 1;
|
||||
};
|
||||
|
||||
namespace pointer_type_imp {
|
||||
|
||||
template <class T, class D, bool = has_pointer_type<D>::value>
|
||||
struct pointer_type
|
||||
{
|
||||
typedef typename D::pointer type;
|
||||
};
|
||||
|
||||
template <class T, class D>
|
||||
struct pointer_type<T, D, false>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
} //namespace pointer_type_imp {
|
||||
|
||||
template <class T, class D>
|
||||
struct pointer_type
|
||||
{
|
||||
typedef typename pointer_type_imp::pointer_type<T,
|
||||
typename boost::remove_reference<D>::type>::type type;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
@@ -713,31 +375,67 @@ struct pair
|
||||
: first(p.first), second(p.second)
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class D, class S>
|
||||
pair(const detail::moved_object<std::pair<D, S> >& p)
|
||||
: first(move(p.get().first)), second(move(p.get().second))
|
||||
{}
|
||||
#else
|
||||
template <class D, class S>
|
||||
pair(std::pair<D, S> && p)
|
||||
: first(move(p.first)), second(move(p.second))
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class D, class S>
|
||||
pair(const detail::moved_object<pair<D, S> >& p)
|
||||
: first(move(p.get().first)), second(move(p.get().second))
|
||||
{}
|
||||
#else
|
||||
template <class D, class S>
|
||||
pair(pair<D, S> && p)
|
||||
: first(move(p.first)), second(move(p.second))
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class U, class V>
|
||||
pair(const detail::moved_object<U> &x, const detail::moved_object<V> &y)
|
||||
: first(move(x.get())), second(move(y.get()))
|
||||
{}
|
||||
#else
|
||||
template <class U, class V>
|
||||
pair(U &&x, V &&y)
|
||||
: first(move(x)), second(move(y))
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
pair(const detail::moved_object<pair> &p)
|
||||
: first(move(p.get().first)), second(move(p.get().second))
|
||||
{}
|
||||
#else
|
||||
pair(pair &&p)
|
||||
: first(move(p.first)), second(move(p.second))
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
pair& operator=(const detail::moved_object<pair> &p)
|
||||
{
|
||||
first = move(p.get().first);
|
||||
second = move(p.get().second);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
pair& operator=(pair &&p)
|
||||
{
|
||||
first = move(p.first);
|
||||
second = move(p.second);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
pair& operator=(const pair &p)
|
||||
{
|
||||
@@ -746,6 +444,7 @@ struct pair
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class D, class S>
|
||||
pair& operator=(const detail::moved_object<std::pair<D, S> > &p)
|
||||
{
|
||||
@@ -753,12 +452,27 @@ struct pair
|
||||
second = move(p.get().second);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
template <class D, class S>
|
||||
pair& operator=(std::pair<D, S> &&p)
|
||||
{
|
||||
first = move(p.first);
|
||||
second = move(p.second);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(const detail::moved_object<pair> &p)
|
||||
{ std::swap(*this, p.get()); }
|
||||
|
||||
void swap(pair& p)
|
||||
{ std::swap(*this, p); }
|
||||
|
||||
#else
|
||||
void swap(pair &&p)
|
||||
{ std::swap(*this, p); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
@@ -790,6 +504,7 @@ template <class T1, class T2>
|
||||
inline pair<T1, T2> make_pair(T1 x, T2 y)
|
||||
{ return pair<T1, T2>(x, y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class T1, class T2>
|
||||
inline void swap(const detail::moved_object<pair<T1, T2> > &x, pair<T1, T2>& y)
|
||||
{
|
||||
@@ -811,6 +526,15 @@ inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
|
||||
swap(x.second, y.second);
|
||||
}
|
||||
|
||||
#else
|
||||
template <class T1, class T2>
|
||||
inline void swap(pair<T1, T2>&&x, pair<T1, T2>&&y)
|
||||
{
|
||||
swap(x.first, y.first);
|
||||
swap(x.second, y.second);
|
||||
}
|
||||
#endif
|
||||
|
||||
} //namespace detail {
|
||||
|
||||
//!The pair is movable if any of its members is movable
|
||||
@@ -832,9 +556,7 @@ struct is_movable<std::pair<T1, T2> >
|
||||
template <class T>
|
||||
struct has_trivial_destructor_after_move
|
||||
: public boost::has_trivial_destructor<T>
|
||||
{
|
||||
enum{ value = false };
|
||||
};
|
||||
{};
|
||||
|
||||
enum create_enum_t
|
||||
{ DoCreate, DoOpen, DoCreateOrOpen };
|
||||
|
||||
@@ -221,11 +221,13 @@ extern "C" __declspec(dllimport) int __stdcall LockFile (void *hnd, unsigned lo
|
||||
extern "C" __declspec(dllimport) int __stdcall UnlockFile(void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high);
|
||||
extern "C" __declspec(dllimport) int __stdcall LockFileEx(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
|
||||
extern "C" __declspec(dllimport) int __stdcall UnlockFileEx(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
|
||||
/*
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long volatile *, long);
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
|
||||
*/
|
||||
|
||||
} //namespace winapi {
|
||||
} //namespace interprocess {
|
||||
@@ -346,19 +348,19 @@ static inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned lo
|
||||
{ return 0 != UnlockFileEx(hnd, reserved, size_low, size_high, overlapped); }
|
||||
|
||||
static inline long interlocked_increment(long volatile *addr)
|
||||
{ return InterlockedIncrement(addr); }
|
||||
{ return BOOST_INTERLOCKED_INCREMENT(addr); }
|
||||
|
||||
static inline long interlocked_decrement(long volatile *addr)
|
||||
{ return InterlockedDecrement(addr); }
|
||||
{ return BOOST_INTERLOCKED_DECREMENT(addr); }
|
||||
|
||||
static inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2)
|
||||
{ return InterlockedCompareExchange(addr, val1, val2); }
|
||||
{ return BOOST_INTERLOCKED_COMPARE_EXCHANGE(addr, val1, val2); }
|
||||
|
||||
static inline long interlocked_exchange_add(long volatile* addend, long value)
|
||||
{ return InterlockedExchangeAdd((long*)addend, value); }
|
||||
{ return BOOST_INTERLOCKED_EXCHANGE_ADD((long*)addend, value); }
|
||||
|
||||
static inline long interlocked_exchange(long volatile* addend, long value)
|
||||
{ return InterlockedExchange((long*)addend, value); }
|
||||
{ return BOOST_INTERLOCKED_EXCHANGE((long*)addend, value); }
|
||||
|
||||
} //namespace winapi
|
||||
} //namespace interprocess
|
||||
|
||||
@@ -18,19 +18,6 @@
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
|
||||
#if defined (BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
#define BOOST_INTERPROCESS_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
// old Dinkumware
|
||||
# include <boost/compatibility/cpp_c_headers/cstddef>
|
||||
#else
|
||||
# include <cstddef>
|
||||
#endif
|
||||
|
||||
#if !(defined BOOST_WINDOWS) || (defined BOOST_DISABLE_WIN32)
|
||||
#if defined(_POSIX_THREAD_PROCESS_SHARED) && (_POSIX_THREAD_PROCESS_SHARED - 0 > 0)
|
||||
#if !defined(__CYGWIN__)
|
||||
@@ -68,12 +55,26 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
|
||||
// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are
|
||||
// passed on the command line, which in turn defines
|
||||
// __GXX_EXPERIMENTAL_CXX0X__. Note: __GXX_EXPERIMENTAL_CPP0X__ is
|
||||
// defined by some very early development versions of GCC 4.3; we will
|
||||
// remove this part of the check in the near future.
|
||||
# if defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
# define BOOST_INTERPROCESS_VARIADIC_TEMPLATES
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) || defined(BOOST_INTERPROCESS_VARIADIC_TEMPLATES)
|
||||
#define BOOST_INTERPROCESS_PERFECT_FORWARDING
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace interprocess {
|
||||
namespace workaround{
|
||||
|
||||
namespace workaround
|
||||
{
|
||||
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*//
|
||||
// //
|
||||
// We want generally const_shm_ptr to inherit//
|
||||
|
||||
@@ -54,12 +54,18 @@ class file_mapping
|
||||
/*!Moves the ownership of "moved"'s shared memory object to *this.
|
||||
After the call, "moved" does not represent any shared memory object.
|
||||
Does not throw*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
file_mapping(detail::moved_object<file_mapping> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
file_mapping(file_mapping &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
/*!Moves the ownership of "moved"'s shared memory to *this.
|
||||
After the call, "moved" does not represent any shared memory.
|
||||
Does not throw*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
file_mapping &operator=
|
||||
(detail::moved_object<file_mapping> &moved)
|
||||
{
|
||||
@@ -67,6 +73,14 @@ class file_mapping
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
file_mapping &operator=(file_mapping &&moved)
|
||||
{
|
||||
file_mapping tmp(move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Swaps to file_mappings. Does not throw*/
|
||||
void swap(file_mapping &other);
|
||||
|
||||
@@ -33,11 +33,11 @@ struct flat_map_index_aux
|
||||
typedef typename MapConfig::key_type key_type;
|
||||
typedef typename MapConfig::mapped_type mapped_type;
|
||||
typedef typename MapConfig::
|
||||
restricted_segment_manager restricted_segment_manager;
|
||||
basic_segment_manager basic_segment_manager;
|
||||
typedef std::less<key_type> key_less;
|
||||
typedef std::pair<key_type, mapped_type> value_type;
|
||||
typedef allocator<value_type
|
||||
,restricted_segment_manager> allocator_type;
|
||||
,basic_segment_manager> allocator_type;
|
||||
typedef flat_map<key_type, mapped_type,
|
||||
key_less, allocator_type> index_t;
|
||||
};
|
||||
@@ -53,12 +53,12 @@ class flat_map_index
|
||||
typedef flat_map_index_aux<MapConfig> index_aux;
|
||||
typedef typename index_aux::index_t base_type;
|
||||
typedef typename index_aux::
|
||||
restricted_segment_manager restricted_segment_manager;
|
||||
basic_segment_manager basic_segment_manager;
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
//!Constructor. Takes a pointer to the segment manager. Can throw
|
||||
flat_map_index(restricted_segment_manager *segment_mngr)
|
||||
flat_map_index(basic_segment_manager *segment_mngr)
|
||||
: base_type(typename index_aux::key_less(),
|
||||
typename index_aux::allocator_type(segment_mngr))
|
||||
{}
|
||||
|
||||
@@ -34,10 +34,10 @@ template <class MapConfig>
|
||||
struct iset_index_aux
|
||||
{
|
||||
typedef typename
|
||||
MapConfig::restricted_segment_manager restricted_segment_manager;
|
||||
MapConfig::basic_segment_manager basic_segment_manager;
|
||||
|
||||
typedef typename
|
||||
restricted_segment_manager::void_pointer void_pointer;
|
||||
basic_segment_manager::void_pointer void_pointer;
|
||||
|
||||
typedef boost::intrusive::set_base_hook
|
||||
< boost::intrusive::tag
|
||||
@@ -86,7 +86,7 @@ class iset_index
|
||||
{
|
||||
bool operator()(const intrusive_compare_key_type &i, const value_type &b) const
|
||||
{
|
||||
std::size_t blen = b.length();
|
||||
std::size_t blen = b.name_length();
|
||||
return (i.m_len < blen) ||
|
||||
(i.m_len == blen &&
|
||||
std::char_traits<char_type>::compare
|
||||
@@ -95,7 +95,7 @@ class iset_index
|
||||
|
||||
bool operator()(const value_type &b, const intrusive_compare_key_type &i) const
|
||||
{
|
||||
std::size_t blen = b.length();
|
||||
std::size_t blen = b.name_length();
|
||||
return (blen < i.m_len) ||
|
||||
(blen == i.m_len &&
|
||||
std::char_traits<char_type>::compare
|
||||
@@ -109,7 +109,7 @@ class iset_index
|
||||
|
||||
/*!Constructor. Takes a pointer to the
|
||||
segment manager. Can throw*/
|
||||
iset_index(typename MapConfig::restricted_segment_manager *)
|
||||
iset_index(typename MapConfig::basic_segment_manager *)
|
||||
: index_type(/*typename index_aux::value_compare()*/)
|
||||
{}
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ template <class MapConfig>
|
||||
struct iunordered_set_index_aux
|
||||
{
|
||||
typedef typename
|
||||
MapConfig::restricted_segment_manager restricted_segment_manager;
|
||||
MapConfig::basic_segment_manager basic_segment_manager;
|
||||
|
||||
typedef typename
|
||||
restricted_segment_manager::void_pointer void_pointer;
|
||||
basic_segment_manager::void_pointer void_pointer;
|
||||
|
||||
typedef boost::intrusive::unordered_set_base_hook
|
||||
< boost::intrusive::tag
|
||||
@@ -59,23 +59,23 @@ struct iunordered_set_index_aux
|
||||
{
|
||||
bool operator()(const intrusive_compare_key_type &i, const value_type &b) const
|
||||
{
|
||||
return (i.m_len == b.length()) &&
|
||||
return (i.m_len == b.name_length()) &&
|
||||
(std::char_traits<char_type>::compare
|
||||
(i.mp_str, b.name(), i.m_len) == 0);
|
||||
}
|
||||
|
||||
bool operator()(const value_type &b, const intrusive_compare_key_type &i) const
|
||||
{
|
||||
return (i.m_len == b.length()) &&
|
||||
return (i.m_len == b.name_length()) &&
|
||||
(std::char_traits<char_type>::compare
|
||||
(i.mp_str, b.name(), i.m_len) == 0);
|
||||
}
|
||||
|
||||
bool operator()(const value_type &b1, const value_type &b2) const
|
||||
{
|
||||
return (b1.length() == b2.length()) &&
|
||||
return (b1.name_length() == b2.name_length()) &&
|
||||
(std::char_traits<char_type>::compare
|
||||
(b1.name(), b2.name(), b1.length()) == 0);
|
||||
(b1.name(), b2.name(), b1.name_length()) == 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -85,7 +85,7 @@ struct iunordered_set_index_aux
|
||||
std::size_t operator()(const value_type &val) const
|
||||
{
|
||||
const char_type *beg = detail::get_pointer(val.name()),
|
||||
*end = beg + val.length();
|
||||
*end = beg + val.name_length();
|
||||
return boost::hash_range(beg, end);
|
||||
}
|
||||
|
||||
@@ -104,11 +104,11 @@ struct iunordered_set_index_aux
|
||||
typedef typename index_t::bucket_type bucket_type;
|
||||
|
||||
typedef allocator
|
||||
<bucket_type, restricted_segment_manager> allocator_type;
|
||||
<bucket_type, basic_segment_manager> allocator_type;
|
||||
|
||||
struct allocator_holder
|
||||
{
|
||||
allocator_holder(restricted_segment_manager *mngr)
|
||||
allocator_holder(basic_segment_manager *mngr)
|
||||
: alloc(mngr)
|
||||
{}
|
||||
allocator_type alloc;
|
||||
@@ -131,7 +131,6 @@ class iunordered_set_index
|
||||
intrusive_compare_key_type intrusive_compare_key_type;
|
||||
typedef typename index_aux::equal_function equal_function;
|
||||
typedef typename index_aux::hash_function hash_function;
|
||||
typedef typename index_aux::bucket_type bucket_type;
|
||||
typedef typename MapConfig::char_type char_type;
|
||||
typedef typename
|
||||
iunordered_set_index_aux<MapConfig>::allocator_type allocator_type;
|
||||
@@ -145,12 +144,13 @@ class iunordered_set_index
|
||||
typedef typename index_type::insert_commit_data insert_commit_data;
|
||||
typedef typename index_type::value_type value_type;
|
||||
typedef typename index_type::bucket_ptr bucket_ptr;
|
||||
typedef typename index_type::bucket_type bucket_type;
|
||||
typedef typename index_type::size_type size_type;
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
typedef typename index_aux::
|
||||
restricted_segment_manager restricted_segment_manager;
|
||||
basic_segment_manager basic_segment_manager;
|
||||
|
||||
enum { InitBufferSize = 64};
|
||||
|
||||
@@ -160,7 +160,7 @@ class iunordered_set_index
|
||||
bucket_ptr buckets = alloc.allocate(num);
|
||||
bucket_ptr buckets_init = buckets;
|
||||
for(std::size_t i = 0; i < num; ++i){
|
||||
alloc.construct(buckets_init++);
|
||||
new(get_pointer(buckets_init++))bucket_type();
|
||||
}
|
||||
return buckets;
|
||||
}
|
||||
@@ -170,7 +170,7 @@ class iunordered_set_index
|
||||
{
|
||||
bucket_ptr buckets_destroy = buckets;
|
||||
for(std::size_t i = 0; i < num; ++i){
|
||||
alloc.destroy(buckets_destroy++);
|
||||
get_pointer(buckets_destroy++)->~bucket_type();
|
||||
}
|
||||
alloc.deallocate(buckets, num);
|
||||
}
|
||||
@@ -179,7 +179,7 @@ class iunordered_set_index
|
||||
public:
|
||||
/*!Constructor. Takes a pointer to the
|
||||
segment manager. Can throw*/
|
||||
iunordered_set_index(restricted_segment_manager *mngr)
|
||||
iunordered_set_index(basic_segment_manager *mngr)
|
||||
: allocator_holder(mngr)
|
||||
, index_type
|
||||
(create_buckets( allocator_holder::alloc
|
||||
|
||||
@@ -38,7 +38,7 @@ struct map_index_aux
|
||||
typedef private_adaptive_pool
|
||||
<value_type,
|
||||
typename MapConfig::
|
||||
restricted_segment_manager> allocator_type;
|
||||
basic_segment_manager> allocator_type;
|
||||
|
||||
typedef boost::interprocess::map
|
||||
<key_type, mapped_type,
|
||||
@@ -56,13 +56,13 @@ class map_index
|
||||
typedef map_index_aux<MapConfig> index_aux;
|
||||
typedef typename index_aux::index_t base_type;
|
||||
typedef typename MapConfig::
|
||||
restricted_segment_manager restricted_segment_manager;
|
||||
basic_segment_manager basic_segment_manager;
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
/*!Constructor. Takes a pointer to the
|
||||
segment manager. Can throw*/
|
||||
map_index(restricted_segment_manager *segment_mngr)
|
||||
map_index(basic_segment_manager *segment_mngr)
|
||||
: base_type(typename index_aux::key_less(),
|
||||
segment_mngr){}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class null_index
|
||||
{
|
||||
/// @cond
|
||||
typedef typename MapConfig::
|
||||
restricted_segment_manager restricted_segment_manager;
|
||||
basic_segment_manager basic_segment_manager;
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
@@ -48,7 +48,7 @@ class null_index
|
||||
{ return iterator(0); }
|
||||
|
||||
/*!Dummy function*/
|
||||
null_index(restricted_segment_manager *){}
|
||||
null_index(basic_segment_manager *){}
|
||||
};
|
||||
|
||||
}} //namespace boost { namespace interprocess {
|
||||
|
||||
@@ -38,7 +38,7 @@ struct unordered_map_index_aux
|
||||
typedef private_adaptive_pool
|
||||
<value_type,
|
||||
typename MapConfig::
|
||||
restricted_segment_manager> allocator_type;
|
||||
basic_segment_manager> allocator_type;
|
||||
struct hasher
|
||||
: std::unary_function<key_type, std::size_t>
|
||||
{
|
||||
@@ -65,13 +65,13 @@ class unordered_map_index
|
||||
typedef unordered_map_index_aux<MapConfig> index_aux;
|
||||
typedef typename index_aux::index_t base_type;
|
||||
typedef typename
|
||||
MapConfig::restricted_segment_manager restricted_segment_manager;
|
||||
MapConfig::basic_segment_manager basic_segment_manager;
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
/*!Constructor. Takes a pointer to the
|
||||
segment manager. Can throw*/
|
||||
unordered_map_index(restricted_segment_manager *segment_mngr)
|
||||
unordered_map_index(basic_segment_manager *segment_mngr)
|
||||
: base_type(0,
|
||||
typename index_aux::hasher(),
|
||||
typename index_aux::key_equal(),
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <boost/interprocess/offset_ptr.hpp>
|
||||
#include <boost/interprocess/detail/creation_tags.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
#include <algorithm> //std::lower_bound
|
||||
|
||||
@@ -65,14 +65,26 @@ class basic_managed_external_buffer
|
||||
}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_external_buffer
|
||||
(detail::moved_object<basic_managed_external_buffer> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
basic_managed_external_buffer
|
||||
(basic_managed_external_buffer &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_external_buffer &operator=
|
||||
(detail::moved_object<basic_managed_external_buffer> &moved)
|
||||
{ this->swap(moved.get()); return *this; }
|
||||
#else
|
||||
basic_managed_external_buffer &operator=
|
||||
(basic_managed_external_buffer &&moved)
|
||||
{ this->swap(moved); return *this; }
|
||||
#endif
|
||||
|
||||
void grow(std::size_t extra_bytes)
|
||||
{ base_t::grow(extra_bytes); }
|
||||
|
||||
@@ -101,15 +101,26 @@ class basic_managed_heap_memory
|
||||
}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_heap_memory
|
||||
(detail::moved_object<basic_managed_heap_memory> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
basic_managed_heap_memory(basic_managed_heap_memory &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_heap_memory &operator=
|
||||
(detail::moved_object<basic_managed_heap_memory> &moved)
|
||||
{ this->swap(moved.get()); return *this; }
|
||||
|
||||
#else
|
||||
basic_managed_heap_memory &operator=
|
||||
(basic_managed_heap_memory &&moved)
|
||||
{ this->swap(moved); return *this; }
|
||||
#endif
|
||||
|
||||
//!Tries to resize internal heap memory so that
|
||||
//!we have room for more objects.
|
||||
//!WARNING: If memory is reallocated, all the objects will
|
||||
|
||||
@@ -87,14 +87,24 @@ class basic_managed_mapped_file
|
||||
{}
|
||||
|
||||
/*!Moves the ownership of "moved"'s managed memory to *this. Does not throw*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_mapped_file
|
||||
(detail::moved_object<basic_managed_mapped_file> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
basic_managed_mapped_file(basic_managed_mapped_file &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
/*!Moves the ownership of "moved"'s managed memory to *this. Does not throw*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_mapped_file &operator=
|
||||
(detail::moved_object<basic_managed_mapped_file> &moved)
|
||||
{ this->swap(moved.get()); return *this; }
|
||||
#else
|
||||
basic_managed_mapped_file &operator=(basic_managed_mapped_file &&moved)
|
||||
{ this->swap(moved); return *this; }
|
||||
#endif
|
||||
|
||||
/*!Destructor. Never throws.*/
|
||||
~basic_managed_mapped_file()
|
||||
|
||||
@@ -96,14 +96,24 @@ class basic_managed_shared_memory
|
||||
{}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_shared_memory
|
||||
(detail::moved_object<basic_managed_shared_memory> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
basic_managed_shared_memory(basic_managed_shared_memory &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_shared_memory &operator=
|
||||
(detail::moved_object<basic_managed_shared_memory> &moved)
|
||||
{ this->swap(moved.get()); return *this; }
|
||||
#else
|
||||
basic_managed_shared_memory &operator=(basic_managed_shared_memory &&moved)
|
||||
{ this->swap(moved); return *this; }
|
||||
#endif
|
||||
|
||||
//!Swaps the ownership of the managed shared memories managed by *this and other.
|
||||
//!Never throws.
|
||||
|
||||
@@ -96,14 +96,25 @@ class basic_managed_windows_shared_memory
|
||||
{}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_windows_shared_memory
|
||||
(detail::moved_object<basic_managed_windows_shared_memory> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
basic_managed_windows_shared_memory(basic_managed_windows_shared_memory &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
basic_managed_windows_shared_memory &operator=
|
||||
(detail::moved_object<basic_managed_windows_shared_memory> &moved)
|
||||
{ this->swap(moved.get()); return *this; }
|
||||
#else
|
||||
basic_managed_windows_shared_memory &operator=
|
||||
(basic_managed_windows_shared_memory &&moved)
|
||||
{ this->swap(moved); return *this; }
|
||||
#endif
|
||||
|
||||
//!Destructor. Never throws.
|
||||
~basic_managed_windows_shared_memory()
|
||||
|
||||
@@ -71,14 +71,22 @@ class mapped_region
|
||||
|
||||
/*!Move constructor. *this will be constructed taking ownership of "other"'s
|
||||
region and "other" will be left in default constructor state.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
mapped_region(detail::moved_object<mapped_region> other);
|
||||
#else
|
||||
mapped_region(mapped_region &&other);
|
||||
#endif
|
||||
|
||||
/*!Destroys the mapped region. Does not throw*/
|
||||
~mapped_region();
|
||||
|
||||
/*!Move assignment. If *this owns a memory mapped region, it will be
|
||||
destroyed and it will take ownership of "other"'s memory mapped region.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
mapped_region &operator=(detail::moved_object<mapped_region> other);
|
||||
#else
|
||||
mapped_region &operator=(mapped_region &&other);
|
||||
#endif
|
||||
|
||||
/*!Returns the size of the mapping. Note for windows users: If
|
||||
windows_shared_memory is mapped using 0 as the size, it returns 0
|
||||
@@ -128,8 +136,13 @@ class mapped_region
|
||||
inline void swap(mapped_region &x, mapped_region &y)
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
inline mapped_region &mapped_region::operator=(detail::moved_object<mapped_region> other)
|
||||
{ this->swap(other.get()); return *this; }
|
||||
#else
|
||||
inline mapped_region &mapped_region::operator=(mapped_region &&other)
|
||||
{ this->swap(other); return *this; }
|
||||
#endif
|
||||
|
||||
inline mapped_region::~mapped_region()
|
||||
{ this->priv_close(); }
|
||||
@@ -150,11 +163,19 @@ inline mapped_region::mapped_region()
|
||||
, m_file_mapping_hnd(0)
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
inline mapped_region::mapped_region(detail::moved_object<mapped_region> other)
|
||||
: m_base(0), m_size(0), m_offset(0)
|
||||
, m_extra_offset(0)
|
||||
, m_file_mapping_hnd(0)
|
||||
{ this->swap(other.get()); }
|
||||
#else
|
||||
inline mapped_region::mapped_region(mapped_region &&other)
|
||||
: m_base(0), m_size(0), m_offset(0)
|
||||
, m_extra_offset(0)
|
||||
, m_file_mapping_hnd(0)
|
||||
{ this->swap(other); }
|
||||
#endif
|
||||
|
||||
template<int dummy>
|
||||
inline std::size_t mapped_region::page_size_holder<dummy>::get_page_size()
|
||||
@@ -335,10 +356,17 @@ inline mapped_region::mapped_region()
|
||||
: m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0)
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
inline mapped_region::mapped_region(detail::moved_object<mapped_region> other)
|
||||
: m_base(MAP_FAILED), m_size(0), m_offset(0)
|
||||
, m_extra_offset(0)
|
||||
{ this->swap(other.get()); }
|
||||
#else
|
||||
inline mapped_region::mapped_region(mapped_region &&other)
|
||||
: m_base(MAP_FAILED), m_size(0), m_offset(0)
|
||||
, m_extra_offset(0)
|
||||
{ this->swap(other); }
|
||||
#endif
|
||||
|
||||
template<int dummy>
|
||||
inline std::size_t mapped_region::page_size_holder<dummy>::get_page_size()
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/min_max.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
@@ -137,6 +138,9 @@ class simple_seq_fit_impl
|
||||
/*!Returns the size of the memory segment*/
|
||||
std::size_t get_size() const;
|
||||
|
||||
/*!Returns the number of free bytes of the memory segment*/
|
||||
std::size_t get_free_memory() const;
|
||||
|
||||
/*!Increases managed memory in extra_size bytes more*/
|
||||
void grow(std::size_t extra_size);
|
||||
|
||||
@@ -148,7 +152,7 @@ class simple_seq_fit_impl
|
||||
|
||||
//!Initializes to zero all the memory that's not in use.
|
||||
//!This function is normally used for security reasons.
|
||||
void clear_free_memory();
|
||||
void zero_free_memory();
|
||||
|
||||
std::pair<void *, bool>
|
||||
allocation_command (allocation_type command, std::size_t limit_size,
|
||||
@@ -288,6 +292,13 @@ template<class MutexFamily, class VoidPointer>
|
||||
inline std::size_t simple_seq_fit_impl<MutexFamily, VoidPointer>::get_size() const
|
||||
{ return m_header.m_size; }
|
||||
|
||||
template<class MutexFamily, class VoidPointer>
|
||||
inline std::size_t simple_seq_fit_impl<MutexFamily, VoidPointer>::get_free_memory() const
|
||||
{
|
||||
return m_header.m_size - m_header.m_allocated -
|
||||
((char*)detail::get_pointer(m_header.m_root.m_next) - (char*)this);
|
||||
}
|
||||
|
||||
template<class MutexFamily, class VoidPointer>
|
||||
inline std::size_t simple_seq_fit_impl<MutexFamily, VoidPointer>::
|
||||
get_min_size (std::size_t extra_hdr_bytes)
|
||||
@@ -309,7 +320,7 @@ inline bool simple_seq_fit_impl<MutexFamily, VoidPointer>::
|
||||
}
|
||||
|
||||
template<class MutexFamily, class VoidPointer>
|
||||
inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::clear_free_memory()
|
||||
inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::zero_free_memory()
|
||||
{
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
|
||||
@@ -448,7 +459,6 @@ void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
|
||||
detail::get_rounded_size(preferred_size - extra_forward, Alignment);
|
||||
|
||||
if(!only_preferred_backwards){
|
||||
needs_backwards =
|
||||
max_value(detail::get_rounded_size(min_size - extra_forward, Alignment)
|
||||
,min_value(prev->get_user_bytes(), needs_backwards));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/min_max.hpp>
|
||||
#include <boost/interprocess/detail/gcd_lcm.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
@@ -80,10 +81,10 @@ class rbtree_best_fit
|
||||
{
|
||||
//!This block's memory size (including block_ctrl
|
||||
//!header) in Alignment units
|
||||
unsigned m_prev_size : sizeof(std::size_t)*CHAR_BIT - 1;
|
||||
unsigned m_end : 1;
|
||||
unsigned m_size : sizeof(std::size_t)*CHAR_BIT - 1;
|
||||
unsigned m_allocated : 1;
|
||||
std::size_t m_prev_size : sizeof(std::size_t)*CHAR_BIT - 1;
|
||||
std::size_t m_end : 1;
|
||||
std::size_t m_size : sizeof(std::size_t)*CHAR_BIT - 1;
|
||||
std::size_t m_allocated : 1;
|
||||
};
|
||||
|
||||
//!Block control structure
|
||||
@@ -153,9 +154,12 @@ class rbtree_best_fit
|
||||
//!Returns the size of the memory segment
|
||||
std::size_t get_size() const;
|
||||
|
||||
//!Returns the number of free bytes of the segment
|
||||
std::size_t get_free_memory() const;
|
||||
|
||||
//!Initializes to zero all the memory that's not in use.
|
||||
//!This function is normally used for security reasons.
|
||||
void clear_free_memory();
|
||||
void zero_free_memory();
|
||||
|
||||
//!Increases managed memory in extra_size bytes more
|
||||
void grow(std::size_t extra_size);
|
||||
@@ -410,6 +414,13 @@ template<class MutexFamily, class VoidPointer>
|
||||
inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::get_size() const
|
||||
{ return m_header.m_size; }
|
||||
|
||||
template<class MutexFamily, class VoidPointer>
|
||||
inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::get_free_memory() const
|
||||
{
|
||||
return m_header.m_size - m_header.m_allocated -
|
||||
priv_multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
|
||||
}
|
||||
|
||||
template<class MutexFamily, class VoidPointer>
|
||||
inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
|
||||
get_min_size (std::size_t extra_hdr_bytes)
|
||||
@@ -510,7 +521,7 @@ inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
|
||||
}
|
||||
|
||||
template<class MutexFamily, class VoidPointer>
|
||||
inline void rbtree_best_fit<MutexFamily, VoidPointer>::clear_free_memory()
|
||||
inline void rbtree_best_fit<MutexFamily, VoidPointer>::zero_free_memory()
|
||||
{
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
|
||||
@@ -1182,7 +1193,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer>::priv_check_and_allocate
|
||||
priv_check_alignment(block);
|
||||
|
||||
//Clear the memory occupied by the tree hook, since this won't be
|
||||
//cleared with clear_free_memory
|
||||
//cleared with zero_free_memory
|
||||
TreeHook *t = static_cast<TreeHook*>(block);
|
||||
std::memset(t, 0, sizeof(*t));
|
||||
return priv_get_user_buffer(block);
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
#include <boost/interprocess/detail/cast_tags.hpp>
|
||||
#include <boost/interprocess/detail/generic_cast.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
/*!\file
|
||||
Describes a smart pointer that stores the offset between this pointer and
|
||||
@@ -33,6 +30,13 @@
|
||||
*/
|
||||
namespace boost {
|
||||
|
||||
//Predeclarations
|
||||
template <class T>
|
||||
struct has_trivial_constructor;
|
||||
|
||||
template <class T>
|
||||
struct has_trivial_destructor;
|
||||
|
||||
namespace interprocess {
|
||||
|
||||
/*!A smart pointer that stores the offset between between the pointer and the
|
||||
@@ -320,15 +324,13 @@ inline boost::interprocess::offset_ptr<T>
|
||||
/// @cond
|
||||
//!has_trivial_constructor<> == true_type specialization for optimizations
|
||||
template <class T>
|
||||
struct has_trivial_constructor
|
||||
< boost::interprocess::offset_ptr<T> >
|
||||
struct has_trivial_constructor< boost::interprocess::offset_ptr<T> >
|
||||
: public true_type
|
||||
{};
|
||||
|
||||
///has_trivial_destructor<> == true_type specialization for optimizations
|
||||
template <class T>
|
||||
struct has_trivial_destructor
|
||||
< boost::interprocess::offset_ptr<T> >
|
||||
struct has_trivial_destructor< boost::interprocess::offset_ptr<T> >
|
||||
: public true_type
|
||||
{};
|
||||
|
||||
@@ -380,13 +382,13 @@ class cast_to< offset_ptr<T> >
|
||||
namespace intrusive {
|
||||
|
||||
//Predeclaration to avoid including header
|
||||
template<class Pointer>
|
||||
template<class VoidPointer, std::size_t N>
|
||||
struct has_pointer_plus_bit;
|
||||
|
||||
template<class T>
|
||||
struct has_pointer_plus_bit<boost::interprocess::offset_ptr<T> >
|
||||
template<std::size_t N>
|
||||
struct has_pointer_plus_bit<boost::interprocess::offset_ptr<void>, N>
|
||||
{
|
||||
enum { value = (boost::alignment_of<T>::value % 4u) == 0 };
|
||||
enum { value = (N % 4u) == 0 };
|
||||
};
|
||||
|
||||
//Predeclaration
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -75,13 +75,19 @@ class shared_memory_object
|
||||
//!Moves the ownership of "moved"'s shared memory object to *this.
|
||||
//!After the call, "moved" does not represent any shared memory object.
|
||||
//!Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
shared_memory_object
|
||||
(detail::moved_object<shared_memory_object> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
shared_memory_object(shared_memory_object &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
//!Moves the ownership of "moved"'s shared memory to *this.
|
||||
//!After the call, "moved" does not represent any shared memory.
|
||||
//!Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
shared_memory_object &operator=
|
||||
(detail::moved_object<shared_memory_object> &moved)
|
||||
{
|
||||
@@ -89,6 +95,14 @@ class shared_memory_object
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
shared_memory_object &operator=(shared_memory_object &&moved)
|
||||
{
|
||||
shared_memory_object tmp(move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//!Swaps the shared_memory_objects. Does not throw
|
||||
void swap(shared_memory_object &other);
|
||||
@@ -122,8 +136,8 @@ class shared_memory_object
|
||||
bool priv_open_or_create(create_enum_t type, const char *filename, mode_t mode);
|
||||
|
||||
file_handle_t m_handle;
|
||||
mode_t m_mode;
|
||||
std::string m_filename;
|
||||
mode_t m_mode;
|
||||
std::string m_filename;
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
@@ -261,10 +275,15 @@ inline bool shared_memory_object::priv_open_or_create
|
||||
const char *filename,
|
||||
mode_t mode)
|
||||
{
|
||||
m_filename = filename;
|
||||
bool slash_added = filename[0] != '/';
|
||||
//First add precedding "/"
|
||||
m_filename.clear();
|
||||
if(slash_added){
|
||||
m_filename = '/';
|
||||
}
|
||||
m_filename += filename;
|
||||
|
||||
//Create new mapping
|
||||
|
||||
int oflag = 0;
|
||||
if(mode == read_only){
|
||||
oflag |= O_RDONLY;
|
||||
@@ -295,7 +314,7 @@ inline bool shared_memory_object::priv_open_or_create
|
||||
}
|
||||
|
||||
//Open file using POSIX API
|
||||
m_handle = shm_open(filename, oflag, S_IRWXO | S_IRWXG | S_IRWXU);
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, S_IRWXO | S_IRWXG | S_IRWXU);
|
||||
|
||||
//Check for error
|
||||
if(m_handle == -1){
|
||||
@@ -304,13 +323,28 @@ inline bool shared_memory_object::priv_open_or_create
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
|
||||
if(slash_added){
|
||||
m_filename.erase(m_filename.begin());
|
||||
}
|
||||
|
||||
m_mode = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool shared_memory_object::remove(const char *filename)
|
||||
{
|
||||
return 0 != shm_unlink(filename);
|
||||
try{
|
||||
std::string file_str;
|
||||
//First add precedding "/"
|
||||
if(filename[0] != '/'){
|
||||
file_str = '/';
|
||||
}
|
||||
file_str += filename;
|
||||
return 0 != shm_unlink(file_str.c_str());
|
||||
}
|
||||
catch(...){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void shared_memory_object::truncate(offset_t length)
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// This file is the adaptation for shared memory memory mapped
|
||||
// files of boost/detail/sp_counted_base_pt.hpp
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Ion Gaztanaga
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/interprocess/sync/posix/pthread_helpers.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace interprocess{
|
||||
|
||||
namespace detail{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
mutable pthread_mutex_t m_mut;
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
detail::mutexattr_wrapper mut_attr;
|
||||
detail::mutex_initializer mut(m_mut, mut_attr);
|
||||
mut.release();
|
||||
}
|
||||
|
||||
~sp_counted_base() // nothrow
|
||||
{
|
||||
int res = pthread_mutex_destroy(&m_mut);
|
||||
assert(res == 0);(void)res;
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
/*
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
*/
|
||||
void add_ref_copy()
|
||||
{
|
||||
pthread_mutex_lock( &m_mut );
|
||||
++use_count_;
|
||||
pthread_mutex_unlock( &m_mut );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
pthread_mutex_lock( &m_mut );
|
||||
bool r = use_count_ == 0? false: ( ++use_count_, true );
|
||||
pthread_mutex_unlock( &m_mut );
|
||||
return r;
|
||||
}
|
||||
|
||||
bool ref_release() // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_mut );
|
||||
long new_use_count = --use_count_;
|
||||
pthread_mutex_unlock( &m_mut );
|
||||
|
||||
return new_use_count == 0;
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_mut );
|
||||
++weak_count_;
|
||||
pthread_mutex_unlock( &m_mut );
|
||||
}
|
||||
|
||||
bool weak_release() // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_mut );
|
||||
long new_weak_count = --weak_count_;
|
||||
pthread_mutex_unlock( &m_mut );
|
||||
|
||||
return new_weak_count == 0;
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_mut );
|
||||
long r = use_count_;
|
||||
pthread_mutex_unlock( &m_mut );
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace interprocess
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
||||
@@ -1,119 +0,0 @@
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
||||
#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// This file is the adaptation for shared memory memory mapped
|
||||
// files of boost/detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Ion Gaztanaga
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/win32_api.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace interprocess {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
long use_count_; // #shared
|
||||
long weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{}
|
||||
|
||||
~sp_counted_base() // nothrow
|
||||
{}
|
||||
/*
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
*/
|
||||
void add_ref_copy()
|
||||
{
|
||||
winapi::interlocked_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
long tmp = static_cast< long const volatile& >( use_count_ );
|
||||
if( tmp == 0 ) return false;
|
||||
if( winapi::interlocked_compare_exchange( &use_count_, tmp + 1, tmp ) == tmp ) return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ref_release() // nothrow
|
||||
{ return winapi::interlocked_decrement( &use_count_ ) == 0; }
|
||||
|
||||
/*
|
||||
void release() // nothrow
|
||||
{
|
||||
if(ref_release()){
|
||||
//dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
*/
|
||||
void weak_add_ref() // nothrow
|
||||
{ winapi::interlocked_increment( &weak_count_ ); }
|
||||
|
||||
bool weak_release() // nothrow
|
||||
{ return winapi::interlocked_decrement( &weak_count_ ) == 0; }
|
||||
|
||||
long use_count() const // nothrow
|
||||
{ return static_cast<long const volatile &>( use_count_ ); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace interprocess
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
||||
@@ -28,8 +28,7 @@
|
||||
#include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
|
||||
#include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <functional> // std::less
|
||||
|
||||
namespace boost {
|
||||
@@ -84,7 +83,7 @@ class shared_count
|
||||
m_pi = alloc.allocate(1);
|
||||
//Anti-exception deallocator
|
||||
scoped_ptr<counted_impl,
|
||||
scoped_deallocator<counted_impl_allocator> >
|
||||
scoped_ptr_deallocator<counted_impl_allocator> >
|
||||
deallocator(m_pi, alloc);
|
||||
//It's more correct to use A::construct but
|
||||
//this needs copy constructor and we don't like it
|
||||
|
||||
@@ -84,8 +84,9 @@ class sp_counted_impl_pd
|
||||
this_pointer this_ptr (this);
|
||||
//Do it now!
|
||||
scoped_ptr<this_type,
|
||||
scoped_deallocator<this_allocator> >(this_ptr, a_copy);
|
||||
a_copy.destroy(this_ptr);
|
||||
scoped_ptr_deallocator<this_allocator> >(this_ptr, a_copy);
|
||||
typedef typename this_allocator::value_type value_type;
|
||||
detail::get_pointer(this_ptr)->~value_type();
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/pointer_type.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/compressed_pair.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <cstddef>
|
||||
@@ -103,7 +104,7 @@ class unique_ptr
|
||||
{}
|
||||
|
||||
unique_ptr(pointer p
|
||||
,typename boost::mpl::if_<boost::is_reference<D>
|
||||
,typename if_<boost::is_reference<D>
|
||||
,D
|
||||
,typename boost::add_reference<const D>::type>::type d)
|
||||
: ptr_(p, d)
|
||||
@@ -113,9 +114,15 @@ class unique_ptr
|
||||
: ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter())
|
||||
{}
|
||||
*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
unique_ptr(detail::moved_object<unique_ptr> u)
|
||||
: ptr_(u.get().release(), u.get().get_deleter())
|
||||
{}
|
||||
#else
|
||||
unique_ptr(unique_ptr &&u)
|
||||
: ptr_(u.release(), u.get_deleter())
|
||||
{}
|
||||
#endif
|
||||
/*
|
||||
template <class U, class E>
|
||||
unique_ptr(const unique_ptr<U, E>& u,
|
||||
@@ -132,6 +139,7 @@ class unique_ptr
|
||||
: ptr_(const_cast<unique_ptr<U,E>&>(u).release(), u.get_deleter())
|
||||
{}
|
||||
*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
template <class U, class E>
|
||||
unique_ptr(const detail::moved_object<unique_ptr<U, E> >& u,
|
||||
typename boost::enable_if_c<
|
||||
@@ -146,6 +154,22 @@ class unique_ptr
|
||||
>::type = nat())
|
||||
: ptr_(const_cast<unique_ptr<U,E>&>(u.get()).release(), u.get().get_deleter())
|
||||
{}
|
||||
#else
|
||||
template <class U, class E>
|
||||
unique_ptr(unique_ptr<U, E> && u,
|
||||
typename boost::enable_if_c<
|
||||
boost::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
|
||||
boost::is_convertible<E, D>::value &&
|
||||
(
|
||||
!boost::is_reference<D>::value ||
|
||||
boost::is_same<D, E>::value
|
||||
)
|
||||
,
|
||||
nat
|
||||
>::type = nat())
|
||||
: ptr_(const_cast<unique_ptr<U,E>&>(u).release(), u.get_deleter())
|
||||
{}
|
||||
#endif
|
||||
|
||||
// destructor
|
||||
~unique_ptr()
|
||||
@@ -211,11 +235,16 @@ class unique_ptr
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(unique_ptr& u)
|
||||
{ ptr_.swap(u.ptr_); }
|
||||
|
||||
|
||||
void swap(detail::moved_object<unique_ptr> mu)
|
||||
{ ptr_.swap(mu.get().ptr_); }
|
||||
#else
|
||||
void swap(unique_ptr&&u)
|
||||
{ ptr_.swap(u.ptr_); }
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
@@ -247,7 +276,7 @@ public:
|
||||
// constructors
|
||||
unique_ptr() : ptr_(pointer()) {}
|
||||
explicit unique_ptr(pointer p) : ptr_(p) {}
|
||||
unique_ptr(pointer p, typename boost::mpl::if_<
|
||||
unique_ptr(pointer p, typename if_<
|
||||
boost::is_reference<D>,
|
||||
D,
|
||||
typename boost::add_reference<const D>::type>::type d)
|
||||
@@ -326,7 +355,7 @@ public:
|
||||
// constructors
|
||||
unique_ptr() : ptr_(pointer()) {}
|
||||
explicit unique_ptr(pointer p) : ptr_(p) {}
|
||||
unique_ptr(pointer p, typename boost::mpl::if_<
|
||||
unique_ptr(pointer p, typename if_<
|
||||
boost::is_reference<D>,
|
||||
D,
|
||||
typename boost::add_reference<const D>::type>::type d)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
|
||||
@@ -127,9 +127,15 @@ class scoped_lock
|
||||
can be moved with the expression: "move(lock);". This
|
||||
constructor does not alter the state of the mutex, only potentially
|
||||
who owns it.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
explicit scoped_lock(detail::moved_object<scoped_lock<Mutex> > scop)
|
||||
: mp_mutex(0), m_locked(scop.get().owns())
|
||||
{ mp_mutex = scop.get().release(); }
|
||||
#else
|
||||
explicit scoped_lock(scoped_lock<Mutex> &&scop)
|
||||
: mp_mutex(0), m_locked(scop.owns())
|
||||
{ mp_mutex = scop.release(); }
|
||||
#endif
|
||||
|
||||
/*!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the
|
||||
referenced mutex. upgr.release() is called.
|
||||
@@ -143,6 +149,7 @@ class scoped_lock
|
||||
the expression: "move(lock);" This constructor may block if
|
||||
other threads hold a sharable_lock on this mutex (sharable_lock's can
|
||||
share ownership with an upgradable_lock).*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
explicit scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
@@ -153,6 +160,18 @@ class scoped_lock
|
||||
}
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
#else
|
||||
explicit scoped_lock(upgradable_lock<Mutex> &&upgr)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
upgradable_lock<mutex_type> &u_lock = upgr;
|
||||
if(u_lock.owns()){
|
||||
u_lock.mutex()->unlock_upgradable_and_lock();
|
||||
m_locked = true;
|
||||
}
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the
|
||||
referenced mutex:
|
||||
@@ -169,6 +188,7 @@ class scoped_lock
|
||||
first place, the mutex merely changes type to an unlocked "write lock".
|
||||
If the "read lock" is held, then mutex transfer occurs only if it can
|
||||
do so in a non-blocking manner.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
|
||||
,detail::try_to_lock_type)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
@@ -183,6 +203,22 @@ class scoped_lock
|
||||
u_lock.release();
|
||||
}
|
||||
}
|
||||
#else
|
||||
scoped_lock(upgradable_lock<Mutex> &&upgr
|
||||
,detail::try_to_lock_type)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
upgradable_lock<mutex_type> &u_lock = upgr;
|
||||
if(u_lock.owns()){
|
||||
if((m_locked = u_lock.mutex()->try_unlock_upgradable_and_lock()) == true){
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
}
|
||||
else{
|
||||
u_lock.release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time)
|
||||
on the referenced mutex:
|
||||
@@ -198,6 +234,7 @@ class scoped_lock
|
||||
"write lock". If the "read lock" isn't held in the first place, the mutex
|
||||
merely changes type to an unlocked "write lock". If the "read lock" is held,
|
||||
then mutex transfer occurs only if it can do so in a non-blocking manner.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
|
||||
,boost::posix_time::ptime &abs_time)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
@@ -212,6 +249,22 @@ class scoped_lock
|
||||
u_lock.release();
|
||||
}
|
||||
}
|
||||
#else
|
||||
scoped_lock(upgradable_lock<Mutex> &&upgr
|
||||
,boost::posix_time::ptime &abs_time)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
upgradable_lock<mutex_type> &u_lock = upgr;
|
||||
if(u_lock.owns()){
|
||||
if((m_locked = u_lock.mutex()->timed_unlock_upgradable_and_lock(abs_time)) == true){
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
}
|
||||
else{
|
||||
u_lock.release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If shar.owns() then calls try_unlock_sharable_and_lock() on the
|
||||
referenced mutex.
|
||||
@@ -228,6 +281,7 @@ class scoped_lock
|
||||
first place, the mutex merely changes type to an unlocked "write lock".
|
||||
If the "read lock" is held, then mutex transfer occurs only if it can
|
||||
do so in a non-blocking manner.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
scoped_lock(detail::moved_object<sharable_lock<Mutex> > shar
|
||||
,detail::try_to_lock_type)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
@@ -242,6 +296,22 @@ class scoped_lock
|
||||
s_lock.release();
|
||||
}
|
||||
}
|
||||
#else
|
||||
scoped_lock(sharable_lock<Mutex> &&shar
|
||||
,detail::try_to_lock_type)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
sharable_lock<mutex_type> &s_lock = shar;
|
||||
if(s_lock.owns()){
|
||||
if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock()) == true){
|
||||
mp_mutex = s_lock.release();
|
||||
}
|
||||
}
|
||||
else{
|
||||
s_lock.release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: if (owns()) mp_mutex->unlock().
|
||||
Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
|
||||
@@ -257,6 +327,7 @@ class scoped_lock
|
||||
the same mutex before the assignment. In this case, this will own the
|
||||
mutex after the assignment (and scop will not), but the mutex's lock
|
||||
count will be decremented by one.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
scoped_lock &operator=(detail::moved_object<scoped_lock<Mutex> > scop)
|
||||
{
|
||||
if(this->owns())
|
||||
@@ -265,6 +336,16 @@ class scoped_lock
|
||||
mp_mutex = scop.get().release();
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
scoped_lock &operator=(scoped_lock<Mutex> &&scop)
|
||||
{
|
||||
if(this->owns())
|
||||
this->unlock();
|
||||
m_locked = scop.owns();
|
||||
mp_mutex = scop.release();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
|
||||
exception. Calls lock() on the referenced mutex.
|
||||
@@ -348,11 +429,20 @@ class scoped_lock
|
||||
|
||||
/*!Effects: Swaps state with moved lock.
|
||||
Throws: Nothing.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(detail::moved_object<scoped_lock<mutex_type> > other)
|
||||
{
|
||||
std::swap(mp_mutex, other.get().mp_mutex);
|
||||
std::swap(m_locked, other.get().m_locked);
|
||||
}
|
||||
#else
|
||||
void swap(scoped_lock<mutex_type> &&other)
|
||||
{
|
||||
std::swap(mp_mutex, other.mp_mutex);
|
||||
std::swap(m_locked, other.m_locked);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
mutex_type *mp_mutex;
|
||||
|
||||
@@ -130,9 +130,15 @@ class sharable_lock
|
||||
signature. An non-moved sharable_lock can be moved with the expression:
|
||||
"move(lock);". This constructor does not alter the state of the mutex,
|
||||
only potentially who owns it.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
explicit sharable_lock(detail::moved_object<sharable_lock<mutex_type> > upgr)
|
||||
: mp_mutex(0), m_locked(upgr.get().owns())
|
||||
{ mp_mutex = upgr.get().release(); }
|
||||
#else
|
||||
explicit sharable_lock(sharable_lock<mutex_type> &&upgr)
|
||||
: mp_mutex(0), m_locked(upgr.owns())
|
||||
{ mp_mutex = upgr.release(); }
|
||||
#endif
|
||||
|
||||
/*!Effects: If upgr.owns() then calls unlock_upgradable_and_lock_sharable() on the
|
||||
referenced mutex.
|
||||
@@ -143,6 +149,7 @@ class sharable_lock
|
||||
unlocking upgr. Only a moved sharable_lock's will match this
|
||||
signature. An non-moved upgradable_lock can be moved with the expression:
|
||||
"move(lock);".*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
explicit sharable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
@@ -153,6 +160,18 @@ class sharable_lock
|
||||
}
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
#else
|
||||
explicit sharable_lock(upgradable_lock<mutex_type> &&upgr)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
upgradable_lock<mutex_type> &u_lock = upgr;
|
||||
if(u_lock.owns()){
|
||||
u_lock.mutex()->unlock_upgradable_and_lock_sharable();
|
||||
m_locked = true;
|
||||
}
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If scop.owns() then calls unlock_and_lock_sharable() on the
|
||||
referenced mutex.
|
||||
@@ -164,6 +183,7 @@ class sharable_lock
|
||||
Only a moved scoped_lock's will match this
|
||||
signature. An non-moved scoped_lock can be moved with the expression:
|
||||
"move(lock);".*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
explicit sharable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
@@ -174,6 +194,18 @@ class sharable_lock
|
||||
}
|
||||
mp_mutex = e_lock.release();
|
||||
}
|
||||
#else
|
||||
explicit sharable_lock(scoped_lock<mutex_type> &&scop)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
scoped_lock<mutex_type> &e_lock = scop;
|
||||
if(e_lock.owns()){
|
||||
e_lock.mutex()->unlock_and_lock_sharable();
|
||||
m_locked = true;
|
||||
}
|
||||
mp_mutex = e_lock.release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: if (owns()) mp_mutex->unlock_sharable().
|
||||
Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
|
||||
@@ -190,6 +222,7 @@ class sharable_lock
|
||||
Notes: With a recursive mutex it is possible that both this and upgr own the mutex
|
||||
before the assignment. In this case, this will own the mutex after the assignment
|
||||
(and upgr will not), but the mutex's lock count will be decremented by one.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
sharable_lock &operator=(detail::moved_object<sharable_lock<mutex_type> > upgr)
|
||||
{
|
||||
if(this->owns())
|
||||
@@ -198,6 +231,16 @@ class sharable_lock
|
||||
mp_mutex = upgr.get().release();
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
sharable_lock &operator=(sharable_lock<mutex_type> &&upgr)
|
||||
{
|
||||
if(this->owns())
|
||||
this->unlock();
|
||||
m_locked = upgr.owns();
|
||||
mp_mutex = upgr.release();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If mutex() == 0 or already locked, throws a lock_exception()
|
||||
exception. Calls lock_sharable() on the referenced mutex.
|
||||
@@ -284,11 +327,20 @@ class sharable_lock
|
||||
|
||||
/*!Effects: Swaps state with moved lock.
|
||||
Throws: Nothing.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(detail::moved_object<sharable_lock<mutex_type> > other)
|
||||
{
|
||||
std::swap(mp_mutex, other.get().mp_mutex);
|
||||
std::swap(m_locked, other.get().m_locked);
|
||||
}
|
||||
#else
|
||||
void swap(sharable_lock<mutex_type> &&other)
|
||||
{
|
||||
std::swap(mp_mutex, other.mp_mutex);
|
||||
std::swap(m_locked, other.m_locked);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
mutex_type *mp_mutex;
|
||||
|
||||
@@ -125,9 +125,15 @@ class upgradable_lock
|
||||
signature. An non-moved upgradable_lock can be moved with the
|
||||
expression: "move(lock);". This constructor does not alter the
|
||||
state of the mutex, only potentially who owns it.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
explicit upgradable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
|
||||
: mp_mutex(0), m_locked(upgr.get().owns())
|
||||
{ mp_mutex = upgr.get().release(); }
|
||||
#else
|
||||
explicit upgradable_lock(upgradable_lock<mutex_type> &&upgr)
|
||||
: mp_mutex(0), m_locked(upgr.owns())
|
||||
{ mp_mutex = upgr.release(); }
|
||||
#endif
|
||||
|
||||
/*!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
|
||||
Postconditions: mutex() == the value scop.mutex() had before the construction.
|
||||
@@ -138,6 +144,7 @@ class upgradable_lock
|
||||
Only a moved sharable_lock's will match this
|
||||
signature. An non-moved sharable_lock can be moved with the
|
||||
expression: "move(lock);".*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
explicit upgradable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
@@ -148,6 +155,18 @@ class upgradable_lock
|
||||
}
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
#else
|
||||
explicit upgradable_lock(scoped_lock<mutex_type> &&scop)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
scoped_lock<mutex_type> &u_lock = scop;
|
||||
if(u_lock.owns()){
|
||||
u_lock.mutex()->unlock_and_lock_upgradable();
|
||||
m_locked = true;
|
||||
}
|
||||
mp_mutex = u_lock.release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If shar.owns() then calls try_unlock_sharable_and_lock_upgradable()
|
||||
on the referenced mutex.
|
||||
@@ -164,6 +183,7 @@ class upgradable_lock
|
||||
in the first place, the mutex merely changes type to an unlocked
|
||||
"upgradable lock". If the "read lock" is held, then mutex transfer
|
||||
occurs only if it can do so in a non-blocking manner.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
upgradable_lock( detail::moved_object<sharable_lock<mutex_type> > shar
|
||||
, detail::try_to_lock_type)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
@@ -178,6 +198,22 @@ class upgradable_lock
|
||||
s_lock.release();
|
||||
}
|
||||
}
|
||||
#else
|
||||
upgradable_lock( sharable_lock<mutex_type> &&shar
|
||||
, detail::try_to_lock_type)
|
||||
: mp_mutex(0), m_locked(false)
|
||||
{
|
||||
sharable_lock<mutex_type> &s_lock = shar;
|
||||
if(s_lock.owns()){
|
||||
if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock_upgradable()) == true){
|
||||
mp_mutex = s_lock.release();
|
||||
}
|
||||
}
|
||||
else{
|
||||
s_lock.release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: if (owns()) m_->unlock_upgradable().
|
||||
Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
|
||||
@@ -195,6 +231,7 @@ class upgradable_lock
|
||||
mutex before the assignment. In this case, this will own the mutex
|
||||
after the assignment (and upgr will not), but the mutex's upgradable lock
|
||||
count will be decremented by one.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
upgradable_lock &operator=(detail::moved_object<upgradable_lock<mutex_type> > upgr)
|
||||
{
|
||||
if(this->owns())
|
||||
@@ -203,6 +240,16 @@ class upgradable_lock
|
||||
mp_mutex = upgr.get().release();
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
upgradable_lock &operator=(upgradable_lock<mutex_type> &&upgr)
|
||||
{
|
||||
if(this->owns())
|
||||
this->unlock();
|
||||
m_locked = upgr.owns();
|
||||
mp_mutex = upgr.release();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
|
||||
exception. Calls lock_upgradable() on the referenced mutex.
|
||||
@@ -289,11 +336,20 @@ class upgradable_lock
|
||||
|
||||
/*!Effects: Swaps state with moved lock.
|
||||
Throws: Nothing.*/
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
void swap(detail::moved_object<upgradable_lock<mutex_type> > other)
|
||||
{
|
||||
std::swap(mp_mutex, other.get().mp_mutex);
|
||||
std::swap(m_locked, other.get().m_locked);
|
||||
}
|
||||
#else
|
||||
void swap(upgradable_lock<mutex_type> &&other)
|
||||
{
|
||||
std::swap(mp_mutex, other.mp_mutex);
|
||||
std::swap(m_locked, other.m_locked);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
mutex_type *mp_mutex;
|
||||
|
||||
@@ -77,13 +77,19 @@ class windows_shared_memory
|
||||
//!Moves the ownership of "moved"'s shared memory object to *this.
|
||||
//!After the call, "moved" does not represent any shared memory object.
|
||||
//!Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
windows_shared_memory
|
||||
(detail::moved_object<windows_shared_memory> &moved)
|
||||
{ this->swap(moved.get()); }
|
||||
#else
|
||||
windows_shared_memory(windows_shared_memory &&moved)
|
||||
{ this->swap(moved); }
|
||||
#endif
|
||||
|
||||
//!Moves the ownership of "moved"'s shared memory to *this.
|
||||
//!After the call, "moved" does not represent any shared memory.
|
||||
//!Does not throw
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
windows_shared_memory &operator=
|
||||
(detail::moved_object<windows_shared_memory> &moved)
|
||||
{
|
||||
@@ -91,6 +97,14 @@ class windows_shared_memory
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
windows_shared_memory &operator=(windows_shared_memory &&moved)
|
||||
{
|
||||
windows_shared_memory tmp(move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//!Swaps to shared_memory_objects. Does not throw
|
||||
void swap(windows_shared_memory &other);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
|
||||
<meta http-equiv="refresh" content="0; URL=../../doc/html/interprocess.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to <a href="doc/html/index.html">doc/html/interprocess.html</a>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="../../../doc/html/interprocess.html">../../doc/html/interprocess.html</a>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ProcessA"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792619}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/ProcessA"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessA_d.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/ProcessA.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/ProcessA"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessA.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\process_a_example.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,133 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ProcessAFixed"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792618}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/ProcessAFixed"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessAFixed_d.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/ProcessAFixed.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/ProcessAFixed"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessAFixed.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\process_a_fixed_example.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,132 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ProcessB"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792617}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/ProcessB"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessB_d.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/ProcessB.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/ProcessB"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessB.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\process_b_example.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,132 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ProcessBFixed"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792616}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/ProcessBFixed"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessBFixed_d.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/ProcessBFixed.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/ProcessBFixed"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/ProcessBFixed.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\process_b_fixed_example.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="allocate_ex"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792663}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/allocate_ex"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/allocate_ex_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/allocate_ex.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/allocate_ex"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/allocate_ex.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\alloc_example.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="file_lock_test"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792639}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/file_lock_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/file_lock_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/file_lock_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/file_lock_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/file_lock_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{7FCFEF41-3746-C7A5-8B8E-A352A2F22D7F}">
|
||||
<File
|
||||
RelativePath="..\..\test\file_lock_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{95393980-8912-4b74-66A0-607BE52EB5FB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="hash_table_test"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792636}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/hash_table_ex"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/hash_table_ex_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/hash_table_ex.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/hash_table_ex"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/hash_table_ex.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\test\hash_table_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,137 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="intersegment_ptr_test"
|
||||
ProjectGUID="{58CCE183-6092-12FE-A4F7-BA0D3A767634}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/intersegment_ptr_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/intersegment_ptr_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/intersegment_ptr_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/intersegment_ptr_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/intersegment_ptr_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-CAA5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\test\intersegment_ptr_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-8ABD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="named_allocate_ex"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792626}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/named_allocate_ex"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/named_allocate_ex_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/named_allocate_ex.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/named_allocate_ex"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/named_allocate_ex.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\named_alloc_example.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="read_write_mutex_test"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792615}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/shared_read_write_mutex_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/shared_read_write_mutex_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/shared_read_write_mutex_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/shared_read_write_mutex_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/shared_read_write_mutex_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\test\read_write_mutex_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="sharable_mutex_test"
|
||||
ProjectGUID="{5E188CC3-0962-F7A4-8F4E-A0D3B606A712}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/sharable_mutex_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/sharable_mutex_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/sharable_mutex_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/sharable_mutex_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/sharable_mutex_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4737FCF1-C7A5-A606-4376-2A3252AD72FF}">
|
||||
<File
|
||||
RelativePath="..\..\test\sharable_mutex_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{98903953-8D9B-88EB-4b04-6BBF2E52E5FB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -275,10 +275,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_heap_memory", "
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocate_ex", "allocate_ex.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792663}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocexcept_test", "allocexcept_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792662}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
@@ -335,10 +331,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_where_allocate", "doc_w
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file_lock_test", "file_lock_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792639}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file_mapping_test", "file_mapping_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792638}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
@@ -347,14 +339,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_tree_test", "flat_tree
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hash_table_test", "hash_table_ex.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792636}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intersegment_ptr_test", "intersegment_ptr_test.vcproj", "{58CCE183-6092-12FE-A4F7-BA0D3A767634}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intrusive_ptr_test", "intrusive_ptr_test.vcproj", "{5821C383-6092-12FE-A877-BA0D33467633}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
@@ -383,34 +367,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutex_test", "mutex_test.vc
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_allocate_ex", "named_allocate_ex.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792626}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_index_test", "null_index_test.vcproj", "{0000058C-0000-0000-0000-000000000021}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProcessA", "ProcessA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792619}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProcessAFixed", "ProcessAFixed.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792618}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProcessB", "ProcessB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792617}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProcessBFixed", "ProcessBFixed.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792616}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "read_write_mutex_test", "read_write_mutex_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792615}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recursive_mutex_test", "recursive_mutex_test.vcproj", "{83581CCE-487E-3292-A4E7-BA07926D3A14}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
@@ -419,10 +379,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "semaphore_test", "semaphore
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sharable_mutex_test", "sharable_mutex.vcproj", "{5E188CC3-0962-F7A4-8F4E-A0D3B606A712}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -707,10 +663,6 @@ Global
|
||||
{58CCE183-6092-48FE-A4FC-BA0D3A792647}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4FC-BA0D3A792647}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4FC-BA0D3A792647}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792663}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792663}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792663}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792663}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792662}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792662}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792662}.Release.ActiveCfg = Release|Win32
|
||||
@@ -767,10 +719,6 @@ Global
|
||||
{58CCE183-6092-48FE-A677-BA0D3A832640}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A677-BA0D3A832640}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A677-BA0D3A832640}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792638}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792638}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792638}.Release.ActiveCfg = Release|Win32
|
||||
@@ -779,14 +727,6 @@ Global
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792636}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792636}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792636}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792636}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-12FE-A4F7-BA0D3A767634}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-12FE-A4F7-BA0D3A767634}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-12FE-A4F7-BA0D3A767634}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-12FE-A4F7-BA0D3A767634}.Release.Build.0 = Release|Win32
|
||||
{5821C383-6092-12FE-A877-BA0D33467633}.Debug.ActiveCfg = Debug|Win32
|
||||
{5821C383-6092-12FE-A877-BA0D33467633}.Debug.Build.0 = Debug|Win32
|
||||
{5821C383-6092-12FE-A877-BA0D33467633}.Release.ActiveCfg = Release|Win32
|
||||
@@ -815,34 +755,10 @@ Global
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A27}.Debug.Build.0 = Debug|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A27}.Release.ActiveCfg = Release|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A27}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792626}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792626}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792626}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792626}.Release.Build.0 = Release|Win32
|
||||
{0000058C-0000-0000-0000-000000000021}.Debug.ActiveCfg = Debug|Win32
|
||||
{0000058C-0000-0000-0000-000000000021}.Debug.Build.0 = Debug|Win32
|
||||
{0000058C-0000-0000-0000-000000000021}.Release.ActiveCfg = Release|Win32
|
||||
{0000058C-0000-0000-0000-000000000021}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792619}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792619}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792619}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792619}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792618}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792618}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792618}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792618}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792617}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792617}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792617}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792617}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792616}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792616}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792616}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792616}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792615}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792615}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792615}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792615}.Release.Build.0 = Release|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.ActiveCfg = Debug|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.Build.0 = Debug|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.ActiveCfg = Release|Win32
|
||||
@@ -851,10 +767,6 @@ Global
|
||||
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.Build.0 = Debug|Win32
|
||||
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.ActiveCfg = Release|Win32
|
||||
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.Build.0 = Release|Win32
|
||||
{5E188CC3-0962-F7A4-8F4E-A0D3B606A712}.Debug.ActiveCfg = Debug|Win32
|
||||
{5E188CC3-0962-F7A4-8F4E-A0D3B606A712}.Debug.Build.0 = Debug|Win32
|
||||
{5E188CC3-0962-F7A4-8F4E-A0D3B606A712}.Release.ActiveCfg = Release|Win32
|
||||
{5E188CC3-0962-F7A4-8F4E-A0D3B606A712}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
||||
@@ -1,134 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_shared_memory"
|
||||
ProjectGUID="{58CCE183-6032-12FE-4FC7-83A79F760B61}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/doc_shared_memory"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_shared_memory_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/doc_shared_memory.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/doc_shared_memory"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_shared_memory.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4F7371DF-A5DA-6437-60A6-22A352A2D7FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_shared_memory.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93909538-DA9B-44D0-8EB8-E55F262BEBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_shared_memory"
|
||||
ProjectGUID="{58CCE183-6032-12FE-4FC7-83A79F760B61}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/doc_shared_memory"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_shared_memory_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/doc_shared_memory.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/doc_shared_memory"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_shared_memory.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4F7371DF-A5DA-6437-60A6-22A352A2D7FF}">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_shared_memory.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93909538-DA9B-44D0-8EB8-E55F262BEBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
||||
@@ -331,9 +331,6 @@
|
||||
<Filter
|
||||
Name="Memory algorithms"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\mem_algo\multi_simple_seq_fit.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\mem_algo\rbtree_best_fit.hpp">
|
||||
</File>
|
||||
@@ -395,9 +392,15 @@
|
||||
<Filter
|
||||
Name="Detail"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\algorithms.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\atomic.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\basic_segment_manager.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\cast_tags.hpp">
|
||||
</File>
|
||||
@@ -407,21 +410,36 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\config_end.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\construction_table.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\creation_tags.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\file_wrapper.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\gcd_lcm.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\generic_cast.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\in_place_interface.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_open_or_create_impl.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\min_max.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\move.hpp">
|
||||
</File>
|
||||
@@ -431,6 +449,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\moved_default_iterator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\mpl.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\named_proxy.hpp">
|
||||
</File>
|
||||
@@ -443,6 +464,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\os_thread_functions.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\pointer_type.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\posix_time_types_wrk.hpp">
|
||||
</File>
|
||||
@@ -461,13 +485,6 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\workaround.hpp">
|
||||
</File>
|
||||
<Filter
|
||||
Name="IPC"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\ipc\message_queue.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Documentation"
|
||||
@@ -633,6 +650,13 @@
|
||||
RelativePath="..\..\example\Jamfile.v2">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="IPC"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\ipc\message_queue.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\interprocess_fwd.hpp">
|
||||
</File>
|
||||
|
||||
@@ -77,6 +77,10 @@ int main ()
|
||||
if(InstanceCounter::counter != 0)
|
||||
return 1;
|
||||
}
|
||||
catch(std::length_error &){
|
||||
if(InstanceCounter::counter != 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
shared_memory_object::remove(shMemName);
|
||||
|
||||
@@ -111,18 +111,6 @@ int list_test (bool copied_allocators_equal = true)
|
||||
|
||||
MyStdList *stdlist = new MyStdList;
|
||||
|
||||
/*
|
||||
{
|
||||
typedef typename MyShmList::value_type IntType;
|
||||
for(int i = 0; i < max; ++i){
|
||||
IntType move_me(i);
|
||||
shmlist->push_front(move(move_me));
|
||||
stdlist->push_front(i);
|
||||
}
|
||||
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
if(push_data_t::execute(max, shmlist, stdlist)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "print_container.hpp"
|
||||
#include <boost/interprocess/detail/move_iterator.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/iterators.hpp>
|
||||
|
||||
template<class T1, class T2, class T3, class T4>
|
||||
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
|
||||
|
||||
@@ -49,6 +49,7 @@ template<class Allocator>
|
||||
bool test_allocation_direct_deallocation(Allocator &a)
|
||||
{
|
||||
std::vector<void*> buffers;
|
||||
std::size_t free_memory = a.get_free_memory();
|
||||
|
||||
for(int i = 0; true; ++i){
|
||||
void *ptr = a.allocate(i, std::nothrow);
|
||||
@@ -63,7 +64,8 @@ bool test_allocation_direct_deallocation(Allocator &a)
|
||||
a.deallocate(buffers[j]);
|
||||
}
|
||||
|
||||
return a.all_memory_deallocated() && a.check_sanity();
|
||||
return free_memory == a.get_free_memory() &&
|
||||
a.all_memory_deallocated() && a.check_sanity();
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
@@ -453,7 +455,7 @@ bool test_continuous_aligned_allocation(Allocator &a)
|
||||
}
|
||||
|
||||
//This test allocates memory, writes it with a non-zero value and
|
||||
//tests clear_free_memory initializes to zero for the next allocation
|
||||
//tests zero_free_memory initializes to zero for the next allocation
|
||||
template<class Allocator>
|
||||
bool test_clear_free_memory(Allocator &a)
|
||||
{
|
||||
@@ -484,7 +486,7 @@ bool test_clear_free_memory(Allocator &a)
|
||||
return false;
|
||||
|
||||
//Now clear all free memory
|
||||
a.clear_free_memory();
|
||||
a.zero_free_memory();
|
||||
|
||||
if(!a.all_memory_deallocated() && a.check_sanity())
|
||||
return false;
|
||||
|
||||
@@ -33,13 +33,24 @@ class movable_int
|
||||
explicit movable_int(int a)
|
||||
: m_int(a)
|
||||
{}
|
||||
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_int(const detail::moved_object<movable_int> &mmi)
|
||||
: m_int(mmi.get().m_int)
|
||||
{ mmi.get().m_int = 0; }
|
||||
|
||||
#else
|
||||
movable_int(movable_int &&mmi)
|
||||
: m_int(mmi.m_int)
|
||||
{ mmi.m_int = 0; }
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_int & operator= (const detail::moved_object<movable_int> &mmi)
|
||||
{ this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; }
|
||||
#else
|
||||
movable_int & operator= (movable_int &&mmi)
|
||||
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
|
||||
#endif
|
||||
|
||||
bool operator ==(const movable_int &mi) const
|
||||
{ return this->m_int == mi.m_int; }
|
||||
@@ -93,13 +104,24 @@ class movable_and_copyable_int
|
||||
|
||||
movable_and_copyable_int &operator= (const movable_and_copyable_int& mi)
|
||||
{ this->m_int = mi.m_int; return *this; }
|
||||
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_and_copyable_int(const detail::moved_object<movable_and_copyable_int> &mmi)
|
||||
: m_int(mmi.get().m_int)
|
||||
{ mmi.get().m_int = 0; }
|
||||
|
||||
#else
|
||||
movable_and_copyable_int(movable_and_copyable_int &&mmi)
|
||||
: m_int(mmi.m_int)
|
||||
{ mmi.m_int = 0; }
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_and_copyable_int & operator= (const detail::moved_object<movable_and_copyable_int> &mmi)
|
||||
{ this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; }
|
||||
#else
|
||||
movable_and_copyable_int & operator= (movable_and_copyable_int &&mmi)
|
||||
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
|
||||
#endif
|
||||
|
||||
bool operator ==(const movable_and_copyable_int &mi) const
|
||||
{ return this->m_int == mi.m_int; }
|
||||
|
||||
@@ -15,11 +15,15 @@
|
||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||
#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
|
||||
#include <boost/interprocess/sync/mutex_family.hpp>
|
||||
#include <boost/interprocess/streams/bufferstream.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace interprocess { namespace test {
|
||||
|
||||
@@ -28,23 +32,36 @@ namespace boost { namespace interprocess { namespace test {
|
||||
template<class ManagedMemory>
|
||||
bool test_names_and_types(ManagedMemory &m)
|
||||
{
|
||||
typedef typename ManagedMemory::char_type char_type;
|
||||
typedef std::char_traits<char_type> char_traits_type;
|
||||
std::vector<char*> buffers;
|
||||
const int BufferLen = 100;
|
||||
char name[BufferLen];
|
||||
char_type name[BufferLen];
|
||||
|
||||
basic_bufferstream<char_type> formatter(name, BufferLen);
|
||||
|
||||
for(int i = 0; true; ++i){
|
||||
std::sprintf(name, "%s%010d", "prefix_name_", i);
|
||||
formatter.seekp(0);
|
||||
formatter << "prefix_name_" << i << std::ends;
|
||||
|
||||
char *ptr = m.template construct<char>(name, std::nothrow)(i);
|
||||
|
||||
if(!ptr)
|
||||
break;
|
||||
if(std::strcmp(m.get_name(ptr), name) != 0)
|
||||
return false;
|
||||
|
||||
std::size_t namelen = char_traits_type::length(m.get_name(ptr));
|
||||
if(namelen != char_traits_type::length(name)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(char_traits_type::compare(m.get_name(ptr), name, namelen) != 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(m.template find<char>(name).first == 0)
|
||||
return false;
|
||||
|
||||
if(m.get_type(ptr) != named_type)
|
||||
if(m.get_type(ptr) != detail::named_type)
|
||||
return false;
|
||||
|
||||
buffers.push_back(ptr);
|
||||
@@ -64,17 +81,92 @@ bool test_names_and_types(ManagedMemory &m)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that deallocates all in the same order
|
||||
template<class ManagedMemory>
|
||||
bool test_named_iterators(ManagedMemory &m)
|
||||
{
|
||||
typedef typename ManagedMemory::char_type char_type;
|
||||
typedef std::char_traits<char_type> char_traits_type;
|
||||
std::vector<char*> buffers;
|
||||
const int BufferLen = 100;
|
||||
char_type name[BufferLen];
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
std::set<string_type> names;
|
||||
|
||||
basic_bufferstream<char_type> formatter(name, BufferLen);
|
||||
|
||||
string_type aux_str;
|
||||
|
||||
for(int i = 0; true; ++i){
|
||||
formatter.seekp(0);
|
||||
formatter << "prefix_name_" << i << std::ends;
|
||||
char *ptr = m.template construct<char>(name, std::nothrow)(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
aux_str = name;
|
||||
names.insert(aux_str);
|
||||
buffers.push_back(ptr);
|
||||
}
|
||||
|
||||
if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
|
||||
return false;
|
||||
|
||||
typedef typename ManagedMemory::const_named_iterator const_named_iterator;
|
||||
const_named_iterator named_beg = m.named_begin();
|
||||
const_named_iterator named_end = m.named_end();
|
||||
|
||||
if(std::distance(named_beg, named_end) != (int)buffers.size()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(; named_beg != named_end; ++named_beg){
|
||||
const char_type *name = named_beg->name();
|
||||
aux_str = name;
|
||||
if(names.find(aux_str) == names.end()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(aux_str.size() != named_beg->name_length()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
const void *found_value = m.template find<char>(name).first;
|
||||
|
||||
if(found_value == 0)
|
||||
return false;
|
||||
if(found_value != named_beg->value())
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int j = 0, max = (int)buffers.size()
|
||||
;j < max
|
||||
;++j){
|
||||
m.destroy_ptr(buffers[j]);
|
||||
}
|
||||
|
||||
if(m.get_num_named_objects() != 0 || !m.check_sanity())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//This test allocates until there is no more memory
|
||||
//and after that deallocates all in the same order
|
||||
template<class ManagedMemory>
|
||||
bool test_direct_named_allocation_destruction(ManagedMemory &m)
|
||||
{
|
||||
typedef typename ManagedMemory::char_type char_type;
|
||||
typedef std::char_traits<char_type> char_traits_type;
|
||||
std::vector<char*> buffers;
|
||||
const int BufferLen = 100;
|
||||
char name[BufferLen];
|
||||
char_type name[BufferLen];
|
||||
|
||||
basic_bufferstream<char_type> formatter(name, BufferLen);
|
||||
|
||||
for(int i = 0; true; ++i){
|
||||
std::sprintf(name, "%s%010d", "prefix_name_", i);
|
||||
formatter.seekp(0);
|
||||
formatter << "prefix_name_" << i << std::ends;
|
||||
char *ptr = m.template construct<char>(name, std::nothrow)(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
@@ -102,12 +194,18 @@ bool test_direct_named_allocation_destruction(ManagedMemory &m)
|
||||
template<class ManagedMemory>
|
||||
bool test_named_allocation_inverse_destruction(ManagedMemory &m)
|
||||
{
|
||||
typedef typename ManagedMemory::char_type char_type;
|
||||
typedef std::char_traits<char_type> char_traits_type;
|
||||
|
||||
std::vector<char*> buffers;
|
||||
const int BufferLen = 100;
|
||||
char name[BufferLen];
|
||||
char_type name[BufferLen];
|
||||
|
||||
basic_bufferstream<char_type> formatter(name, BufferLen);
|
||||
|
||||
for(int i = 0; true; ++i){
|
||||
std::sprintf(name, "%s%010d", "prefix_name_", i);
|
||||
formatter.seekp(0);
|
||||
formatter << "prefix_name_" << i << std::ends;
|
||||
char *ptr = m.template construct<char>(name, std::nothrow)(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
@@ -133,12 +231,18 @@ bool test_named_allocation_inverse_destruction(ManagedMemory &m)
|
||||
template<class ManagedMemory>
|
||||
bool test_named_allocation_mixed_destruction(ManagedMemory &m)
|
||||
{
|
||||
typedef typename ManagedMemory::char_type char_type;
|
||||
typedef std::char_traits<char_type> char_traits_type;
|
||||
|
||||
std::vector<char*> buffers;
|
||||
const int BufferLen = 100;
|
||||
char name[BufferLen];
|
||||
char_type name[BufferLen];
|
||||
|
||||
basic_bufferstream<char_type> formatter(name, BufferLen);
|
||||
|
||||
for(int i = 0; true; ++i){
|
||||
std::sprintf(name, "%s%010d", "prefix_name_", i);
|
||||
formatter.seekp(0);
|
||||
formatter << "prefix_name_" << i << std::ends;
|
||||
char *ptr = m.template construct<char>(name, std::nothrow)(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
@@ -166,13 +270,18 @@ bool test_named_allocation_mixed_destruction(ManagedMemory &m)
|
||||
template<class ManagedMemory>
|
||||
bool test_inverse_named_allocation_destruction(ManagedMemory &m)
|
||||
{
|
||||
typedef typename ManagedMemory::char_type char_type;
|
||||
typedef std::char_traits<char_type> char_traits_type;
|
||||
|
||||
std::vector<char*> buffers;
|
||||
const int BufferLen = 100;
|
||||
char name[BufferLen];
|
||||
const unsigned int FirstNumber = (unsigned int)-1;
|
||||
char_type name[BufferLen];
|
||||
|
||||
basic_bufferstream<char_type> formatter(name, BufferLen);
|
||||
|
||||
for(unsigned int i = 0; true; ++i){
|
||||
std::sprintf(name, "%s%010u", "prefix_name_", FirstNumber - i);
|
||||
formatter.seekp(0);
|
||||
formatter << "prefix_name_" << i << std::ends;
|
||||
char *ptr = m.template construct<char>(name, std::nothrow)(i);
|
||||
if(!ptr)
|
||||
break;
|
||||
@@ -242,6 +351,12 @@ bool test_all_named_allocation(ManagedMemory &m)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!test_named_iterators(m)){
|
||||
std::cout << "test_named_iterators failed. Class: "
|
||||
<< typeid(m).name() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -275,7 +390,7 @@ bool test_named_allocation()
|
||||
throw;
|
||||
}
|
||||
shared_memory_object::remove(shMemName);
|
||||
/*
|
||||
|
||||
//Now test it with wchar_t
|
||||
try
|
||||
{
|
||||
@@ -300,7 +415,7 @@ bool test_named_allocation()
|
||||
throw;
|
||||
}
|
||||
shared_memory_object::remove(shMemName);
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user