diff --git a/include/boost/interprocess/containers/old_string.hpp b/include/boost/interprocess/containers/old_string.hpp deleted file mode 100644 index 093c617..0000000 --- a/include/boost/interprocess/containers/old_string.hpp +++ /dev/null @@ -1,1879 +0,0 @@ -/* - * Copyright (c) 1997-1999 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005. 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/shmem/ for documentation. -// -////////////////////////////////////////////////////////////////////////////// -// -// This file comes from SGI's string file. Modified by Ion Gaztañaga 2004 -// Renaming, isolating and porting to generic algorithms. Pointer typedef -// set to allocator::pointer to allow placing it in shared memory. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_SHMEM_STRING_HPP -#define BOOST_SHMEM_STRING_HPP - -#include -#include - -#ifdef min -#undef min -#endif - -#ifdef max -#undef max -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include - -// Standard C++ string class. This class has performance -// characteristics very much like vector<>, meaning, for example, that -// it does not perform reference-count or copy-on-write, and that -// concatenation of two strings is an O(N) operation. - -// There are three reasons why basic_string is not identical to -// vector. First, basic_string always stores a null character at the -// end; this makes it possible for c_str to be a fast operation. -// Second, the C++ standard requires basic_string to copy elements -// using char_traits<>::assign, char_traits<>::copy, and -// char_traits<>::move. This means that all of vector<>'s low-level -// operations must be rewritten. Third, basic_string<> has a lot of -// extra functions in its interface that are convenient but, strictly -// speaking, redundant. - -namespace boost { namespace shmem { - -// ------------------------------------------------------------ -// Class basic_string_base. - -// basic_string_base is a helper class that makes it it easier to write -// an exception-safe version of basic_string. The constructor allocates, -// but does not initialize, a block of memory. The destructor -// deallocates, but does not destroy elements within, a block of -// memory. The destructor assumes that this->m_start either is null, or else -// points to a block of memory that was allocated using _String_base's -// allocator and whose size is this->m_end_of_storage - this->m_start. -template -class basic_string_base : public Alloc -{ - public: - typedef Alloc allocator_type; - typedef typename Alloc::pointer pointer; - typedef typename Alloc::value_type value_type; - - allocator_type get_allocator() const { return *this; } - - basic_string_base(const allocator_type& a) - : allocator_type(a), - m_start(0), - m_finish(0), - m_end_of_storage(0) - {} - - basic_string_base(const allocator_type& a, std::size_t n) - : allocator_type(a), - m_start(0), - m_finish(0), - m_end_of_storage(0) - { allocate_block(n); } - - ~basic_string_base() - { deallocate_block(); } - -protected: - pointer allocate(std::size_t n) - { return allocator_type::allocate(n); } - - void deallocate(pointer p, std::size_t n) - { if (p) allocator_type::deallocate(p, n); } - - void construct(pointer p, const value_type &value = value_type()) - { allocator_type::construct(p, value); } - - void destroy(pointer p, pointer p2) - { for(;p != p2; ++p) allocator_type::destroy(p); } - - void destroy(pointer p) - { allocator_type::destroy(p); } - - void allocate_block(std::size_t n) { - if (n <= max_size()) { - m_start = allocate(n); - m_finish = m_start; - m_end_of_storage = m_start + n; - } - else - throw_length_error(); - } - - void deallocate_block() - { deallocate(m_start, m_end_of_storage - m_start); } - - std::size_t max_size() const { return (std::size_t(-1) / sizeof(value_type)) - 1; } - - // Helper functions for exception handling. - void throw_length_error() const - { throw(std::length_error("basic_string")); } - - void throw_out_of_range() const - { throw(std::out_of_range("basic_string")); } - -protected: - pointer m_start; - pointer m_finish; - pointer m_end_of_storage; -}; - -// ------------------------------------------------------------ -// Class basic_string. - -// Class invariants: -// (1) [start, finish) is a valid range. -// (2) Each iterator in [start, finish) points to a valid object -// of type value_type. -// (3) *finish is a valid object of type value_type; in particular, -// it is value_type(). -// (4) [finish + 1, end_of_storage) is a valid range. -// (5) Each iterator in [finish + 1, end_of_storage) points to -// uninitialized memory. - -// Note one important consequence: a string of length n must manage -// a block of memory whose size is at least n + 1. - - -template -class basic_string : private basic_string_base -{ - private: - typedef basic_string_base base_t; - - protected: - // A helper class to use a char_traits as a function object. - - template - struct Eq_traits - : public std::binary_function - { - bool operator()(const typename Tr::char_type& x, - const typename Tr::char_type& y) const - { return Tr::eq(x, y); } - }; - - template - struct Not_within_traits - : public std::unary_function - { - typedef const typename Tr::char_type* Pointer; - const Pointer m_first; - const Pointer m_last; - - Not_within_traits(Pointer f, Pointer l) - : m_first(f), m_last(l) {} - - bool operator()(const typename Tr::char_type& x) const - { - return find_if(m_first, m_last, - bind1st(Eq_traits(), x)) == m_last; - } - }; - - public: - typedef Alloc allocator_type; - typedef CharT value_type; - typedef Traits traits_type; - typedef typename Alloc::pointer pointer; - typedef typename Alloc::const_pointer const_pointer; - typedef typename Alloc::reference reference; - typedef typename Alloc::const_reference const_reference; - typedef typename Alloc::size_type size_type; - typedef typename Alloc::difference_type difference_type; - typedef const_pointer const_iterator; - typedef pointer iterator; - typedef boost::reverse_iterator reverse_iterator; - typedef boost::reverse_iterator const_reverse_iterator; - static const size_type npos; - - public: // Constructor, destructor, assignment. - allocator_type get_allocator() const - { return base_t::get_allocator(); } - - explicit basic_string(const allocator_type& a = allocator_type()) - : base_t(a, 8) { this->priv_terminate_string(); } - - struct reserve_t {}; - - basic_string(reserve_t, std::size_t n, - const allocator_type& a = allocator_type()) - : base_t(a, n + 1) { this->priv_terminate_string(); } - - basic_string(const basic_string& s) - : base_t(s.get_allocator()) - { this->priv_range_initialize(s.begin(), s.end()); } - - basic_string(const basic_string& s, size_type pos, size_type n = npos, - const allocator_type& a = allocator_type()) - : base_t(a) - { - if (pos > s.size()) - this->throw_out_of_range(); - else - this->priv_range_initialize - (s.begin() + pos, s.begin() + pos + std::min(n, s.size() - pos)); - } - - basic_string(const CharT* s, size_type n, - const allocator_type& a = allocator_type()) - : base_t(a) - { this->priv_range_initialize(s, s + n); } - - basic_string(const CharT* s, - const allocator_type& a = allocator_type()) - : base_t(a) - { this->priv_range_initialize(s, s + Traits::length(s)); } - - basic_string(size_type n, CharT c, - const allocator_type& a = allocator_type()) - : base_t(a, n + 1) - { - priv_uninitialized_fill_n(this->m_start, n, c, *this); - this->m_finish = this->m_start+n; - this->priv_terminate_string(); - } - - // Check to see if InputIterator is an integer type. If so, then - // it can't be an iterator. - template - basic_string(InputIterator f, InputIterator l, - const allocator_type& a = allocator_type()) - : base_t(a) - { - //Dispatch depending on integer/iterator - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - this->priv_initialize_dispatch(f, l, Result()); - } - - ~basic_string() - { this->destroy(this->m_start, this->m_finish + 1); } - - basic_string& operator=(const basic_string& s) { - if (&s != this) - assign(s.begin(), s.end()); - return *this; - } - - basic_string& operator=(const CharT* s) - { return assign(s, s + Traits::length(s)); } - - basic_string& operator=(CharT c) - { return assign(static_cast(1), c); } - - private: // Helper functions used by constructors - // and elsewhere. - void priv_construct_null(pointer p) { - this->construct(p, 0); - } - - static CharT priv_null() { - return (CharT) 0; - } - - private: - // Helper functions used by constructors. It is a severe error for - // any of them to be called anywhere except from within constructors. - void priv_terminate_string() - { - BOOST_TRY{ - this->priv_construct_null(this->m_finish); - } - BOOST_CATCH(...){ - this->destroy(this->m_start, this->m_finish); - } - BOOST_CATCH_END - } - - template - void priv_range_initialize(InputIter f, InputIter l, - std::input_iterator_tag) { - this->allocate_block(8); - this->priv_construct_null(this->m_finish); - BOOST_TRY{ - append(f, l); - } - BOOST_CATCH(...){ - this->destroy(this->m_start, this->m_finish + 1); - BOOST_RETHROW - } - BOOST_CATCH_END - } - - template - void priv_range_initialize(ForwardIter f, ForwardIter l, - std::forward_iterator_tag) { - difference_type n = 0; - n = std::distance(f, l); - this->allocate_block(n + 1); - this->m_finish = priv_uninitialized_copy(f, l, this->m_start, *this); - this->priv_terminate_string(); - } - - template - void priv_range_initialize(InputIter f, InputIter l) { - typedef typename std::iterator_traits::iterator_category Category; - this->priv_range_initialize(f, l, Category()); - } - - template - void priv_initialize_dispatch(Integer n, Integer x, boost::mpl::true_) { - this->allocate_block(n + 1); - priv_uninitialized_fill_n(this->m_start, n, x, *this); - this->m_finish = this->m_start + n; - this->priv_terminate_string(); - } - - template - void priv_initialize_dispatch(InputIter f, InputIter l, boost::mpl::false_) { - this->priv_range_initialize(f, l); - } - - public: // Iterators. - iterator begin() { return this->m_start; } - iterator end() { return this->m_finish; } - const_iterator begin() const { return this->m_start; } - const_iterator end() const { return this->m_finish; } - - reverse_iterator rbegin() - { return reverse_iterator(this->m_finish); } - reverse_iterator rend() - { return reverse_iterator(this->m_start); } - const_reverse_iterator rbegin() const - { return const_reverse_iterator(this->m_finish); } - const_reverse_iterator rend() const - { return const_reverse_iterator(this->m_start); } - - public: // Size, capacity, etc. - size_type size() const { return this->m_finish - this->m_start; } - size_type length() const { return size(); } - - size_type max_size() const { return base_t::max_size(); } - - - void resize(size_type n, CharT c) { - if (n <= size()) - erase(begin() + n, end()); - else - append(n - size(), c); - } - - void resize(size_type n) { resize(n, this->priv_null()); } - - // Change the string's capacity so that it is large enough to hold - // at least priv_res_arg elements, plus the terminating null. Note that, - // if priv_res_arg < capacity(), this member function may actually decrease - // the string's capacity. - void reserve(size_type res_arg) - { - if (res_arg > this->max_size()) - this->throw_length_error(); - - size_type n = std::max(res_arg, size()) + 1; - pointer new_start = this->allocate(n); - pointer new_finish = new_start; - - BOOST_TRY{ - new_finish = priv_uninitialized_copy - (this->m_start, this->m_finish, new_start, *this); - this->priv_construct_null(new_finish); - } - BOOST_CATCH(...){ - this->destroy(new_start, new_finish); - this->deallocate(new_start, n); - } - BOOST_CATCH_END - - this->destroy(this->m_start, this->m_finish + 1); - this->deallocate_block(); - this->m_start = new_start; - this->m_finish = new_finish; - this->m_end_of_storage = new_start + n; - } - - size_type capacity() const { return (this->m_end_of_storage - this->m_start) - 1; } - - void clear() { - if (!empty()) { - Traits::assign(*this->m_start, this->priv_null()); - this->destroy(this->m_start+1, this->m_finish+1); - this->m_finish = this->m_start; - } - } - - bool empty() const { return this->m_start == this->m_finish; } - - public: // Element access. - - const_reference operator[](size_type n) const - { return *(this->m_start + n); } - reference operator[](size_type n) - { return *(this->m_start + n); } - - const_reference at(size_type n) const { - if (n >= size()) - this->throw_out_of_range(); - return *(this->m_start + n); - } - - reference at(size_type n) { - if (n >= size()) - this->throw_out_of_range(); - return *(this->m_start + n); - } - - public: // Append, operator+=, push_back. - - basic_string& operator+=(const basic_string& s) { return append(s); } - basic_string& operator+=(const CharT* s) { return append(s); } - basic_string& operator+=(CharT c) { push_back(c); return *this; } - - basic_string& append(const basic_string& s) - { return append(s.begin(), s.end()); } - - basic_string& append(const basic_string& s, - size_type pos, size_type n) - { - if (pos > s.size()) - this->throw_out_of_range(); - return append(s.begin() + pos, - s.begin() + pos + std::min(n, s.size() - pos)); - } - - basic_string& append(const CharT* s, size_type n) - { return append(s, s+n); } - - basic_string& append(const CharT* s) - { return append(s, s + Traits::length(s)); } - - basic_string& append(size_type n, CharT c) - { - if (n > this->max_size() || size() > this->max_size() - n) - this->throw_length_error(); - if (size() + n > capacity()) - reserve(size() + std::max(size(), n)); - if (n > 0) { - priv_uninitialized_fill_n(this->m_finish + 1, n - 1, c, *this); - BOOST_TRY{ - this->priv_construct_null(this->m_finish + n); - } - BOOST_CATCH(...){ - this->destroy(this->m_finish + 1, this->m_finish + n); - } - BOOST_CATCH_END - Traits::assign(*this->m_finish, c); - this->m_finish += n; - } - return *this; - } - - // Check to see if InputIterator is an integer type. If so, then - // it can't be an iterator. - template - basic_string& append(InputIter first, InputIter last) { - //Dispatch depending on integer/iterator - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - return this->priv_append_dispatch(first, last, Result()); - } - - void push_back(CharT c) { - if (this->m_finish + 1 == this->m_end_of_storage) - reserve(size() + std::max(size(), static_cast(1))); - this->priv_construct_null(this->m_finish + 1); - Traits::assign(*this->m_finish, c); - ++this->m_finish; - } - - void pop_back() { - Traits::assign(*(this->m_finish - 1), this->priv_null()); - this->destroy(this->m_finish); - --this->m_finish; - } - - private: // Helper functions for append. - - template inline - void priv_uninitialized_fill_n(FwdIt first, Count count, - const CharT val, A& 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 inline - FwdIt priv_uninitialized_copy(InpIt first, InpIt last, - FwdIt dest, A& al) - { - //Save initial destination position - FwdIt dest_init = dest; - - BOOST_TRY{ - //Try to build objects - for (; first != last; ++dest, ++first){ - 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 - basic_string& append(InputIter first, InputIter last, std::input_iterator_tag) - { - for ( ; first != last ; ++first) - push_back(*first); - return *this; - } - - template - basic_string& append(ForwardIter first, ForwardIter last, - std::forward_iterator_tag) - { - if (first != last) { - const size_type old_size = size(); - difference_type n = 0; - n = std::distance(first, last); - if (static_cast(n) > this->max_size() || - old_size > this->max_size() - static_cast(n)) - this->throw_length_error(); - if (old_size + static_cast(n) > capacity()) { - const size_type len = old_size + - std::max(old_size, static_cast(n)) + 1; - pointer new_start = this->allocate(len); - pointer new_finish = new_start; - BOOST_TRY{ - new_finish = priv_uninitialized_copy - (this->m_start, this->m_finish, new_start, *this); - new_finish = priv_uninitialized_copy - (first, last, new_finish, *this); - this->priv_construct_null(new_finish); - } - BOOST_CATCH(...){ - this->destroy(new_start,new_finish); - this->deallocate(new_start,len); - } - BOOST_CATCH_END - - this->destroy(this->m_start, this->m_finish + 1); - this->deallocate_block(); - this->m_start = new_start; - this->m_finish = new_finish; - this->m_end_of_storage = new_start + len; - } - else { - ForwardIter f1 = first; - ++f1; - priv_uninitialized_copy(f1, last, this->m_finish + 1, *this); - BOOST_TRY{ - this->priv_construct_null(this->m_finish + n); - } - BOOST_CATCH(...){ - this->destroy(this->m_finish + 1, this->m_finish + n); - } - BOOST_CATCH_END - Traits::assign(*this->m_finish, *first); - this->m_finish += n; - } - } - return *this; - - } - - template - basic_string& priv_append_dispatch(Integer n, Integer x, boost::mpl::true_) { - return append((size_type) n, (CharT) x); - } - - template - basic_string& priv_append_dispatch(InputIter f, InputIter l, - boost::mpl::false_) { - typedef typename std::iterator_traits::iterator_category Category; - return append(f, l, Category()); - } - - public: // Assign - - basic_string& assign(const basic_string& s) - { return assign(s.begin(), s.end()); } - - basic_string& assign(const basic_string& s, - size_type pos, size_type n) { - if (pos > s.size()) - this->throw_out_of_range(); - return assign(s.begin() + pos, - s.begin() + pos + std::min(n, s.size() - pos)); - } - - basic_string& assign(const CharT* s, size_type n) - { return assign(s, s + n); } - - basic_string& assign(const CharT* s) - { return assign(s, s + Traits::length(s)); } - - basic_string& assign(size_type n, CharT c) - { - if (n <= size()) { - Traits::assign(detail::get_pointer(this->m_start), n, c); - erase(this->m_start + n, this->m_finish); - } - else { - Traits::assign(detail::get_pointer(this->m_start), size(), c); - append(n - size(), c); - } - return *this; - } - - // Check to see if InputIterator is an integer type. If so, then - // it can't be an iterator. - template - basic_string& assign(InputIter first, InputIter last) - { - //Dispatch depending on integer/iterator - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - return this->priv_assign_dispatch(first, last, Result()); - } - - basic_string& assign(const CharT* f, const CharT* l) - { - const std::ptrdiff_t n = l - f; - if (static_cast(n) <= size()) { - Traits::copy(detail::get_pointer(this->m_start), f, n); - erase(this->m_start + n, this->m_finish); - } - else { - Traits::copy(detail::get_pointer(this->m_start), f, size()); - append(f + size(), l); - } - return *this; - } - - private: // Helper functions for assign. - - template - basic_string& priv_assign_dispatch(Integer n, Integer x, boost::mpl::true_) - { return assign((size_type) n, (CharT) x); } - - template - basic_string& priv_assign_dispatch(InputIter f, InputIter l, - boost::mpl::false_) - { - pointer cur = this->m_start; - while (f != l && cur != this->m_finish) { - Traits::assign(*cur, *f); - ++f; - ++cur; - } - if (f == l) - erase(cur, this->m_finish); - else - append(f, l); - return *this; - - } - - public: // Insert - - basic_string& insert(size_type pos, const basic_string& s) - { - if (pos > size()) - this->throw_out_of_range(); - if (size() > this->max_size() - s.size()) - this->throw_length_error(); - insert(this->m_start + pos, s.begin(), s.end()); - return *this; - } - - basic_string& insert(size_type pos, const basic_string& s, - size_type beg, size_type n) - { - if (pos > size() || beg > s.size()) - this->throw_out_of_range(); - size_type len = std::min(n, s.size() - beg); - if (size() > this->max_size() - len) - this->throw_length_error(); - insert(this->m_start + pos, s.begin() + beg, s.begin() + beg + len); - return *this; - } - - basic_string& insert(size_type pos, const CharT* s, size_type n) - { - if (pos > size()) - this->throw_out_of_range(); - if (size() > this->max_size() - n) - this->throw_length_error(); - insert(this->m_start + pos, s, s + n); - return *this; - } - - basic_string& insert(size_type pos, const CharT* s) - { - if (pos > size()) - this->throw_out_of_range(); - size_type len = Traits::length(s); - if (size() > this->max_size() - len) - this->throw_length_error(); - insert(this->m_start + pos, s, s + len); - return *this; - } - - basic_string& insert(size_type pos, size_type n, CharT c) - { - if (pos > size()) - this->throw_out_of_range(); - if (size() > this->max_size() - n) - this->throw_length_error(); - insert(this->m_start + pos, n, c); - return *this; - } - - iterator insert(iterator p, CharT c) - { - if (p == this->m_finish) { - push_back(c); - return this->m_finish - 1; - } - else - return this->priv_insert_aux(p, c); - } - - void insert(iterator position, std::size_t n, CharT c) - { - if (n != 0) { - if (size_type(this->m_end_of_storage - this->m_finish) >= n + 1) { - const size_type elems_after = this->m_finish - position; - iterator old_finish = this->m_finish; - if (elems_after >= n) { - priv_uninitialized_copy((this->m_finish - n) + 1, - this->m_finish + 1, - this->m_finish + 1, *this); - this->m_finish += n; - Traits::move(detail::get_pointer(position + n), - detail::get_pointer(position), - (elems_after - n) + 1); - Traits::assign(detail::get_pointer(position), n, c); - } - else { - priv_uninitialized_fill_n - (this->m_finish + 1, n - elems_after - 1, c, *this); - this->m_finish += n - elems_after; - BOOST_TRY{ - priv_uninitialized_copy - (position, old_finish + 1, this->m_finish, *this); - this->m_finish += elems_after; - } - BOOST_CATCH(...){ - this->destroy(old_finish + 1, this->m_finish); - this->m_finish = old_finish; - } - BOOST_CATCH_END - Traits::assign(detail::get_pointer(position), elems_after + 1, c); - } - } - else { - const size_type old_size = size(); - const size_type len = old_size + std::max(old_size, n) + 1; - iterator new_start = this->allocate(len); - iterator new_finish = new_start; - BOOST_TRY{ - new_finish = priv_uninitialized_copy - (this->m_start, position, new_start, *this); - priv_uninitialized_fill_n(new_finish, n, c, *this); - new_finish = new_finish + n; - new_finish = priv_uninitialized_copy(position, this->m_finish, - new_finish, *this); - this->priv_construct_null(new_finish); - } - BOOST_CATCH(...){ - this->destroy(new_start,new_finish); - this->deallocate(new_start,len); - } - BOOST_CATCH_END - this->destroy(this->m_start, this->m_finish + 1); - this->deallocate_block(); - this->m_start = new_start; - this->m_finish = new_finish; - this->m_end_of_storage = new_start + len; - } - } - } - - // Check to see if InputIterator is an integer type. If so, then - // it can't be an iterator. - template - void insert(iterator p, InputIter first, InputIter last) - { - //Dispatch depending on integer/iterator - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - this->priv_insert_dispatch(p, first, last, Result()); - } - - private: // Helper functions for insert. - - template - void insert(iterator p, InputIter first, InputIter last, std::input_iterator_tag) - { - for ( ; first != last; ++first) { - p = insert(p, *first); - ++p; - } - } - - template - void insert(iterator position, ForwardIter first, - ForwardIter last, std::forward_iterator_tag) - { - if (first != last) { - difference_type n = 0; - n = std::distance(first, last); - if (this->m_end_of_storage - this->m_finish >= n + 1) { - const difference_type elems_after = this->m_finish - position; - iterator old_finish = this->m_finish; - if (elems_after >= n) { - priv_uninitialized_copy((this->m_finish - n) + 1, this->m_finish + 1, - this->m_finish + 1, *this); - this->m_finish += n; - Traits::move(detail::get_pointer(position + n), - detail::get_pointer(position), - (elems_after - n) + 1); - this->priv_copy(first, last, position); - } - else { - ForwardIter mid = first; - std::advance(mid, elems_after + 1); - priv_uninitialized_copy(mid, last, this->m_finish + 1, *this); - this->m_finish += n - elems_after; - BOOST_TRY{ - priv_uninitialized_copy - (position, old_finish + 1, this->m_finish, *this); - this->m_finish += elems_after; - } - BOOST_CATCH(...){ - this->destroy(old_finish + 1, this->m_finish); - this->m_finish = old_finish; - } - BOOST_CATCH_END - this->priv_copy(first, mid, position); - } - } - else { - const size_type old_size = size(); - const size_type len - = old_size + std::max(old_size, static_cast(n)) + 1; - pointer new_start = this->allocate(len); - pointer new_finish = new_start; - BOOST_TRY{ - new_finish = priv_uninitialized_copy - (this->m_start, position, new_start, *this); - new_finish = priv_uninitialized_copy - (first, last, new_finish, *this); - new_finish = priv_uninitialized_copy - (position, this->m_finish, new_finish, *this); - this->priv_construct_null(new_finish); - } - BOOST_CATCH(...){ - this->destroy(new_start,new_finish); - this->deallocate(new_start,len); - } - BOOST_CATCH_END - this->destroy(this->m_start, this->m_finish + 1); - this->deallocate_block(); - this->m_start = new_start; - this->m_finish = new_finish; - this->m_end_of_storage = new_start + len; - } - } - } - - template - void priv_insert_dispatch(iterator p, Integer n, Integer x, - boost::mpl::true_) - { insert(p, (size_type) n, (CharT) x); } - - template - void priv_insert_dispatch(iterator p, InputIter first, InputIter last, - boost::mpl::false_) - { - typedef typename std::iterator_traits::iterator_category Category; - insert(p, first, last, Category()); - } - - template - void priv_copy(InputIterator first, InputIterator last, iterator result) - { - for ( ; first != last; ++first, ++result) - Traits::assign(*result, *first); - } - - iterator priv_insert_aux(iterator p, CharT c) - { - iterator new_pos = p; - if (this->m_finish + 1 < this->m_end_of_storage) { - this->priv_construct_null(this->m_finish + 1); - Traits::move(detail::get_pointer(p + 1), - detail::get_pointer(p), - this->m_finish - p); - Traits::assign(*p, c); - ++this->m_finish; - } - else { - const size_type old_len = size(); - const size_type len = old_len + - std::max(old_len, static_cast(1)) + 1; - iterator new_start = this->allocate(len); - iterator new_finish = new_start; - BOOST_TRY{ - new_pos = priv_uninitialized_copy - (this->m_start, p, new_start, *this); - this->construct(new_pos, c); - new_finish = new_pos + 1; - new_finish = priv_uninitialized_copy - (p, this->m_finish, new_finish, *this); - this->priv_construct_null(new_finish); - } - BOOST_CATCH(...){ - this->destroy(new_start,new_finish); - this->deallocate(new_start,len); - } - BOOST_CATCH_END - this->destroy(this->m_start, this->m_finish + 1); - this->deallocate_block(); - this->m_start = new_start; - this->m_finish = new_finish; - this->m_end_of_storage = new_start + len; - } - return new_pos; - } - - void priv_copy(const CharT* first, const CharT* last, CharT* result) - { Traits::copy(result, first, last - first); } - - public: // Erase. - - basic_string& erase(size_type pos = 0, size_type n = npos) - { - if (pos > size()) - this->throw_out_of_range(); - erase(this->m_start + pos, this->m_start + pos + std::min(n, size() - pos)); - return *this; - } - - iterator erase(iterator position) - { - // The move includes the terminating null. - Traits::move(detail::get_pointer(position), - detail::get_pointer(position + 1), - this->m_finish - position); - this->destroy(this->m_finish); - --this->m_finish; - return position; - } - - iterator erase(iterator first, iterator last) - { - if (first != last) { // The move includes the terminating null. - Traits::move(detail::get_pointer(first), - detail::get_pointer(last), - (this->m_finish - last) + 1); - const iterator new_finish = this->m_finish - (last - first); - this->destroy(new_finish + 1, this->m_finish + 1); - this->m_finish = new_finish; - } - return first; - } - - public: // Replace. (Conceptually equivalent - // to erase followed by insert.) - basic_string& replace(size_type pos, size_type n, - const basic_string& s) - { - if (pos > size()) - this->throw_out_of_range(); - const size_type len = std::min(n, size() - pos); - if (size() - len >= this->max_size() - s.size()) - this->throw_length_error(); - return replace(this->m_start + pos, this->m_start + pos + len, - s.begin(), s.end()); - } - - basic_string& replace(size_type pos1, size_type n1, - const basic_string& s, - size_type pos2, size_type n2) - { - if (pos1 > size() || pos2 > s.size()) - this->throw_out_of_range(); - const size_type len1 = std::min(n1, size() - pos1); - const size_type len2 = std::min(n2, s.size() - pos2); - if (size() - len1 >= this->max_size() - len2) - this->throw_length_error(); - return replace(this->m_start + pos1, this->m_start + pos1 + len1, - s.m_start + pos2, s.m_start + pos2 + len2); - } - - basic_string& replace(size_type pos, size_type n1, - const CharT* s, size_type n2) - { - if (pos > size()) - this->throw_out_of_range(); - const size_type len = std::min(n1, size() - pos); - if (n2 > this->max_size() || size() - len >= this->max_size() - n2) - this->throw_length_error(); - return replace(this->m_start + pos, this->m_start + pos + len, - s, s + n2); - } - - basic_string& replace(size_type pos, size_type n1, - const CharT* s) - { - if (pos > size()) - this->throw_out_of_range(); - const size_type len = std::min(n1, size() - pos); - const size_type n2 = Traits::length(s); - if (n2 > this->max_size() || size() - len >= this->max_size() - n2) - this->throw_length_error(); - return replace(this->m_start + pos, this->m_start + pos + len, - s, s + Traits::length(s)); - } - - basic_string& replace(size_type pos, size_type n1, - size_type n2, CharT c) - { - if (pos > size()) - this->throw_out_of_range(); - const size_type len = std::min(n1, size() - pos); - if (n2 > this->max_size() || size() - len >= this->max_size() - n2) - this->throw_length_error(); - return replace(this->m_start + pos, this->m_start + pos + len, n2, c); - } - - basic_string& replace(iterator first, iterator last, - const basic_string& s) - { return replace(first, last, s.begin(), s.end()); } - - basic_string& replace(iterator first, iterator last, - const CharT* s, size_type n) - { return replace(first, last, s, s + n); } - - basic_string& replace(iterator first, iterator last, - const CharT* s) - { return replace(first, last, s, s + Traits::length(s)); } - - basic_string& replace(iterator first, iterator last, - size_type n, CharT c) - { - const size_type len = static_cast(last - first); - if (len >= n) { - Traits::assign(detail::get_pointer(first), n, c); - erase(first + n, last); - } - else { - Traits::assign(detail::get_pointer(first), len, c); - insert(last, n - len, c); - } - return *this; - } - - // Check to see if InputIterator is an integer type. If so, then - // it can't be an iterator. - template - basic_string& replace(iterator first, iterator last, - InputIter f, InputIter l) - { - //Dispatch depending on integer/iterator - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - return this->priv_replace_dispatch(first, last, f, l, Result()); - } - - private: // Helper functions for replace. - - template - basic_string& priv_replace_dispatch(iterator first, iterator last, - Integer n, Integer x, - boost::mpl::true_) - { return replace(first, last, (size_type) n, (CharT) x); } - - template - basic_string& priv_replace_dispatch(iterator first, iterator last, - InputIter f, InputIter l, - boost::mpl::false_) - { - typedef typename std::iterator_traits::iterator_category Category; - return replace(first, last, f, l, Category()); - } - - - template - basic_string& replace(iterator first, iterator last, - InputIter f, InputIter l, std::input_iterator_tag) - { - for ( ; first != last && f != l; ++first, ++f) - Traits::assign(*first, *f); - - if (f == l) - erase(first, last); - else - insert(last, f, l); - return *this; - } - - template - basic_string& replace(iterator first, iterator last, - ForwardIter f, ForwardIter l, - std::forward_iterator_tag) - { - difference_type n = 0; - n = std::distance(f, l); - const difference_type len = last - first; - if (len >= n) { - this->priv_copy(f, l, first); - erase(first + n, last); - } - else { - ForwardIter m = f; - std::advance(m, len); - this->priv_copy(f, m, first); - insert(last, m, l); - } - return *this; - } - - public: // Other modifier member functions. - - size_type copy(CharT* s, size_type n, size_type pos = 0) const - { - if (pos > size()) - this->throw_out_of_range(); - const size_type len = std::min(n, size() - pos); - Traits::copy(s, detail::get_pointer(this->m_start + pos), len); - return len; - } - - void swap(basic_string& s) - { - detail::do_swap(this->m_start, s.m_start); - detail::do_swap(this->m_finish, s.m_finish); - detail::do_swap(this->m_end_of_storage, s.m_end_of_storage); - allocator_type & this_al = *this, &s_al = s; - if(this_al != s_al){ - detail::do_swap(this_al, s_al); - } - } - - public: // Conversion to C string. - - const CharT* c_str() const - { return detail::get_pointer(this->m_start); } - - const CharT* data() const - { return detail::get_pointer(this->m_start); } - - public: // find. - - size_type find(const basic_string& s, size_type pos = 0) const - { return find(s.c_str(), pos, s.size()); } - - size_type find(const CharT* s, size_type pos = 0) const - { return find(s, pos, Traits::length(s)); } - - size_type find(const CharT* s, size_type pos, size_type n) const - { - if (pos + n > size()) - return npos; - else { - const const_iterator result = - search(detail::get_pointer(this->m_start + pos), - detail::get_pointer(this->m_finish), - s, s + n, Eq_traits()); - return result != this->m_finish ? result - begin() : npos; - } - } - - size_type find(CharT c, size_type pos = 0) const - { - if (pos >= size()) - return npos; - else { - const const_iterator result = - find_if(this->m_start + pos, this->m_finish, - std::bind2nd(Eq_traits(), c)); - return result != this->m_finish ? result - begin() : npos; - } - } - - public: // rfind. - - size_type rfind(const basic_string& s, size_type pos = npos) const - { return rfind(s.c_str(), pos, s.size()); } - - size_type rfind(const CharT* s, size_type pos = npos) const - { return rfind(s, pos, Traits::length(s)); } - - size_type rfind(const CharT* s, size_type pos, size_type n) const - { - const std::size_t len = size(); - - if (n > len) - return npos; - else if (n == 0) - return std::min(len, pos); - else { - const const_iterator last = begin() + std::min(len - n, pos) + n; - const const_iterator result = find_end(begin(), last, - s, s + n, - Eq_traits()); - return result != last ? result - begin() : npos; - } - } - - size_type rfind(CharT c, size_type pos = npos) const - { - const size_type len = size(); - - if (len < 1) - return npos; - else { - const const_iterator last = begin() + std::min(len - 1, pos) + 1; - const_reverse_iterator rresult = - find_if(const_reverse_iterator(last), rend(), - std::bind2nd(Eq_traits(), c)); - return rresult != rend() ? (rresult.base() - 1) - begin() : npos; - } - } - - public: // find_first_of - - size_type find_first_of(const basic_string& s, size_type pos = 0) const - { return find_first_of(s.c_str(), pos, s.size()); } - - size_type find_first_of(const CharT* s, size_type pos = 0) const - { return find_first_of(s, pos, Traits::length(s)); } - - size_type find_first_of(const CharT* s, size_type pos, - size_type n) const - { - if (pos >= size()) - return npos; - else { - const_iterator result = std::find_first_of(begin() + pos, end(), - s, s + n, - Eq_traits()); - return result != this->m_finish ? result - begin() : npos; - } - } - - size_type find_first_of(CharT c, size_type pos = 0) const - { return find(c, pos); } - - public: // find_last_of - - size_type find_last_of(const basic_string& s, - size_type pos = npos) const - { return find_last_of(s.c_str(), pos, s.size()); } - - size_type find_last_of(const CharT* s, size_type pos = npos) const - { return find_last_of(s, pos, Traits::length(s)); } - - size_type find_last_of(const CharT* s, size_type pos, size_type n) const - { - const size_type len = size(); - - if (len < 1) - return npos; - else { - const const_iterator last = this->m_start + std::min(len - 1, pos) + 1; - const const_reverse_iterator rresult = - std::find_first_of(const_reverse_iterator(last), rend(), - s, s + n, - Eq_traits()); - return rresult != rend() ? (rresult.base() - 1) - this->m_start : npos; - } - } - - size_type find_last_of(CharT c, size_type pos = npos) const - { return rfind(c, pos); } - - public: // find_first_not_of - - size_type find_first_not_of(const basic_string& s, - size_type pos = 0) const - { return find_first_not_of(s.c_str(), pos, s.size()); } - - size_type find_first_not_of(const CharT* s, size_type pos = 0) const - { return find_first_not_of(s, pos, Traits::length(s)); } - - size_type find_first_not_of(const CharT* s, size_type pos, - size_type n) const - { - if (pos > size()) - return npos; - else { - const_iterator result = find_if(this->m_start + pos, this->m_finish, - Not_within_traits(s, s + n)); - return result != this->m_finish ? result - this->m_start : npos; - } - } - - size_type find_first_not_of(CharT c, size_type pos = 0) const - { - if (pos > size()) - return npos; - else { - const_iterator result - = find_if(begin() + pos, end(), - not1(std::bind2nd(Eq_traits(), c))); - return result != this->m_finish ? result - begin() : npos; - } - } - - public: // find_last_not_of - - size_type find_last_not_of(const basic_string& s, - size_type pos = npos) const - { return find_last_not_of(s.c_str(), pos, s.size()); } - - size_type find_last_not_of(const CharT* s, size_type pos = npos) const - { return find_last_not_of(s, pos, Traits::length(s)); } - - size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const - { - const size_type len = size(); - - if (len < 1) - return npos; - else { - const const_iterator last = begin() + std::min(len - 1, pos) + 1; - const const_reverse_iterator rresult = - find_if(const_reverse_iterator(last), rend(), - Not_within_traits(s, s + n)); - return rresult != rend() ? (rresult.base() - 1) - begin() : npos; - } - } - - size_type find_last_not_of(CharT c, size_type pos = npos) const - { - const size_type len = size(); - - if (len < 1) - return npos; - else { - const const_iterator last = begin() + std::min(len - 1, pos) + 1; - const_reverse_iterator rresult = - find_if(const_reverse_iterator(last), rend(), - not1(std::bind2nd(Eq_traits(), c))); - return rresult != rend() ? (rresult.base() - 1) - begin() : npos; - } - } - - public: // Substring. - - basic_string substr(size_type pos = 0, size_type n = npos) const - { - if (pos > size()) - this->throw_out_of_range(); - return basic_string(this->m_start + pos, - this->m_start + pos + std::min(n, size() - pos), *this); - } - - public: // Compare - - int compare(const basic_string& s) const - { return this->s_compare(this->m_start, this->m_finish, s.m_start, s.m_finish); } - - int compare(size_type pos1, size_type n1, const basic_string& s) const - { - if (pos1 > size()) - this->throw_out_of_range(); - return this->s_compare(this->m_start + pos1, - this->m_start + pos1 + std::min(n1, size() - pos1), - s.m_start, s.m_finish); - } - - int compare(size_type pos1, size_type n1, - const basic_string& s, - size_type pos2, size_type n2) const { - if (pos1 > size() || pos2 > s.size()) - this->throw_out_of_range(); - return this->s_compare(this->m_start + pos1, - this->m_start + pos1 + std::min(n1, size() - pos1), - s.m_start + pos2, - s.m_start + pos2 + std::min(n2, size() - pos2)); - } - - int compare(const CharT* s) const - { return this->s_compare(this->m_start, this->m_finish, s, s + Traits::length(s)); } - - int compare(size_type pos1, size_type n1, const CharT* s) const - { - if (pos1 > size()) - this->throw_out_of_range(); - return this->s_compare(this->m_start + pos1, - this->m_start + pos1 + std::min(n1, size() - pos1), - s, s + Traits::length(s)); - } - - int compare(size_type pos1, size_type n1, const CharT* s, - size_type n2) const - { - if (pos1 > size()) - this->throw_out_of_range(); - return this->s_compare(this->m_start + pos1, - this->m_start + pos1 + std::min(n1, size() - pos1), - s, s + n2); - } - -public: // Helper function for compare. - static int s_compare(const_pointer f1, const_pointer l1, - const_pointer f2, const_pointer l2) - { - const std::ptrdiff_t n1 = l1 - f1; - const std::ptrdiff_t n2 = l2 - f2; - const int cmp = Traits::compare(detail::get_pointer(f1), - detail::get_pointer(f2), - std::min(n1, n2)); - return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0)); - } -}; - -template -const typename basic_string::size_type -basic_string::npos - = (typename basic_string::size_type) -1; - -// ------------------------------------------------------------ -// Non-member functions. - -// Operator+ - -template -inline basic_string -operator+(const basic_string& x, - const basic_string& y) -{ - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - str_t result(reserve, x.size() + y.size(), x.get_allocator()); - result.append(x); - result.append(y); - return result; -} - -template -inline basic_string -operator+(const CharT* s, const basic_string& y) -{ - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - const std::size_t n = Traits::length(s); - str_t result(reserve, n + y.size()); - result.append(s, s + n); - result.append(y); - return result; -} - -template -inline basic_string -operator+(CharT c, const basic_string& y) -{ - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - str_t result(reserve, 1 + y.size()); - result.push_back(c); - result.append(y); - return result; -} - -template -inline basic_string -operator+(const basic_string& x, const CharT* s) -{ - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - const std::size_t n = Traits::length(s); - str_t result(reserve, x.size() + n, x.get_allocator()); - result.append(x); - result.append(s, s + n); - return result; -} - -template -inline basic_string -operator+(const basic_string& x, const CharT c) -{ - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - str_t result(reserve, x.size() + 1, x.get_allocator()); - result.append(x); - result.push_back(c); - return result; -} - -// Operator== and operator!= - -template -inline bool -operator==(const basic_string& x, - const basic_string& y) -{ - return x.size() == y.size() && - Traits::compare(x.data(), y.data(), x.size()) == 0; -} - -template -inline bool -operator==(const CharT* s, const basic_string& y) -{ - std::size_t n = Traits::length(s); - return n == y.size() && Traits::compare(s, y.data(), n) == 0; -} - -template -inline bool -operator==(const basic_string& x, const CharT* s) -{ - std::size_t n = Traits::length(s); - return x.size() == n && Traits::compare(x.data(), s, n) == 0; -} - -template -inline bool -operator!=(const basic_string& x, - const basic_string& y) - { return !(x == y); } - -template -inline bool -operator!=(const CharT* s, const basic_string& y) - { return !(s == y); } - -template -inline bool -operator!=(const basic_string& x, const CharT* s) - { return !(x == s); } - - -// Operator< (and also >, <=, and >=). - -template -inline bool -operator<(const basic_string& x, - const basic_string& y) -{ - return basic_string - ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0; -} - -template -inline bool -operator<(const CharT* s, const basic_string& y) -{ - std::size_t n = Traits::length(s); - return basic_string - ::s_compare(s, s + n, y.begin(), y.end()) < 0; -} - -template -inline bool -operator<(const basic_string& x, - const CharT* s) -{ - std::size_t n = Traits::length(s); - return basic_string - ::s_compare(x.begin(), x.end(), s, s + n) < 0; -} - -template -inline bool -operator>(const basic_string& x, - const basic_string& y) { - return y < x; -} - -template -inline bool -operator>(const CharT* s, const basic_string& y) { - return y < s; -} - -template -inline bool -operator>(const basic_string& x, const CharT* s) -{ - return s < x; -} - -template -inline bool -operator<=(const basic_string& x, - const basic_string& y) -{ - return !(y < x); -} - -template -inline bool -operator<=(const CharT* s, const basic_string& y) - { return !(y < s); } - -template -inline bool -operator<=(const basic_string& x, const CharT* s) - { return !(s < x); } - -template -inline bool -operator>=(const basic_string& x, - const basic_string& y) - { return !(x < y); } - -template -inline bool -operator>=(const CharT* s, const basic_string& y) - { return !(s < y); } - -template -inline bool -operator>=(const basic_string& x, const CharT* s) - { return !(x < s); } - -// Swap. - -template -inline void swap(basic_string& x, - basic_string& y) - { x.swap(y); } - -// I/O. - -template -inline bool -sgi_string_fill(std::basic_ostream& os, - std::basic_streambuf* buf, - std::size_t n) -{ - CharT f = os.fill(); - std::size_t i; - bool ok = true; - - for (i = 0; i < n; i++) - ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof()); - return ok; -} - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, - const basic_string& s) -{ - typename std::basic_ostream::sentry sentry(os); - bool ok = false; - - if (sentry) { - ok = true; - std::size_t n = s.size(); - std::size_t pad_len = 0; - const bool left = (os.flags() & std::ios::left) != 0; - const std::size_t w = os.width(0); - std::basic_streambuf* buf = os.rdbuf(); - - if (w != 0 && n < w) - pad_len = w - n; - - if (!left) - ok = sgi_string_fill(os, buf, pad_len); - - ok = ok && - buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n); - - if (left) - ok = ok && sgi_string_fill(os, buf, pad_len); - } - - if (!ok) - os.setstate(std::ios_base::failbit); - - return os; -} - -template -std::basic_istream& -operator>>(std::basic_istream& is, - basic_string& s) -{ - typename std::basic_istream::sentry sentry(is); - - if (sentry) { - std::basic_streambuf* buf = is.rdbuf(); - const std::ctype& ctype = std::use_facet >(is.getloc()); - - s.clear(); - std::size_t n = is.width(0); - if (n == 0) - n = static_cast(-1); - else - s.reserve(n); - - while (n-- > 0) { - typename Traits::int_type c1 = buf->sbumpc(); - - if (Traits::eq_int_type(c1, Traits::eof())) { - is.setstate(std::ios_base::eofbit); - break; - } - else { - CharT c = Traits::to_char_type(c1); - - if (ctype.is(std::ctype::space, c)) { - if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof())) - is.setstate(std::ios_base::failbit); - break; - } - else - s.push_back(c); - } - } - - // If we have read no characters, then set failbit. - if (s.size() == 0) - is.setstate(std::ios_base::failbit); - } - else - is.setstate(std::ios_base::failbit); - - return is; -} - -template -std::basic_istream& -getline(std::istream& is, - basic_string& s, - CharT delim) -{ - std::size_t nread = 0; - typename std::basic_istream::sentry sentry(is, true); - if (sentry) { - std::basic_streambuf* buf = is.rdbuf(); - s.clear(); - - int c1; - while (nread < s.max_size()) { - int c1 = buf->sbumpc(); - if (Traits::eq_int_type(c1, Traits::eof())) { - is.setstate(std::ios_base::eofbit); - break; - } - else { - ++nread; - CharT c = Traits::to_char_type(c1); - if (!Traits::eq(c, delim)) - s.push_back(c); - else - break; // Character is extracted but not appended. - } - } - } - if (nread == 0 || nread >= s.max_size()) - is.setstate(std::ios_base::failbit); - - return is; -} - -template -inline std::basic_istream& -getline(std::basic_istream& is, - basic_string& s) -{ - return getline(is, s, '\n'); -} - -template -inline std::size_t hash_value(std::basic_string, A> const& v) -{ - return hash_range(v.begin(), v.end()); -} - -typedef basic_string, std::allocator > string; - -}} //namespace boost { namespace shmem - -#include - -#endif // BOOST_SHMEM_STRING_HPP - - -// Local Variables: -// mode:C++ -// End: - diff --git a/include/boost/interprocess/containers/vector_old.hpp b/include/boost/interprocess/containers/vector_old.hpp deleted file mode 100644 index 87f91e0..0000000 --- a/include/boost/interprocess/containers/vector_old.hpp +++ /dev/null @@ -1,974 +0,0 @@ -/* - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1996 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess/ for documentation. -// -////////////////////////////////////////////////////////////////////////////// -// -// This file comes from SGI's stl_vector.h file. Modified by Ion Gaztañaga. -// Renaming, isolating and porting to generic algorithms. Pointer typedef -// set to allocator::pointer to allow placing it in shared memory. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_SHMEM_VECTOR_HPP -#define BOOST_SHMEM_VECTOR_HPP - -#if (defined _MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace boost { - -namespace interprocess { - -namespace detail { - -/*!This struct deallocates and allocated memory */ -template -struct vector_alloc_holder : public A -{ - typedef typename A::pointer pointer; - - //Constructor, does not throw - vector_alloc_holder(const A &a) - : A(a), m_start(0), m_finish(0), m_end(0) - {} - - //Destructor - ~vector_alloc_holder() - { this->priv_deallocate(); } - - pointer m_start; - pointer m_finish; - pointer m_end; - - private: - void priv_deallocate() - { - if(!m_start) return; - this->deallocate(m_start, m_end - m_start); - m_end = m_start; - } -}; - -} //namespace detail { - - -//vector class -template -class vector : private detail::vector_alloc_holder -{ - typedef vector self_t; - typedef detail::vector_alloc_holder base_t; - typedef detail::scoped_array_deallocator dealloc_t; - - public: - //STL container typedefs - typedef T value_type; - typedef A allocator_type; - typedef typename A::pointer pointer; - typedef typename A::const_pointer const_pointer; - typedef typename A::reference reference; - typedef typename A::const_reference const_reference; - typedef typename A::size_type size_type; - typedef typename A::difference_type difference_type; - //This shouldn't be needed but VC6.0 needs this - typedef typename A::pointer vec_ptr; - typedef typename A::const_pointer vec_cptr; - typedef typename A::reference vec_ref; - typedef typename A::const_reference vec_cref; - typedef typename A::difference_type vec_diff; - - private: - typedef range_from_ref_iterator range_from_ref_it; - - public: - //Vector const_iterator - class const_iterator - : public boost::iterator - { - private: - vec_ptr get_ptr() const { return m_ptr; } - - protected: - vec_ptr m_ptr; - explicit const_iterator(vec_ptr ptr) : m_ptr(ptr){} - - public: - friend class vector; - typedef vec_diff difference_type; - - //Constructors - const_iterator() : m_ptr(0){} - - //Pointer like operators - const_reference operator*() const - { return *m_ptr; } - - const_pointer operator->() const - { return m_ptr; } - - const_reference operator[](difference_type off) const - { return m_ptr[off]; } - - //Increment / Decrement - const_iterator& operator++() - { ++m_ptr; return *this; } - - const_iterator operator++(int) - { vec_ptr tmp = m_ptr; ++*this; return const_iterator(tmp); } - - const_iterator& operator--() - { --m_ptr; return *this; } - - const_iterator operator--(int) - { vec_ptr tmp = m_ptr; --*this; return const_iterator(tmp); } - - //Arithmetic - const_iterator& operator+=(difference_type off) - { m_ptr += off; return *this; } - - const_iterator operator+(difference_type off) const - { return const_iterator(m_ptr+off); } - - friend const_iterator operator+(difference_type off, const const_iterator& right) - { return const_iterator(off + right.m_ptr); } - - const_iterator& operator-=(difference_type off) - { m_ptr -= off; return *this; } - - const_iterator operator-(difference_type off) const - { return const_iterator(m_ptr-off); } - - difference_type operator-(const const_iterator& right) const - { return m_ptr - right.m_ptr; } - - //Comparison operators - bool operator== (const const_iterator& r) const - { return m_ptr == r.m_ptr; } - - bool operator!= (const const_iterator& r) const - { return m_ptr != r.m_ptr; } - - bool operator< (const const_iterator& r) const - { return m_ptr < r.m_ptr; } - - bool operator<= (const const_iterator& r) const - { return m_ptr <= r.m_ptr; } - - bool operator> (const const_iterator& r) const - { return m_ptr > r.m_ptr; } - - bool operator>= (const const_iterator& r) const - { return m_ptr >= r.m_ptr; } - }; - - //Vector iterator - class iterator : public const_iterator - { - protected: - explicit iterator(vec_ptr ptr) : const_iterator(ptr){} - - public: - friend class vector; - typedef vec_ptr pointer; - typedef vec_ref reference; - - //Constructors - iterator(){} - - //Pointer like operators - reference operator*() const - { return *this->m_ptr; } - - pointer operator->() const - { return this->m_ptr; } - - reference operator[](difference_type off) const - {return this->m_ptr[off];} - - //Increment / Decrement - iterator& operator++() - { ++this->m_ptr; return *this; } - - iterator operator++(int) - { pointer tmp = this->m_ptr; ++*this; return iterator(tmp); } - - iterator& operator--() - { --this->m_ptr; return *this; } - - iterator operator--(int) - { iterator tmp = *this; --*this; return iterator(tmp); } - - // Arithmetic - iterator& operator+=(difference_type off) - { this->m_ptr += off; return *this; } - - iterator operator+(difference_type off) const - { return iterator(this->m_ptr+off); } - - friend iterator operator+(difference_type off, const iterator& right) - { return iterator(off + right.m_ptr); } - - iterator& operator-=(difference_type off) - { this->m_ptr -= off; return *this; } - - iterator operator-(difference_type off) const - { return iterator(this->m_ptr-off); } - - difference_type operator-(const const_iterator& right) const - { return *((const_iterator*)this) - right; } - }; - - //Reverse iterators - typedef typename boost::reverse_iterator - reverse_iterator; - typedef typename boost::reverse_iterator - const_reverse_iterator; - - public: - - //Constructor - explicit vector(const A& a = A()) - : base_t(a) - {} - - //Construct and fill with n equal objects - vector(size_type n, const T& value = T(), - const allocator_type& a = allocator_type()) - : base_t(a) - { - if(n){ - //If there is an exception, the base class will - //deallocate the memory - this->m_start = this->allocate(n, 0); - this->m_end = this->m_start + n; - this->m_finish = this->m_start; - this->priv_uninitialized_fill_n(this->m_start, n, value, *this); - this->m_finish = this->m_end; - } - } - - //Copy constructor - vector(const vector& x) - : base_t(x.get_allocator()) - { - size_type n = x.size(); - if(n){ - this->m_start = this->allocate(x.size(), 0); - this->m_end = this->m_start + x.size(); - this->m_finish = this->m_start; - this->priv_uninitialized_copy(x.m_start, x.m_finish, this->m_start, *this); - this->m_finish = this->m_end; - } - } - - //Construct from iterator range - template - vector(InIt first, InIt last, - const allocator_type& a = allocator_type()) - : base_t(a) - { - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - this->priv_initialize_aux(first, last, Result()); - } - - //Destructor - ~vector() - { this->priv_destroy_all(); } - - //Functions: begin, rbegin, end, rend - iterator begin() - { return iterator(this->m_start); } - - iterator end() - { return iterator(this->m_finish); } - - const_iterator begin() const - { return const_iterator(this->m_start); } - - const_iterator end() const - { return const_iterator(this->m_finish); } - - reverse_iterator rbegin() - { return reverse_iterator(this->end()); } - - reverse_iterator rend() - { return reverse_iterator(this->begin()); } - - const_reverse_iterator rbegin()const - { return const_reverse_iterator(this->end());} - - const_reverse_iterator rend() const - { return const_reverse_iterator(this->begin()); } - - //Functions: front, back - reference front() - { return *this->m_start; } - - const_reference front() const - { return *this->m_start; } - - reference back() - { return *(this->m_finish - 1); } - - const_reference back() const - { return *(this->m_finish - 1); } - - //Functions: size, max_size, capacity, empty - size_type size() const - { return size_type(this->m_finish - this->m_start); } - - size_type max_size() const - { return allocator_type::max_size(); } - - size_type capacity() const - { return size_type(this->m_end - this->m_start); } - - bool empty() const - { return this->m_start == this->m_finish; } - - //Functions: operator [], at - reference operator[](size_type n) - { return this->m_start[n]; } - - const_reference operator[](size_type n) const - { return this->m_start[n]; } - - reference at(size_type n) - { this->priv_check_range(n); return this->m_start[n]; } - - const_reference at(size_type n) const - { this->priv_check_range(n); return this->m_start[n]; } - - //Functions: get_allocator, reserve - allocator_type get_allocator() const - { return allocator_type(*this); } - - void reserve(size_type n) - { - if (capacity() < n){ - //Allocate new size, copy data and free old buffer - const size_type old_size = size(); - pointer tmp = this->priv_allocate_and_copy(n, this->m_start, this->m_finish); - this->priv_destroy_and_deallocate(); - this->m_start = tmp; - this->m_finish = tmp + old_size; - this->m_end = this->m_start + n; - } - } - - //Assignment - vector& operator=(const vector& x) - { - if (&x != this){ - const size_type xlen = x.size(); - - if (xlen > this->capacity()){ - //There is no memory to hold values from x. Allocate a new buffer, - //copy data from x, and destroy and deallocate previous values - pointer tmp = this->priv_allocate_and_copy(xlen, x.m_start, x.m_finish); - this->priv_destroy_and_deallocate(); - this->m_start = tmp; - this->m_end = this->m_start + xlen; - } - else if (size() >= xlen){ - //There is enough memory but current buffer has more objects than x. - //Copy all objects from x and destroy the remaining objects - pointer i = std::copy(x.m_start, x.m_finish, this->m_start); - this->priv_destroy_range(i, this->m_finish); - } - else { - //There is enough memory but current buffer has less objects than x. - //Copy the first this->size() objects from x and initialize the - //rest of the buffer with remaining x objects - std::copy(x.m_start, x.m_start + size(), this->m_start); - this->priv_uninitialized_copy(x.m_start + size(), x.m_finish, this->m_finish, *this); - } - this->m_finish = this->m_start + xlen; - } - return *this; - } - - void assign(size_type n, const value_type& val = T()) - { - this->assign(range_from_ref_it(val, n) - ,range_from_ref_it()); -/* - if (n > this->capacity()){ - //There is not enough memory, create a temporal vector and swap - vector tmp(n, val, static_cast(*this)); - tmp.swap(*this); - } - else if (n > size()){ - //There is enough memory, but we have less objects. Assign current - //objects and initialize the rest. - std::fill(this->m_start, this->m_finish, val); - size_t rest = n - size(); - this->priv_uninitialized_fill_n(this->m_finish, rest, val, *this); - this->m_finish += rest; - } - else{ - //There is enough memory, but we have more objects. Assign the first - //n objects and destroy the rest - std::fill_n(this->m_start, n, val); - this->erase(iterator(this->m_start + n), iterator(this->m_finish)); - }*/ - } - - template - void assign(InIt first, InIt last) - { - //Dispatch depending on integer/iterator - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - this->priv_assign_dispatch(first, last, Result()); - } - - void push_back(const T& x = T()) - { - if (this->m_finish != this->m_end){ - //There is more memory, just construct a new object at the end - this->construct(this->m_finish, x); - ++this->m_finish; - } - else{ - //No enough memory, insert a new object at the end - this->insert(this->end(), static_cast(1), x); - } - } - - void swap(vector& x) - { - allocator_type &this_al = *this, &other_al = x; - //Just swap pointers - detail::do_swap(this->m_start, x.m_start); - detail::do_swap(this->m_finish, x.m_finish); - detail::do_swap(this->m_end, x.m_end); - - if (this_al != other_al){ - detail::do_swap(this_al, other_al); - } - } - - iterator insert(iterator position, const T& x = T()) - { - //Just call more general insert(pos, size, value) and return iterator - size_type n = position - begin(); - this->insert(position, (size_type)1, x); - return iterator(this->m_start + n); - } - - template - void insert(iterator pos, InIt first, InIt last) - { - //Dispatch depending on integer/iterator - const bool aux_boolean = boost::is_integral::value; - typedef boost::mpl::bool_ Result; - this->priv_insert_dispatch(pos, first, last, Result()); - } - - void insert (iterator position, size_type n, const T& x) - { - this->insert(position - ,range_from_ref_it(x, n) - ,range_from_ref_it()); -/* - if (n != 0){ - if (size_type(this->m_end - this->m_finish) >= n){ - //There is enough memory - const size_type elems_after = this->end() - position; - pointer old_finish = this->m_finish; - - if (elems_after > n){ - //New elements can be just copied. - //Move to uninitialized memory last objects - this->priv_uninitialized_copy(this->m_finish - n, this->m_finish, - this->m_finish, *this); - this->m_finish += n; - //Copy previous to last objects to the initialized end - std::copy_backward(position.get_ptr(), old_finish - n, - old_finish); - //Insert new objects in the position - std::fill(position.get_ptr(), position.get_ptr() + n, x); - } - else { - //The new elements don't fit in the [position, end()) range. Copy - //to the beginning of the unallocated zone the last new elements. - this->priv_uninitialized_fill_n(this->m_finish, n - elems_after, x, *this); - this->m_finish += n - elems_after; - //Copy old [position, end()) elements to the uninitialized memory - this->priv_uninitialized_copy(position.get_ptr(), old_finish, - this->m_finish, *this); - this->m_finish += elems_after; - //Insert first new elements in position - std::fill(position.get_ptr(), old_finish, x); - } - } - else { - //There is not enough memory, allocate a new buffer - size_type old_size = size(); - size_type len = old_size + ((old_size/2 > n) ? old_size/2 : n); - pointer new_start = this->allocate(len, 0); - - scoped_ptr scoped_alloc(new_start, dealloc_t(*this, len)); - pointer new_finish = new_start; - //Initialize [begin(), position) old buffer to the start of the new buffer - new_finish = this->priv_uninitialized_copy(this->m_start, position.get_ptr(), - new_start, *this); - //Initialize new n objects, starting from previous point - this->priv_uninitialized_fill_n(new_finish, n, x, *this); - new_finish = new_finish + n; - //Initialize from the rest of the old buffer, starting from previous point - new_finish = this->priv_uninitialized_copy(position.get_ptr(), this->m_finish, - new_finish, *this); - //New data is in the new buffer, release scoped deallocation - scoped_alloc.release(); - //Destroy and deallocate old elements - this->priv_destroy_and_deallocate(); - this->m_start = new_start; - this->m_finish = new_finish; - this->m_end = new_start + len; - } - }*/ - } - - void pop_back() - { - //Destroy last element - --this->m_finish; - this->destroy(this->m_finish); - } - - // Return type of erase(const_iterator): - // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1753.html#130 - - iterator erase(const_iterator position) - { - if (position + 1 != end()){ - //If not the last element, copy left [position, end()) elements - std::copy((position + 1).get_ptr(), this->m_finish, position.get_ptr()); - } - --this->m_finish; - //Destroy last element - this->destroy(this->m_finish); - return iterator(position.get_ptr()); - } - - iterator erase(const_iterator first, const_iterator last) - { - //Overwrite [last, end()) elements to first - pointer i = std::copy(last.get_ptr(), this->m_finish, first.get_ptr()); - //Destroy remaining objects - this->priv_destroy_range(i, this->m_finish); - this->m_finish = this->m_finish - (last - first); - return iterator(first.get_ptr()); - } - - void resize(size_type new_size, const T& x = T()) - { - if (new_size < size()) - //Destroy last elements - this->erase(iterator(this->m_start + new_size), iterator(this->m_finish)); - else - //Insert new elements at the end - this->insert(iterator(this->m_finish), new_size - size(), x); - } - - void clear() - { this->priv_destroy_all(); } - - private: - - void priv_destroy_all() - { - if(!this->m_start) - return; - - pointer start = this->m_start; - - for(;start != this->m_finish; ++start) - this->destroy(start); - - this->m_finish = this->m_start; - } - - template - void priv_range_initialize(InIt first, - InIt last, std::input_iterator_tag) - { - //Just insert all elements at the end - std::copy(first, last, std::back_inserter(*this)); - } - - template - void priv_range_initialize(FwdIt first, - FwdIt last, std::forward_iterator_tag) - { - //Calculate distance, allocate and copy - size_type n = 0; - n = std::distance(first, last); - this->m_start = this->allocate(n, 0); - - scoped_ptr scoped_alloc(this->m_start, dealloc_t(*this, n)); - this->m_end = this->m_start + n; - this->m_finish = this->priv_uninitialized_copy(first, last, this->m_start, *this); - scoped_alloc.release(); - } - - template - void priv_range_insert(iterator position, FwdIt first, - FwdIt last, std::forward_iterator_tag) - { - if (first != last){ - size_type n = 0; - n = std::distance(first, last); - if (size_type(this->m_end - this->m_finish) >= n){ - //There is enough memory - const size_type elems_after = this->m_finish - position.get_ptr(); - pointer old_finish = this->m_finish; - if (elems_after > n){ - //New elements can be just copied. - //Move to unitialized memory last objects - this->priv_uninitialized_copy(this->m_finish - n, this->m_finish, - this->m_finish, *this); - this->m_finish += n; - //Copy previous to last objects to the initialized end - std::copy_backward(position.get_ptr(), old_finish - n, old_finish); - //Insert new objects in the position - std::copy(first, last, position.get_ptr()); - } - else { - //The new elements don't fit in the [position, end()) range. Copy - //to the beginning of the unalocated zone the last new elements. - FwdIt mid = first; - std::advance(mid, elems_after); - this->priv_uninitialized_copy(mid, last, this->m_finish, *this); - this->m_finish += n - elems_after; - //Copy old [position, end()) elements to the unitialized memory - this->priv_uninitialized_copy(position.get_ptr(), old_finish, - this->m_finish, *this); - this->m_finish += elems_after; - //Copy first new elements in position - std::copy(first, mid, position.get_ptr()); - } - } - else { - //There is not enough memory, allocate a new buffer - const size_type old_size = size(); - const size_type len = old_size + ((old_size/2 > n) ? old_size/2 : n); - pointer new_start = this->allocate(len, 0); - scoped_ptr scoped_alloc(new_start, dealloc_t(*this, len)); - pointer new_finish = new_start; - BOOST_TRY{ - //Initialize with [begin(), position) old buffer - //the start of the new buffer - new_finish = this->priv_uninitialized_copy - (this->m_start, position.get_ptr(), new_start, *this); - //Initialize new objects, starting from previous point - new_finish = this->priv_uninitialized_copy - (first, last, new_finish, *this); - //Initialize from the rest of the old buffer, - //starting from previous point - new_finish = this->priv_uninitialized_copy - (position.get_ptr(), this->m_finish, new_finish, *this); - } - BOOST_CATCH(...){ - this->priv_destroy_range(new_start, new_finish); - this->deallocate(new_start, len); - BOOST_RETHROW - } - BOOST_CATCH_END - scoped_alloc.release(); - //Destroy and deallocate old elements - this->priv_destroy_and_deallocate(); - this->m_start = new_start; - this->m_finish = new_finish; - this->m_end = new_start + len; - } - } - } - - template - void priv_range_insert(iterator pos, - InIt first, InIt last, - std::input_iterator_tag) - { - //Insert range before the pos position - std::copy(std::inserter(*this, pos), first, last); - } - - template - void priv_assign_aux(InIt first, InIt last, - std::input_iterator_tag) - { - //Overwrite all elements we can from [first, last) - iterator cur = begin(); - for ( ; first != last && cur != end(); ++cur, ++first){ - *cur = *first; - } - - if (first == last){ - //There are no more elements in the secuence, erase remaining - this->erase(cur, end()); - } - else{ - //There are more elements in the range, insert the remaining ones - this->insert(end(), first, last); - } - } - - template - void priv_assign_aux(FwdIt first, FwdIt last, - std::forward_iterator_tag) - { - size_type len = 0; - len = std::distance(first, last); - - if (len > capacity()){ - //There is no enough memory, allocate and copy new buffer - pointer tmp = this->priv_allocate_and_copy(len, first, last); - //Destroy and deallocate old buffer - this->priv_destroy_and_deallocate(); - this->m_start = tmp; - this->m_end = this->m_finish = this->m_start + len; - } - else if (size() >= len){ - //There is memory, but there are more old elements than new ones - //Overwrite old elements with new ones - pointer new_finish = std::copy(first, last, this->m_start); - //Destroy remaining old elements - this->priv_destroy_range(new_finish, this->m_finish); - this->m_finish = new_finish; - } - else { - //There is memory, but there are less old elements than new ones - //Overwrite old elements with new ones - FwdIt mid = first; - std::advance(mid, size()); - std::copy(first, mid, this->m_start); - //Initialize the remaining new elements in the unitialized memory - this->m_finish = this->priv_uninitialized_copy(mid, last, this->m_finish, *this); - } - } - - template - void priv_assign_dispatch(Integer n, Integer val, boost::mpl::true_) - { this->assign((size_type) n, (T) val); } - - template - void priv_assign_dispatch(InIt first, InIt last, - boost::mpl::false_) - { - //Dispatch depending on integer/iterator - typedef typename - std::iterator_traits::iterator_category ItCat; - this->priv_assign_aux(first, last, ItCat()); - } - - template - void priv_insert_dispatch( iterator pos, Integer n, - Integer val, boost::mpl::true_) - { this->insert(pos, (size_type)n, (T)val); } - - template - void priv_insert_dispatch(iterator pos, InIt first, - InIt last, boost::mpl::false_) - { - //Dispatch depending on integer/iterator - typedef typename - std::iterator_traits::iterator_category ItCat; - this->priv_range_insert(pos, first, last, ItCat()); - } - - void priv_destroy_range(pointer p, pointer p2) - { for(;p != p2; ++p) this->destroy(p); } - - template - void priv_initialize_aux(Integer n, Integer value, boost::mpl::true_) - { - //Allocate and initialize integer vector buffer - this->m_start = this->allocate(n, 0); - scoped_ptr scoped_alloc(this->m_start, dealloc_t(*this, n)); - this->m_end = this->m_start + n; - this->m_finish = this->m_start; - this->priv_uninitialized_fill_n(this->m_start, n, value, *this); - this->m_finish = this->m_start + n; - scoped_alloc.release(); - } - - template - void priv_initialize_aux(InIt first, InIt last, - boost::mpl::false_) - { - //Dispatch depending on integer/iterator - typedef typename - std::iterator_traits::iterator_category ItCat; - 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->priv_destroy_range(this->m_start, this->m_finish); - this->deallocate(this->m_start, this->m_end - this->m_start); - } - } - - template - pointer priv_allocate_and_copy(size_type n, FwdIt first, - FwdIt last) - { - //Allocate n element buffer and initialize from range - pointer result = this->allocate(n, 0); - scoped_ptr scoped_alloc(result, dealloc_t(*this, n)); - this->priv_uninitialized_copy(first, last, result, *this); - scoped_alloc.release(); - return result; - } - - void priv_check_range(size_type n) const - { - //If n is out of range, throw an out_of_range exception - if (n >= size()) - throw std::out_of_range("vector::at"); - } - - template inline - FwdIt priv_uninitialized_copy(InIt first, InIt last, - FwdIt dest, alloc& al) - { - //Save initial destination position - FwdIt dest_init = dest; - - BOOST_TRY{ - //Try to build objects - for (; first != last; ++dest, ++first){ - 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 inline - void priv_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 -inline bool -operator==(const vector& x, const vector& y) -{ - //Check first size and each element if needed - return x.size() == y.size() && - std::equal(x.begin(), x.end(), y.begin()); -} - -template -inline bool -operator!=(const vector& x, const vector& y) -{ - //Check first size and each element if needed - return x.size() != y.size() || - !std::equal(x.begin(), x.end(), y.begin()); -} - -template -inline bool -operator<(const vector& x, const vector& y) -{ - return std::lexicographical_compare(x.begin(), x.end(), - y.begin(), y.end()); -} - -template -inline void swap(vector& x, vector& y) -{ - x.swap(y); -} - - -} //namespace interprocess { - -} //namespace boost { - -#include - -#endif // #ifndef BOOST_SHMEM_VECTOR_HPP - diff --git a/include/boost/interprocess/detail/global_lock.hpp b/include/boost/interprocess/detail/global_lock.hpp deleted file mode 100644 index 6b1bc54..0000000 --- a/include/boost/interprocess/detail/global_lock.hpp +++ /dev/null @@ -1,136 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_INTERPROCESS_DETAIL_GLOBAL_LOCK_HPP -#define BOOST_INTERPROCESS_DETAIL_GLOBAL_LOCK_HPP - -#include -#include - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -# include -#else - -# ifdef BOOST_HAS_UNISTD_H -# include //O_CREAT, O_*... -# include //ftruncate, close -# include //sem_t* family, SEM_VALUE_MAX -# include //mode_t, S_IRWXG, S_IRWXO, S_IRWXU, -# else -# error Unknown platform -# endif - -#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -namespace boost { - -namespace interprocess { - -namespace detail { - -class global_lock -{ - public: - global_lock(); - bool acquire(); - ~global_lock(); - void release(); - private: - #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - void *m_mut; - #else - sem_t *m_sem; - #endif - bool m_acquired; -}; - -inline global_lock::~global_lock() -{ this->release(); } - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline global_lock::global_lock() - : m_mut(0), m_acquired(false){} - -inline bool global_lock::acquire() -{ - m_mut = winapi::create_mutex("/boost_shmem_shm_global_mutex"); - if(m_mut == 0) - return false; - unsigned long ret = winapi::wait_for_single_object(m_mut, winapi::infinite_time); - //Other thread has abandoned this without closing the handle - if(ret == winapi::wait_abandoned){ - ret = winapi::wait_for_single_object(m_mut, winapi::infinite_time); - } - m_acquired = ret == winapi::wait_object_0; - return m_acquired; -} - -inline void global_lock::release() -{ - if(m_acquired){ - winapi::release_mutex(m_mut); - m_acquired = false; - } - - if(m_mut){ - winapi::close_handle(m_mut); - m_mut = 0; - } -} - -#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline global_lock::global_lock() - : m_sem((sem_t*)-1), m_acquired(false){} - -inline bool global_lock::acquire() -{ - const unsigned int BufSize = 64; - char globalMutexName[BufSize]; - const char *prefix = "/boost_shmem_shm_global_mutex-"; - if((strlen(getenv("LOGNAME") + strlen(prefix) + 1)) > BufSize){ - return false; - } - strcpy(globalMutexName, prefix); - strcat(globalMutexName, getenv("LOGNAME")); - mode_t mode = S_IRWXG | S_IRWXO | S_IRWXU; - m_sem = sem_open(globalMutexName, O_CREAT, mode, 1); - - if(m_sem == SEM_FAILED) - return false; - m_acquired = sem_wait(m_sem) == 0; - return m_acquired; -} - -inline void global_lock::release() -{ - if(m_acquired){ - sem_post(m_sem); - m_acquired = false; - } - - if(m_sem != ((sem_t*)-1)){ - sem_close(m_sem); - m_sem = ((sem_t*)-1); - } -} - -#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -} //namespace detail { - -} //namespace interprocess { - -} //namespace boost { - -#include - -#endif //BOOST_INTERPROCESS_DETAIL_GLOBAL_LOCK_HPP diff --git a/include/boost/interprocess/ipc/named_fifo.hpp b/include/boost/interprocess/ipc/named_fifo.hpp deleted file mode 100644 index 3e8230d..0000000 --- a/include/boost/interprocess/ipc/named_fifo.hpp +++ /dev/null @@ -1,21 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_NAMED_FIFO_HPP -#define BOOST_NAMED_FIFO_HPP - -#include -#include - -//TO-DO - -#include - -#endif //#ifndef BOOST_NAMED_FIFO_HPP \ No newline at end of file diff --git a/include/boost/interprocess/mapped_file.hpp b/include/boost/interprocess/mapped_file.hpp deleted file mode 100644 index 2a87060..0000000 --- a/include/boost/interprocess/mapped_file.hpp +++ /dev/null @@ -1,541 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_INTERPROCESS_MAPPED_FILE_HPP -#define BOOST_INTERPROCESS_MAPPED_FILE_HPP - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include //std::auto_ptr -#include //std::string -#include //std::remove -#include - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -# include -#else -# ifdef BOOST_HAS_UNISTD_H -# include -# include //mmap, off64_t -# include -# include -# else -# error Unknown platform -# endif - -#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -/*!\file - Describes file_mapping and mapped region classes -*/ - -namespace boost { - -namespace interprocess { - -/*!A class that wraps a file-mapping that can be used to - create mapped regions from the mapped files*/ -class file_mapping : public memory_mappable -{ - public: - typedef memory_mappable::accessmode_t accessmode_t; - typedef memory_mappable::mapping_handle_t mapping_handle_t; - - /*!Opens a file mapping of file "filename", starting in offset - "file_offset", and the mapping's size will be "size". The mapping - can be opened for read-only "read_only" or read-write "read_write" - modes. Throws interprocess_exception on error.*/ - file_mapping(const char *filename, accessmode_t mode); - - /*!Destroys the file mapping. All mapped regions created from this are still - valid. Does not throw*/ - ~file_mapping(); - - /*!Returns the name of the file.*/ - const char *get_name() const; - - - private: - /*!Closes a previously opened file mapping. Never throws.*/ - void priv_close(); - - std::string m_filename; -}; - -inline file_mapping::~file_mapping() -{ this->priv_close(); } - -inline const char *file_mapping::get_name() const -{ return m_filename.c_str(); } - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline file_mapping::file_mapping - (const char *filename, memory_mappable::accessmode_t mode) - : memory_mappable() - , m_filename(filename) -{ - unsigned long file_access = 0; - unsigned long file_creation_flags = 0; - - //Set accesses - if (mode == read_write){ - file_access |= winapi::generic_read | winapi::generic_write; - } - else if (mode == read_only){ - file_access |= winapi::generic_read; - } - - file_creation_flags = winapi::open_existing; - - //Open file using windows API since we need the handle - memory_mappable::mapping_handle_t hnd = - winapi::create_file(filename, file_access, file_creation_flags); - - //Check for error - if(hnd == winapi::invalid_handle_value){ - error_info err = winapi::get_last_error(); - this->priv_close(); - throw interprocess_exception(err); - } - - memory_mappable::assign_data(hnd, mode); -} - -inline void file_mapping::priv_close() -{ - if(memory_mappable::get_mapping_handle() != winapi::invalid_handle_value){ - winapi::close_handle(memory_mappable::get_mapping_handle()); - memory_mappable::assign_data - (winapi::invalid_handle_value, memory_mappable::get_mode()); - } -} - -#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline file_mapping::file_mapping - (const char *filename, memory_mappable::accessmode_t mode) - : m_filename(filename) -{ - //Create new mapping - int oflag = 0; - - if(mode == read_only){ - oflag |= O_RDONLY; - } - else if(mode == read_write){ - oflag |= O_RDWR; - } - else{ - error_info err(mode_error); - throw interprocess_exception(err); - } - - //Open file and get handle - int hnd = ::open(filename, // filename - oflag, // read/write access - S_IRWXO | S_IRWXG | S_IRWXU); // permissions - if(hnd == -1){ - error_info err = system_error_code(); - this->priv_close(); - throw interprocess_exception(err); - } - memory_mappable::assign_data(hnd, mode); -} - -inline void file_mapping::priv_close() -{ - if(memory_mappable::get_mapping_handle() != -1){ - ::close(memory_mappable::get_mapping_handle()); - memory_mappable::assign_data(-1, memory_mappable::get_mode()); - } -} - -#endif //##if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -/*!A class that wraps basic file-mapping management*/ -class mapped_file -{ - //Non-copyable - mapped_file(); - mapped_file(const mapped_file &); - mapped_file &operator=(const mapped_file &); - - public: - /*!Creates a memory mapped file with name "name", and size "size". - If the file was previously created it throws an error. - The mapping can be opened in read-only "read_only" or read-write "read_write" modes. - The user can also specify the mapping address in "addr". If "addr" is 0, - the operating system will choose the mapping address. - - This function can throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc)*/ - mapped_file(detail::create_only_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode = memory_mappable::read_write, - const void *addr = 0); - - /*!Creates a memory mapped file with name "name", and size "size" if - the file was not previously created. If it was previously - created it tries to open it. - The file can be opened in read-only "read_only" or read-write "read_write" modes. - The user can also specify the mapping address in "addr". If "addr" is 0, - the operating system will choose the mapping address. - - This function can throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc)*/ - mapped_file(detail::open_only_t, - const char *name, - memory_mappable::accessmode_t mode = memory_mappable::read_write, - const void *addr = 0); - - /*!Creates a shared memory segment with name "name", and size "size" if - the shared memory was not previously created. If it was previously - created it tries to open it. - The file can be opened in read-only "read_only" or read-write "read_write" modes. - The user can specify the mapping address in "addr". - If "addr" is 0, the operating system will choose the mapping address. - - This function can throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc)*/ - mapped_file(detail::open_or_create_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode = memory_mappable::read_write, - const void *addr = 0); - - /*!Creates a shared memory segment with name "name", with size "size". - The file can be opened in read-only "read_only" or read-write "read_write" modes. - The user must specify the mapping address in "addr". - If "addr" is 0, the operating system will choose the mapping address. - It also executes a copy of the functor "construct_func" atomically if - the segment is created. The functor must have the following signature: - - bool operator()(const mapped_file_info_t * info, bool created) - - "info" is an initialized segment info structure, and "created" - must be "true". If the functor returns "false", or throws an error - is supposed and the shared memory won't be created. - The user must specify a destroy_func, that will be copied in this - constructor and executed in the destructor, before unmapping the - shared memory segment. - The functor must have the following signature: - - void operator()(const mapped_file_info_t * info, bool last) const - - "info" is an initialized segment info structure, and "last" - indicates if this unmapping is the last unmapping so that - there will be no no other processes attached to the segment. - The functor must NOT throw. - - This function can throw if copying any functor throws, - the construct_func execution throws, and it - will throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc) on any error*/ - template - mapped_file(detail::create_only_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func); - - /*!Creates a shared memory segment with name "name", and size "size" if - the shared memory was not previously created. If it was previously - created tries to open it. - The file can be opened in read-only "read_only" or read-write "read_write" modes. - The user must specify the mapping address in "addr". - If "addr" is 0, the operating system will choose the mapping address. - It also executes a copy of the functor "construct_func" atomically - if the segment is opened. The functor must have the following signature: - - bool operator()(const mapped_file_info_t * info, bool created) - - "info" is an initialized segment info structure, and "created" - must be "false". If the functor returns "false", or throws an error - is supposed and the shared memory won't be opened. - The user must specify a destroy_func, that will be copied in this - constructor and executed in the destructor, before unmapping the - shared memory segment. - The functor must have the following signature: - - void operator()(const mapped_file_info_t * info, bool last) const - - "info" is an initialized segment info structure, and "last" - indicates if this unmapping is the last unmapping so that - there will be no no other processes attached to the segment. - The functor must NOT throw. - - This function can throw if copying any functor throws, - the construct_func execution throws, and it - will throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc) on any error*/ - template - mapped_file(detail::open_only_t, - const char *name, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func); - - /*!Creates a shared memory segment with name "name", and size "size" if - the shared memory was not previously created. If it was previously - created it tries to open it. - The file can be opened in read-only "read_only" or read-write "read_write" modes. - The user must specify the mapping address in "addr". - If "addr" is 0, the operating system will choose the mapping address. - It also executes the functor "construct_func" atomically if the segment is - created or opened. The functor must have the following signature: - - bool operator()(const mapped_file_info_t * info, bool created) - - "info" is an initialized segment info structure, and "created" - will be "true" if the shared memory was created. If the functor - returns "false", or throws an error is supposed and the - shared memory won't be opened. - The user must specify a destroy_func, that will be copied in this - constructor and executed in the destructor, before unmapping the - shared memory segment. - The functor must have the following signature: - - void operator()(const mapped_file_info_t * info, bool last) const - - "info" is an initialized segment info structure, and "last" - indicates if this unmapping is the last unmapping so that - there will be no no other processes attached to the segment. - The functor must NOT throw. - - This function can throw if copying any functor throws, - the construct_func execution throws, and it - will throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc) on any error*/ - template - mapped_file(detail::open_or_create_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func); - - /*!Destructor. Unmaps the file from process' address space. - It also executes the destruction functor atomically if - the user has registered that the destruction functor - in the constructor of this class. - Never throws.*/ - ~mapped_file(); - - /*!Returns the size of the file mapping. Never throws.*/ - std::size_t get_size() const; - - /*!Returns the base address of the file mapping. Never throws.*/ - void* get_address() const; - - /*!Flushes to the disk the whole file. - Never throws*/ - bool flush(); - - /*!Returns the name of the shared memory segment used in the - constructor. Never throws.*/ - const char *get_name() const; - - private: - enum type_t { DoCreate, DoOpen, DoCreateOrOpen }; - - template - bool priv_open_or_create(type_t type, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr, - ConstructFunc construct_func); - - //Members - mapped_region m_mapped_region; - std::string m_name; -}; - -inline -mapped_file::mapped_file - (detail::create_only_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr) -{ - this->priv_open_or_create(DoCreate, name, size, mode, addr, null_mapped_region_function()); -} - -inline -mapped_file::mapped_file - (detail::open_only_t, - const char *name, - memory_mappable::accessmode_t mode, - const void *addr) -{ - this->priv_open_or_create(DoOpen, name, 0, mode, addr, null_mapped_region_function()); -} - -inline -mapped_file::mapped_file - (detail::open_or_create_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr) -{ - this->priv_open_or_create(DoCreateOrOpen, name, size, mode, addr, null_mapped_region_function()); -} - -template inline -mapped_file::mapped_file(detail::create_only_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func) -{ - this->priv_open_or_create(DoCreate, name, size, mode, addr, construct_func); -} - -template inline -mapped_file::mapped_file(detail::open_only_t, - const char *name, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func) -{ - this->priv_open_or_create(DoOpen, name, 0, mode, addr, construct_func); -} - - -template inline -mapped_file::mapped_file(detail::open_or_create_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func) -{ - this->priv_open_or_create(DoCreateOrOpen, name, size, mode, addr, construct_func); -} - - -inline -mapped_file::~mapped_file() -{} - -std::size_t mapped_file::get_size() const -{ return m_mapped_region.get_size(); } - -void* mapped_file::get_address() const -{ return m_mapped_region.get_address(); } - -bool mapped_file::flush() -{ return m_mapped_region.flush(); } - -inline const char *mapped_file::get_name() const -{ return m_name.c_str(); } - -template inline -bool mapped_file::priv_open_or_create - (mapped_file::type_t type, const char *name, - std::size_t size, memory_mappable::accessmode_t mode, - const void *addr, ConstructFunc construct_func) -{ - error_info err; - bool created = true; - - m_name = name; - - //This global interprocess_mutex guarantees synchronized creation/open logic - detail::global_lock mut; - if(!mut.acquire()){ - #ifdef BOOST_NO_EXCEPTIONS - return false; - #else - throw interprocess_exception(err); - #endif - } - - if(type == DoOpen){ - //Open existing shared memory - created = false; - } - else if(type == DoCreateOrOpen || type == DoCreate){ - detail::OS_file_handle_t hnd = detail::create_new_file(name); - if(hnd != detail::invalid_file()){ - if(!detail::truncate_file(hnd, size)){ - err = system_error_code(); - detail::close_file(hnd); - std::remove(name); - #ifdef BOOST_NO_EXCEPTIONS - return false; - #else - throw interprocess_exception(err); - #endif - } - //Free resources - if(!detail::close_file(hnd)){ - err = system_error_code(); - #ifdef BOOST_NO_EXCEPTIONS - return false; - #else - throw interprocess_exception(err); - #endif - } - } - else if(type == DoCreate){ - err = system_error_code(); - #ifdef BOOST_NO_EXCEPTIONS - return false; - #else - throw interprocess_exception(err); - #endif - } - } - else{ - throw interprocess_exception(err); - } - - //Open file mapping - file_mapping mapping(name, mode); - mapped_region mapped(mapping, (mapped_region::accessmode_t)mode, 0, size, addr); - - //Now swap mapped region - m_mapped_region.swap(mapped); - - //Execute atomic functor - construct_func(m_mapped_region, created); - - return true; -} - -} //namespace interprocess { - -} //namespace boost { - -#include - -#endif //BOOST_INTERPROCESS_MAPPED_FILE_HPP - diff --git a/include/boost/interprocess/memory_mappable.hpp b/include/boost/interprocess/memory_mappable.hpp deleted file mode 100644 index e123337..0000000 --- a/include/boost/interprocess/memory_mappable.hpp +++ /dev/null @@ -1,505 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_INTERPROCESS_memory_mappable_HPP -#define BOOST_INTERPROCESS_memory_mappable_HPP - -#include -#include - -#include -#include -#include -#include - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -# include -#else -# ifdef BOOST_HAS_UNISTD_H -# include -# include //mmap, off64_t -# include -# include -# else -# error Unknown platform -# endif - -#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -/*!\file - Describes memory_mappable and mapped region classes -*/ - -namespace boost { - -namespace interprocess { - -/*!A base class for all objects that can be memory mapped. The derived - classes must initialize this base class with a mapping handle and the - mode of the mapping handle.*/ -class memory_mappable -{ - //Non-copyable - memory_mappable(const memory_mappable &); - memory_mappable &operator=(const memory_mappable &); - - public: - #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - typedef void * mapping_handle_t; - typedef long long mapping_offset_t; - enum { invalid_handle = 0 }; - #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - typedef int mapping_handle_t; - typedef off64_t mapping_offset_t; - enum { invalid_handle = -1 }; - #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - - typedef enum { read_only = 0x01 - , read_write = 0x02 - , invalid_mode = 0xff - } accessmode_t; - - /*!Constructor. Initializes internal mapping handle to an invalid value. - Does not throw.*/ - memory_mappable() - : m_handle(mapping_handle_t(invalid_handle)) - {} - - /*!Stores the mapping handle and the mode of the handle. This method must be called - by the derived class. The assigned handle will be used to create mapped regions. - Does not throw.*/ - void assign_data(mapping_handle_t handle, accessmode_t mode) - { m_handle = handle; m_mode = mode; } - - /*!Stores the mapping handle and the mode of the handle. This method must be called - by the derived class and the assigned handle will be used to create mapped regions. - memory_mappable does not duplicate the handle using operating system functions. Just - stores the handle internally. Does not throw.*/ - mapping_handle_t get_mapping_handle() const - { return m_handle; } - - /*!Returns the registered access mode. Does not throw.*/ - accessmode_t get_mode() const - { return m_mode; } - - /*!Virtual pure destructor. memory_mappable does not destroy the handle. This must - be done by the derived class. Does not throw.*/ - virtual ~memory_mappable() = 0; - - private: - mapping_handle_t m_handle; - accessmode_t m_mode; -}; - -inline memory_mappable::~memory_mappable() -{} - -/*!The mapped_region class represents a portion or region created from a - memory_mappable object.*/ -class mapped_region -{ - //Non-copyable - mapped_region(const mapped_region &); - mapped_region &operator=(const mapped_region &); - - typedef memory_mappable::mapping_offset_t mapping_offset_t; - - public: - - #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - typedef long long offset_t; - #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - typedef off64_t offset_t; - #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - - typedef enum { read_only = 0x01 - , read_write = 0x02 - , copy_on_write = 0x03 - , invalid_mode = 0xff - } accessmode_t; - - - /*!Creates a mapping region of the mapped memory "mapping", starting in - offset "offset", and the mapping's size will be "size". The mapping - can be opened for read-only "memory_mappable::read_only" or read-write - "memory_mappable::read_write.*/ - mapped_region(const memory_mappable& mapping - ,mapped_region::accessmode_t mode - ,offset_t offset = 0 - ,std::size_t size = 0 - ,const void *address = 0); - - /*!Default constructor. Address and size and offset will be 0. Does not throw*/ - mapped_region(); - - /*!Destroys the mapped region. Does not throw*/ - ~mapped_region(); - - /*!Returns the size of the mapping. Never throws.*/ - std::size_t get_size() const; - - /*!Returns the base address of the mapping. Never throws.*/ - void* get_address() const; - - /*!Returns the offset of the mapping from the beginning of the - mapped memory. Never throws.*/ - offset_t get_offset() const; - - /*!Flushes to the disk a byte range within the mapped memory. - Never throws*/ - bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0); - - /*!Swaps the mapped_region with another mapped region*/ - void swap(mapped_region &other); - - static std::size_t get_page_size(); - - private: - /*!Closes a previously opened memory mapping. Never throws.*/ - void priv_close(); - - void* m_base; - std::size_t m_size; - offset_t m_offset; -// #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - offset_t m_extra_offset; -// #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -// #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -}; - -inline void swap(mapped_region &x, mapped_region &y) -{ x.swap(y); } - -inline mapped_region::mapped_region() - : m_base(0), m_size(0), m_offset(0) -// #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - , m_extra_offset(0) -// #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - // empty -// #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -{} - -inline mapped_region::~mapped_region() -{ this->priv_close(); } - -inline std::size_t mapped_region::get_size() const -{ return m_size; } - -inline mapped_region::offset_t mapped_region::get_offset() const -{ return m_offset; } - -inline void* mapped_region::get_address() const -{ return m_base; } - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline mapped_region::mapped_region - (const memory_mappable &mapping - ,mapped_region::accessmode_t mode - ,mapped_region::offset_t offset - ,std::size_t size - ,const void *address) - : m_base(0) -{ - //Update mapping size if the user does not specify it - if(size == 0){ - __int64 total_size; - if(!winapi::get_file_size(mapping.get_mapping_handle(), total_size)){ - error_info err(winapi::get_last_error()); - throw interprocess_exception(err); - } - if(total_size > (__int64)((std::size_t)(-1))){ - error_info err(size_error); - throw interprocess_exception(err); - } - size = static_cast(total_size - offset); - } - - //Set accesses - unsigned long file_map_access = 0; - unsigned long map_access = 0; - - switch(mode) - { - case read_only: - file_map_access |= winapi::page_readonly; - map_access |= winapi::file_map_read; - break; - case read_write: - file_map_access |= winapi::page_readwrite; - map_access |= winapi::file_map_write; - break; - case copy_on_write: - file_map_access |= winapi::page_writecopy; - file_map_access |= winapi::file_map_copy; - break; - default: - { - error_info err(mode_error); - throw interprocess_exception(err); - } - break; - } - - //Create file mapping - memory_mappable::mapping_handle_t hnd = - winapi::create_file_mapping - (mapping.get_mapping_handle(), file_map_access, 0, 0, 0); - - //Check if all is correct - if(!hnd){ - error_info err = winapi::get_last_error(); - this->priv_close(); - throw interprocess_exception(err); - } - - //We can't map any offset so we have to obtain system's - //memory granularity - unsigned long granularity = 0; - unsigned long foffset_low; - unsigned long foffset_high; - - winapi::system_info info; - get_system_info(&info); - granularity = info.dwAllocationGranularity; - - //Now we calculate valid offsets - foffset_low = (unsigned long)(offset / granularity) * granularity; - foffset_high = (unsigned long)(((offset / granularity) * granularity) >> 32); - - //We calculate the difference between demanded and valid offset - m_extra_offset = (offset - (offset / granularity) * granularity); - - //Store user values in memory - m_offset = offset; - m_size = size; - - //Update the mapping address - if(address){ - address = static_cast(address) - m_extra_offset; - } - - //Map with new offsets and size - m_base = winapi::map_view_of_file_ex - (hnd, - map_access, - foffset_high, - foffset_low, - static_cast(m_extra_offset + m_size), - (void*)address); - - //We don't need the file mapping anymore - winapi::close_handle(hnd); - - //Check error - if(!m_base){ - error_info err = winapi::get_last_error(); - this->priv_close(); - throw interprocess_exception(err); - } - - //Calculate new base for the user - m_base = static_cast(m_base) + m_extra_offset; -} - -inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes) -{ - //Check some errors - if(m_base == 0) - return false; - - if(mapping_offset >= m_size || (mapping_offset + numbytes) > m_size){ - return false; - } - - //Update flush size if the user does not provide it - if(numbytes == 0){ - numbytes = m_size - mapping_offset; - } - - //Flush it all - return 0 == winapi::flush_view_of_file - (static_cast(m_base)+mapping_offset, - static_cast(numbytes)); -} - -inline void mapped_region::priv_close() -{ - if(m_base){ - this->flush(); - winapi::unmap_view_of_file(static_cast(m_base) - m_extra_offset); - m_base = 0; - } -} - -inline std::size_t get_page_size() -{ - winapi::system_info info; - get_system_info(&info); - return std::size_t(info.dwAllocationGranularity); -} - -#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline mapped_region::mapped_region - (const memory_mappable &mapping, - mapped_region::accessmode_t mode, - mapped_region::mapping_offset_t offset, - std::size_t size, - const void *address) - : m_base(MAP_FAILED) -{ - if(size == 0){ - mapping_offset_t filesize = lseek64(mapping.get_mapping_handle(), offset, SEEK_END); - - if(filesize == -1 ){ - error_info err(system_error_code()); - throw interprocess_exception(err); - } - if(offset >= filesize){ - error_info err(size_error); - throw interprocess_exception(err); - } - filesize -= offset; - - size = (size_t)filesize; - if((mapping_offset_t)size != filesize){ - error_info err(size_error); - throw interprocess_exception(err); - } - } - - //Create new mapping - int prot = 0; - int flags = 0; - - switch(mode) - { - case mapped_region::read_only: - prot |= PROT_READ; - flags |= MAP_SHARED; - break; - - case mapped_region::read_write: - prot |= (PROT_WRITE | PROT_READ); - flags |= MAP_SHARED; - break; - - case mapped_region::copy_on_write: - prot |= PROT_READ; - flags |= MAP_PRIVATE; - break; - - default: - { - error_info err(mode_error); - throw interprocess_exception(err); - } - break; - } - - //We calculate the difference between demanded and valid offset - std::size_t page_size = this->get_page_size(); - m_extra_offset = (offset - (offset / page_size) * page_size); - - //Store user values in memory - m_offset = offset; - m_size = size; - - //Update the mapping address - if(address){ - address = static_cast(address) - m_extra_offset; - } - - //Map it to the address space - m_base = mmap64( (void*)address - , static_cast(m_extra_offset + m_size) - , prot - , flags - , mapping.get_mapping_handle() - , offset); - - //Check if mapping was successful - if(m_base == MAP_FAILED){ - error_info err = system_error_code(); - this->priv_close(); - throw interprocess_exception(err); - } - - //Check for fixed mapping error - if(address && (m_base != (void*)address)){ - error_info err = system_error_code(); - this->priv_close(); - throw interprocess_exception(err); - } - - //Calculate new base for the user - m_base = static_cast(m_base) + m_extra_offset; - m_offset = offset; - m_size = size; -} - -inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes) -{ - if(mapping_offset >= m_size || (mapping_offset+numbytes)> m_size){ - return false; - } - - if(numbytes == 0){ - numbytes = m_size - mapping_offset; - } - //Flush it all - return msync(static_cast(m_base)+mapping_offset, - numbytes, MS_SYNC) == 0; -} - -inline void mapped_region::priv_close() -{ - if(m_base != MAP_FAILED){ - this->flush(); - munmap(static_cast(m_base) - m_extra_offset, m_size + m_extra_offset); - m_base = MAP_FAILED; - } -} - -inline std::size_t mapped_region::get_page_size() -{ return std::size_t(sysconf(_SC_PAGESIZE)); } - -#endif //##if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline void mapped_region::swap(mapped_region &other) -{ - detail::do_swap(this->m_base, other.m_base); - detail::do_swap(this->m_size, other.m_size); - detail::do_swap(this->m_offset, other.m_offset); -// #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - detail::do_swap(this->m_extra_offset, other.m_extra_offset); -// #else -// #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -} - - - -/*!No-op functor*/ -struct null_mapped_region_function -{ - bool operator()(const mapped_region ®ion, bool) const - { return true; } -}; - - -} //namespace interprocess { - -} //namespace boost { - -#include - -#endif //BOOST_INTERPROCESS_memory_mappable_HPP - diff --git a/include/boost/interprocess/shared_memory.hpp b/include/boost/interprocess/shared_memory.hpp deleted file mode 100644 index 558ccee..0000000 --- a/include/boost/interprocess/shared_memory.hpp +++ /dev/null @@ -1,695 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_INTERPROCESS_MEMORY_HPP -#define BOOST_INTERPROCESS_MEMORY_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -/* -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -# include -#else - -# ifdef BOOST_HAS_UNISTD_H -# include //O_CREAT, O_*... -# include //mmap -# include //ftruncate, close -# include //sem_t* family, SEM_VALUE_MAX -# include //std::string -# include //mode_t, S_IRWXG, S_IRWXO, S_IRWXU, -# else -# error Unknown platform -# endif - -#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -*/ - -/*!\file - Describes shared_memory class -*/ - -namespace boost { - -namespace interprocess { - -/*!A class that wraps a shared memory mapping that can be used to - create mapped regions from the mapped files*/ -class shared_memory_object : public memory_mappable -{ - enum type_t { DoCreate, DoOpen, DoCreateOrOpen }; - public: - - shared_memory_object(); - - /*!Creates a shared memory object with name "name" and size "size", with the access mode "mode" - If the file previously exists, throws an error.*/ - shared_memory_object(detail::create_only_t, const char *name, memory_mappable::accessmode_t mode) - { this->priv_open_or_create(DoCreate, name, mode); } - - /*!Tries to create a shared memory object with name "name" and size "size", with the - access mode "mode". If the file previously exists, it tries to open it with mode "mode". - Otherwise throws an error.*/ - shared_memory_object(detail::open_or_create_t, const char *name, memory_mappable::accessmode_t mode) - { this->priv_open_or_create(DoCreateOrOpen, name, mode); } - - // Tries to open a shared memory object with name "name", with the access mode "mode". - // If the file does not previously exist, it throws an error. - shared_memory_object(detail::open_only_t, const char *name, memory_mappable::accessmode_t mode) - { this->priv_open_or_create(DoOpen, name, mode); } - - // Erases a shared memory object from the system. - static bool remove(const char *name); - - //Sets the size of the shared memory mapping - void truncate(memory_mappable::mapping_offset_t length); - - // Closes the shared memory mapping. All mapped regions are still - // valid after destruction. The shared memory object still exists and - // can be newly opened. - ~shared_memory_object(); - - /*!Returns the name of the file.*/ - const char *get_name() const; - - /*!Return access mode*/ - accessmode_t get_mode() const; - - /*!Get mapping handle*/ - mapping_handle_t get_mapping_handle() const; - - private: - /*!Closes a previously opened file mapping. Never throws.*/ - void priv_close(); - - bool priv_open_or_create(type_t type, const char *filename, - memory_mappable::accessmode_t mode); - - std::string m_filename; -}; - -inline shared_memory_object::~shared_memory_object() -{ this->priv_close(); } - -/*!Returns the name of the file.*/ -inline const char *shared_memory_object::get_name() const -{ return m_filename.c_str(); } - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline bool shared_memory_object::priv_open_or_create - (type_t type, - const char *filename, - memory_mappable::accessmode_t mode) -{ - m_filename = filename; - - //Make sure a temporary path is created for shared memory - const unsigned long BufferSize = 512; - - std::string shmfile; - shmfile.resize(BufferSize); - - unsigned long n = winapi::get_temp_path(BufferSize, &shmfile[0]); - if(n > BufferSize){ - shmfile.resize(n); - n = winapi::get_temp_path(n, &shmfile[0]); - } - - if(!n){ - error_info err = winapi::get_last_error(); - throw interprocess_exception(err); - } - - //Remove final null. - shmfile.resize(n); - shmfile += "boost_interprocess\\"; - - if(!winapi::create_directory(shmfile.c_str(), 0)){ - unsigned long err = winapi::get_last_error(); - if(err != winapi::error_already_exists){ - error_info err = winapi::get_last_error(); - throw interprocess_exception(err); - } - } - - shmfile += filename; - - unsigned long file_access = 0; - unsigned long file_creation_flags = 0; - - //Set accesses - if (mode == read_write){ - file_access |= winapi::generic_read | winapi::generic_write; - } - else if (mode == read_only){ - file_access |= winapi::generic_read; - } - - switch(type){ - case DoOpen: - file_creation_flags = winapi::open_existing; - break; - case DoCreate: - file_creation_flags = winapi::create_new; - break; - case DoCreateOrOpen: - file_creation_flags = winapi::open_always; - break; - default: - { - error_info err = other_error; - throw interprocess_exception(err); - } - } - - //Open file using windows API since we need the handle - memory_mappable::mapping_handle_t hnd = winapi::create_file - (shmfile.c_str(), file_access, file_creation_flags, winapi::file_attribute_temporary); - - //Check for error - if(hnd == winapi::invalid_handle_value){ - error_info err = winapi::get_last_error(); - this->priv_close(); - throw interprocess_exception(err); - } - - memory_mappable::assign_data(hnd, mode); - return true; -} - -inline bool shared_memory_object::remove(const char *filename) -{ - try{ - //Make sure a temporary path is created for shared memory - const unsigned long BufferSize = 512; - - std::string shmfile; - shmfile.resize(BufferSize); - - unsigned long n = winapi::get_temp_path(BufferSize, &shmfile[0]); - if(n > BufferSize){ - shmfile.resize(n); - n = winapi::get_temp_path(n, &shmfile[0]); - } - - if(!n){ - error_info err = winapi::get_last_error(); - throw interprocess_exception(err); - } - - //Remove final null. - shmfile.resize(n); - shmfile += "boost_interprocess\\"; - shmfile += filename; - return std::remove(shmfile.c_str()) == 0; - } - catch(...){ - return false; - } -} - -inline void shared_memory_object::truncate(memory_mappable::mapping_offset_t length) -{ - if(!winapi::set_file_pointer_ex( memory_mappable::get_mapping_handle(), length - , 0, winapi::file_begin)){ - error_info err = winapi::get_last_error(); - throw interprocess_exception(err); - } - - if(!winapi::set_end_of_file(memory_mappable::get_mapping_handle())){ - error_info err = winapi::get_last_error(); - throw interprocess_exception(err); - } -} - -inline void shared_memory_object::priv_close() -{ - if(memory_mappable::get_mapping_handle() != winapi::invalid_handle_value){ - winapi::close_handle(memory_mappable::get_mapping_handle()); - memory_mappable::assign_data - (winapi::invalid_handle_value, memory_mappable::get_mode()); - } -} - -#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - -inline bool shared_memory_object::priv_open_or_create - (type_t type, - const char *filename, - memory_mappable::accessmode_t mode) -{ - m_filename = filename; - - //Create new mapping - - int oflag = 0; - if(mode == memory_mappable::read_only){ - oflag |= O_RDONLY; - } - else if(mode == memory_mappable::read_write){ - oflag |= O_RDWR; - } - else{ - error_info err(mode_error); - throw interprocess_exception(err); - } - - switch(type){ - case DoOpen: - //No addition - break; - case DoCreate: - oflag |= (O_CREAT | O_EXCL); - break; - case DoCreateOrOpen: - oflag |= O_CREAT; - break; - default: - { - error_info err = other_error; - throw interprocess_exception(err); - } - } - - //Open file using windows API since we need the handle - memory_mappable::mapping_handle_t hnd = shm_open - (filename, oflag, S_IRWXO | S_IRWXG | S_IRWXU); - - //Check for error - if(hnd == -1){ - error_info err = errno; - this->priv_close(); - throw interprocess_exception(err); - } - - memory_mappable::assign_data(hnd, mode); - return true; -} - -inline bool shared_memory_object::remove(const char *filename) -{ - return 0 != shm_unlink(filename); -} - -inline void shared_memory_object::truncate(memory_mappable::mapping_offset_t length) -{ - if(0 != ftruncate(memory_mappable::get_mapping_handle(), length)){ - error_info err(system_error_code()); - throw interprocess_exception(err); - } -} - -inline void shared_memory_object::priv_close() -{ - if(memory_mappable::get_mapping_handle() != -1){ - ::close(memory_mappable::get_mapping_handle()); - memory_mappable::assign_data - (-1, memory_mappable::get_mode()); - } -} - -#endif //##if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - - -/*!A class that wraps basic shared memory management*/ -class shared_memory -{ - //Non-copyable - shared_memory(); - shared_memory(const shared_memory &); - shared_memory &operator=(const shared_memory &); - - enum type_t { DoCreate, DoOpen, DoCreateOrOpen }; - - public: - - /*!Creates a shared memory segment with name "name", with size "size". - If the segment was previously created it throws an error. - The segment can be created in two modes: read-only "read_only" or read-write "read_write". - The user can also specify the mapping address in "addr". If "addr" is 0, - the operating system will choose the mapping address. - - This function can throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc)*/ - shared_memory(detail::create_only_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode = memory_mappable::read_write, - const void *addr = 0); - - /*!Opens a shared memory segment with name "name". If it was previously - created throws an error. - The segment can be opened in two modes: read-only "read_only" or read-write "read_write". - The user can also specify the mapping address in "addr". If "addr" is 0, - the operating system will choose the mapping address. - - This function can throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc)*/ - shared_memory(detail::open_only_t, - const char *name, - memory_mappable::accessmode_t mode = memory_mappable::read_write, - const void *addr = 0); - - /*!Creates a shared memory segment with name "name", and size "size" if - the shared memory was not previously created. If it was previously - created it tries to open it. User can specify the mapping address in "addr". - The segment can be opened in two modes: read-only "read_only" or read-write "read_write". - If "addr" is 0, the operating system will choose the mapping address. - - This function can throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc)*/ - shared_memory(detail::open_or_create_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode = memory_mappable::read_write, - const void *addr = 0); - - /*!Creates a shared memory segment with name "name", with size "size". - The user must also specify the mapping address in "addr". If "addr" is 0, - the operating system will choose the mapping address. - It also executes a copy of the functor "construct_func" atomically if - the segment is created. The functor must have the following signature: - - bool operator()(const segment_info_t * info, bool created) - - "info" is an initialized segment info structure, and "created" - must be "true". If the functor returns "false", or throws an error - is supposed and the shared memory won't be created. - The user must specify a destroy_func, that will be copied in this - constructor and executed in the destructor, before unmapping the - shared memory segment. - The functor must have the following signature: - - void operator()(const segment_info_t * info, bool last) const - - "info" is an initialized segment info structure, and "last" - indicates if this unmapping is the last unmapping so that - there will be no no other processes attached to the segment. - The functor must NOT throw. - - This function can throw if copying any functor throws, - the construct_func execution throws, and it - will throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc) on any error*/ - template - shared_memory(detail::create_only_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func); - - /*!Creates a shared memory segment with name "name", and size "size" if - the shared memory was not previously created. If it was previously - created tries to open it. - User must specify the mapping address in "addr". If "addr" is 0, - the operating system will choose the mapping address. - It also executes a copy of the functor "construct_func" atomically - if the segment is opened. The functor must have the following signature: - - bool operator()(const segment_info_t * info, bool created) - - "info" is an initialized segment info structure, and "created" - must be "false". If the functor returns "false", or throws an error - is supposed and the shared memory won't be opened. - The user must specify a destroy_func, that will be copied in this - constructor and executed in the destructor, before unmapping the - shared memory segment. - The functor must have the following signature: - - void operator()(const segment_info_t * info, bool last) const - - "info" is an initialized segment info structure, and "last" - indicates if this unmapping is the last unmapping so that - there will be no no other processes attached to the segment. - The functor must NOT throw. - - This function can throw if copying any functor throws, - the construct_func execution throws, and it - will throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc) on any error*/ - template - shared_memory(detail::open_only_t, - const char *name, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_funcc); - - /*!Creates a shared memory segment with name "name", and size "size" if - the shared memory was not previously created. If it was previously - created it tries to open it. User can specify the mapping address in "addr". - If "addr" is 0, the operating system will choose the mapping address. - It also executes the functor "construct_func" atomically if the segment is - created or opened. The functor must have the following signature: - - bool operator()(const segment_info_t * info, bool created) - - "info" is an initialized segment info structure, and "created" - will be "true" if the shared memory was created. If the functor - returns "false", or throws an error is supposed and the - shared memory won't be opened. - The user must specify a destroy_func, that will be copied in this - constructor and executed in the destructor, before unmapping the - shared memory segment. - The functor must have the following signature: - - void operator()(const segment_info_t * info, bool last) const - - "info" is an initialized segment info structure, and "last" - indicates if this unmapping is the last unmapping so that - there will be no no other processes attached to the segment. - The functor must NOT throw. - - This function can throw if copying any functor throws, - the construct_func execution throws, and it - will throw boost::inteprocess_exception and - other standard exceptions derived from std::exception - (like std::bad_alloc) on any error*/ - template - shared_memory(detail::open_or_create_t, - const char *name, - std::size_t size, - memory_mappable::accessmode_t mode, - const void *addr, - const ConstructFunc &construct_func); - - /*!Destructor. Unmaps shared memory from process' address space. - It also executes the destruction functor atomically if - the user has registered that the destruction functor - in the constructor of this class. - Never throws.*/ - ~shared_memory(); - - /*!Returns the size of the shared memory segment. Never throws.*/ - std::size_t get_size() const; - - /*!Returns shared memory segment's address for this process. - Never throws.*/ - void* get_address() const; - - /*!Swaps the shared memory segment this shared_memory object - manages with another managed by "other". - Never throws.*/ - void swap(shared_memory &other); - - /*!Returns the name of the shared memory segment used in the - constructor. Never throws.*/ - const char *get_name() const; - - #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - typedef void * OS_handle_t; - #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - typedef int OS_handle_t; - #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) - - /*!Returns the handle that identifies the shared memory - segment in a operating system. This is operating system - and implementation dependent and should be used only - in special situations. - Never throws.*/ - OS_handle_t get_OS_handle() const; - - private: - - template - bool priv_open_or_create(type_t type, const char *name, std::size_t size, - memory_mappable::accessmode_t mode, const void *addr, - ConstructFunc construct_func); - mapped_region m_mapped_region; - std::string m_name; -}; - -inline shared_memory::shared_memory - (detail::create_only_t, const char *name, std::size_t size, - memory_mappable::accessmode_t mode, const void *addr) -{ - this->priv_open_or_create(DoCreate, name, size, mode, addr, null_mapped_region_function()); -} - -inline shared_memory::shared_memory - (detail::open_only_t, const char *name, - memory_mappable::accessmode_t mode, const void *addr) -{ - this->priv_open_or_create(DoOpen, name, 0, mode, addr, null_mapped_region_function()); -} - -inline shared_memory::shared_memory - (detail::open_or_create_t, const char *name, std::size_t size, - memory_mappable::accessmode_t mode, const void *addr) -{ - this->priv_open_or_create(DoCreateOrOpen, name, size, mode, addr, null_mapped_region_function()); -} - -template -inline shared_memory::shared_memory - (detail::create_only_t, const char *name, std::size_t size, - memory_mappable::accessmode_t mode, const void *addr, - const ConstructFunc &construct_func) -{ - this->priv_open_or_create(DoCreate, name, size, mode, addr, construct_func); -} - -template -inline shared_memory::shared_memory - (detail::open_only_t, const char *name, - memory_mappable::accessmode_t mode, const void *addr, - const ConstructFunc &construct_func) -{ - this->priv_open_or_create(DoOpen, name, 0, mode, addr, construct_func); -} - -template -inline shared_memory::shared_memory - (detail::open_or_create_t, const char *name, std::size_t size, - memory_mappable::accessmode_t mode, const void *addr, - const ConstructFunc &construct_func) -{ - this->priv_open_or_create(DoCreateOrOpen, name, size, mode, addr, construct_func); -} - -inline shared_memory::~shared_memory() -{} - -inline std::size_t shared_memory::get_size() const -{ return m_mapped_region.get_size(); } - -inline void* shared_memory::get_address() const -{ return m_mapped_region.get_address(); } - -inline const char *shared_memory::get_name() const -{ return m_name.c_str(); } - -inline void shared_memory::swap(shared_memory &other) -{ - this->m_name.swap(other.m_name); - this->m_mapped_region.swap(other.m_mapped_region); -} - -inline void swap(shared_memory &x, shared_memory &y) -{ x.swap(y); } - -template inline -bool shared_memory::priv_open_or_create - (shared_memory::type_t type, const char *name, std::size_t size, - memory_mappable::accessmode_t mode, const void *addr, - ConstructFunc construct_func) -{ - error_info err; - - m_name = name; - - //This global interprocess_mutex guarantees synchronized creation/open logic - detail::global_lock mut; - if(!mut.acquire()){ - #ifdef BOOST_NO_EXCEPTIONS - return false; - #else - throw interprocess_exception(err); - #endif - } - - //Do some in-place construction - bool created = false; - switch(type){ - case DoOpen: - { - shared_memory_object mapping(open_only, name, memory_mappable::read_write); - mapped_region region(mapping, (mapped_region::accessmode_t)mode, 0, size, addr); - m_mapped_region.swap(region); - } - break; - case DoCreateOrOpen: - { - try{ - shared_memory_object mapping(create_only, name, memory_mappable::read_write); - mapping.truncate(size); - mapped_region region(mapping, (mapped_region::accessmode_t)mode, 0, size, addr); - m_mapped_region.swap(region); - created = true; - } - catch(interprocess_exception &ex){ - if(ex.get_error_code() != already_exists_error){ - throw; - } - shared_memory_object mapping(open_only, name, memory_mappable::read_write); - mapped_region region(mapping, (mapped_region::accessmode_t)mode, 0, size, addr); - m_mapped_region.swap(region); - } - } - break; - case DoCreate: - { - shared_memory_object mapping(create_only, name, memory_mappable::read_write); - mapping.truncate(size); - mapped_region region(mapping, (mapped_region::accessmode_t)mode, 0, size, addr); - m_mapped_region.swap(region); - created = true; - } - break; - default: - break; - } - - //Execute atomic functor - construct_func(m_mapped_region, created); - - return true; -} - -} //namespace interprocess { - -} //namespace boost { - -#include - -#endif //BOOST_INTERPROCESS_MEMORY_HPP diff --git a/include/boost/interprocess/smart_ptr/unique_ptr_emulation.hpp b/include/boost/interprocess/smart_ptr/unique_ptr_emulation.hpp deleted file mode 100644 index 3d11313..0000000 --- a/include/boost/interprocess/smart_ptr/unique_ptr_emulation.hpp +++ /dev/null @@ -1,419 +0,0 @@ -// I, Howard Hinnant, hereby place this code in the public domain. - -#ifdef _MSC_VER - #pragma warning (push) - //Disable "multiple copy constructors specified" - #pragma warning (disable : 4521) - #pragma warning (disable : 4522) -#endif - -#include -#include -#include -#include -#include -#include - -namespace boost_ext{ - -namespace detail -{ - -struct two {char _[2];}; - -namespace pointer_type_imp -{ - -template static two test(...); -template static char test(typename U::pointer* = 0); - -} - -template -struct has_pointer_type -{ - static const bool value = sizeof(pointer_type_imp::test(0)) == 1; -}; - -namespace pointer_type_imp -{ - -template ::value> -struct pointer_type -{ - typedef typename D::pointer type; -}; - -template -struct pointer_type -{ - typedef T* type; -}; - -} - -template -struct pointer_type -{ - typedef typename pointer_type_imp::pointer_type::type>::type type; -}; - -} - -template -struct default_delete -{ - default_delete() {} - template default_delete(const default_delete&) {} - void operator() (T* ptr) const - { - BOOST_STATIC_ASSERT(sizeof(T) > 0); - delete ptr; - } -}; - -template -struct default_delete -{ - void operator() (T* ptr) const - { - BOOST_STATIC_ASSERT(sizeof(T) > 0); - delete [] ptr; - } -}; - -template -struct default_delete -{ - void operator() (T* ptr, std::size_t) const - { - BOOST_STATIC_ASSERT(sizeof(T) > 0); - delete [] ptr; - } -}; - -template class unique_ptr; - -namespace detail -{ - -template struct unique_ptr_error; - -template -struct unique_ptr_error > -{ - typedef unique_ptr type; -}; - -} // detail - -template > -class unique_ptr -{ - struct nat {int for_bool_;}; - typedef typename boost::add_reference::type deleter_reference; - typedef typename boost::add_reference::type deleter_const_reference; -public: - typedef T element_type; - typedef D deleter_type; - typedef typename detail::pointer_type::type pointer; - - // constructors - unique_ptr() : ptr_(pointer()) {} - explicit unique_ptr(pointer p) : ptr_(p) {} - unique_ptr(pointer p, typename boost::mpl::if_< - boost::is_reference, - D, - typename boost::add_reference::type>::type d) - : ptr_(p, d) {} - unique_ptr(const unique_ptr& u) - : ptr_(const_cast(u).release(), u.get_deleter()) {} - - template - unique_ptr(const unique_ptr& u, - typename boost::enable_if_c< - boost::is_convertible::pointer, pointer>::value && - boost::is_convertible::value && - ( - !boost::is_reference::value || - boost::is_same::value - ) - , - nat - >::type = nat()) - : ptr_(const_cast&>(u).release(), u.get_deleter()) {} - - // destructor - ~unique_ptr() {reset();} - - // assignment - unique_ptr& operator=(const unique_ptr& cu) - { - unique_ptr& u = const_cast(cu); - reset(u.release()); - ptr_.second() = u.get_deleter(); - return *this; - } - template - unique_ptr& operator=(const unique_ptr& cu) - { - unique_ptr& u = const_cast&>(cu); - reset(u.release()); - ptr_.second() = u.get_deleter(); - return *this; - } - unique_ptr& operator=(int nat::*) - { - reset(); - return *this; - } - - // observers - typename boost::add_reference::type operator*() const {return *ptr_.first();} - pointer operator->() const {return ptr_.first();} - pointer get() const {return ptr_.first();} - deleter_reference get_deleter() {return ptr_.second();} - deleter_const_reference get_deleter() const {return ptr_.second();} - operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} - - // modifiers - pointer release() - { - pointer tmp = ptr_.first(); - ptr_.first() = pointer(); - return tmp; - } - void reset(pointer p = pointer()) - { - if (ptr_.first() != p) - { - if (ptr_.first()) - ptr_.second()(ptr_.first()); - ptr_.first() = p; - } - } - void swap(unique_ptr& u) {ptr_.swap(u.ptr_);} -private: - boost::compressed_pair ptr_; - - unique_ptr(unique_ptr&); - template unique_ptr(unique_ptr&); - template unique_ptr(U&, typename detail::unique_ptr_error::type = 0); - - - unique_ptr& operator=(unique_ptr&); - template unique_ptr& operator=(unique_ptr&); - template typename detail::unique_ptr_error::type operator=(U&); -}; - -template -class unique_ptr -{ - struct nat {int for_bool_;}; - typedef typename boost::add_reference::type deleter_reference; - typedef typename boost::add_reference::type deleter_const_reference; -public: - typedef T element_type; - typedef D deleter_type; - typedef typename detail::pointer_type::type pointer; - - // constructors - unique_ptr() : ptr_(pointer()) {} - explicit unique_ptr(pointer p) : ptr_(p) {} - unique_ptr(pointer p, typename boost::mpl::if_< - boost::is_reference, - D, - typename boost::add_reference::type>::type d) - : ptr_(p, d) {} - unique_ptr(const unique_ptr& u) - : ptr_(const_cast(u).release(), u.get_deleter()) {} - - // destructor - ~unique_ptr() {reset();} - - // assignment - unique_ptr& operator=(const unique_ptr& cu) - { - unique_ptr& u = const_cast(cu); - reset(u.release()); - ptr_.second() = u.get_deleter(); - return *this; - } - unique_ptr& operator=(int nat::*) - { - reset(); - return *this; - } - - // observers - typename boost::add_reference::type operator[](std::size_t i) const {return ptr_.first()[i];} - pointer get() const {return ptr_.first();} - deleter_reference get_deleter() {return ptr_.second();} - deleter_const_reference get_deleter() const {return ptr_.second();} - operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} - - // modifiers - pointer release() - { - pointer tmp = ptr_.first(); - ptr_.first() = pointer(); - return tmp; - } - void reset(pointer p = pointer()) - { - if (ptr_.first() != p) - { - if (ptr_.first()) - ptr_.second()(ptr_.first()); - ptr_.first() = p; - } - } - void swap(unique_ptr& u) {ptr_.swap(u.ptr_);} -private: - boost::compressed_pair ptr_; - - template unique_ptr(U p, E, - typename boost::enable_if >::type* = 0); - template explicit unique_ptr(U, - typename boost::enable_if >::type* = 0); - - unique_ptr(unique_ptr&); - template unique_ptr(U&, typename detail::unique_ptr_error::type = 0); - - unique_ptr& operator=(unique_ptr&); - template typename detail::unique_ptr_error::type operator=(U&); -}; - -template -class unique_ptr -{ - struct nat {int for_bool_;}; - typedef typename boost::add_reference::type deleter_reference; - typedef typename boost::add_reference::type deleter_const_reference; -public: - typedef T element_type; - typedef D deleter_type; - typedef typename detail::pointer_type::type pointer; - static const std::size_t size = N; - - // constructors - unique_ptr() : ptr_(pointer()) {} - explicit unique_ptr(pointer p) : ptr_(p) {} - unique_ptr(pointer p, typename boost::mpl::if_< - boost::is_reference, - D, - typename boost::add_reference::type>::type d) - : ptr_(p, d) {} - unique_ptr(const unique_ptr& u) - : ptr_(const_cast(u).release(), u.get_deleter()) {} - - // destructor - ~unique_ptr() {reset();} - - // assignment - unique_ptr& operator=(const unique_ptr& cu) - { - unique_ptr& u = const_cast(cu); - reset(u.release()); - ptr_.second() = u.get_deleter(); - return *this; - } - unique_ptr& operator=(int nat::*) - { - reset(); - return *this; - } - - // observers - typename boost::add_reference::type operator[](std::size_t i) const {return ptr_.first()[i];} - pointer get() const {return ptr_.first();} - deleter_reference get_deleter() {return ptr_.second();} - deleter_const_reference get_deleter() const {return ptr_.second();} - operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} - - // modifiers - pointer release() - { - pointer tmp = ptr_.first(); - ptr_.first() = pointer(); - return tmp; - } - void reset(pointer p = pointer()) - { - if (ptr_.first() != p) - { - if (ptr_.first()) - ptr_.second()(ptr_.first(), N); - ptr_.first() = p; - } - } - void swap(unique_ptr& u) {ptr_.swap(u.ptr_);} -private: - boost::compressed_pair ptr_; - - template unique_ptr(U p, E, - typename boost::enable_if >::type* = 0); - template explicit unique_ptr(U, - typename boost::enable_if >::type* = 0); - - unique_ptr(unique_ptr&); - template unique_ptr(U&, typename detail::unique_ptr_error::type = 0); - - unique_ptr& operator=(unique_ptr&); - template typename detail::unique_ptr_error::type operator=(U&); -}; - -template -inline -void swap(unique_ptr& x, unique_ptr& y) {x.swap(y);} - -template -inline -bool -operator==(const unique_ptr& x, const unique_ptr& y) - {return x.get() == y.get();} - -template -inline -bool -operator!=(const unique_ptr& x, const unique_ptr& y) - {return x.get() != y.get();} - -template -inline -bool -operator <(const unique_ptr& x, const unique_ptr& y) - {return x.get() < y.get();} - -template -inline -bool -operator<=(const unique_ptr& x, const unique_ptr& y) - {return x.get() <= y.get();} - -template -inline -bool -operator >(const unique_ptr& x, const unique_ptr& y) - {return x.get() > y.get();} - -template -inline -bool -operator>=(const unique_ptr& x, const unique_ptr& y) - {return x.get() >= y.get();} - -template -inline -unique_ptr -move(unique_ptr& p) -{ - return unique_ptr(p.release(), p.get_deleter()); -} - -} //namespace boost_ext{ - -#ifdef _MSC_VER - #pragma warning (pop) -#endif diff --git a/include/boost/interprocess/smart_ptr/unique_ptr_reference.hpp b/include/boost/interprocess/smart_ptr/unique_ptr_reference.hpp deleted file mode 100644 index 10bba15..0000000 --- a/include/boost/interprocess/smart_ptr/unique_ptr_reference.hpp +++ /dev/null @@ -1,407 +0,0 @@ -// I, Howard Hinnant, hereby place this code in the public domain. - -namespace std { namespace detail { - -template -struct select -{ - typedef Then type; -}; - -template -struct select -{ - typedef Else type; -}; - -template struct restrict_to {}; -template struct restrict_to {typedef T type;}; - -using boost::compressed_pair; - -struct two {char _[2];}; - -namespace pointer_type_imp -{ - -template static two test(...); -template static char test(typename U::pointer* = 0); - -} - -template -struct has_pointer_type -{ - static const bool value = sizeof(pointer_type_imp::test(0)) == 1; -}; - -namespace pointer_type_imp -{ - -template ::value> -struct pointer_type -{ - typedef typename D::pointer type; -}; - -template -struct pointer_type -{ - typedef T* type; -}; - -} - -template -struct pointer_type -{ - typedef typename pointer_type_imp::pointer_type::type>::type type; -}; - -} } - -namespace std -{ - -template -struct default_delete -{ - default_delete() {} - template default_delete(const default_delete&) {} - void operator() (T* ptr) const - { - static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type"); - delete ptr; - } -}; - -template -struct default_delete -{ - void operator() (T* ptr) const - { - static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type"); - delete [] ptr; - } -}; - -template -struct default_delete -{ - void operator() (T* ptr, std::size_t) const - { - static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type"); - delete [] ptr; - } -}; - -template > -class unique_ptr -{ - struct nat {int for_bool_;}; -public: - typedef T element_type; - typedef D deleter_type; - typedef typename detail::pointer_type::type pointer; - - // constructors - unique_ptr() : ptr_(pointer()) {} - explicit unique_ptr(pointer p) : ptr_(p) {} - unique_ptr(pointer p, typename detail::select< - tr1::is_reference::value, - D, - const D&>::type d) - : ptr_(p, d) {} - unique_ptr(pointer p, typename tr1::remove_reference::type&& d) - : ptr_(p, std::move(d)) - { - static_assert(!tr1::is_reference::value, "rvalue deleter bound to reference"); - } - unique_ptr(unique_ptr&& u) - : ptr_(u.release(), std::forward(u.get_deleter())) {} - template - unique_ptr(unique_ptr&& u, - typename detail::restrict_to< - tr1::is_convertible::pointer, pointer>::value && - tr1::is_convertible::value && - ( - !tr1::is_reference::value || - tr1::is_same::value - ) - , - nat - >::type = nat()) - : ptr_(u.release(), std::forward(u.get_deleter())) {} - - // destructor - ~unique_ptr() {reset();} - - // assignment - unique_ptr& operator=(unique_ptr&& u) - { - reset(u.release()); - ptr_.second() = std::move(u.get_deleter()); - return *this; - } - template - unique_ptr& operator=(unique_ptr&& u) - { - reset(u.release()); - ptr_.second() = std::move(u.get_deleter()); - return *this; - } - unique_ptr& operator=(int nat::*) - { - reset(); - return *this; - } - - // observers - typename tr1::add_reference::type operator*() const {return *ptr_.first();} - pointer operator->() const {return ptr_.first();} - pointer get() const {return ptr_.first();} - D& get_deleter() {return ptr_.second();} - const D& get_deleter() const {return ptr_.second();} - operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} - - // modifiers - pointer release() - { - pointer tmp = ptr_.first(); - ptr_.first() = pointer(); - return tmp; - } - void reset(pointer p = pointer()) - { - if (ptr_.first() != p) - { - if (ptr_.first()) - ptr_.second()(ptr_.first()); - ptr_.first() = p; - } - } - void swap(unique_ptr&& u) {ptr_.swap(u.ptr_);} -private: - detail::compressed_pair ptr_; - - unique_ptr(const unique_ptr&); - template unique_ptr(const unique_ptr&); - unique_ptr& operator=(const unique_ptr&); - template unique_ptr& operator=(const unique_ptr&); -}; - -template -class unique_ptr -{ - struct nat {int for_bool_;}; -public: - typedef T element_type; - typedef D deleter_type; - typedef typename detail::pointer_type::type pointer; - - // constructors - unique_ptr() : ptr_(pointer()) {} - explicit unique_ptr(pointer p) : ptr_(p) {} - unique_ptr(pointer p, typename detail::select< - tr1::is_reference::value, - D, - const D&>::type d) - : ptr_(p, d) {} - unique_ptr(pointer p, typename tr1::remove_reference::type&& d) - : ptr_(p, std::move(d)) - { - static_assert(!tr1::is_reference::value, "rvalue deleter bound to reference"); - } - unique_ptr(unique_ptr&& u) - : ptr_(u.release(), std::forward(u.get_deleter())) {} - - // destructor - ~unique_ptr() {reset();} - - // assignment - unique_ptr& operator=(unique_ptr&& u) - { - reset(u.release()); - ptr_.second() = std::move(u.get_deleter()); - return *this; - } - unique_ptr& operator=(int nat::*) - { - reset(); - return *this; - } - - // observers - typename tr1::add_reference::type operator[](std::size_t i) const {return ptr_.first()[i];} - pointer get() const {return ptr_.first();} - D& get_deleter() {return ptr_.second();} - const D& get_deleter() const {return ptr_.second();} - operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} - - // modifiers - pointer release() - { - pointer tmp = ptr_.first(); - ptr_.first() = pointer(); - return tmp; - } - void reset(pointer p = pointer()) - { - if (ptr_.first() != p) - { - if (ptr_.first()) - ptr_.second()(ptr_.first()); - ptr_.first() = p; - } - } - void swap(unique_ptr&& u) {ptr_.swap(u.ptr_);} -private: - detail::compressed_pair ptr_; - - template unique_ptr(U p, - typename detail::select< - tr1::is_reference::value, - D, - const D&>::type d, - typename detail::restrict_to::value>::type* = 0); - template unique_ptr(U p, typename tr1::remove_reference::type&& d, - typename detail::restrict_to::value>::type* = 0); - template explicit unique_ptr(U, - typename detail::restrict_to::value>::type* = 0); - unique_ptr(const unique_ptr&); - unique_ptr& operator=(const unique_ptr&); -}; - -template -class unique_ptr -{ - struct nat {int for_bool_;}; -public: - typedef T element_type; - typedef D deleter_type; - typedef typename detail::pointer_type::type pointer; - static const std::size_t size = N; - - // constructors - unique_ptr() : ptr_(pointer()) {} - explicit unique_ptr(pointer p) : ptr_(p) {} - unique_ptr(pointer p, typename detail::select< - tr1::is_reference::value, - D, - const D&>::type d) - : ptr_(p, d) {} - unique_ptr(pointer p, typename tr1::remove_reference::type&& d) - : ptr_(p, std::move(d)) - { - static_assert(!tr1::is_reference::value, "rvalue deleter bound to reference"); - } - unique_ptr(unique_ptr&& u) - : ptr_(u.release(), std::forward(u.get_deleter())) {} - - // destructor - ~unique_ptr() {reset();} - - // assignment - unique_ptr& operator=(unique_ptr&& u) - { - reset(u.release()); - ptr_.second() = std::move(u.get_deleter()); - return *this; - } - unique_ptr& operator=(int nat::*) - { - reset(); - return *this; - } - - // observers - typename tr1::add_reference::type operator[](std::size_t i) const {return ptr_.first()[i];} - pointer get() const {return ptr_.first();} - D& get_deleter() {return ptr_.second();} - const D& get_deleter() const {return ptr_.second();} - operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} - - // modifiers - pointer release() - { - pointer tmp = ptr_.first(); - ptr_.first() = pointer(); - return tmp; - } - void reset(pointer p = pointer()) - { - if (ptr_.first() != p) - { - if (ptr_.first()) - ptr_.second()(ptr_.first(), N); - ptr_.first() = p; - } - } - void swap(unique_ptr&& u) {ptr_.swap(u.ptr_);} -private: - detail::compressed_pair ptr_; - - template unique_ptr(U p, - typename detail::select< - tr1::is_reference::value, - D, - const D&>::type d, - typename detail::restrict_to::value>::type* = 0); - template unique_ptr(U p, typename tr1::remove_reference::type&& d, - typename detail::restrict_to::value>::type* = 0); - template explicit unique_ptr(U, - typename detail::restrict_to::value>::type* = 0); - unique_ptr(const unique_ptr&); - unique_ptr& operator=(const unique_ptr&); -}; - -template -inline -void swap(unique_ptr& x, unique_ptr& y) {x.swap(y);} - -template -inline -void swap(unique_ptr&& x, unique_ptr& y) {x.swap(y);} - -template -inline -void swap(unique_ptr& x, unique_ptr&& y) {x.swap(y);} - -template -inline -bool -operator==(const unique_ptr& x, const unique_ptr& y) - {return x.get() == y.get();} - -template -inline -bool -operator!=(const unique_ptr& x, const unique_ptr& y) - {return x.get() != y.get();} - -template -inline -bool -operator <(const unique_ptr& x, const unique_ptr& y) - {return x.get() < y.get();} - -template -inline -bool -operator<=(const unique_ptr& x, const unique_ptr& y) - {return x.get() <= y.get();} - -template -inline -bool -operator >(const unique_ptr& x, const unique_ptr& y) - {return x.get() > y.get();} - -template -inline -bool -operator>=(const unique_ptr& x, const unique_ptr& y) - {return x.get() >= y.get();} - -} // std \ No newline at end of file diff --git a/include/boost/interprocess/streams/stringstream.hpp b/include/boost/interprocess/streams/stringstream.hpp deleted file mode 100644 index a82735a..0000000 --- a/include/boost/interprocess/streams/stringstream.hpp +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (c) 1998 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// -// -// This file comes from SGI's sstream file. Modified by Ion Gaztañaga 2005. -// Changed internal SGI string to a generic, templatized string. Added efficient -// internal buffer get/set/swap functions, so that we can obtain/establish the -// internal buffer without any reallocation or copy. Kill those temporaries! -/////////////////////////////////////////////////////////////////////////////// - -/*!\file - This file defines basic_stringbuf, basic_istringstream, - basic_ostringstream, and basic_stringstreamclasses. These classes - represent streamsbufs and streams whose sources or destinations are - STL-like strings that can be swapped with external strings to avoid - unnecessary allocations/copies. -*/ - -#ifndef BOOST_INTERPROCESS_STRINGSTREAM_HPP -#define BOOST_INTERPROCESS_STRINGSTREAM_HPP - -#include -#include - -#include -#include -#include -#include -#include // char traits -#include // ptrdiff_t -#include -#include - -namespace boost { namespace interprocess { - -/*!A streambuf class that controls the transmission of elements to and from - a basic_istringstream, basic_ostringstream or basic_stringstream. - It holds a character string specified by CharString template parameter - as its formatting buffer. The string must have contiguous storage, like - std::string, boost::interprocess::string or boost::interprocess::basic_string*/ -template -class basic_stringbuf - : public std::basic_streambuf -{ - public: - typedef CharString string_type; - typedef typename CharString::value_type char_type; - typedef typename CharTraits::int_type int_type; - typedef typename CharTraits::pos_type pos_type; - typedef typename CharTraits::off_type off_type; - typedef CharTraits traits_type; - - private: - typedef std::basic_streambuf base_t; - - basic_stringbuf(const basic_stringbuf&); - basic_stringbuf & operator =(const basic_stringbuf&); - - public: - /*!Constructor. Throws if string_type default constructor throws.*/ - explicit basic_stringbuf(std::ios_base::openmode mode - = std::ios_base::in | std::ios_base::out) - : base_t(), m_mode(mode) - { this->set_pointers(); } - - /*!Constructor. Throws if string_type(const VectorParameter ¶m) throws.*/ - template - explicit basic_stringbuf(const VectorParameter ¶m, - std::ios_base::openmode mode - = std::ios_base::in | std::ios_base::out) - : base_t(), m_mode(mode), m_string(param) - { this->set_pointers(); } - - virtual ~basic_stringbuf(){} - - public: - - /*!Swaps the underlying string with the passed string. - This function resets the read/write position in the stream. - Does not throw.*/ - void swap_string(string_type &vect) - { m_string.swap(vect); this->set_pointers(); } - - /*!Returns a const reference to the internal string. - Does not throw.*/ - const string_type &string() const { return m_string; } - - /*!Calls resize() method of the internal string. - Resets the stream to the first position. - Throws if the internals string's resize throws.*/ - void resize(typename string_type::size_type size) - { m_string.resize(size); this->set_pointers(); } - - private: - void set_pointers() - { - // The initial read position is the beginning of the string. - if(m_mode & std::ios_base::in) - this->setg(&m_string[0], &m_string[0], &m_string[m_string.size()]); - - // The initial write position is the beginning of the string. - if(m_mode & std::ios_base::out) - this->setp(&m_string[0], &m_string[m_string.size()]); - } - - protected: - virtual int_type underflow() - { - // Precondition: gptr() >= egptr(). Returns a character, if available. - return this->gptr() != this->egptr() - ? CharTraits::to_int_type(*this->gptr()) - : CharTraits::eof(); - } - - virtual int_type uflow() - { - // Precondition: gptr() >= egptr(). - if(this->gptr() != this->egptr()) { - int_type c = CharTraits::to_int_type(*this->gptr()); - this->gbump(1); - return c; - } - else - return CharTraits::eof(); - } - - virtual int_type pbackfail(int_type c = CharTraits::eof()) - { - if(this->gptr() != this->eback()) { - if(!CharTraits::eq_int_type(c, CharTraits::eof())) { - if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { - this->gbump(-1); - return c; - } - else if(m_mode & std::ios_base::out) { - this->gbump(-1); - *this->gptr() = c; - return c; - } - else - return CharTraits::eof(); - } - else { - this->gbump(-1); - return CharTraits::not_eof(c); - } - } - else - return CharTraits::eof(); - } - - virtual int_type overflow(int_type c = CharTraits::eof()) - { - if(m_mode & std::ios_base::out) { - if(!CharTraits::eq_int_type(c, CharTraits::eof())) { - if(!(m_mode & std::ios_base::in)) { - if(this->pptr() != this->epptr()) { - *this->pptr() = CharTraits::to_char_type(c); - this->pbump(1); - return c; - } - else - return CharTraits::eof(); - } - else { - // We're not using a special append buffer, just the string itself. - if(this->pptr() == this->epptr()) { - std::ptrdiff_t offset = this->gptr() - this->eback(); - m_string.push_back(CharTraits::to_char_type(c)); - this->setg(&m_string[0], &m_string[offset], &m_string[m_string.size()]); - this->setp(&m_string[0], &m_string[m_string.size()]); - this->pbump(static_cast(m_string.size())); - return c; - } - else { - *this->pptr() = CharTraits::to_char_type(c); - this->pbump(1); - return c; - } - } - } - else // c is EOF, so we don't have to do anything - return CharTraits::not_eof(c); - } - else // Overflow always fails if it's read-only. - return CharTraits::eof(); - } - - virtual std::streamsize xsputn(const char_type* s, std::streamsize n) - { - std::streamsize nwritten = 0; - - if((m_mode & std::ios_base::out) && n > 0) { - // If the put pointer is somewhere in the middle of the - // string, then overwrite instead of append. - assert(this->pbase() == &m_string[0]); -// if(this->pbase() == &m_string[0]) { - std::streamsize avail = static_cast( - &m_string[m_string.size()] - this->pptr()); - if(avail > n) { - CharTraits::copy(this->pptr(), s, n); - this->pbump(n); - return n; - } - else if(avail){ - CharTraits::copy(this->pptr(), s, avail); - nwritten += avail; - n -= avail; - s += avail; - } -// } - - // At this point we know we're appending. - if(m_mode & std::ios_base::in) { - std::ptrdiff_t get_offset = this->gptr() - this->eback(); - m_string.insert(m_string.end(), s, s + n); - this->setg(&m_string[0], &m_string[get_offset], &m_string[m_string.size()]); - this->setp(&m_string[0], &m_string[m_string.size()]); - this->pbump(static_cast(m_string.size())); - } - else { - m_string.insert(m_string.end(), s, s + n); - } - nwritten += n; - } - return nwritten; - } - - virtual std::streamsize xsputnc(char_type c, std::streamsize n) - { - std::streamsize nwritten = 0; - - if((m_mode & std::ios_base::out) && n > 0) { - // If the put pointer is somewhere in the middle of the string, - // then overwrite instead of append. - assert(this->pbase() == &m_string[0]); -// if(this->pbase() == &m_string[0]) { - std::streamsize avail = static_cast - (&m_string[m_string.size()] - this->pptr()); - if(avail > n) { - CharTraits::assign(this->pptr(), n, c); - this->pbump(n); - return n; - } - else if(avail){ - CharTraits::assign(this->pptr(), avail, c); - nwritten += avail; - n -= avail; - } -// } - - // At this point we know we're appending. - if(this->m_mode & std::ios_base::in) { - std::streamsize get_offset = static_cast - (this->gptr() - this->eback()); - m_string.insert(m_string.end(), n, c); - this->setg(&m_string[0], &m_string[get_offset], &m_string[m_string.size()]); - this->setp(&m_string[0], &m_string[m_string.size()]); - this->pbump(static_cast(m_string.size())); - } - else { - m_string.insert(m_string.end(), n, c); - } - nwritten += n; - } - - return nwritten; - } - - virtual base_t* setbuf(char_type* buf, std::streamsize n) - { - // According to the C++ standard the effects of setbuf are implementation - // defined, except that setbuf(0, 0) has no effect. In this implementation, - // setbuf(, n), for n > 0, calls resize(n) on the underlying - // string. - if(n > 0) { -// bool do_get_area = false; -// bool do_put_area = false; - std::ptrdiff_t offg = 0; - std::ptrdiff_t offp = 0; - - assert(this->pbase() == &m_string[0]); - //if(this->pbase() == &m_string[0]) { - //do_put_area = true; - offp = this->pptr() - this->pbase(); - //} - - assert(this->eback() == &m_string[0]); - //if(this->eback() == &m_string[0]) { - //do_get_area = true; - offg = this->gptr() - this->eback(); - //} - - m_string.resize(n); - - //if(do_get_area) { - this->setg(&m_string[0], &m_string[offg], &m_string[m_string.size()]); - //} - - //if(do_put_area) { - this->setp(&m_string[0], &m_string[m_string.size()]); - this->pbump(static_cast(offp)); - //} - } - return this; - } - - virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, - std::ios_base::openmode mode - = std::ios_base::in | std::ios_base::out) - { - bool in = false; - bool out = false; - - const std::ios_base::openmode inout = - std::ios_base::in | std::ios_base::out; - - if((mode & inout) == inout) { - if(dir == std::ios_base::beg || dir == std::ios_base::end) - in = out = true; - } - else if(mode & std::ios_base::in) - in = true; - else if(mode & std::ios_base::out) - out = true; - - if(!in && !out) - return pos_type(off_type(-1)); - else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) || - (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0))) - return pos_type(off_type(-1)); - - std::streamoff newoff; - switch(dir) { - case std::ios_base::beg: - newoff = 0; - break; - case std::ios_base::end: - newoff = static_cast(m_string.size()); - break; - case std::ios_base::cur: - newoff = in ? static_cast(this->gptr() - this->eback()) - : static_cast(this->pptr() - this->pbase()); - break; - default: - return pos_type(off_type(-1)); - } - - off += newoff; - - if(in) { - std::ptrdiff_t n = this->egptr() - this->eback(); - - if(off < 0 || off > n) - return pos_type(off_type(-1)); - else - this->setg(this->eback(), this->eback() + off, this->eback() + n); - } - - if(out) { - std::ptrdiff_t n = this->epptr() - this->pbase(); - - if(off < 0 || off > n) - return pos_type(off_type(-1)); - else { - this->setp(this->pbase(), this->pbase() + n); - this->pbump(off); - } - } - return pos_type(off); - } - - virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode - = std::ios_base::in | std::ios_base::out) - { - bool in = (mode & std::ios_base::in) != 0; - bool out = (mode & std::ios_base::out) != 0; - - if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) || - (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0))) - return pos_type(off_type(-1)); - - const off_type n = pos - pos_type(off_type(0)); - - if(in) { - if(n < 0 || n > this->egptr() - this->eback()) - return pos_type(off_type(-1)); - this->setg(this->eback(), this->eback() + n, this->egptr()); - } - - if(out) { - if(n < 0 || n > off_type(m_string.size())) - return pos_type(off_type(-1)); - this->setp(&m_string[0], &m_string[m_string.size()]); - this->pbump(n); - } - return pos; - } - - private: - std::ios_base::openmode m_mode; - string_type m_string; -}; - -/*!A basic_istream class that holds a character string specified by CharString - template parameter as its formatting buffer. The string must have - contiguous storage, like std::string, boost::interprocess::string or - boost::interprocess::basic_string*/ -template -class basic_istringstream -: public std::basic_istream -{ - public: - typedef CharString string_type; - typedef typename std::basic_ios - ::char_type char_type; - typedef typename std::basic_ios::int_type int_type; - typedef typename std::basic_ios::pos_type pos_type; - typedef typename std::basic_ios::off_type off_type; - typedef typename std::basic_ios::traits_type traits_type; - - private: - typedef std::basic_ios basic_ios_t; - typedef std::basic_istream base_t; - - public: - /*!Constructor. Throws if string_type default constructor throws.*/ - basic_istringstream(std::ios_base::openmode mode = std::ios_base::in) - : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::in) - { basic_ios_t::init(&m_buf); } - - /*!Constructor. Throws if string_type(const VectorParameter ¶m) throws.*/ - template - basic_istringstream(const VectorParameter ¶m, - std::ios_base::openmode mode = std::ios_base::in) - : basic_ios_t(), base_t(0), - m_buf(param, mode | std::ios_base::in) - { basic_ios_t::init(&m_buf); } - - ~basic_istringstream(){}; - - public: - /*!Returns the address of the stored stream buffer.*/ - basic_stringbuf* rdbuf() const - { return const_cast*>(&m_buf); } - - /*!Swaps the underlying string with the passed string. - This function resets the read position in the stream. - Does not throw.*/ - void swap_string(string_type &vect) - { m_buf.swap_string(vect); } - - /*!Returns a const reference to the internal string. - Does not throw.*/ - const string_type &string() const - { return m_buf.string(); } - - /*!Calls resize() method of the internal string. - Resets the stream to the first position. - Throws if the internals string's resize throws.*/ - void resize(typename string_type::size_type size) - { m_buf.resize(size); } - - private: - basic_stringbuf m_buf; -}; - -/*!A basic_ostream class that holds a character string specified by CharString - template parameter as its formatting buffer. The string must have - contiguous storage, like std::string, boost::interprocess::string or - boost::interprocess::basic_string*/ -template -class basic_ostringstream - : public std::basic_ostream -{ - public: - typedef CharString string_type; - typedef typename std::basic_ios - ::char_type char_type; - typedef typename std::basic_ios::int_type int_type; - typedef typename std::basic_ios::pos_type pos_type; - typedef typename std::basic_ios::off_type off_type; - typedef typename std::basic_ios::traits_type traits_type; - - private: - typedef std::basic_ios basic_ios_t; - typedef std::basic_ostream base_t; - - public: - /*!Constructor. Throws if string_type default constructor throws.*/ - basic_ostringstream(std::ios_base::openmode mode = std::ios_base::out) - : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::out) - { basic_ios_t::init(&m_buf); } - - /*!Constructor. Throws if string_type(const VectorParameter ¶m) throws.*/ - template - basic_ostringstream(const VectorParameter ¶m, - std::ios_base::openmode mode = std::ios_base::out) - : basic_ios_t(), base_t(0), m_buf(param, mode | std::ios_base::out) - { basic_ios_t::init(&m_buf); } - - ~basic_ostringstream(){} - - public: - /*!Returns the address of the stored stream buffer.*/ - basic_stringbuf* rdbuf() const - { return const_cast*>(&m_buf); } - - /*!Swaps the underlying string with the passed string. - This function resets the write position in the stream. - Does not throw.*/ - void swap_string(string_type &vect) - { m_buf.swap_string(vect); } - - /*!Returns a const reference to the internal string. - Does not throw.*/ - const string_type &string() const - { return m_buf.string(); } - - /*!Calls resize() method of the internal string. - Resets the stream to the first position. - Throws if the internals string's resize throws.*/ - void resize(typename string_type::size_type size) - { m_buf.resize(size); } - - private: - basic_stringbuf m_buf; -}; - - -/*!A basic_iostream class that holds a character string specified by CharString - template parameter as its formatting buffer. The string must have - contiguous storage, like std::string, boost::interprocess::string or - boost::interprocess::basic_string*/ -template -class basic_stringstream -: public std::basic_iostream - -{ - public: - typedef CharString string_type; - typedef typename std::basic_ios - ::char_type char_type; - typedef typename std::basic_ios::int_type int_type; - typedef typename std::basic_ios::pos_type pos_type; - typedef typename std::basic_ios::off_type off_type; - typedef typename std::basic_ios::traits_type traits_type; - - private: - typedef std::basic_ios basic_ios_t; - typedef std::basic_iostream base_t; - - public: - /*!Constructor. Throws if string_type default constructor throws.*/ - basic_stringstream(std::ios_base::openmode mode - = std::ios_base::in | std::ios_base::out) - : basic_ios_t(), base_t(0), m_buf(mode) - { basic_ios_t::init(&m_buf); } - - /*!Constructor. Throws if string_type(const VectorParameter ¶m) throws.*/ - template - basic_stringstream(const VectorParameter ¶m, std::ios_base::openmode mode - = std::ios_base::in | std::ios_base::out) - : basic_ios_t(), base_t(0), m_buf(param, mode) - { basic_ios_t::init(&m_buf); } - - ~basic_stringstream(){} - - public: - //Returns the address of the stored stream buffer. - basic_stringbuf* rdbuf() const - { return const_cast*>(&m_buf); } - - /*!Swaps the underlying string with the passed string. - This function resets the read/write position in the stream. - Does not throw.*/ - void swap_string(string_type &vect) - { m_buf.swap_string(vect); } - - /*!Returns a const reference to the internal string. - Does not throw.*/ - const string_type &string() const - { return m_buf.string(); } - - /*!Calls resize() method of the internal string. - Resets the stream to the first position. - Throws if the internals string's resize throws.*/ - void resize(typename string_type::size_type size) - { m_buf.resize(size); } - - private: - basic_stringbuf m_buf; -}; - -//Some typedefs to simplify usage -/* -typedef basic_stringbuf > stringbuf; -typedef basic_stringstream > stringstream; -typedef basic_istringstream > istringstream; -typedef basic_ostringstream > ostringstream; - -typedef basic_stringbuf > wstringbuf; -typedef basic_stringstream > wstringstream; -typedef basic_istringstream > wistringstream; -typedef basic_ostringstream > wostringstream; -*/ -}} //namespace boost { namespace interprocess { - -#include - -#endif /* BOOST_INTERPROCESS_STRINGSTREAM_HPP */ diff --git a/include/boost/interprocess/sync/interprocess_sharable_mutex.hpp b/include/boost/interprocess/sync/interprocess_sharable_mutex.hpp deleted file mode 100644 index e12b950..0000000 --- a/include/boost/interprocess/sync/interprocess_sharable_mutex.hpp +++ /dev/null @@ -1,1271 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess/ for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_INTERPROCESS_SHARABLE_MUTEX_HPP -#define BOOST_INTERPROCESS_SHARABLE_MUTEX_HPP - -#if (defined _MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { - -namespace interprocess { - -/*!An object of class shared_read_write_mutex is a read_write_mutex that - can be placed in shared memory so that it can be used to synchronize - threads of different processes.*/ -class interprocess_sharable_mutex -{ - public: - - enum sharable_mutex_policy - { -// system_default, //The default behavior of the system - sharable_priority, //Prefer readers; can starve writers - exclusive_priority, //Prefer writers; can starve readers - no_priority, - max_priority - // rw_alternating_many_reads, //Alternate readers and writers; before a writer, release all queued readers - // rw_alternating_single_read //Alternate readers and writers; before a writer, release only on queued reader - }; - - interprocess_sharable_mutex(sharable_mutex_policy policy = sharable_priority) - : m_policy (policy) - { this->priv_init(); } - - ~interprocess_sharable_mutex() - { this->priv_fini(); } - - void lock_sharable() - { this->priv_sharable_lock(false, 0); } - - bool try_lock_sharable() - { return this->priv_sharable_lock(true, 0); } - - bool timed_lock_sharable(const boost::posix_time::ptime &pt) - { return this->priv_sharable_lock(true, &pt); } - - void unlock_sharable() - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - { - se_priority_t *const m = this->priv_members(); - scoped_lock lock(m->mut); - --m->shared_active; - if(m->shared_active == 0 && m->exclusive_waiting > 0){ - m->exclusive_cond.notify_one(); - } - } - break; - case no_priority: - priv_alt_priority_unlock(); - break; - default: - assert(0); - } - } - - void lock() - { this->priv_lock(false, 0); } - - bool try_lock() - { return this->priv_lock(true, 0); } - - bool timed_lock(const boost::posix_time::ptime &pt) - { return this->priv_lock(true, &pt); } - - void unlock() - { - switch(m_policy){ - case sharable_priority: - { - se_priority_t *const m = this->priv_members(); - scoped_lock lock(m->mut); - m->exclusive_active = 0; - if(m->shared_waiting > 0){ - m->shared_cond.notify_all(); - } - else if (m->exclusive_waiting > 0){ - m->exclusive_cond.notify_one(); - } - } - break; - case exclusive_priority: - { - se_priority_t *const m = this->priv_members(); - scoped_lock lock(m->mut); - m->exclusive_active = 0; - if(m->exclusive_waiting > 0){ - m->exclusive_cond.notify_one(); - } - else if (m->shared_waiting > 0){ - m->shared_cond.notify_all(); - } - } - break; - case no_priority: - priv_alt_priority_unlock(); - break; - default: - assert(0); - } - } - - sharable_mutex_policy get_policy() const - { return m_policy; } - - private: - - //Anti-exception RAII - struct counter_decrementer - { - counter_decrementer(std::size_t &count) - : m_count(count){} - ~counter_decrementer() - { --m_count; } - std::size_t &m_count; - }; - - struct a_priority_wlock_rollback - { - a_priority_wlock_rollback(interprocess_sharable_mutex *lock) - : m_lock(lock){} - - ~a_priority_wlock_rollback() - { - if(m_lock){ - no_priority_t *const m = m_lock->priv_members(); - m->shared_count = -m->completed_shared_count; - m->completed_shared_count = 0; - } - } - - void release(){ m_lock = 0; } - - private: - interprocess_sharable_mutex *m_lock; - }; - - bool priv_sharable_lock(bool timed, const boost::posix_time::ptime *pt) - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - { - se_priority_t *const m = this->priv_members(); - scoped_lock lock(m->mut); - if(m->exclusive_active && !this->priv_se_priority_s_wait(lock, timed, pt)){ - return false; - } - ++m->shared_active; - } - break; - case exclusive_priority: - { - se_priority_t *const m = this->priv_members(); - scoped_lock lock(m->mut); - if((m->exclusive_active || m->exclusive_waiting > 0) && - !this->priv_se_priority_s_wait(lock, timed, pt)){ - return false; - } - ++m->shared_active; - } - break; - - case no_priority: - { - no_priority_t *const m = this->priv_members(); - scoped_lock lock(m->exclusive_mutex, dont_lock); - - if(!this->priv_locking(lock, timed, pt)){ - return false; - } - - if(++m->shared_count == INT_MAX){ - scoped_lock lock(m->shared_mutex, *pt); - if(!lock.locked()){ - ++m->completed_shared_count; - return false; - } - m->shared_count -= m->completed_shared_count; - m->completed_shared_count = 0; - } - return true; - } - break; - default: - assert(0); - return false; - } - return true; - } - - bool priv_lock(bool timed, const boost::posix_time::ptime *pt) - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - { - se_priority_t *const m = this->priv_members(); - scoped_lock lock(m->mut); - if((m->exclusive_active || m->shared_active > 0) && - !this->priv_se_priority_e_wait(lock, timed, pt)){ - return false; - } - m->exclusive_active = 1; - } - break; - - case no_priority: - { - no_priority_t *const m = this->priv_members(); - - //Initialize scoped locks - scoped_lock lock_exclusive(m->exclusive_mutex, dont_lock); - scoped_lock lock_shared (m->shared_mutex, dont_lock); - - if(!this->priv_locking(lock_exclusive, timed, pt))return false; - if(!this->priv_locking(lock_shared, timed, pt))return false; - - if(m->exclusive_count == 0){ - if(m->completed_shared_count > 0){ - m->shared_count -= m->completed_shared_count; - m->completed_shared_count = 0; - } - if(m->shared_count > 0){ - //This logic is for timed a infinite waits - m->completed_shared_count = -m->shared_count; - a_priority_wlock_rollback rollback(this); - - do{ - if(!this->priv_waiting - (lock_shared, m->shared_cond, timed, pt)){ - m->shared_count = 0; - return false; - } - }while (m->completed_shared_count < 0); - - m->shared_count = 0; - rollback.release(); - } - } - - ++m->exclusive_count; - //Let mutexes locked - lock_exclusive.release(); - lock_shared.release(); - } - default: - return false; - } - return true; - } - - bool priv_se_priority_s_wait(scoped_lock &lock, bool timed, const boost::posix_time::ptime *pt) - { - se_priority_t *const m = this->priv_members(); - //We should block - ++m->shared_waiting; - counter_decrementer decrementer(m->shared_waiting); - do{ - if(!this->priv_waiting(lock, m->shared_cond, timed, pt)) - return false; - }while(m->exclusive_active); - return true; - } - - bool priv_se_priority_e_wait(scoped_lock &lock, bool timed, const boost::posix_time::ptime *pt) - { - se_priority_t *const m = this->priv_members(); - //We should block - ++m->exclusive_waiting; - counter_decrementer decrementer(m->exclusive_waiting); - do{ - if(!this->priv_waiting(lock, m->exclusive_cond, timed, pt)){ - return false; - } - }while(m->exclusive_active || m->shared_active > 0); - return true; - } - - void priv_alt_priority_unlock() - { - no_priority_t *const m = this->priv_members(); - if (m->exclusive_count == 0){ - scoped_lock lock(m->shared_mutex); - if(++m->completed_shared_count == 0) { - m->shared_cond.notify_one(); - } - } - else{ - --m->exclusive_count; - m->shared_mutex.unlock(); - m->exclusive_mutex.unlock(); - } - } - - private: - - bool priv_locking(scoped_lock &lock, - bool timed, - const boost::posix_time::ptime *pt) - { - return timed ? (!pt ? lock.try_lock() : lock.timed_lock(*pt)) - : (lock.lock(), true); - } - - bool priv_waiting(scoped_lock &lock, - interprocess_condition &cond, - bool timed, - const boost::posix_time::ptime *pt) - { - return timed ? (!pt ? false : cond.timed_wait(lock, *pt)) - : (cond.wait(lock), true); - } - - struct se_priority_t - { - se_priority_t() - : mut(), shared_cond(), exclusive_cond() - , shared_active(0), shared_waiting(0) - , exclusive_active(0), exclusive_waiting(0) - {} - - interprocess_mutex mut; - interprocess_condition shared_cond; - interprocess_condition exclusive_cond; - std::size_t shared_active; - std::size_t shared_waiting; - std::size_t exclusive_active; - std::size_t exclusive_waiting; - }; - - struct no_priority_t - { - no_priority_t() - : exclusive_mutex(), shared_mutex(), shared_cond() - , completed_shared_count(0), shared_count(0), exclusive_count(0) - {} - - //shared by all methods - interprocess_mutex exclusive_mutex; - interprocess_mutex shared_mutex; - interprocess_condition shared_cond; - int completed_shared_count; - int shared_count; - int exclusive_count; - }; - - //Let's make a smart "union" type - typedef boost::mpl::vector types; - //Let's get the size of the "union" - typedef boost::mpl::max_element - - > >::type iter; - //This is the instance of the variant - typedef boost::aligned_storage - ::type::value>::type raw_data_t; - - template - const T * const priv_members() const - { return static_cast(static_cast(&m_raw)); } - - template - T * const priv_members() - { return static_cast(static_cast(&m_raw)); } - - void priv_init() - { - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - new (&m_raw)se_priority_t(); - break; - case no_priority: - new (&m_raw)no_priority_t(); - break; - default: - { throw interprocess_exception(error_info(bad_sharable_lock)); } - } - } - - void priv_fini() - { - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - this->priv_members()->~se_priority_t(); - break; - case no_priority: - this->priv_members()->~no_priority_t(); - break; - default: - //This sharable lock type is unknown - assert(0); - } - } - - const sharable_mutex_policy m_policy; - raw_data_t m_raw; -}; - -/* -class interprocess_sharable_mutex -{ - public: - - enum sharable_mutex_policy - { - sharable_priority, //Prefer readers; can starve writers - exclusive_priority, //Prefer writers; can starve readers - no_priority, - max_priority - // rw_alternating_many_reads, //Alternate readers and writers; before a writer, release all queued readers - // rw_alternating_single_read //Alternate readers and writers; before a writer, release only on queued reader - }; - - interprocess_sharable_mutex(sharable_mutex_policy policy = sharable_priority) - : m_policy (policy) - { this->init(); } - - ~interprocess_sharable_mutex() - { this->fini(); } - - void lock_sharable() - { this->do_sharable_lock(false, 0); } - - bool try_lock_sharable() - { return this->do_sharable_lock(true, 0); } - - bool timed_lock_sharable(const boost::posix_time::ptime &pt) - { return this->do_sharable_lock(true, &pt); } - - void unlock_sharable() - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - { - se_priority_t *const m = this->get_se_priority_t(); - scoped_lock lock(m->interprocess_mutex); - --m->shared_active; - if(m->shared_active == 0 && m->exclusive_waiting > 0){ - m->exclusive_cond.notify_one(); - } - } - break; - case no_priority: - do_alt_priority_unlock(); - break; - default: - assert(0); - } - } - - void lock() - { this->do_lock(false, 0); } - - bool try_lock() - { return this->do_lock(true, 0); } - - bool timed_lock(const boost::posix_time::ptime &pt) - { return this->do_lock(true, &pt); } - - void unlock() - { - switch(m_policy){ - case sharable_priority: - { - se_priority_t *const m = this->get_se_priority_t(); - scoped_lock lock(m->interprocess_mutex); - m->exclusive_active = 0; - if(m->shared_waiting > 0){ - m->shared_cond.notify_all(); - } - else if (m->exclusive_waiting > 0){ - m->exclusive_cond.notify_one(); - } - } - break; - case exclusive_priority: - { - se_priority_t *const m = this->get_se_priority_t(); - scoped_lock lock(m->interprocess_mutex); - m->exclusive_active = 0; - if(m->exclusive_waiting > 0){ - m->exclusive_cond.notify_one(); - } - else if (m->shared_waiting > 0){ - m->shared_cond.notify_all(); - } - } - break; - case no_priority: - do_alt_priority_unlock(); - break; - default: - assert(0); - } - } - - sharable_mutex_policy get_policy() const - { return m_policy; } - - private: - - //Anti-exception RAII - struct counter_decrementer - { - counter_decrementer(std::size_t &count) - : m_count(count){} - ~counter_decrementer() - { --m_count; } - std::size_t &m_count; - }; - - struct a_priority_wlock_rollback - { - a_priority_wlock_rollback(interprocess_sharable_mutex *lock) - : m_lock(lock){} - - ~a_priority_wlock_rollback() - { - if(m_lock){ - no_priority_t *const m = m_lock->get_members(); - m->shared_count = -m->completed_shared_count; - m->completed_shared_count = 0; - } - } - - void release(){ m_lock = 0; } - - private: - interprocess_sharable_mutex *m_lock; - }; - - bool do_sharable_lock(bool timed, const boost::posix_time::ptime *pt) - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - { - se_priority_t *const m = this->get_se_priority_t(); - scoped_lock lock(m->interprocess_mutex); - if(m->exclusive_active && !this->do_se_priority_s_wait(lock, timed, pt)){ - return false; - } - ++m->shared_active; - } - break; - case exclusive_priority: - { - se_priority_t *const m = this->get_se_priority_t(); - scoped_lock lock(m->interprocess_mutex); - if((m->exclusive_active || m->exclusive_waiting > 0) && - !this->do_se_priority_s_wait(lock, timed, pt)){ - return false; - } - ++m->shared_active; - } - break; - - case no_priority: - { - no_priority_t *const m = this->get_members(); - if(timed && !pt){ - scoped_lock lock(m->exclusive_mutex, try_to_lock); - if(!lock.locked()) return false; - - if(++m->shared_count == INT_MAX){ - //Is better to throw in this case? - //m->shared_mutex.do_lock(); - scoped_lock lock(m->shared_mutex); - m->shared_count -= m->completed_shared_count; - m->completed_shared_count = 0; - } - } - else if(timed){ - scoped_lock lock(m->exclusive_mutex, *pt); - if(!lock.locked()){ - return false; - } - if(++m->shared_count == INT_MAX){ - //Is better to throw in this case? - //m->shared_mutex.do_lock(); - scoped_lock lock(m->shared_mutex, *pt); - if(!lock.locked()){ - ++m->completed_shared_count; - return false; - } - m->shared_count -= m->completed_shared_count; - m->completed_shared_count = 0; - return true; - } - } - else{ - scoped_lock lock(m->exclusive_mutex); - if(++m->shared_count == INT_MAX){ - //Is better to throw in this case? - //m->shared_mutex.do_lock(); - scoped_lock lock(m->shared_mutex); - m->shared_count -= m->completed_shared_count; - m->completed_shared_count = 0; - return true; - } - } - } - break; - default: - assert(0); - return false; - } - return true; - } - - bool do_lock(bool timed, const boost::posix_time::ptime *pt) - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - { - se_priority_t *const m = this->get_se_priority_t(); - scoped_lock lock(m->interprocess_mutex); - if((m->exclusive_active || m->shared_active > 0) && - !this->do_se_priority_e_wait(lock, timed, pt)){ - return false; - } - m->exclusive_active = 1; - } - break; - - case no_priority: - { - no_priority_t *const m = this->get_members(); - //Initialize scoped locks - scoped_lock lock_exclusive(m->exclusive_mutex, dont_lock); - scoped_lock lock_shared (m->shared_mutex, dont_lock); - - //Do initialization depending on lock type - if(timed && !pt){ - if(!lock_exclusive.try_lock())return false; - if(!lock_shared.try_lock()) return false; - } - else if(timed){ - if(!lock_exclusive.timed_lock(*pt))return false; - if(!lock_shared.timed_lock(*pt)) return false; - } - else{ - lock_exclusive.lock(); - lock_shared.lock(); - } - - if(m->exclusive_count == 0){ - if(m->completed_shared_count > 0){ - m->shared_count -= m->completed_shared_count; - m->completed_shared_count = 0; - } - if(m->shared_count > 0){ - //This logic is for timed a infinite waits - m->completed_shared_count = -m->shared_count; - a_priority_wlock_rollback rollback(this); - - do{ - if(timed && !pt){ - m->shared_count = 0; - return false; - } - else if(timed){ - if(!m->shared_cond.timed_wait(lock_shared, *pt)){ - m->shared_count = 0; - return false; - } - } - else{ - m->shared_cond.wait(lock_shared); - } - }while (m->completed_shared_count < 0); - - m->shared_count = 0; - rollback.release(); - } - } - - ++m->exclusive_count; - //Let mutexes locked - lock_exclusive.release(); - lock_shared.release(); - return true; - } - break; - default: - assert(0); - return false; - } - return true; - } - - bool do_se_priority_s_wait(scoped_lock &lock, bool timed, const boost::posix_time::ptime *pt) - { - if(timed && !pt) return false; - se_priority_t *const m = this->get_se_priority_t(); - //We should block - ++m->shared_waiting; - counter_decrementer decrementer(m->shared_waiting); - do{ - if(timed){ - if(!m->shared_cond.timed_wait(lock, *pt)) - return false; - } - else{ - m->shared_cond.wait(lock); - } - }while(m->exclusive_active); - return true; - } - - bool do_se_priority_e_wait(scoped_lock &lock, bool timed, const boost::posix_time::ptime *pt) - { - if(timed && !pt) return false; - se_priority_t *const m = this->get_se_priority_t(); - //We should block - ++m->exclusive_waiting; - counter_decrementer decrementer(m->exclusive_waiting); - do{ - if(timed && !m->exclusive_cond.timed_wait(lock, *pt)){ - return false; - } - else{ - m->exclusive_cond.wait(lock); - } - }while(m->exclusive_active || m->shared_active > 0); - return true; - } - - void do_alt_priority_unlock() - { - no_priority_t *const m = this->get_members(); - if (m->exclusive_count == 0){ - scoped_lock lock(m->shared_mutex); - if(++m->completed_shared_count == 0) { - m->shared_cond.notify_one(); - } - } - else{ - --m->exclusive_count; - m->shared_mutex.unlock(); - m->exclusive_mutex.unlock(); - } - } - - private: - - struct se_priority_t - { - se_priority_t() - : shared_active(0), shared_waiting(0), - exclusive_waiting(0),exclusive_active(0) - {} - - interprocess_mutex interprocess_mutex; - interprocess_condition shared_cond; - interprocess_condition exclusive_cond; - std::size_t shared_active; - std::size_t shared_waiting; - std::size_t exclusive_active; - std::size_t exclusive_waiting; - }; - - struct no_priority_t - { - no_priority_t() - : completed_shared_count(0), shared_count(0), exclusive_count(0) - {} - - //shared by all methods - interprocess_mutex exclusive_mutex; - interprocess_mutex shared_mutex; - interprocess_condition shared_cond; - int completed_shared_count; - int shared_count; - int exclusive_count; - }; - - typedef boost::mpl::vector types; - typedef boost::mpl::max_element - - > >::type iter; - - typedef boost::aligned_storage - ::type::value>::type raw_data_t; - - const se_priority_t *get_se_priority_t() const - { return static_cast(static_cast(&m_raw)); } - - se_priority_t *get_se_priority_t() - { return static_cast(static_cast(&m_raw)); } - - const no_priority_t *get_members() const - { return static_cast(static_cast(&m_raw)); } - - no_priority_t *get_members() - { return static_cast(static_cast(&m_raw)); } - - void init() - { - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - new (&m_raw)se_priority_t(); - break; - case no_priority: - new (&m_raw)no_priority_t(); - break; - default: - { throw interprocess_exception(error_info(bad_sharable_lock)); } - } - } - - void fini() - { - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - this->get_se_priority_t()->~se_priority_t(); - break; - case no_priority: - this->get_members()->~no_priority_t(); - break; - default: - //This sharable lock type is unknown - assert(0); - } - } - - const sharable_mutex_policy m_policy; - raw_data_t m_raw; -}; -*/ -/* -class interprocess_sharable_mutex -{ - public: - - enum sharable_mutex_policy - { - sharable_priority, //Prefer readers; can starve writers - exclusive_priority, //Prefer writers; can starve readers - no_priority, - max_priority - // rw_alternating_many_reads, //Alternate readers and writers; before a writer, release all queued readers - // rw_alternating_single_read //Alternate readers and writers; before a writer, release only on queued reader - }; - - interprocess_sharable_mutex(sharable_mutex_policy policy = sharable_priority) - : m_policy (policy), - m_r_active_completed_shared_count(0), m_r_wait_shared_count(0), m_w_wait_exclusive_count(0), m_w_active(0), - m_completed_shared_count(0), m_shared_count(0), m_exclusive_count(0) - {} - - ~interprocess_sharable_mutex() - {} - - void lock_sharable() - { this->do_sharable_lock(false, 0); } - - bool try_lock_sharable() - { return this->do_sharable_lock(true, 0); } - - bool timed_lock_sharable(const boost::posix_time::ptime &pt) - { return this->do_sharable_lock(true, &pt); } - - void unlock_sharable() - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - { - scoped_lock lock(m_mutex_exclusive_mutex); - --m_r_active_completed_shared_count; - if(m_r_active_completed_shared_count == 0 && m_w_wait_exclusive_count > 0){ - exclusive_cond.notify_one(); - } - } - break; - case no_priority: - { - do_alt_priority_unlock(); - } - break; - default: - assert(0); - } - } - - void lock() - { this->do_lock(false, 0); } - - bool try_lock() - { return this->do_lock(true, 0); } - - bool timed_lock(const boost::posix_time::ptime &pt) - { return this->do_lock(true, &pt); } - - void unlock() - { - switch(m_policy){ - case sharable_priority: - { - scoped_lock lock(m_mutex_exclusive_mutex); - m_w_active = 0; - if(m_r_wait_shared_count > 0){ - m_reader_shared_cond.notify_all(); - } - else if (m_w_wait_exclusive_count > 0){ - exclusive_cond.notify_one(); - } - } - break; - case exclusive_priority: - { - scoped_lock lock(m_mutex_exclusive_mutex); - m_w_active = 0; - if(m_w_wait_exclusive_count > 0){ - exclusive_cond.notify_one(); - } - else if (m_r_wait_shared_count > 0){ - m_reader_shared_cond.notify_all(); - } - } - break; - case no_priority: - do_alt_priority_unlock(); - break; - default: - assert(0); - } - } - - sharable_mutex_policy get_policy() const - { return m_policy; } - - private: - - //Anti-exception RAII - struct counter_decrementer - { - counter_decrementer(std::size_t &count) - : m_count(count){} - ~counter_decrementer() - { --m_count; } - std::size_t &m_count; - }; - - struct a_priority_wlock_rollback - { - a_priority_wlock_rollback(interprocess_sharable_mutex *lock) - : m_lock(lock){} - - ~a_priority_wlock_rollback() - { - if(m_lock){ - m_lock->m_shared_count = -m_lock->m_completed_shared_count; - m_lock->m_completed_shared_count = 0; - } - } - - void release(){ m_lock = 0; } - - private: - interprocess_sharable_mutex *m_lock; - }; - - - bool do_sharable_lock(bool timed, const boost::posix_time::ptime *pt) - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - { - scoped_lock lock(m_mutex_exclusive_mutex); - if(m_w_active && !this->do_se_priority_s_wait(lock, timed, pt)){ - return false; - } - ++m_r_active_completed_shared_count; - } - break; - case exclusive_priority: - { - scoped_lock lock(m_mutex_exclusive_mutex); - if((m_w_active || m_w_wait_exclusive_count > 0) && - !this->do_se_priority_s_wait(lock, timed, pt)){ - return false; - } - ++m_r_active_completed_shared_count; - } - break; - - case no_priority: - { - if(timed && !pt){ - scoped_lock lock - (m_mutex_exclusive_mutex, try_to_lock); - if(!lock.locked()) return false; - - if(++m_shared_count == INT_MAX){ - //Is better to throw in this case? - //m_mutex_shared_completed.do_lock(); - scoped_lock lock(m_mutex_shared_completed); - m_shared_count -= m_completed_shared_count; - m_completed_shared_count = 0; - } - } - else if(timed){ - scoped_lock lock - (m_mutex_exclusive_mutex, *pt); - if(!lock.locked()) return false; - if(++m_shared_count == INT_MAX){ - //Is better to throw in this case? - //m_mutex_shared_completed.do_lock(); - scoped_lock lock - (m_mutex_shared_completed, *pt); - if(!lock.locked()){ - ++m_completed_shared_count; - return false; - } - m_shared_count -= m_completed_shared_count; - m_completed_shared_count = 0; - return true; - } - } - else{ - scoped_lock lock - (m_mutex_exclusive_mutex); - if(++m_shared_count == INT_MAX){ - //Is better to throw in this case? - //m_mutex_shared_completed.do_lock(); - scoped_lock lock - (m_mutex_shared_completed); - m_shared_count -= m_completed_shared_count; - m_completed_shared_count = 0; - return true; - } - } - } - break; - default: - assert(0); - return false; - } - return true; - } - - bool do_lock(bool timed, const boost::posix_time::ptime *pt) - { - assert(m_policy < max_priority); - switch(m_policy){ - case sharable_priority: - case exclusive_priority: - { - scoped_lock lock(m_mutex_exclusive_mutex); - if((m_w_active || m_r_active_completed_shared_count > 0) && - !this->do_se_priority_e_wait(lock, timed, pt)){ - return false; - } - m_w_active = 1; - } - break; - - case no_priority: - { - //Initialize scoped locks - scoped_lock lock_exclusive - (m_mutex_exclusive_mutex, dont_lock); - scoped_lock lock_shared - (m_mutex_shared_completed, dont_lock); - //Do initialization depending on lock type - if(timed && !pt){ - if(!lock_exclusive.try_lock())return false; - if(!lock_shared.try_lock()) return false; - } - else if(timed){ - if(!lock_exclusive.timed_lock(*pt))return false; - if(!lock_shared.timed_lock(*pt)) return false; - } - else{ - lock_exclusive.lock(); - lock_shared.lock(); - } - //Now do common logic - if(!do_alt_priority_e_wait(lock_shared, timed, pt)) - return false; - //We left the mutexes locked - lock_shared.release(); - lock_exclusive.release(); - return true; - } - break; - default: - assert(0); - return false; - } - return true; - } - - bool do_se_priority_s_wait(scoped_lock &lock, bool timed, const boost::posix_time::ptime *pt) - { - if(timed && !pt) return false; - //We should block - ++m_r_wait_shared_count; - counter_decrementer decrementer(m_r_wait_shared_count); - do{ - if(timed){ - if(!m_reader_shared_cond.timed_wait(lock, *pt)) - return false; - } - else{ - m_reader_shared_cond.wait(lock); - } - }while(m_w_active); - return true; - } - - bool do_se_priority_e_wait(scoped_lock &lock, bool timed, const boost::posix_time::ptime *pt) - { - if(timed && !pt) return false; - //We should block - ++m_w_wait_exclusive_count; - counter_decrementer decrementer(m_w_wait_exclusive_count); - do{ - if(timed && !exclusive_cond.timed_wait(lock, *pt)){ - return false; - } - else{ - exclusive_cond.wait(lock); - } - }while(m_w_active || m_r_active_completed_shared_count > 0); - return true; - } - - bool do_alt_priority_e_wait(scoped_lock &lock_shared, bool timed, const boost::posix_time::ptime *pt) - { - //This would be a try lock - if(timed && !pt) return false; - - if(m_exclusive_count == 0){ - if(m_completed_shared_count > 0){ - m_shared_count -= m_completed_shared_count; - m_completed_shared_count = 0; - } - if(m_shared_count > 0){ - //This logic is for timed a infinite waits - m_completed_shared_count = -m_shared_count; - a_priority_wlock_rollback rollback(this); - do{ - if(timed){ - if(!m_reader_shared_cond.timed_wait(lock_shared, *pt)){ - return false; - } - } - else{ - m_reader_shared_cond.wait(lock_shared); - } - }while (m_completed_shared_count < 0); - m_shared_count = 0; - rollback.release(); - } - } -// else{ -// //Is this case correct? -// lock_shared.release(); -// lock_exclusive.release(); -// return false; -// } - - ++m_exclusive_count; - return true; - } - - void do_alt_priority_unlock() - { - if (m_exclusive_count == 0){ - scoped_lock lock(m_mutex_exclusive_mutex); - if(++m_completed_shared_count == 0) { - m_reader_shared_cond.notify_one(); - } - } - else{ - --m_exclusive_count; - m_mutex_shared_completed.unlock(); - m_mutex_exclusive_mutex.unlock(); - } - } - - private: - - const sharable_mutex_policy m_policy; - //shared by all methods - interprocess_mutex m_mutex_exclusive_mutex; - interprocess_condition m_reader_shared_cond; - std::size_t m_r_active_completed_shared_count; - std::size_t m_r_wait_shared_count; - std::size_t m_w_wait_exclusive_count; - //Only for reader-writer - interprocess_condition exclusive_cond; - std::size_t m_w_active; - //Only for no_priority - interprocess_mutex m_mutex_shared_completed; - int m_completed_shared_count; - int m_shared_count; - int m_exclusive_count; -}; - -*/ - - -} // namespace interprocess - -} // namespace boost - -#include - -#endif - diff --git a/include/boost/interprocess/sync/win32/interprocess_condition.hpp b/include/boost/interprocess/sync/win32/interprocess_condition.hpp deleted file mode 100644 index 235f9ea..0000000 --- a/include/boost/interprocess/sync/win32/interprocess_condition.hpp +++ /dev/null @@ -1,197 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#include - -namespace boost { - -namespace interprocess { - - -inline interprocess_condition::interprocess_condition() -{ - m_command = SLEEP; - m_num_waiters = 0; -} - -inline interprocess_condition::~interprocess_condition() -{} - - -inline void interprocess_condition::notify_one() -{ - this->notify(NOTIFY_ONE); -} - -inline void interprocess_condition::notify_all() -{ - this->notify(NOTIFY_ALL); -} - -inline void interprocess_condition::notify(long command) -{ - //This interprocess_mutex guarantees that no other thread can enter to the - //do_timed_wait method logic, so that thread count will be - //constant until the function writes a NOTIFY_ALL command. - //It also guarantees that no other notification can be signaled - //on this interprocess_condition before this one ends - using namespace boost::detail; - m_enter_mut.lock(); - - //Return if there are no waiters -// if(!winapi::exchange_and_add(&m_num_waiters, 0)){ - if(!m_num_waiters) { - m_enter_mut.unlock(); - return; - } - - //Notify that all threads should execute wait logic - while(SLEEP != BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)&m_command, command, SLEEP)){ - winapi::sched_yield(); - } -/* - //Wait until the threads are waked - while(SLEEP != winapi::exchange_and_add((long*)&m_command, 0)){ - winapi::sched_yield(); - } -*/ - //The enter interprocess_mutex will rest locked until the last waiting thread unlocks it -} - -inline void interprocess_condition::do_wait(interprocess_mutex &mut) -{ - this->do_timed_wait(false, boost::posix_time::ptime(), mut); -} - -inline bool interprocess_condition::do_timed_wait - (const boost::posix_time::ptime &abs_time, interprocess_mutex &mut) -{ - return this->do_timed_wait(true, abs_time, mut); -} - -inline bool interprocess_condition::do_timed_wait(bool tout_enabled, - const boost::posix_time::ptime &abs_time, - interprocess_mutex &mut) -{ - using namespace boost::detail; - boost::posix_time::ptime now = - boost::posix_time::microsec_clock::universal_time(); - - if(tout_enabled){ - if(now >= abs_time) return false; - } - - //The enter interprocess_mutex guarantees that while executing a notification, - //no other thread can execute the do_timed_wait method. - { - //--------------------------------------------------------------- - boost::interprocess::scoped_lock lock(m_enter_mut); - //--------------------------------------------------------------- - //We increment the waiting thread count protected so that it will be - //always constant when another thread enters the notification logic. - //The increment marks this thread as "waiting on interprocess_condition" - BOOST_INTERLOCKED_INCREMENT((long*)&m_num_waiters); - - //We unlock the external interprocess_mutex atomically with the increment - mut.unlock(); - } - - //By default, we suppose that no timeout has happened - bool timed_out = false, unlock_enter_mut= false; - - //Loop until a notification indicates that the thread should - //exit or timeout occurs - while(1){ - //The thread sleeps/spins until a interprocess_condition commands a notification - //Notification occurred, we will lock the checking interprocess_mutex so that - while(m_command == SLEEP){ -// while(winapi::exchange_and_add(&m_command, 0) == SLEEP){ - winapi::sched_yield(); - - //Check for timeout - if(tout_enabled){ - now = boost::posix_time::microsec_clock::universal_time(); - - if(now >= abs_time){ - //If we can lock the interprocess_mutex it means that no notification - //is being executed in this interprocess_condition variable - timed_out = m_enter_mut.try_lock(); - - //If locking fails, indicates that another thread is executing - //notification, so we play the notification game - if(!timed_out){ - //There is an ongoing notification, we will try again later - continue; - } - //No notification in execution, since enter interprocess_mutex is locked. - //We will execute time-out logic, so we will decrement count, - //release the enter interprocess_mutex and return false. - break; - } - } - } - - //If a timeout occurred, the interprocess_mutex will not execute checking logic - if(tout_enabled && timed_out){ - //Decrement wait count - BOOST_INTERLOCKED_DECREMENT((long*)&m_num_waiters); - unlock_enter_mut = true; - break; - } - else{ - //Notification occurred, we will lock the checking interprocess_mutex so that - //if a notify_one notification occurs, only one thread can exit - //--------------------------------------------------------------- - boost::interprocess::scoped_lock lock(m_check_mut); - //--------------------------------------------------------------- - long result = BOOST_INTERLOCKED_COMPARE_EXCHANGE - ((long*)&m_command, SLEEP, NOTIFY_ONE); - if(result == SLEEP){ - //Other thread has been notified and since it was a NOTIFY one - //command, this thread must sleep again - continue; - } - else if(result == NOTIFY_ONE){ - //If it was a NOTIFY_ONE command, only this thread should - //exit. This thread has atomically marked command as sleep before - //so no other thread will exit. - //Decrement wait count. - unlock_enter_mut = true; - BOOST_INTERLOCKED_DECREMENT((long*)&m_num_waiters); - break; - } - else{ - //If it is a NOTIFY_ALL command, all threads should return - //from do_timed_wait function. Decrement wait count. - unlock_enter_mut = BOOST_INTERLOCKED_DECREMENT((long*)&m_num_waiters) == 0; - //Check if this is the last thread of notify_all waiters - //Only the last thread will release the interprocess_mutex - if(unlock_enter_mut){ - BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)&m_command, SLEEP, NOTIFY_ALL); - } - break; - } - } - } - - //Unlock the enter interprocess_mutex if it is a single notification, if this is - //the last notified thread in a notify_all or a timeout has occurred - if(unlock_enter_mut){ - m_enter_mut.unlock(); - } - - //Lock external again before returning from the method - mut.lock(); - return !timed_out; -} - -} //namespace interprocess - -} // namespace boost diff --git a/include/boost/interprocess/sync/win32/interprocess_mutex.hpp b/include/boost/interprocess/sync/win32/interprocess_mutex.hpp deleted file mode 100644 index 69efa0b..0000000 --- a/include/boost/interprocess/sync/win32/interprocess_mutex.hpp +++ /dev/null @@ -1,120 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// -// -// Parts of the pthread code come from Boost Threads code: -// -////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2001-2003 -// William E. Kempf -// -// Permission to use, copy, modify, distribute and sell this software -// and its documentation for any purpose is hereby granted without fee, -// provided that the above copyright notice appear in all copies and -// that both that copyright notice and this permission notice appear -// in supporting documentation. William E. Kempf makes no representations -// about the suitability of this software for any purpose. -// It is provided "as is" without express or implied warranty. -////////////////////////////////////////////////////////////////////////////// - -#include - -namespace boost { - -namespace interprocess { - -inline static void do_lock_func(volatile long &m_s) -{ - using namespace boost::detail; - do{ - long prev_s = BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)&m_s, 0, 1); - - if (m_s == 0 && prev_s == 1){ - break; - } - // relinquish current timeslice - winapi::sched_yield(); - }while (true); -} - -inline static bool do_trylock_func(volatile long &m_s) -{ - using namespace boost::detail; - long prev_s = BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)&m_s, 0, 1); - - if (m_s == 0 && prev_s == 1){ - return true; - } - return false; -} - -inline static bool do_timedlock_func(volatile long &m_s, const boost::posix_time::ptime &abs_time) -{ - //Obtain current count and target time - boost::posix_time::ptime now = - boost::posix_time::microsec_clock::universal_time(); - using namespace boost::detail; - - if(now >= abs_time) return false; - - do{ - long prev_s = BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)&m_s, 0, 1); - - if (m_s == 0 && prev_s == 1){ - break; - } - now = boost::posix_time::microsec_clock::universal_time(); - - if(now >= abs_time){ - return false; - } - // relinquish current time slice - winapi::sched_yield(); - }while (true); - - return true; -} - -inline static void do_unlock_func(volatile long &m_s) -{ - using namespace boost::detail; - BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)&m_s, 1, 0); -} - -inline interprocess_mutex::interprocess_mutex() - : m_s(1) -{} - -inline interprocess_mutex::~interprocess_mutex() -{} - -inline void interprocess_mutex::lock(void) -{ - do_lock_func(m_s); -} - -inline bool interprocess_mutex::try_lock(void) -{ - return do_trylock_func(m_s); -} - -inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time) -{ - return do_timedlock_func(m_s, abs_time); -} - -inline void interprocess_mutex::unlock(void) -{ - do_unlock_func(m_s); -} - -} //namespace interprocess { - -} //namespace boost { diff --git a/include/boost/interprocess/sync/win32/interprocess_recursive_mutex.hpp b/include/boost/interprocess/sync/win32/interprocess_recursive_mutex.hpp deleted file mode 100644 index 3519154..0000000 --- a/include/boost/interprocess/sync/win32/interprocess_recursive_mutex.hpp +++ /dev/null @@ -1,96 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// -// -// Parts of the pthread code come from Boost Threads code: -// -////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2001-2003 -// William E. Kempf -// -// Permission to use, copy, modify, distribute and sell this software -// and its documentation for any purpose is hereby granted without fee, -// provided that the above copyright notice appear in all copies and -// that both that copyright notice and this permission notice appear -// in supporting documentation. William E. Kempf makes no representations -// about the suitability of this software for any purpose. -// It is provided "as is" without express or implied warranty. -////////////////////////////////////////////////////////////////////////////// - -#include - -namespace boost { - -namespace interprocess { - -inline interprocess_recursive_mutex::interprocess_recursive_mutex() - : m_nLockCount(0), m_nOwner(0xffffffff){} - -inline interprocess_recursive_mutex::~interprocess_recursive_mutex(){} - -inline void interprocess_recursive_mutex::lock() -{ - unsigned long pNumber = winapi::current_thread_id(); - if(pNumber == m_nOwner){ - ++m_nLockCount; - } - else{ - m_shared_timed_mutex.lock(); - m_nOwner = pNumber; - ++m_nLockCount; - } -} - -inline bool interprocess_recursive_mutex::try_lock() -{ - unsigned long pNumber = winapi::current_thread_id(); - if(pNumber == m_nOwner) { // we own it - ++m_nLockCount; - return true; - } - if(m_shared_timed_mutex.try_lock()){ - m_nOwner = pNumber; - ++m_nLockCount; - return true; - } - return false; -} - -inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) -{ - unsigned long pNumber = winapi::current_thread_id(); - if(pNumber == m_nOwner) { // we own it - ++m_nLockCount; - return true; - } - if(m_shared_timed_mutex.timed_lock(abs_time)){ - m_nOwner = pNumber; - ++m_nLockCount; - return true; - } - return false; -} - -inline void interprocess_recursive_mutex::unlock() -{ - unsigned long pNumber = winapi::current_thread_id(); - assert(pNumber == m_nOwner); - --m_nLockCount; - if(!m_nLockCount){ - m_nOwner = m_nLockCount; - --m_nOwner; - m_shared_timed_mutex.unlock(); - } -} - -} //namespace interprocess { - -} //namespace boost { - diff --git a/include/boost/interprocess/sync/win32/interprocess_semaphore.hpp b/include/boost/interprocess/sync/win32/interprocess_semaphore.hpp deleted file mode 100644 index 705a3e0..0000000 --- a/include/boost/interprocess/sync/win32/interprocess_semaphore.hpp +++ /dev/null @@ -1,71 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include - -namespace boost { -namespace interprocess { - -inline interprocess_semaphore::~interprocess_semaphore() -{} - -inline interprocess_semaphore::interprocess_semaphore(int initialCount) - : m_mut(), m_cond(), m_count(initialCount) -{} - -inline void interprocess_semaphore::post() -{ - scoped_lock lock(m_mut); - if(m_count == 0){ - m_cond.notify_one(); - } - ++m_count; -} - -inline void interprocess_semaphore::wait() -{ - scoped_lock lock(m_mut); - while(m_count == 0){ - m_cond.wait(lock); - } - --m_count; -} - -inline bool interprocess_semaphore::try_wait() -{ - scoped_lock lock(m_mut); - if(m_count == 0){ - return false; - } - --m_count; - return true; -} - -inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) -{ - scoped_lock lock(m_mut); - while(m_count == 0){ - if(!m_cond.timed_wait(lock, abs_time)) - return false; - } - --m_count; - return true; -} -/* -inline int interprocess_semaphore::get_count() const -{ - scoped_lock lock(m_mut); - return count; -}*/ - -} //namespace interprocess { -} //namespace boost { diff --git a/include/boost/interprocess/sync/win32/win32_sync_primitives.hpp b/include/boost/interprocess/sync/win32/win32_sync_primitives.hpp deleted file mode 100644 index 6785fdb..0000000 --- a/include/boost/interprocess/sync/win32/win32_sync_primitives.hpp +++ /dev/null @@ -1,351 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP -#define BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP - -#if (defined _MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif - -#include -#include - -#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) -# include -# include -# include -#else -# error "This file can only be included in Windows OS" -#endif - -//The structures used in Interprocess with the -//same binary interface as windows ones -namespace boost { -namespace interprocess { -namespace winapi { - -//Some used constants -static const unsigned long infinite_time = 0xFFFFFFFF; -static const unsigned long error_already_exists = 183L; -static const unsigned long error_file_not_found = 2u; - -static const unsigned long semaphore_all_access = (0x000F0000L)|(0x00100000L)|0x3; -static const unsigned long mutex_all_access = (0x000F0000L)|(0x00100000L)|0x0001; - -static const unsigned long page_readonly = 0x02; -static const unsigned long page_readwrite = 0x04; -static const unsigned long page_writecopy = 0x08; - -static const unsigned long standard_rights_required = 0x000F0000L; -static const unsigned long section_query = 0x0001; -static const unsigned long section_map_write = 0x0002; -static const unsigned long section_map_read = 0x0004; -static const unsigned long section_map_execute = 0x0008; -static const unsigned long section_extend_size = 0x0010; -static const unsigned long section_all_access = standard_rights_required | - section_query | - section_map_write | - section_map_read | - section_map_execute | - section_extend_size | - section_all_access ; - -static const unsigned long file_map_copy = section_query; -static const unsigned long file_map_write = section_map_write; -static const unsigned long file_map_read = section_map_read; -static const unsigned long file_map_all_access = section_all_access; - -static const unsigned long file_share_read = 0x00000001; -static const unsigned long file_share_write = 0x00000002; - -static const unsigned long generic_read = 0x80000000L; -static const unsigned long generic_write = 0x40000000L; - -static const unsigned long wait_object_0 = 0; -static const unsigned long wait_abandoned = 0x00000080L; -static const unsigned long wait_timeout = 258L; -static const unsigned long wait_failed = (unsigned long)0xFFFFFFFF; - -static const unsigned long format_message_allocate_buffer - = (unsigned long)0x00000100; -static const unsigned long format_message_ignore_inserts - = (unsigned long)0x00000200; -static const unsigned long format_message_from_string - = (unsigned long)0x00000400; -static const unsigned long format_message_from_hmodule - = (unsigned long)0x00000800; -static const unsigned long format_message_from_system - = (unsigned long)0x00001000; -static const unsigned long format_message_argument_array - = (unsigned long)0x00002000; -static const unsigned long format_message_max_width_mask - = (unsigned long)0x000000FF; -static const unsigned long lang_neutral = (unsigned long)0x00; -static const unsigned long sublang_default = (unsigned long)0x01; -static const unsigned long invalid_file_size = (unsigned long)0xFFFFFFFF; -static void * const invalid_handle_value = (void*)(long*)-1; -static const unsigned long create_new = 1; -static const unsigned long create_always = 2; -static const unsigned long open_existing = 3; -static const unsigned long open_always = 4; -static const unsigned long truncate_existing = 5; - -static const unsigned long file_attribute_temporary = 0x00000100; - -static const unsigned long file_begin = 0; -static const unsigned long file_current = 1; -static const unsigned long file_end = 2; - -static const unsigned long lockfile_fail_immediately = 1; -static const unsigned long lockfile_exclusive_lock = 2; -static const unsigned long error_lock_violation = 33; - -} //namespace winapi { -} //namespace interprocess { -} //namespace boost { - -#if !defined( BOOST_USE_WINDOWS_H ) - -namespace boost { -namespace interprocess { -namespace winapi { - -struct interprocess_overlapped -{ - unsigned long *internal; - unsigned long *internal_high; - union { - struct { - unsigned long offset; - unsigned long offset_high; - }dummy; - void *pointer; - }; - - void *h_event; -}; - -struct interprocess_filetime -{ - unsigned long dwLowDateTime; - unsigned long dwHighDateTime; -}; - -struct interprocess_security_attributes -{ - unsigned long nLength; - void *lpSecurityDescriptor; - int bInheritHandle; -}; - -struct system_info { - union { - unsigned long dwOemId; // Obsolete field...do not use - struct { - unsigned short wProcessorArchitecture; - unsigned short wReserved; - } dummy; - }; - unsigned long dwPageSize; - void * lpMinimumApplicationAddress; - void * lpMaximumApplicationAddress; - unsigned long * dwActiveProcessorMask; - unsigned long dwNumberOfProcessors; - unsigned long dwProcessorType; - unsigned long dwAllocationGranularity; - unsigned short wProcessorLevel; - unsigned short wProcessorRevision; -}; - -//Some windows API declarations -extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); -extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long); -extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError(); -extern "C" __declspec(dllimport) int __stdcall CloseHandle(void*); -extern "C" __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(interprocess_filetime*); -extern "C" __declspec(dllimport) void * __stdcall CreateMutexA(interprocess_security_attributes*, int, const char *); -extern "C" __declspec(dllimport) void * __stdcall OpenMutexA(unsigned long, int, const char *); -extern "C" __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void *, unsigned long); -extern "C" __declspec(dllimport) int __stdcall ReleaseMutex(void *); -extern "C" __declspec(dllimport) int __stdcall UnmapViewOfFile(void *); -extern "C" __declspec(dllimport) void * __stdcall CreateSemaphoreA(interprocess_security_attributes*, long, long, const char *); -extern "C" __declspec(dllimport) int __stdcall ReleaseSemaphore(void *, long, long *); -extern "C" __declspec(dllimport) void * __stdcall OpenSemaphoreA(unsigned long, int, const char *); -extern "C" __declspec(dllimport) void * __stdcall CreateFileMappingA (void *, interprocess_security_attributes*, unsigned long, unsigned long, unsigned long, const char *); -extern "C" __declspec(dllimport) void * __stdcall MapViewOfFileEx (void *, unsigned long, unsigned long, unsigned long, size_t, void*); -extern "C" __declspec(dllimport) void * __stdcall OpenFileMappingA (unsigned long, int, const char *); -extern "C" __declspec(dllimport) void * __stdcall CreateFileA (const char *, unsigned long, unsigned long, struct _SECURITY_ATTRIBUTES*, unsigned long, unsigned long, void *); -extern "C" __declspec(dllimport) int __stdcall DeleteFileA (const char *); -extern "C" __declspec(dllimport) void __stdcall GetSystemInfo (struct system_info *); -extern "C" __declspec(dllimport) int __stdcall FlushViewOfFile (void *, size_t); -extern "C" __declspec(dllimport) int __stdcall GetFileSizeEx (void *, __int64 *size); -extern "C" __declspec(dllimport) unsigned long __stdcall FormatMessageA - (unsigned long dwFlags, const void *lpSource, unsigned long dwMessageId, - unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize, - va_list *Arguments); -extern "C" __declspec(dllimport) void *__stdcall LocalFree (void *); -extern "C" __declspec(dllimport) int __stdcall CreateDirectoryA(const char *, interprocess_security_attributes*); -extern "C" __declspec(dllimport) int __stdcall GetTempPathA(unsigned long length, char *buffer); -extern "C" __declspec(dllimport) int __stdcall CreateDirectory(const char *, interprocess_security_attributes*); -extern "C" __declspec(dllimport) int __stdcall SetFileValidData(void *, __int64 size); -extern "C" __declspec(dllimport) int __stdcall SetEndOfFile(void *); -extern "C" __declspec(dllimport) int __stdcall SetFilePointerEx(void *, __int64 distance, __int64 *new_file_pointer, unsigned long move_method); -extern "C" __declspec(dllimport) int __stdcall LockFile (void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high); -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); - -} //namespace winapi { -} //namespace interprocess { -} //namespace boost { - -#else -# include -#endif //#if !defined( BOOST_USE_WINDOWS_H ) - -namespace boost { -namespace interprocess { -namespace winapi { - -static inline unsigned long format_message - (unsigned long dwFlags, const void *lpSource, - unsigned long dwMessageId, unsigned long dwLanguageId, - char *lpBuffer, unsigned long nSize, va_list *Arguments) -{ - return FormatMessageA - (dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments); -} - -//And now, wrapper functions -static inline void * local_free(void *hmem) -{ return LocalFree(hmem); } - -static inline unsigned long make_lang_id(unsigned long p, unsigned long s) -{ return ((((unsigned short)(s)) << 10) | (unsigned short)(p)); } - -static inline void sched_yield() -{ Sleep(1); } - -static inline unsigned long get_current_thread_id() -{ return GetCurrentThreadId(); } - -static inline unsigned int close_handle(void* handle) -{ return CloseHandle(handle); } - -static inline unsigned long get_last_error() -{ return GetLastError(); } - -static inline void get_system_time_as_file_time(interprocess_filetime *filetime) -{ GetSystemTimeAsFileTime(filetime); } - -static inline void *create_mutex(const char *name) -{ return CreateMutexA(0, 0, name); } - -static inline void *open_mutex(const char *name) -{ return OpenMutexA(mutex_all_access, 0, name); } - -static inline unsigned long wait_for_single_object(void *handle, unsigned long time) -{ return WaitForSingleObject(handle, time); } - -static inline int release_mutex(void *handle) -{ return ReleaseMutex(handle); } - -static inline int unmap_view_of_file(void *address) -{ return UnmapViewOfFile(address); } - -static inline void *create_semaphore(long initialCount, const char *name) -{ return CreateSemaphoreA(0, initialCount, (long)(((unsigned long)(-1))>>1), name); } - -static inline int release_semaphore(void *handle, long release_count, long *prev_count) -{ return ReleaseSemaphore(handle, release_count, prev_count); } - -static inline void *open_semaphore(const char *name) -{ return OpenSemaphoreA(semaphore_all_access, 1, name); } - -static inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name) -{ return CreateFileMappingA (handle, 0, access, high_size, low_size, name); } - -static inline void * open_file_mapping (unsigned long access, const char *name) -{ return OpenFileMappingA (access, 0, name); } - -static inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned long highoffset, unsigned long lowoffset, std::size_t numbytes, void *base_addr) -{ return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr); } - -static inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes = 0) -{ return CreateFileA(name, access, file_share_read | file_share_write, 0, creation_flags, attributes, 0); } - -static inline bool delete_file(const char *name) -{ return 0 != DeleteFileA(name); } - -static inline void get_system_info(system_info *info) -{ GetSystemInfo(info); } - -static inline int flush_view_of_file(void *base_addr, std::size_t numbytes) -{ return FlushViewOfFile(base_addr, numbytes); } - -static inline bool get_file_size(void *handle, __int64 &size) -{ - return 0 != GetFileSizeEx(handle, &size); -} - -static inline bool create_directory(const char *name, interprocess_security_attributes* security) -{ - return 0 != CreateDirectoryA(name, security); -} - -static inline unsigned long get_temp_path(unsigned long length, char *buffer) -{ - return GetTempPathA(length, buffer); -} - -static inline int set_end_of_file(void *handle) -{ - return 0 != SetEndOfFile(handle); -} - -static inline bool set_file_pointer_ex(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method) -{ - return 0 != SetFilePointerEx(handle, distance, new_file_pointer, move_method); -} - -static inline bool lock_file_ex(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped) -{ - return 0 != LockFileEx(hnd, flags, reserved, size_low, size_high, overlapped); -} - -static inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped) -{ - return 0 != UnlockFileEx(hnd, reserved, size_low, size_high, overlapped); -} - -static inline long interlocked_increment(long volatile *addr) -{ return InterlockedIncrement(addr); } - -static inline long interlocked_decrement(long volatile *addr) -{ return InterlockedDecrement(addr); } - -static inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2) -{ return InterlockedCompareExchange(addr, val1, val2); } - -static inline long exchange_and_add(long volatile* addend, long value) -{ return InterlockedExchangeAdd((long*)addend, value); } - -} //namespace winapi -} //namespace interprocess -} //namespace boost - -#include - -#endif //#ifdef BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP