Removed unused files

[SVN r35626]
This commit is contained in:
Ion Gaztañaga
2006-10-16 05:08:33 +00:00
parent 61b7be3c68
commit 7715ac0c45
16 changed files with 0 additions and 8312 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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 <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <cstddef>
#include <memory>
#include <algorithm>
#include <stdexcept>
#include <iterator>
#include <boost/detail/no_exceptions_support.hpp>
namespace boost {
namespace interprocess {
namespace detail {
/*!This struct deallocates and allocated memory */
template <class A>
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 T, class A>
class vector : private detail::vector_alloc_holder<A>
{
typedef vector<T, A> self_t;
typedef detail::vector_alloc_holder<A> base_t;
typedef detail::scoped_array_deallocator<A> 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<const T, difference_type> range_from_ref_it;
public:
//Vector const_iterator
class const_iterator
: public boost::iterator<std::random_access_iterator_tag,
value_type, vec_diff,
vec_cptr, vec_cref >
{
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<T, A>;
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<T, A>;
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<iterator>
reverse_iterator;
typedef typename boost::reverse_iterator<const_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<T, A>& 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 <class InIt>
vector(InIt first, InIt last,
const allocator_type& a = allocator_type())
: base_t(a)
{
const bool aux_boolean = boost::is_integral<InIt>::value;
typedef boost::mpl::bool_<aux_boolean> 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<T, A>& operator=(const vector<T, A>& 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<T, A> tmp(n, val, static_cast<const allocator_type&>(*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 <class InIt>
void assign(InIt first, InIt last)
{
//Dispatch depending on integer/iterator
const bool aux_boolean = boost::is_integral<InIt>::value;
typedef boost::mpl::bool_<aux_boolean> 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<size_type>(1), x);
}
}
void swap(vector<T, A>& 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 <class InIt>
void insert(iterator pos, InIt first, InIt last)
{
//Dispatch depending on integer/iterator
const bool aux_boolean = boost::is_integral<InIt>::value;
typedef boost::mpl::bool_<aux_boolean> 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<T, dealloc_t> 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 <class InIt>
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 <class FwdIt>
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<T, dealloc_t> 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 <class FwdIt>
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<T, dealloc_t> 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 <class InIt>
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 <class InIt>
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 <class FwdIt>
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 <class Integer>
void priv_assign_dispatch(Integer n, Integer val, boost::mpl::true_)
{ this->assign((size_type) n, (T) val); }
template <class InIt>
void priv_assign_dispatch(InIt first, InIt last,
boost::mpl::false_)
{
//Dispatch depending on integer/iterator
typedef typename
std::iterator_traits<InIt>::iterator_category ItCat;
this->priv_assign_aux(first, last, ItCat());
}
template <class Integer>
void priv_insert_dispatch( iterator pos, Integer n,
Integer val, boost::mpl::true_)
{ this->insert(pos, (size_type)n, (T)val); }
template <class InIt>
void priv_insert_dispatch(iterator pos, InIt first,
InIt last, boost::mpl::false_)
{
//Dispatch depending on integer/iterator
typedef typename
std::iterator_traits<InIt>::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 <class Integer>
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<T, dealloc_t> 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 <class InIt>
void priv_initialize_aux(InIt first, InIt last,
boost::mpl::false_)
{
//Dispatch depending on integer/iterator
typedef typename
std::iterator_traits<InIt>::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 <class FwdIt>
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<T, dealloc_t> 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<class InIt, class FwdIt, class alloc> 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<class FwdIt, class Count, class Alloc> 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 <class T, class A>
inline bool
operator==(const vector<T, A>& x, const vector<T, A>& y)
{
//Check first size and each element if needed
return x.size() == y.size() &&
std::equal(x.begin(), x.end(), y.begin());
}
template <class T, class A>
inline bool
operator!=(const vector<T, A>& x, const vector<T, A>& y)
{
//Check first size and each element if needed
return x.size() != y.size() ||
!std::equal(x.begin(), x.end(), y.begin());
}
template <class T, class A>
inline bool
operator<(const vector<T, A>& x, const vector<T, A>& y)
{
return std::lexicographical_compare(x.begin(), x.end(),
y.begin(), y.end());
}
template <class T, class A>
inline void swap(vector<T, A>& x, vector<T, A>& y)
{
x.swap(y);
}
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif // #ifndef BOOST_SHMEM_VECTOR_HPP

View File

@@ -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 <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
# include <boost/interprocess/sync/win32/win32_sync_primitives.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
# include <fcntl.h> //O_CREAT, O_*...
# include <unistd.h> //ftruncate, close
# include <semaphore.h> //sem_t* family, SEM_VALUE_MAX
# include <sys/stat.h> //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 <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_DETAIL_GLOBAL_LOCK_HPP

View File

@@ -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 <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
//TO-DO
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_NAMED_FIFO_HPP

View File

@@ -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 <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/creation_tags.hpp>
#include <boost/interprocess/memory_mappable.hpp>
#include <boost/interprocess/detail/global_lock.hpp>
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <memory> //std::auto_ptr
#include <string> //std::string
#include <cstdio> //std::remove
#include <string>
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
# include <boost/interprocess/sync/win32/win32_sync_primitives.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
# include <fcntl.h>
# include <sys/mman.h> //mmap, off64_t
# include <unistd.h>
# include <sys/stat.h>
# 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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc> 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 <class ConstructFunc> 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 <class ConstructFunc> 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 <class ConstructFunc> 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 <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_MAPPED_FILE_HPP

View File

@@ -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 <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <string>
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
# include <boost/interprocess/sync/win32/win32_sync_primitives.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
# include <fcntl.h>
# include <sys/mman.h> //mmap, off64_t
# include <unistd.h>
# include <sys/stat.h>
# 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<std::size_t>(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<const char*>(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<std::size_t>(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<char*>(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<char*>(m_base)+mapping_offset,
static_cast<std::size_t>(numbytes));
}
inline void mapped_region::priv_close()
{
if(m_base){
this->flush();
winapi::unmap_view_of_file(static_cast<char*>(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<const char*>(address) - m_extra_offset;
}
//Map it to the address space
m_base = mmap64( (void*)address
, static_cast<std::size_t>(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<char*>(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<char*>(m_base)+mapping_offset,
numbytes, MS_SYNC) == 0;
}
inline void mapped_region::priv_close()
{
if(m_base != MAP_FAILED){
this->flush();
munmap(static_cast<char*>(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 &region, bool) const
{ return true; }
};
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_memory_mappable_HPP

View File

@@ -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 <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/function.hpp>
#include <boost/interprocess/detail/global_lock.hpp>
#include <boost/compatibility/cpp_c_headers/cstddef>
#include <boost/interprocess/memory_mappable.hpp>
//#include <boost/optional.hpp>
//#include <boost/utility/in_place_factory.hpp>
/*
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
# include <boost/interprocess/sync/win32/win32_sync_primitives.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
# include <fcntl.h> //O_CREAT, O_*...
# include <sys/mman.h> //mmap
# include <unistd.h> //ftruncate, close
# include <semaphore.h> //sem_t* family, SEM_VALUE_MAX
# include <string> //std::string
# include <sys/stat.h> //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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc>
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 <class ConstructFunc> 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 <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_MEMORY_HPP

View File

@@ -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 <boost/compressed_pair.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <cstddef>
namespace boost_ext{
namespace detail
{
struct two {char _[2];};
namespace pointer_type_imp
{
template <class U> static two test(...);
template <class U> static char test(typename U::pointer* = 0);
}
template <class T>
struct has_pointer_type
{
static const bool value = sizeof(pointer_type_imp::test<T>(0)) == 1;
};
namespace pointer_type_imp
{
template <class T, class D, bool = has_pointer_type<D>::value>
struct pointer_type
{
typedef typename D::pointer type;
};
template <class T, class D>
struct pointer_type<T, D, false>
{
typedef T* type;
};
}
template <class T, class D>
struct pointer_type
{
typedef typename pointer_type_imp::pointer_type<T,
typename boost::remove_reference<D>::type>::type type;
};
}
template <class T>
struct default_delete
{
default_delete() {}
template <class U> default_delete(const default_delete<U>&) {}
void operator() (T* ptr) const
{
BOOST_STATIC_ASSERT(sizeof(T) > 0);
delete ptr;
}
};
template <class T>
struct default_delete<T[]>
{
void operator() (T* ptr) const
{
BOOST_STATIC_ASSERT(sizeof(T) > 0);
delete [] ptr;
}
};
template <class T, std::size_t N>
struct default_delete<T[N]>
{
void operator() (T* ptr, std::size_t) const
{
BOOST_STATIC_ASSERT(sizeof(T) > 0);
delete [] ptr;
}
};
template <class T, class D> class unique_ptr;
namespace detail
{
template <class T> struct unique_ptr_error;
template <class T, class D>
struct unique_ptr_error<const unique_ptr<T, D> >
{
typedef unique_ptr<T, D> type;
};
} // detail
template <class T, class D = default_delete<T> >
class unique_ptr
{
struct nat {int for_bool_;};
typedef typename boost::add_reference<D>::type deleter_reference;
typedef typename boost::add_reference<const D>::type deleter_const_reference;
public:
typedef T element_type;
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::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>,
D,
typename boost::add_reference<const D>::type>::type d)
: ptr_(p, d) {}
unique_ptr(const unique_ptr& u)
: ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter()) {}
template <class U, class E>
unique_ptr(const unique_ptr<U, E>& u,
typename boost::enable_if_c<
boost::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
boost::is_convertible<E, D>::value &&
(
!boost::is_reference<D>::value ||
boost::is_same<D, E>::value
)
,
nat
>::type = nat())
: ptr_(const_cast<unique_ptr<U,E>&>(u).release(), u.get_deleter()) {}
// destructor
~unique_ptr() {reset();}
// assignment
unique_ptr& operator=(const unique_ptr& cu)
{
unique_ptr& u = const_cast<unique_ptr&>(cu);
reset(u.release());
ptr_.second() = u.get_deleter();
return *this;
}
template <class U, class E>
unique_ptr& operator=(const unique_ptr<U, E>& cu)
{
unique_ptr<U, E>& u = const_cast<unique_ptr<U, E>&>(cu);
reset(u.release());
ptr_.second() = u.get_deleter();
return *this;
}
unique_ptr& operator=(int nat::*)
{
reset();
return *this;
}
// observers
typename boost::add_reference<T>::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<pointer, D> ptr_;
unique_ptr(unique_ptr&);
template <class U, class E> unique_ptr(unique_ptr<U, E>&);
template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
unique_ptr& operator=(unique_ptr&);
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&);
template <class U> typename detail::unique_ptr_error<U>::type operator=(U&);
};
template <class T, class D>
class unique_ptr<T[], D>
{
struct nat {int for_bool_;};
typedef typename boost::add_reference<D>::type deleter_reference;
typedef typename boost::add_reference<const D>::type deleter_const_reference;
public:
typedef T element_type;
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::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>,
D,
typename boost::add_reference<const D>::type>::type d)
: ptr_(p, d) {}
unique_ptr(const unique_ptr& u)
: ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter()) {}
// destructor
~unique_ptr() {reset();}
// assignment
unique_ptr& operator=(const unique_ptr& cu)
{
unique_ptr& u = const_cast<unique_ptr&>(cu);
reset(u.release());
ptr_.second() = u.get_deleter();
return *this;
}
unique_ptr& operator=(int nat::*)
{
reset();
return *this;
}
// observers
typename boost::add_reference<T>::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<pointer, D> ptr_;
template <class U, class E> unique_ptr(U p, E,
typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
template <class U> explicit unique_ptr(U,
typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
unique_ptr(unique_ptr&);
template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
unique_ptr& operator=(unique_ptr&);
template <class U> typename detail::unique_ptr_error<U>::type operator=(U&);
};
template <class T, class D, std::size_t N>
class unique_ptr<T[N], D>
{
struct nat {int for_bool_;};
typedef typename boost::add_reference<D>::type deleter_reference;
typedef typename boost::add_reference<const D>::type deleter_const_reference;
public:
typedef T element_type;
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::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>,
D,
typename boost::add_reference<const D>::type>::type d)
: ptr_(p, d) {}
unique_ptr(const unique_ptr& u)
: ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter()) {}
// destructor
~unique_ptr() {reset();}
// assignment
unique_ptr& operator=(const unique_ptr& cu)
{
unique_ptr& u = const_cast<unique_ptr&>(cu);
reset(u.release());
ptr_.second() = u.get_deleter();
return *this;
}
unique_ptr& operator=(int nat::*)
{
reset();
return *this;
}
// observers
typename boost::add_reference<T>::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<pointer, D> ptr_;
template <class U, class E> unique_ptr(U p, E,
typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
template <class U> explicit unique_ptr(U,
typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
unique_ptr(unique_ptr&);
template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
unique_ptr& operator=(unique_ptr&);
template <class U> typename detail::unique_ptr_error<U>::type operator=(U&);
};
template <class T, class D>
inline
void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) {x.swap(y);}
template <class T1, class D1, class T2, class D2>
inline
bool
operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() == y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() != y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator <(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() < y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() <= y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator >(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() > y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() >= y.get();}
template <class T, class D>
inline
unique_ptr<T, D>
move(unique_ptr<T, D>& p)
{
return unique_ptr<T, D>(p.release(), p.get_deleter());
}
} //namespace boost_ext{
#ifdef _MSC_VER
#pragma warning (pop)
#endif

View File

@@ -1,407 +0,0 @@
// I, Howard Hinnant, hereby place this code in the public domain.
namespace std { namespace detail {
template <bool cond, class Then, class Else>
struct select
{
typedef Then type;
};
template <class Then, class Else>
struct select<false, Then, Else>
{
typedef Else type;
};
template <bool b, class T = void> struct restrict_to {};
template <class T> struct restrict_to<true, T> {typedef T type;};
using boost::compressed_pair;
struct two {char _[2];};
namespace pointer_type_imp
{
template <class U> static two test(...);
template <class U> static char test(typename U::pointer* = 0);
}
template <class T>
struct has_pointer_type
{
static const bool value = sizeof(pointer_type_imp::test<T>(0)) == 1;
};
namespace pointer_type_imp
{
template <class T, class D, bool = has_pointer_type<D>::value>
struct pointer_type
{
typedef typename D::pointer type;
};
template <class T, class D>
struct pointer_type<T, D, false>
{
typedef T* type;
};
}
template <class T, class D>
struct pointer_type
{
typedef typename pointer_type_imp::pointer_type<T,
typename tr1::remove_reference<D>::type>::type type;
};
} }
namespace std
{
template <class T>
struct default_delete
{
default_delete() {}
template <class U> default_delete(const default_delete<U>&) {}
void operator() (T* ptr) const
{
static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type");
delete ptr;
}
};
template <class T>
struct default_delete<T[]>
{
void operator() (T* ptr) const
{
static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type");
delete [] ptr;
}
};
template <class T, std::size_t N>
struct default_delete<T[N]>
{
void operator() (T* ptr, std::size_t) const
{
static_assert(sizeof(T) > 0, "Can't delete pointer to incomplete type");
delete [] ptr;
}
};
template <class T, class D = default_delete<T> >
class unique_ptr
{
struct nat {int for_bool_;};
public:
typedef T element_type;
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::type pointer;
// constructors
unique_ptr() : ptr_(pointer()) {}
explicit unique_ptr(pointer p) : ptr_(p) {}
unique_ptr(pointer p, typename detail::select<
tr1::is_reference<D>::value,
D,
const D&>::type d)
: ptr_(p, d) {}
unique_ptr(pointer p, typename tr1::remove_reference<D>::type&& d)
: ptr_(p, std::move(d))
{
static_assert(!tr1::is_reference<D>::value, "rvalue deleter bound to reference");
}
unique_ptr(unique_ptr&& u)
: ptr_(u.release(), std::forward<D>(u.get_deleter())) {}
template <class U, class E>
unique_ptr(unique_ptr<U, E>&& u,
typename detail::restrict_to<
tr1::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
tr1::is_convertible<E, D>::value &&
(
!tr1::is_reference<D>::value ||
tr1::is_same<D, E>::value
)
,
nat
>::type = nat())
: ptr_(u.release(), std::forward<D>(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 <class U, class E>
unique_ptr& operator=(unique_ptr<U, E>&& 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<T>::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<pointer, D> ptr_;
unique_ptr(const unique_ptr&);
template <class U, class E> unique_ptr(const unique_ptr<U, E>&);
unique_ptr& operator=(const unique_ptr&);
template <class U, class E> unique_ptr& operator=(const unique_ptr<U, E>&);
};
template <class T, class D>
class unique_ptr<T[], D>
{
struct nat {int for_bool_;};
public:
typedef T element_type;
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::type pointer;
// constructors
unique_ptr() : ptr_(pointer()) {}
explicit unique_ptr(pointer p) : ptr_(p) {}
unique_ptr(pointer p, typename detail::select<
tr1::is_reference<D>::value,
D,
const D&>::type d)
: ptr_(p, d) {}
unique_ptr(pointer p, typename tr1::remove_reference<D>::type&& d)
: ptr_(p, std::move(d))
{
static_assert(!tr1::is_reference<D>::value, "rvalue deleter bound to reference");
}
unique_ptr(unique_ptr&& u)
: ptr_(u.release(), std::forward<D>(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<T>::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<pointer, D> ptr_;
template <class U> unique_ptr(U p,
typename detail::select<
tr1::is_reference<D>::value,
D,
const D&>::type d,
typename detail::restrict_to<tr1::is_convertible<U, pointer>::value>::type* = 0);
template <class U> unique_ptr(U p, typename tr1::remove_reference<D>::type&& d,
typename detail::restrict_to<tr1::is_convertible<U, pointer>::value>::type* = 0);
template <class U> explicit unique_ptr(U,
typename detail::restrict_to<tr1::is_convertible<U, pointer>::value>::type* = 0);
unique_ptr(const unique_ptr&);
unique_ptr& operator=(const unique_ptr&);
};
template <class T, class D, std::size_t N>
class unique_ptr<T[N], D>
{
struct nat {int for_bool_;};
public:
typedef T element_type;
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::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<D>::value,
D,
const D&>::type d)
: ptr_(p, d) {}
unique_ptr(pointer p, typename tr1::remove_reference<D>::type&& d)
: ptr_(p, std::move(d))
{
static_assert(!tr1::is_reference<D>::value, "rvalue deleter bound to reference");
}
unique_ptr(unique_ptr&& u)
: ptr_(u.release(), std::forward<D>(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<T>::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<pointer, D> ptr_;
template <class U> unique_ptr(U p,
typename detail::select<
tr1::is_reference<D>::value,
D,
const D&>::type d,
typename detail::restrict_to<tr1::is_convertible<U, pointer>::value>::type* = 0);
template <class U> unique_ptr(U p, typename tr1::remove_reference<D>::type&& d,
typename detail::restrict_to<tr1::is_convertible<U, pointer>::value>::type* = 0);
template <class U> explicit unique_ptr(U,
typename detail::restrict_to<tr1::is_convertible<U, pointer>::value>::type* = 0);
unique_ptr(const unique_ptr&);
unique_ptr& operator=(const unique_ptr&);
};
template <class T, class D>
inline
void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) {x.swap(y);}
template <class T, class D>
inline
void swap(unique_ptr<T, D>&& x, unique_ptr<T, D>& y) {x.swap(y);}
template <class T, class D>
inline
void swap(unique_ptr<T, D>& x, unique_ptr<T, D>&& y) {x.swap(y);}
template <class T1, class D1, class T2, class D2>
inline
bool
operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() == y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() != y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator <(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() < y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() <= y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator >(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() > y.get();}
template <class T1, class D1, class T2, class D2>
inline
bool
operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{return x.get() >= y.get();}
} // std

View File

@@ -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 <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <iosfwd>
#include <ios>
#include <istream>
#include <ostream>
#include <string> // char traits
#include <cstddef> // ptrdiff_t
#include <boost/interprocess/interprocess_fwd.hpp>
#include <assert.h>
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 CharString, class CharTraits>
class basic_stringbuf
: public std::basic_streambuf<typename CharString::value_type, CharTraits>
{
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<char_type, traits_type> 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 &param) throws.*/
template<class VectorParameter>
explicit basic_stringbuf(const VectorParameter &param,
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<int>(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<std::streamsize>(
&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<int>(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<std::streamsize>
(&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<std::streamsize>
(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<int>(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(<anything>, 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<int>(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<std::streamoff>(m_string.size());
break;
case std::ios_base::cur:
newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
: static_cast<std::streamoff>(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 CharString, class CharTraits>
class basic_istringstream
: public std::basic_istream<typename CharString::value_type, CharTraits>
{
public:
typedef CharString string_type;
typedef typename std::basic_ios
<typename CharString::value_type, CharTraits>::char_type char_type;
typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
private:
typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
typedef std::basic_istream<char_type, CharTraits> 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 &param) throws.*/
template<class VectorParameter>
basic_istringstream(const VectorParameter &param,
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<CharString, CharTraits>* rdbuf() const
{ return const_cast<basic_stringbuf<CharString, CharTraits>*>(&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<CharString, CharTraits> 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 CharString, class CharTraits>
class basic_ostringstream
: public std::basic_ostream<typename CharString::value_type, CharTraits>
{
public:
typedef CharString string_type;
typedef typename std::basic_ios
<typename CharString::value_type, CharTraits>::char_type char_type;
typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
private:
typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
typedef std::basic_ostream<char_type, CharTraits> 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 &param) throws.*/
template<class VectorParameter>
basic_ostringstream(const VectorParameter &param,
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<CharString, CharTraits>* rdbuf() const
{ return const_cast<basic_stringbuf<CharString, CharTraits>*>(&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<CharString, CharTraits> 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 CharString, class CharTraits>
class basic_stringstream
: public std::basic_iostream<typename CharString::value_type, CharTraits>
{
public:
typedef CharString string_type;
typedef typename std::basic_ios
<typename CharString::value_type, CharTraits>::char_type char_type;
typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
private:
typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
typedef std::basic_iostream<char_type, CharTraits> 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 &param) throws.*/
template<class VectorParameter>
basic_stringstream(const VectorParameter &param, 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<CharString, CharTraits>* rdbuf() const
{ return const_cast<basic_stringbuf<CharString, CharTraits>*>(&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<CharString, CharTraits> m_buf;
};
//Some typedefs to simplify usage
/*
typedef basic_stringbuf<std::string<char> > stringbuf;
typedef basic_stringstream<std::string<char> > stringstream;
typedef basic_istringstream<std::string<char> > istringstream;
typedef basic_ostringstream<std::string<char> > ostringstream;
typedef basic_stringbuf<std::string<wchar_t> > wstringbuf;
typedef basic_stringstream<std::string<wchar_t> > wstringstream;
typedef basic_istringstream<std::string<wchar_t> > wistringstream;
typedef basic_ostringstream<std::string<wchar_t> > wostringstream;
*/
}} //namespace boost { namespace interprocess {
#include <boost/interprocess/detail/config_end.hpp>
#endif /* BOOST_INTERPROCESS_STRINGSTREAM_HPP */

File diff suppressed because it is too large Load Diff

View File

@@ -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 <boost/date_time/posix_time/posix_time_types.hpp>
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<interprocess_mutex> 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<interprocess_mutex> 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

View File

@@ -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 <boost/date_time/posix_time/posix_time_types.hpp>
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 {

View File

@@ -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 <boost/date_time/posix_time/posix_time_types.hpp>
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 {

View File

@@ -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<boost/interprocess/exceptions.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
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<interprocess_mutex> lock(m_mut);
if(m_count == 0){
m_cond.notify_one();
}
++m_count;
}
inline void interprocess_semaphore::wait()
{
scoped_lock<interprocess_mutex> lock(m_mut);
while(m_count == 0){
m_cond.wait(lock);
}
--m_count;
}
inline bool interprocess_semaphore::try_wait()
{
scoped_lock<interprocess_mutex> 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<interprocess_mutex> 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<interprocess_mutex> lock(m_mut);
return count;
}*/
} //namespace interprocess {
} //namespace boost {

View File

@@ -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 <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
# include <stddef.h>
# include <stdarg.h>
# include <boost/detail/interlocked.hpp>
#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 <windows.h>
#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 <boost/interprocess/detail/config_end.hpp>
#endif //#ifdef BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP