fix doc example typo
[boost.git] / boost / interprocess / detail / managed_memory_impl.hpp
blob72645e29c1df6b3bd6319306074bb75a99e7e1f5
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
12 #define BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif
18 #include <boost/interprocess/detail/config_begin.hpp>
19 #include <boost/interprocess/detail/workaround.hpp>
21 #include <boost/interprocess/interprocess_fwd.hpp>
22 #include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
23 #include <boost/interprocess/sync/mutex_family.hpp>
24 #include <boost/interprocess/detail/utilities.hpp>
25 #include <boost/interprocess/detail/os_file_functions.hpp>
26 #include <boost/interprocess/creation_tags.hpp>
27 #include <boost/interprocess/sync/interprocess_mutex.hpp>
28 #include <boost/interprocess/exceptions.hpp>
29 #include <boost/interprocess/offset_ptr.hpp>
30 #include <boost/interprocess/segment_manager.hpp>
31 #include <boost/interprocess/sync/scoped_lock.hpp>
33 #include <boost/detail/no_exceptions_support.hpp>
35 #include <utility>
36 #include <fstream>
37 #include <new>
38 #include <cassert>
40 //!\file
41 //!Describes a named shared memory allocation user class.
42 //!
44 namespace boost {
45 namespace interprocess {
46 namespace detail {
48 template<class BasicManagedMemoryImpl>
49 class create_open_func;
51 template<
52 class CharType,
53 class MemoryAlgorithm,
54 template<class IndexConfig> class IndexType
56 struct segment_manager_type
58 typedef segment_manager<CharType, MemoryAlgorithm, IndexType> type;
61 //!This class is designed to be a base class to classes that manage
62 //!creation of objects in a fixed size memory buffer. Apart
63 //!from allocating raw memory, the user can construct named objects. To
64 //!achieve this, this class uses the reserved space provided by the allocation
65 //!algorithm to place a named_allocator_algo, who takes care of name mappings.
66 //!The class can be customized with the char type used for object names
67 //!and the memory allocation algorithm to be used.*/
68 template < class CharType
69 , class MemoryAlgorithm
70 , template<class IndexConfig> class IndexType
71 , std::size_t Offset = 0
73 class basic_managed_memory_impl
75 //Non-copyable
76 basic_managed_memory_impl(const basic_managed_memory_impl &);
77 basic_managed_memory_impl &operator=(const basic_managed_memory_impl &);
79 template<class BasicManagedMemoryImpl>
80 friend class create_open_func;
82 public:
83 typedef typename segment_manager_type
84 <CharType, MemoryAlgorithm, IndexType>::type segment_manager;
85 typedef CharType char_type;
86 typedef MemoryAlgorithm memory_algorithm;
87 typedef typename MemoryAlgorithm::mutex_family mutex_family;
88 typedef CharType char_t;
89 typedef std::ptrdiff_t handle_t;
90 typedef typename segment_manager::
91 const_named_iterator const_named_iterator;
92 typedef typename segment_manager::
93 const_unique_iterator const_unique_iterator;
95 /// @cond
97 typedef typename
98 segment_manager::char_ptr_holder_t char_ptr_holder_t;
99 //Experimental. Don't use.
101 typedef typename segment_manager::multiallocation_chain multiallocation_chain;
103 /// @endcond
105 static const std::size_t PayloadPerAllocation = segment_manager::PayloadPerAllocation;
107 private:
108 typedef basic_managed_memory_impl
109 <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
110 protected:
111 template<class ManagedMemory>
112 static bool grow(const char *filename, std::size_t extra_bytes)
114 typedef typename ManagedMemory::device_type device_type;
115 //Increase file size
116 try{
117 offset_t old_size;
119 device_type f(open_or_create, filename, read_write);
120 if(!f.get_size(old_size))
121 return false;
122 f.truncate(old_size + extra_bytes);
124 ManagedMemory managed_memory(open_only, filename);
125 //Grow always works
126 managed_memory.self_t::grow(extra_bytes);
128 catch(...){
129 return false;
131 return true;
134 template<class ManagedMemory>
135 static bool shrink_to_fit(const char *filename)
137 typedef typename ManagedMemory::device_type device_type;
138 std::size_t new_size, old_size;
139 try{
140 ManagedMemory managed_memory(open_only, filename);
141 old_size = managed_memory.get_size();
142 managed_memory.self_t::shrink_to_fit();
143 new_size = managed_memory.get_size();
145 catch(...){
146 return false;
149 //Decrease file size
151 device_type f(open_or_create, filename, read_write);
152 f.truncate(new_size);
154 return true;
157 //!Constructor. Allocates basic resources. Never throws.
158 basic_managed_memory_impl()
159 : mp_header(0){}
161 //!Destructor. Calls close. Never throws.
162 ~basic_managed_memory_impl()
163 { this->close_impl(); }
165 //!Places segment manager in the reserved space. This can throw.
166 bool create_impl (void *addr, std::size_t size)
168 if(mp_header) return false;
170 //Check if there is enough space
171 if(size < segment_manager::get_min_size())
172 return false;
174 //This function should not throw. The index construction can
175 //throw if constructor allocates memory. So we must catch it.
176 BOOST_TRY{
177 //Let's construct the allocator in memory
178 mp_header = new(addr) segment_manager(size);
180 BOOST_CATCH(...){
181 return false;
183 BOOST_CATCH_END
184 return true;
187 //!Connects to a segment manager in the reserved buffer. Never throws.
188 bool open_impl (void *addr, std::size_t)
190 if(mp_header) return false;
191 mp_header = static_cast<segment_manager*>(addr);
192 return true;
195 //!Frees resources. Never throws.
196 bool close_impl()
198 bool ret = mp_header != 0;
199 mp_header = 0;
200 return ret;
203 //!Frees resources and destroys common resources. Never throws.
204 bool destroy_impl()
206 if(mp_header == 0)
207 return false;
208 mp_header->~segment_manager();
209 this->close_impl();
210 return true;
214 void grow(std::size_t extra_bytes)
215 { mp_header->grow(extra_bytes); }
217 void shrink_to_fit()
218 { mp_header->shrink_to_fit(); }
220 public:
222 //!Returns segment manager. Never throws.
223 segment_manager *get_segment_manager() const
224 { return mp_header; }
226 //!Returns the base address of the memory in this process. Never throws.
227 void * get_address () const
228 { return reinterpret_cast<char*>(mp_header) - Offset; }
230 //!Returns the size of memory segment. Never throws.
231 std::size_t get_size () const
232 { return mp_header->get_size() + Offset; }
234 //!Returns the number of free bytes of the memory
235 //!segment
236 std::size_t get_free_memory() const
237 { return mp_header->get_free_memory(); }
239 //!Returns the result of "all_memory_deallocated()" function
240 //!of the used memory algorithm
241 bool all_memory_deallocated()
242 { return mp_header->all_memory_deallocated(); }
244 //!Returns the result of "check_sanity()" function
245 //!of the used memory algorithm
246 bool check_sanity()
247 { return mp_header->check_sanity(); }
249 //!Writes to zero free memory (memory not yet allocated) of
250 //!the memory algorithm
251 void zero_free_memory()
252 { mp_header->zero_free_memory(); }
254 //!Transforms an absolute address into an offset from base address.
255 //!The address must belong to the memory segment. Never throws.
256 handle_t get_handle_from_address (const void *ptr) const
258 return reinterpret_cast<const char*>(ptr) -
259 reinterpret_cast<const char*>(this->get_address());
262 //!Returns true if the address belongs to the managed memory segment
263 bool belongs_to_segment (const void *ptr) const
265 return ptr >= this->get_address() &&
266 ptr < (reinterpret_cast<const char*>(ptr) + this->get_size());
269 //!Transforms previously obtained offset into an absolute address in the
270 //!process space of the current process. Never throws.*/
271 void * get_address_from_handle (handle_t offset) const
272 { return reinterpret_cast<char*>(this->get_address()) + offset; }
274 //!Searches for nbytes of free memory in the segment, marks the
275 //!memory as used and return the pointer to the memory. If no
276 //!memory is available throws a boost::interprocess::bad_alloc exception
277 void* allocate (std::size_t nbytes)
278 { return mp_header->allocate(nbytes); }
280 //!Searches for nbytes of free memory in the segment, marks the
281 //!memory as used and return the pointer to the memory. If no memory
282 //!is available returns 0. Never throws.
283 void* allocate (std::size_t nbytes, std::nothrow_t nothrow)
284 { return mp_header->allocate(nbytes, nothrow); }
286 //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
287 //!must be power of two. If no memory
288 //!is available returns 0. Never throws.
289 void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t nothrow)
290 { return mp_header->allocate_aligned(nbytes, alignment, nothrow); }
292 template<class T>
293 std::pair<T *, bool>
294 allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
295 std::size_t preferred_size,std::size_t &received_size,
296 T *reuse_ptr = 0)
298 return mp_header->allocation_command
299 (command, limit_size, preferred_size, received_size, reuse_ptr);
302 //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
303 //!must be power of two. If no
304 //!memory is available throws a boost::interprocess::bad_alloc exception
305 void * allocate_aligned(std::size_t nbytes, std::size_t alignment)
306 { return mp_header->allocate_aligned(nbytes, alignment); }
308 /// @cond
310 //Experimental. Don't use.
312 //!Allocates n_elements of elem_size bytes.
313 multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements)
314 { return mp_header->allocate_many(elem_bytes, num_elements); }
316 //!Allocates n_elements, each one of elem_sizes[i] bytes.
317 multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements)
318 { return mp_header->allocate_many(elem_sizes, n_elements); }
320 //!Allocates n_elements of elem_size bytes.
321 multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t nothrow)
322 { return mp_header->allocate_many(elem_bytes, num_elements, nothrow); }
324 //!Allocates n_elements, each one of elem_sizes[i] bytes.
325 multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::nothrow_t nothrow)
326 { return mp_header->allocate_many(elem_sizes, n_elements, nothrow); }
328 //!Allocates n_elements, each one of elem_sizes[i] bytes.
329 void deallocate_many(multiallocation_chain chain)
330 { return mp_header->deallocate_many(boost::interprocess::move(chain)); }
332 /// @endcond
334 //!Marks previously allocated memory as free. Never throws.
335 void deallocate (void *addr)
336 { if (mp_header) mp_header->deallocate(addr); }
338 //!Tries to find a previous named allocation address. Returns a memory
339 //!buffer and the object count. If not found returned pointer is 0.
340 //!Never throws.
341 template <class T>
342 std::pair<T*, std::size_t> find (char_ptr_holder_t name)
343 { return mp_header->template find<T>(name); }
345 //!Creates a named object or array in memory
347 //!Allocates and constructs a T object or an array of T in memory,
348 //!associates this with the given name and returns a pointer to the
349 //!created object. If an array is being constructed all objects are
350 //!created using the same parameters given to this function.
352 //!-> If the name was previously used, returns 0.
354 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
356 //!-> If T's constructor throws, the function throws that exception.
358 //!Memory is freed automatically if T's constructor throws and if an
359 //!array was being constructed, destructors of created objects are called
360 //!before freeing the memory.
361 template <class T>
362 typename segment_manager::template construct_proxy<T>::type
363 construct(char_ptr_holder_t name)
364 { return mp_header->template construct<T>(name); }
366 //!Finds or creates a named object or array in memory
368 //!Tries to find an object with the given name in memory. If
369 //!found, returns the pointer to this pointer. If the object is not found,
370 //!allocates and constructs a T object or an array of T in memory,
371 //!associates this with the given name and returns a pointer to the
372 //!created object. If an array is being constructed all objects are
373 //!created using the same parameters given to this function.
375 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
377 //!-> If T's constructor throws, the function throws that exception.
379 //!Memory is freed automatically if T's constructor throws and if an
380 //!array was being constructed, destructors of created objects are called
381 //!before freeing the memory.
382 template <class T>
383 typename segment_manager::template construct_proxy<T>::type
384 find_or_construct(char_ptr_holder_t name)
385 { return mp_header->template find_or_construct<T>(name); }
387 //!Creates a named object or array in memory
389 //!Allocates and constructs a T object or an array of T in memory,
390 //!associates this with the given name and returns a pointer to the
391 //!created object. If an array is being constructed all objects are
392 //!created using the same parameters given to this function.
394 //!-> If the name was previously used, returns 0.
396 //!-> Returns 0 if there is no available memory
398 //!-> If T's constructor throws, the function throws that exception.
400 //!Memory is freed automatically if T's constructor throws and if an
401 //!array was being constructed, destructors of created objects are called
402 //!before freeing the memory.
403 template <class T>
404 typename segment_manager::template construct_proxy<T>::type
405 construct(char_ptr_holder_t name, std::nothrow_t nothrow)
406 { return mp_header->template construct<T>(name, nothrow); }
408 //!Finds or creates a named object or array in memory
410 //!Tries to find an object with the given name in memory. If
411 //!found, returns the pointer to this pointer. If the object is not found,
412 //!allocates and constructs a T object or an array of T in memory,
413 //!associates this with the given name and returns a pointer to the
414 //!created object. If an array is being constructed all objects are
415 //!created using the same parameters given to this function.
417 //!-> Returns 0 if there is no available memory
419 //!-> If T's constructor throws, the function throws that exception.
421 //!Memory is freed automatically if T's constructor throws and if an
422 //!array was being constructed, destructors of created objects are called
423 //!before freeing the memory.
424 template <class T>
425 typename segment_manager::template construct_proxy<T>::type
426 find_or_construct(char_ptr_holder_t name, std::nothrow_t nothrow)
427 { return mp_header->template find_or_construct<T>(name, nothrow); }
429 //!Creates a named array from iterators in memory
431 //!Allocates and constructs an array of T in memory,
432 //!associates this with the given name and returns a pointer to the
433 //!created object. Each element in the array is created using the
434 //!objects returned when dereferencing iterators as parameters
435 //!and incrementing all iterators for each element.
437 //!-> If the name was previously used, returns 0.
439 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
441 //!-> If T's constructor throws, the function throws that exception.
443 //!Memory is freed automatically if T's constructor throws and
444 //!destructors of created objects are called before freeing the memory.
445 template <class T>
446 typename segment_manager::template construct_iter_proxy<T>::type
447 construct_it(char_ptr_holder_t name)
448 { return mp_header->template construct_it<T>(name); }
450 //!Finds or creates a named array from iterators in memory
452 //!Tries to find an object with the given name in memory. If
453 //!found, returns the pointer to this pointer. If the object is not found,
454 //!allocates and constructs an array of T in memory,
455 //!associates this with the given name and returns a pointer to the
456 //!created object. Each element in the array is created using the
457 //!objects returned when dereferencing iterators as parameters
458 //!and incrementing all iterators for each element.
460 //!-> If the name was previously used, returns 0.
462 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
464 //!-> If T's constructor throws, the function throws that exception.
466 //!Memory is freed automatically if T's constructor throws and
467 //!destructors of created objects are called before freeing the memory.
468 template <class T>
469 typename segment_manager::template construct_iter_proxy<T>::type
470 find_or_construct_it(char_ptr_holder_t name)
471 { return mp_header->template find_or_construct_it<T>(name); }
473 //!Creates a named array from iterators in memory
475 //!Allocates and constructs an array of T in memory,
476 //!associates this with the given name and returns a pointer to the
477 //!created object. Each element in the array is created using the
478 //!objects returned when dereferencing iterators as parameters
479 //!and incrementing all iterators for each element.
481 //!-> If the name was previously used, returns 0.
483 //!-> If there is no available memory, returns 0.
485 //!-> If T's constructor throws, the function throws that exception.
487 //!Memory is freed automatically if T's constructor throws and
488 //!destructors of created objects are called before freeing the memory.*/
489 template <class T>
490 typename segment_manager::template construct_iter_proxy<T>::type
491 construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
492 { return mp_header->template construct_it<T>(name, nothrow); }
494 //!Finds or creates a named array from iterators in memory
496 //!Tries to find an object with the given name in memory. If
497 //!found, returns the pointer to this pointer. If the object is not found,
498 //!allocates and constructs an array of T in memory,
499 //!associates this with the given name and returns a pointer to the
500 //!created object. Each element in the array is created using the
501 //!objects returned when dereferencing iterators as parameters
502 //!and incrementing all iterators for each element.
504 //!-> If the name was previously used, returns 0.
506 //!-> If there is no available memory, returns 0.
508 //!-> If T's constructor throws, the function throws that exception.
510 //!Memory is freed automatically if T's constructor throws and
511 //!destructors of created objects are called before freeing the memory.*/
512 template <class T>
513 typename segment_manager::template construct_iter_proxy<T>::type
514 find_or_construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
515 { return mp_header->template find_or_construct_it<T>(name, nothrow); }
517 //!Calls a functor and guarantees that no new construction, search or
518 //!destruction will be executed by any process while executing the object
519 //!function call. If the functor throws, this function throws.
520 template <class Func>
521 void atomic_func(Func &f)
522 { mp_header->atomic_func(f); }
524 //!Destroys a named memory object or array.
526 //!Finds the object with the given name, calls its destructors,
527 //!frees used memory and returns true.
529 //!-> If the object is not found, it returns false.
531 //!Exception Handling:
533 //!When deleting a dynamically object or array, the Standard
534 //!does not guarantee that dynamically allocated memory, will be released.
535 //!Also, when deleting arrays, the Standard doesn't require calling
536 //!destructors for the rest of the objects if for one of them the destructor
537 //!terminated with an exception.
539 //!Destroying an object:
541 //!If the destructor throws, the memory will be freed and that exception
542 //!will be thrown.
544 //!Destroying an array:
546 //!When destroying an array, if a destructor throws, the rest of
547 //!destructors are called. If any of these throws, the exceptions are
548 //!ignored. The name association will be erased, memory will be freed and
549 //!the first exception will be thrown. This guarantees the unlocking of
550 //!mutexes and other resources.
552 //!For all theses reasons, classes with throwing destructors are not
553 //!recommended.
554 template <class T>
555 bool destroy(const CharType *name)
556 { return mp_header->template destroy<T>(name); }
558 //!Destroys the unique instance of type T
560 //!Calls the destructor, frees used memory and returns true.
562 //!Exception Handling:
564 //!When deleting a dynamically object, the Standard does not
565 //!guarantee that dynamically allocated memory will be released.
567 //!Destroying an object:
569 //!If the destructor throws, the memory will be freed and that exception
570 //!will be thrown.
572 //!For all theses reasons, classes with throwing destructors are not
573 //!recommended for memory.
574 template <class T>
575 bool destroy(const detail::unique_instance_t *const )
576 { return mp_header->template destroy<T>(unique_instance); }
578 //!Destroys the object (named, unique, or anonymous)
580 //!Calls the destructor, frees used memory and returns true.
582 //!Exception Handling:
584 //!When deleting a dynamically object, the Standard does not
585 //!guarantee that dynamically allocated memory will be released.
587 //!Destroying an object:
589 //!If the destructor throws, the memory will be freed and that exception
590 //!will be thrown.
592 //!For all theses reasons, classes with throwing destructors are not
593 //!recommended for memory.
594 template <class T>
595 void destroy_ptr(const T *ptr)
596 { mp_header->template destroy_ptr<T>(ptr); }
598 //!Returns the name of an object created with construct/find_or_construct
599 //!functions. Does not throw
600 template<class T>
601 static const char_type *get_instance_name(const T *ptr)
602 { return segment_manager::get_instance_name(ptr); }
604 //!Returns is the type an object created with construct/find_or_construct
605 //!functions. Does not throw.
606 template<class T>
607 static instance_type get_instance_type(const T *ptr)
608 { return segment_manager::get_instance_type(ptr); }
610 //!Returns the length of an object created with construct/find_or_construct
611 //!functions (1 if is a single element, >=1 if it's an array). Does not throw.
612 template<class T>
613 static std::size_t get_instance_length(const T *ptr)
614 { return segment_manager::get_instance_length(ptr); }
616 //!Preallocates needed index resources to optimize the
617 //!creation of "num" named objects in the memory segment.
618 //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
619 void reserve_named_objects(std::size_t num)
620 { mp_header->reserve_named_objects(num); }
622 //!Preallocates needed index resources to optimize the
623 //!creation of "num" unique objects in the memory segment.
624 //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
625 void reserve_unique_objects(std::size_t num)
626 { mp_header->reserve_unique_objects(num); }
628 //!Calls shrink_to_fit in both named and unique object indexes
629 //to try to free unused memory from those indexes.
630 void shrink_to_fit_indexes()
631 { mp_header->shrink_to_fit_indexes(); }
633 //!Returns the number of named objects stored
634 //!in the managed segment.
635 std::size_t get_num_named_objects()
636 { return mp_header->get_num_named_objects(); }
638 //!Returns the number of unique objects stored
639 //!in the managed segment.
640 std::size_t get_num_unique_objects()
641 { return mp_header->get_num_unique_objects(); }
643 //!Returns a constant iterator to the index storing the
644 //!named allocations. NOT thread-safe. Never throws.
645 const_named_iterator named_begin() const
646 { return mp_header->named_begin(); }
648 //!Returns a constant iterator to the end of the index
649 //!storing the named allocations. NOT thread-safe. Never throws.
650 const_named_iterator named_end() const
651 { return mp_header->named_end(); }
653 //!Returns a constant iterator to the index storing the
654 //!unique allocations. NOT thread-safe. Never throws.
655 const_unique_iterator unique_begin() const
656 { return mp_header->unique_begin(); }
658 //!Returns a constant iterator to the end of the index
659 //!storing the unique allocations. NOT thread-safe. Never throws.
660 const_unique_iterator unique_end() const
661 { return mp_header->unique_end(); }
663 //!This is the default allocator to allocate types T
664 //!from this managed segment
665 template<class T>
666 struct allocator
668 typedef typename segment_manager::template allocator<T>::type type;
671 //!Returns an instance of the default allocator for type T
672 //!initialized that allocates memory from this segment manager.
673 template<class T>
674 typename allocator<T>::type
675 get_allocator()
676 { return mp_header->get_allocator<T>(); }
678 //!This is the default deleter to delete types T
679 //!from this managed segment.
680 template<class T>
681 struct deleter
683 typedef typename segment_manager::template deleter<T>::type type;
686 //!Returns an instance of the default allocator for type T
687 //!initialized that allocates memory from this segment manager.
688 template<class T>
689 typename deleter<T>::type
690 get_deleter()
691 { return mp_header->get_deleter<T>(); }
693 /// @cond
694 //!Tries to find a previous named allocation address. Returns a memory
695 //!buffer and the object count. If not found returned pointer is 0.
696 //!Never throws.
697 template <class T>
698 std::pair<T*, std::size_t> find_no_lock (char_ptr_holder_t name)
699 { return mp_header->template find_no_lock<T>(name); }
700 /// @endcond
702 protected:
703 //!Swaps the segment manager's managed by this managed memory segment.
704 //!NOT thread-safe. Never throws.
705 void swap(basic_managed_memory_impl &other)
706 { std::swap(mp_header, other.mp_header); }
708 private:
709 segment_manager *mp_header;
712 template<class BasicManagedMemoryImpl>
713 class create_open_func
715 public:
716 create_open_func(BasicManagedMemoryImpl * const frontend, detail::create_enum_t type)
717 : m_frontend(frontend), m_type(type){}
719 bool operator()(void *addr, std::size_t size, bool created) const
721 if(((m_type == detail::DoOpen) && created) ||
722 ((m_type == detail::DoCreate) && !created))
723 return false;
725 if(created)
726 return m_frontend->create_impl(addr, size);
727 else
728 return m_frontend->open_impl (addr, size);
731 private:
732 BasicManagedMemoryImpl *m_frontend;
733 detail::create_enum_t m_type;
736 } //namespace detail {
737 } //namespace interprocess {
738 } //namespace boost {
740 #include <boost/interprocess/detail/config_end.hpp>
742 #endif //BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP