Boost logo

Boost-Commit :

From: igaztanaga_at_[hidden]
Date: 2007-08-24 17:24:25


Author: igaztanaga
Date: 2007-08-24 17:24:23 EDT (Fri, 24 Aug 2007)
New Revision: 38911
URL: http://svn.boost.org/trac/boost/changeset/38911

Log:
Erased old archives imported from CVS
Removed:
   trunk/boost/interprocess/containers/detail/tree_func.hpp
   trunk/boost/interprocess/containers/tree.hpp
   trunk/boost/interprocess/detail/multi_segment_services.hpp
   trunk/boost/interprocess/intersegment_ptr.hpp
   trunk/boost/interprocess/managed_multi_shared_memory.hpp
   trunk/boost/interprocess/mem_algo/multi_simple_seq_fit.hpp

Deleted: trunk/boost/interprocess/containers/detail/tree_func.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/tree_func.hpp 2007-08-24 17:24:23 EDT (Fri, 24 Aug 2007)
+++ (empty file)
@@ -1,899 +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_tree file. Modified by Ion Gaztañaga 2005.
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_TREE_FUNC_HPP
-#define BOOST_INTERPROCESS_TREE_FUNC_HPP
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/iterator.hpp>
-
-namespace boost {
-namespace interprocess {
-namespace detail {
-
-template <class VoidPointer>
-struct rb_tree_node_base
-{
- typedef typename boost::interprocess::detail::pointer_to_other
- <VoidPointer, rb_tree_node_base<VoidPointer> >::type basic_node_pointer;
-
- enum color_t { red_color = false, black_color = true };
-
- const basic_node_pointer &parent() const { return mp_parent; }
- basic_node_pointer &parent() { return mp_parent; }
- const basic_node_pointer &left() const { return mp_left; }
- basic_node_pointer &left() { return mp_left; }
- const basic_node_pointer &right() const { return mp_right; }
- basic_node_pointer &right() { return mp_right; }
- const color_t &color() const { return m_color; }
- color_t &color() { return m_color; }
- private:
- basic_node_pointer mp_parent;
- basic_node_pointer mp_left;
- basic_node_pointer mp_right;
- color_t m_color;
-};
-
-/*!Basic red-black tree functions that don't need
- comparison operator*/
-template <class NodeBase>
-class rb_tree_algo
-{
- typedef typename NodeBase::basic_node_pointer basic_node_pointer;
- public:
- static basic_node_pointer next_node(basic_node_pointer node)
- {
- if (node->right()) {
- node = node->right();
- while (node->left()){
- node = node->left();
- }
- }
- else{
- basic_node_pointer y = node->parent();
- while (node == y->right()) {
- node = y;
- y = y->parent();
- }
- if (node->right() != y)
- node = y;
- }
- return node;
- }
-
- static basic_node_pointer previous_node(basic_node_pointer node)
- {
- if (node->color() == NodeBase::red_color &&
- node->parent()->parent() == node){
- node = node->right();
- }
- else if (node->left()) {
- basic_node_pointer y = node->left();
- while (y->right()){
- y = y->right();
- }
- node = y;
- }
- else{
- basic_node_pointer y = node->parent();
- while (node == y->left()) {
- node = y;
- y = y->parent();
- }
- node = y;
- }
- return node;
- }
-
- static bool is_header (const basic_node_pointer p)
- {
- return p->color() == NodeBase::red_color && p->parent()->parent() == p;
- }
-
- static basic_node_pointer minimum_node(basic_node_pointer x)
- {
- while (x->left()){
- x = x->left();
- }
- return x;
- }
-
- static basic_node_pointer maximum_node(basic_node_pointer x)
- {
- while (x->right()){
- x = x->right();
- }
- return x;
- }
-
- static void replace_own (const basic_node_pointer &header,
- const basic_node_pointer &own,
- const basic_node_pointer &p)
- {
- if (header->parent() == own)
- header->parent() = p;
- else if (own->parent()->left() == own)
- own->parent()->left() = p;
- else
- own->parent()->right() = p;
- }
-
- static void rotate_left(const basic_node_pointer &header, basic_node_pointer x)
- {
- basic_node_pointer y = x->right();
- x->right() = y->left();
- if (y->left() !=0)
- y->left()->parent() = x;
- y->parent() = x->parent();
- replace_own(header, x, y);
- y->left() = x;
- x->parent() = y;
- }
-
- static void rotate_right(const basic_node_pointer &header, basic_node_pointer x)
- {
- basic_node_pointer y = x->left();
- x->left() = y->right();
- if (y->right())
- y->right()->parent() = x;
- y->parent() = x->parent();
- replace_own(header, x, y);
- y->right() = x;
- x->parent() = y;
- }
-
- static void rebalance(const basic_node_pointer &header, basic_node_pointer x)
- {
- x->color() = NodeBase::red_color;
- while (x != header->parent() && x->parent()->color() == NodeBase::red_color) {
- if (x->parent() == x->parent()->parent()->left()) {
- basic_node_pointer y = x->parent()->parent()->right();
- if (y && y->color() == NodeBase::red_color) {
- x->parent()->color() = NodeBase::black_color;
- y->color() = NodeBase::black_color;
- x->parent()->parent()->color() = NodeBase::red_color;
- x = x->parent()->parent();
- }
- else{
- if (x == x->parent()->right()) {
- x = x->parent();
- rotate_left(header, x);
- }
- x->parent()->color() = NodeBase::black_color;
- x->parent()->parent()->color() = NodeBase::red_color;
- rotate_right(header, x->parent()->parent());
- }
- }
- else{
- basic_node_pointer y = x->parent()->parent()->left();
- if (y && y->color() == NodeBase::red_color) {
- x->parent()->color() = NodeBase::black_color;
- y->color() = NodeBase::black_color;
- x->parent()->parent()->color() = NodeBase::red_color;
- x = x->parent()->parent();
- }
- else{
- if (x == x->parent()->left()) {
- x = x->parent();
- rotate_right(header, x);
- }
- x->parent()->color() = NodeBase::black_color;
- x->parent()->parent()->color() = NodeBase::red_color;
- rotate_left(header, x->parent()->parent());
- }
- }
- }
- header->parent()->color() = NodeBase::black_color;
- }
-
- static basic_node_pointer erase_node
- (const basic_node_pointer &header, basic_node_pointer z)
- {
- basic_node_pointer& root = header->parent();
- basic_node_pointer& leftmost = header->left();
- basic_node_pointer& rightmost = header->right();
- basic_node_pointer y = z;
- basic_node_pointer x = 0;
- basic_node_pointer x_parent = 0;
- if (!y->left()) // z has at most one non-null child. y == z.
- x = y->right(); // x might be null.
- else
- if (!y->right()) // z has exactly one non-null child. y == z.
- x = y->left(); // x is not null.
- else{ // z has two non-null children. Set y to
- y = y->right(); // z's successor. x might be null.
- while (y->left())
- y = y->left();
- x = y->right();
- }
- if (y != z) { // relink y in place of z. y is z's successor
- z->left()->parent() = y;
- y->left() = z->left();
- if (y != z->right()) {
- x_parent = y->parent();
- if (x)
- x->parent() = y->parent();
- y->parent()->left() = x; // y must be a child of mp_left
- y->right() = z->right();
- z->right()->parent() = y;
- }
- else
- x_parent = y;
-
- replace_own(header, z, y);
- y->parent() = z->parent();
- std::swap(y->color(), z->color());
- y = z;
- // y now points to node to be actually deleted
- }
- else{ // y == z
- x_parent = y->parent();
- if (x)
- x->parent() = y->parent();
-
- replace_own(header, z, x);
-
- if (leftmost == z)
- if (!z->right()) // z->left must be null also
- leftmost = z->parent();
- // makes leftmost == this->m_header if z == root
- else
- leftmost = minimum_node(x);
- if (rightmost == z)
- if (!z->left()) // z->right must be null also
- rightmost = z->parent();
- // makes rightmost == this->m_header if z == root
- else // x == z->left
- rightmost = maximum_node(x);
- }
- if (y->color() != NodeBase::red_color) {
- while (x != root && (!x || x->color() == NodeBase::black_color))
- if (x == x_parent->left()) {
- basic_node_pointer w = x_parent->right();
- if (w->color() == NodeBase::red_color) {
- w->color() = NodeBase::black_color;
- x_parent->color() = NodeBase::red_color;
- rotate_left(header, x_parent);
- w = x_parent->right();
- }
- if ((!w->left() ||
- w->left()->color() == NodeBase::black_color) &&
- (!w->right() ||
- w->right()->color() == NodeBase::black_color)) {
- w->color() = NodeBase::red_color;
- x = x_parent;
- x_parent = x_parent->parent();
- }
- else{
- if (!w->right() ||
- w->right()->color() == NodeBase::black_color) {
- if (w->left())
- w->left()->color() = NodeBase::black_color;
- w->color() = NodeBase::red_color;
- rotate_right(header, w);
- w = x_parent->right();
- }
- w->color() = x_parent->color();
- x_parent->color() = NodeBase::black_color;
- if (w->right())
- w->right()->color() = NodeBase::black_color;
- rotate_left(header, x_parent);
- break;
- }
- }
- else{
- // same as above, with mp_right <-> mp_left.
- basic_node_pointer w = x_parent->left();
- if (w->color() == NodeBase::red_color) {
- w->color() = NodeBase::black_color;
- x_parent->color() = NodeBase::red_color;
- rotate_right(header, x_parent);
- w = x_parent->left();
- }
- if ((!w->right() ||
- w->right()->color() == NodeBase::black_color) &&
- (!w->left() ||
- w->left()->color() == NodeBase::black_color)) {
- w->color() = NodeBase::red_color;
- x = x_parent;
- x_parent = x_parent->parent();
- }
- else{
- if (!w->left() ||
- w->left()->color() == NodeBase::black_color) {
- if (w->right())
- w->right()->color() = NodeBase::black_color;
- w->color() = NodeBase::red_color;
- rotate_left(header, w);
- w = x_parent->left();
- }
- w->color() = x_parent->color();
- x_parent->color() = NodeBase::black_color;
- if (w->left())
- w->left()->color() = NodeBase::black_color;
- rotate_right(header, x_parent);
- break;
- }
- }
- if (x)
- x->color() = NodeBase::black_color;
- }
- return y;
- }
-
- static basic_node_pointer link_and_rebalance
- (basic_node_pointer header, bool link_left, basic_node_pointer y, basic_node_pointer z)
- {
-
- z->parent() = y;
- z->left() = 0;
- z->right() = 0;
-
- //when y == _header
- if (y == header) {
- header->left() = z;
- header->parent() = z;
- header->right() = z;
- }
- else if (link_left) {
- y->left() = z;
- if (y == header->left()){
- header->left() = z; // maintain header->right() pointing to max node
- }
- }
- else{
- y->right() = z;
- if (y == header->right()){
- header->right() = z; // maintain header->right() pointing to max node
- }
- }
- rebalance(header, z);
- return z;
-/*
- if (link_left) {
- y->left() = z; // also makes header->left() = z
- // when y == _header
- if (y == header) {
- header->parent() = z;
- header->right() = z;
- }
- else if (y == header->left())
- header->left() = z; // maintain header->left() pointing to min node
- }
- else{
- y->right() = z;
- if (y == header->right())
- header->right() = z; // maintain header->right() pointing to max node
- }
- z->parent() = y;
- z->left() = 0;
- z->right() = 0;
- rebalance(header, z);
- return z;*/
- }
-
- static void clear(basic_node_pointer header)
- {
- header->left() = header;
- header->right() = header;
- header->parent() = 0;
- }
-
- static bool empty(const basic_node_pointer &header) { return !header->parent(); }
-};
-
-/*!Basic red-black tree functions that only need
- the comparison functor and functors to obtain the
- key from a value*/
-
-template <class Node, class Key, class KeyOfValue,
- class KeyCompare>
-class rb_tree_func : public rb_tree_algo<Node>
-{
- typedef rb_tree_algo<rb_tree_node_base<typename pointer_to_other
- <typename Node::basic_node_pointer, void>::type> > rb_tree_algo_t;
-
-// typedef rb_tree_algo<Node> rb_tree_algo_t;
- typedef typename Node::node_pointer node_pointer;
- typedef typename Node::basic_node_pointer basic_node_pointer;
-
- static bool node_compare (const KeyCompare &key_compare,
- const node_pointer &node,
- const node_pointer &other_node)
- {
- return key_compare(KeyOfValue()(node->value()),
- KeyOfValue()(other_node->value()));
- }
-
- public:
-
- struct insert_unique_context
- {
- bool link_left;
- basic_node_pointer node;
- };
-
- static node_pointer find(const node_pointer &header,
- const KeyCompare &key_compare,
- const Key& k)
- {
- basic_node_pointer y = header; // Last node which is not less than k.
- basic_node_pointer x = header->parent(); // Current node.
- while (x) {
- if (!(key_compare(KeyOfValue()(Node::downcast(x)->value()), k))){
- y = x, x = x->left();
- }
- else{
- x = x->right();
- }
- }
-
- if(y == header || key_compare(k, KeyOfValue()(Node::downcast(y)->value()))){
- y = header;
- }
- return Node::downcast(y);
- }
-
- static node_pointer upper_bound(const node_pointer &header,
- const KeyCompare &key_compare,
- const Key& k)
- {
- basic_node_pointer y = header; //Last node which is greater than k.
- basic_node_pointer x = header->parent(); //Current node.
-
- while (x){
- if (key_compare(k, KeyOfValue()(Node::downcast(x)->value()))){
- y = x, x = x->left();
- }
- else{
- x = x->right();
- }
- }
- return Node::downcast(y);
- }
-
- static node_pointer lower_bound(const node_pointer &header,
- const KeyCompare &key_compare,
- const Key& k)
- {
- basic_node_pointer y = header; // Last node which is not less than k.
- basic_node_pointer x = header->parent(); // Current node.
-
- while (x){
- if (!key_compare(KeyOfValue()(Node::downcast(x)->value()), k)){
- y = x, x = x->left();
- }
- else{
- x = x->right();
- }
- }
- return Node::downcast(y);
- }
-
- static bool insert_unique (const node_pointer &header,
- const KeyCompare &key_compare,
- node_pointer &new_node,
- node_pointer &out)
- {
- insert_unique_context context;
- if(!insert_unique_prepare(header, key_compare, KeyOfValue()(new_node->value()), out, context)){
- return false;
- }
- insert_unique_commit(header, key_compare, new_node, out, context);
- return true;
- }
-
- static bool insert_unique_hint(const node_pointer &header,
- const KeyCompare &key_compare,
- const node_pointer &hint,
- node_pointer &new_node,
- node_pointer &out)
- {
- insert_unique_context context;
- if(!insert_unique_hint_prepare
- (header, hint, key_compare, KeyOfValue()(new_node->value()), out, context)){
- return false;
- }
- insert_unique_commit(header, key_compare, new_node, out, context);
- return true;
- }
-
- static bool insert_unique_prepare (const node_pointer & header,
- const KeyCompare &key_compare,
- const Key &key,
- insert_unique_context &context)
- {
- basic_node_pointer x(header->parent());
- basic_node_pointer y(header);
- basic_node_pointer prev(0);
-
- //Find the upper bound, and cache the previous value and if we should
- //store it in the left or right node
- bool left_child = true;
- while (x) {
- y = x;
- x = (left_child = key_compare(key, KeyOfValue()(Node::downcast(x)->value())))
- ? (x->left())
- : (prev = y, x->right());
- }
-
- //Since we've found the upper bound there is no other value with the same key if:
- // - There is no previous node
- // - The previous node is less than the key
- if(!prev || key_compare(KeyOfValue()(Node::downcast(prev)->value()), key)){
- context.link_left = left_child;
- context.node = y;
- return true;
- }
- //If the previous value was not less than key, it means that it's equal
- //(because we've checked the upper bound)
- else{
- context.node = prev;
- return false;
- }
- }
-
- static bool insert_unique_hint_prepare(const node_pointer &header,
- const KeyCompare &key_compare,
- const node_pointer &hint,
- const Key &key,
- insert_unique_context &context)
- {
- //hint must be bigger than the key
- if (hint == header || key_compare(key, KeyOfValue()(hint->value()))){
- node_pointer prev = hint;
- //The previous value should be less than the key
- if (prev == header->left() ||
- key_compare(KeyOfValue()((prev = Node::downcast(previous_node(hint)))->value()), key)){
- context.link_left = empty(header) || !hint->left();
- context.node = context.link_left ? hint : prev;
- return true;
- }
- //The value is already present
- else{
- context.link_left = false;
- context.node = prev;
- return false;
- }
- }
- //The hint was wrong, use hintless insert
- else{
- return insert_unique_prepare(header, key_compare, key, context);
- }
- }
-
- static void insert_unique_commit (const node_pointer &header,
- const KeyCompare &key_compare,
- node_pointer &new_node,
- insert_unique_context &context)
- {
- rb_tree_algo_t::link_and_rebalance
- (header, context.link_left, context.node, new_node);
- }
-
- static void insert_equal (const node_pointer & header,
- const KeyCompare &key,
- node_pointer &new_node)
- {
- insert_equal_upper(header, key, new_node);
- }
-
- static void insert_equal_lower (const node_pointer & header,
- const KeyCompare &key,
- node_pointer &new_node)
- {
- basic_node_pointer y = header;
- basic_node_pointer x = header->parent();
-
- while (x) {
- y = x;
- x = !node_compare(key, Node::downcast(x), new_node)
- ? x->left() : x->right();
- }
-
- bool link_left = (y == header) || !node_compare(key, Node::downcast(y), new_node);
- rb_tree_algo_t::link_and_rebalance(header, link_left, y, new_node);
- }
-
- static void insert_equal_upper (const node_pointer & header,
- const KeyCompare &key,
- node_pointer &new_node)
- {
- basic_node_pointer y = header;
- basic_node_pointer x = header->parent();
-
- while (x) {
- y = x;
- x = node_compare(key, new_node, Node::downcast(x))
- ? x->left() : x->right();
- }
-
- bool link_left = (y == header) || node_compare(key, new_node, Node::downcast(y));
- rb_tree_algo_t::link_and_rebalance(header, link_left, y, new_node);
- }
-
- static void insert_equal_hint (const node_pointer & header,
- const KeyCompare &key_compare,
- const node_pointer &hint,
- node_pointer &new_node)
- {
- if(hint == header || !node_compare(key_compare, hint, new_node)){
- node_pointer prev;
- if(hint == header->left() ||
- !node_compare(key_compare, new_node,
- (prev = Node::downcast(previous_node(hint))))){
- bool link_left = empty(header) || !hint->left();
- rb_tree_algo_t::link_and_rebalance
- (header, link_left, link_left ? hint : prev, new_node);
- }
- else{
- insert_equal_upper(header, key_compare, new_node);
- }
- }
- else{
- insert_equal_lower(header, key_compare, new_node);
- }
- }
-
- static std::size_t erase_with_key(const node_pointer &header,
- const KeyCompare &key_compare,
- const Key& k)
- {
- node_pointer lower, upper, tmp;
- rb_tree_algo_t::equal_range(header, k, lower, upper);
- std::size_t count = 0;
-
- while(lower != upper){
- tmp = lower;
- lower = rb_tree_algo_t::next_node(lower);
- rb_tree_algo_t::erase(header, tmp);
- ++count;
- }
- return count;
- }
-
- static void equal_range(const node_pointer &header,
- const KeyCompare &key_compare,
- const Key& k,
- node_pointer &lower,
- node_pointer &upper)
- {
-// lower = lower_bound(header, key_compare, k);
-// upper = upper_bound(header, key_compare, k);
- basic_node_pointer y = header; // Last node which is not less than k.
- basic_node_pointer x = header->parent(); // Current node.
-
- while (x){
- //Execute common logic
- if (key_compare(KeyOfValue()(Node::downcast(x)->value()), k)){
- x = x->right();
- }
- else if (key_compare(k, KeyOfValue()(Node::downcast(x)->value()))){
- y = x, x = x->left();
- }
- //Now lower and upper bounds needs to follow different subtrees
- else{
- basic_node_pointer xu(x), yu(y);
- y = x, x = x->left();
- xu = xu->right();
-
- while (x){
- if (key_compare(KeyOfValue()(Node::downcast(x)->value()), k)){
- x = x->right();
- }
- else{
- y = x, x = x->left();
- }
- }
- while (xu){
- if (key_compare(k, KeyOfValue()(Node::downcast(xu)->value()))){
- yu = xu, xu = xu->left();
- }
- else{
- xu = xu->right();
- }
- }
- lower = Node::downcast(y);
- upper = Node::downcast(yu);
- return;
- }
- }
- lower = upper = Node::downcast(y);
- }
-
- static std::size_t count(const node_pointer &header,
- const KeyCompare &key_compare,
- const Key& k)
- {
- node_pointer lower, upper;
- equal_range(header, key_compare, k, lower, upper);
- std::size_t count = 0;
- while(lower != upper){
- lower = Node::downcast(rb_tree_algo_t::next_node(lower));
- ++count;
- }
- return count;
- }
-
-};
-
-template <class Node>
-class rb_tree_const_iterator
- : public boost::iterator<std::bidirectional_iterator_tag,
- typename Node::value_type,
- typename Node::difference_type,
- typename Node::const_pointer,
- typename Node::const_reference>
-{
- private:
- typedef boost::iterator<std::bidirectional_iterator_tag,
- typename Node::value_type,
- typename Node::difference_type,
- typename Node::const_pointer,
- typename Node::const_reference> base_t;
-
- protected:
- typedef typename Node::node_pointer node_pointer;
- typedef typename Node::basic_node_pointer basic_node_pointer;
- typedef rb_tree_algo<Node> rb_tree_algo_t;
- node_pointer mp_node;
-
- public:
- typedef typename base_t::pointer pointer;
- typedef typename base_t::reference reference;
- typedef typename base_t::difference_type difference_type;
- typedef typename base_t::iterator_category iterator_category;
- typedef typename base_t::value_type value_type;
-
- rb_tree_const_iterator()
- {}
-/*
- explicit rb_tree_const_iterator(const node_pointer &x)
- : mp_node(x)
- {}
-
-*/
- explicit rb_tree_const_iterator(const basic_node_pointer &x)
- : mp_node(Node::downcast(x))
- {}
-
- rb_tree_const_iterator(const rb_tree_const_iterator & it)
- : mp_node(it.get_ptr())
- {}
-
- reference operator*() const
- { return mp_node->value(); }
-
- pointer operator->() const
- { return pointer(&mp_node->value()); }
-
- rb_tree_const_iterator& operator++()
- {
- mp_node = Node::downcast(rb_tree_algo_t::next_node(mp_node));
- return *this;
- }
-
- rb_tree_const_iterator operator++(int)
- {
- rb_tree_const_iterator tmp = *this;
- mp_node = rb_tree_algo_t::next_node(mp_node);
- return tmp;
- }
-
- rb_tree_const_iterator& operator--()
- {
- mp_node = rb_tree_algo_t::previous_node(mp_node);
- return *this;
- }
-
- rb_tree_const_iterator operator--(int)
- {
- rb_tree_const_iterator tmp = *this;
- mp_node = rb_tree_algo_t::previous_node(mp_node);
- return tmp;
- }
-
- friend bool operator==(const rb_tree_const_iterator& x, const rb_tree_const_iterator& y)
- { return x.get_ptr() == y.get_ptr(); }
-
- friend bool operator!=(const rb_tree_const_iterator& x, const rb_tree_const_iterator& y)
- { return x.get_ptr() != y.get_ptr(); }
-
- node_pointer &get_ptr()
- { return mp_node; }
-
- const node_pointer &get_ptr() const
- { return mp_node; }
-};
-
-//list rb_tree_iterator
-template <class Node>
-class rb_tree_iterator : public rb_tree_const_iterator<Node>
-{
- private:
- typedef rb_tree_const_iterator<Node> base_t;
- typedef typename base_t::node_pointer node_pointer;
- typedef typename base_t::basic_node_pointer basic_node_pointer;
- public:
- typedef typename Node::pointer pointer;
- typedef typename Node::reference reference;
-
- //Constructors
- rb_tree_iterator()
- {}
-/*
- explicit rb_tree_iterator(const node_pointer &ptr)
- : base_t(ptr)
- {}
-*/
- explicit rb_tree_iterator(const basic_node_pointer &ptr)
- : base_t(ptr)
- {}
-
- //Pointer like operators
- reference operator*() const { return this->mp_node->value(); }
- pointer operator->() const { return pointer(&this->mp_node->value()); }
-
- //Increment / Decrement
- rb_tree_iterator& operator++()
- { base_t::operator++(); return *this; }
-
- rb_tree_iterator operator++(int)
- { node_pointer tmp = this->mp_node; ++*this; return rb_tree_iterator(tmp); }
-
- rb_tree_iterator& operator--()
- { base_t::operator--(); return *this; }
-
- rb_tree_iterator operator--(int)
- { rb_tree_iterator tmp = *this; --*this; return tmp; }
-};
-
-} //namespace detail {
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_TREE_FUNC_HPP
-

Deleted: trunk/boost/interprocess/containers/tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/tree.hpp 2007-08-24 17:24:23 EDT (Fri, 24 Aug 2007)
+++ (empty file)
@@ -1,839 +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_tree file. Modified by Ion Gaztañaga 2005.
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_TREE_HPP
-#define BOOST_INTERPROCESS_TREE_HPP
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/containers/detail/tree_func.hpp>
-#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
-#include <boost/detail/allocator_utilities.hpp>
-#include <boost/interprocess/detail/generic_cast.hpp>
-#include <boost/iterator/reverse_iterator.hpp>
-#include <boost/type_traits/has_trivial_constructor.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/mpl/if.hpp>
-
-#include <iterator>
-#include <algorithm>
-
-//Red-black tree class, designed for use in implementing STL
-//associative containers (set, multiset, map, and multimap). The
-//insertion and deletion algorithms are based on those in Cormen,
-//Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
-//except that
-//
-//(1) the header cell is maintained with links not only to the root
-//but also to the leftmost node of the tree, to enable constant time
-//this->begin(), and to the rightmost node of the tree, to enable linear time
-//performance when used with the generic set algorithms (set_union,
-//etc.);
-//
-//(2) when a node being deleted has two children its successor node is
-//relinked into its place, rather than copied, so that the only
-//iterators invalidated are those referring to the deleted node.
-
-namespace boost { namespace interprocess { namespace detail {
-
-template <class Alloc>
-struct rb_tree_node
- : rb_tree_node_base<typename pointer_to_other<typename Alloc::pointer, void>::type>
-{
- typedef rb_tree_node_base<typename pointer_to_other
- <typename Alloc::pointer, void>::type> base_t;
- typedef typename boost::detail::allocator::
- rebind_to<Alloc, rb_tree_node<Alloc> >::type node_allocator_t;
-
- typedef typename base_t::basic_node_pointer basic_node_pointer;
- typedef typename node_allocator_t::pointer node_pointer;
- typedef typename Alloc::value_type value_type;
- typedef typename Alloc::const_pointer const_pointer;
- typedef typename Alloc::pointer pointer;
- typedef typename Alloc::const_reference const_reference;
- typedef typename Alloc::reference reference;
- typedef typename Alloc::difference_type difference_type;
-
- rb_tree_node(const value_type & value)
- : m_value(value)
- {}
-
- rb_tree_node(const detail::moved_object<value_type> & value)
- : m_value(move(value.get()))
- {}
-
- static node_pointer downcast(basic_node_pointer upclass_pointer/*const basic_node_pointer &upclass_pointer*/)
- {
- return boost::interprocess::cast_to<node_pointer>::using_static_cast(upclass_pointer);
-// return boost::interprocess::do_static_cast<node_pointer>(upclass_pointer);
- }
-
- const value_type &value() const { return m_value; }
- value_type &value() { return m_value; }
- private:
- value_type m_value;
-};
-
-template <class T, class Alloc>
-class rb_tree_alloc_base/*<T, Alloc, true>*/
- //Inherit from node allocator
- : public boost::detail::allocator::
- rebind_to<Alloc, rb_tree_node<Alloc> >::type
-{
- public:
- typedef typename boost::detail::allocator::
- rebind_to<Alloc, rb_tree_node<Alloc> >::type node_allocator_t;
- typedef typename node_allocator_t::value_type node_val_t;
- typedef typename node_allocator_t::pointer node_pointer;
-
- typedef typename boost::detail::allocator::
- rebind_to<Alloc, T>::type value_allocator_t;
- typedef typename value_allocator_t::value_type value_val_t;
- typedef typename value_allocator_t::pointer value_ptr_t;
- typedef typename value_allocator_t::const_pointer value_cptr_t;
- typedef typename value_allocator_t::reference value_ref_t;
- typedef typename value_allocator_t::const_reference value_cref_t;
-
- typedef typename boost::detail::allocator::
- rebind_to<Alloc, typename node_val_t::
- basic_node_pointer>::type basic_node_ptr_allocator_t;
- typedef typename basic_node_ptr_allocator_t::pointer basic_node_ptr_ptr_t;
- typedef typename basic_node_ptr_allocator_t::value_type basic_node_ptr_t;
-
- typedef typename node_val_t::base_t base_node_t;
-
- typedef detail::scoped_deallocator<node_allocator_t> NodeDeallocator;
- typedef detail::scoped_destructor <basic_node_ptr_allocator_t> BasicPtrDestructor;
-
- rb_tree_alloc_base(const value_allocator_t& a)
- : node_allocator_t(a)
- { this->initialize_when_empty(); }
-
- rb_tree_alloc_base(const rb_tree_alloc_base &x)
- : node_allocator_t(x)
- { this->initialize_when_empty(); }
-
- rb_tree_alloc_base(const detail::moved_object<rb_tree_alloc_base> &x)
- : node_allocator_t(move((node_allocator_t&)x.get()))
- { this->initialize_when_empty(); this->swap(x.get()); }
-
- ~rb_tree_alloc_base()
- { this->uninitialize_when_empty(); }
-
- template<class Convertible>
- static void construct(const node_pointer &ptr, const Convertible &value)
- { new(detail::get_pointer(ptr)) node_val_t(value); }
-
- template<class Convertible1, class Convertible2>
- static void construct(const node_pointer &ptr,
- const detail::moved_object<std::pair<Convertible1, Convertible2> > &value)
- {
- //std::pair is not movable so we define our own type and overwrite it
- typedef detail::pair<typename node_val_t::value_type::first_type
- ,typename node_val_t::value_type::second_type> hack_pair_t;
-
- typedef typename boost::detail::allocator::
- rebind_to<Alloc, hack_pair_t>::type hack_pair_allocator_t;
-
- typedef rb_tree_node<hack_pair_allocator_t> hack_node_t;
-
- new((void*)detail::get_pointer(ptr)) hack_node_t(value);
- }
-
- static void destroy(const node_pointer &ptr)
- { detail::get_pointer(ptr)->~node_val_t(); }
-
- template<class Convertible>
- node_pointer allocate_and_construct_node(const Convertible &x)
- {
- node_pointer p = node_allocator_t::allocate(1);
- scoped_ptr<node_val_t, NodeDeallocator>node_deallocator(p, *this);
-// node_allocator_t::construct(p, x);
- construct(p, x);
- node_deallocator.release();
- return p;
- }
-
- void destroy_and_deallocate_node(node_pointer p)
- {
- node_allocator_t::destroy(p);
- node_allocator_t::deallocate(p, 1);
- }
-
- typename node_allocator_t::size_type max_size() const
- { return node_allocator_t::max_size(); }
-
- void swap (rb_tree_alloc_base &x)
- {
- node_allocator_t& this_alloc = static_cast<node_allocator_t&>(*this);
- node_allocator_t& other_alloc = static_cast<node_allocator_t&>(x);
- if (this_alloc != other_alloc){
- detail::do_swap(this_alloc, other_alloc);
- }
-
- std::swap(this->m_end, x.m_end);
-
- if (this->m_end.parent())
- this->m_end.parent()->parent() = this->end_node();
- else
- this->m_end.left() = this->m_end.right() = this->end_node();
-
- if (x.m_end.parent())
- x.m_end.parent()->parent() = x.end_node();
- else
- x.m_end.left() = x.m_end.right() = x.end_node();
- /*
- node_allocator_t& this_alloc = static_cast<node_allocator_t&>(*this);
- node_allocator_t& other_alloc = static_cast<node_allocator_t&>(x);
- if (this_alloc != other_alloc){
- detail::do_swap(this_alloc, other_alloc);
- }
- detail::do_swap(this->m_header, x.m_header);
-*/
- }
-
- private:
- void initialize_when_empty()
- {
-/*
- this->m_header = node_allocator_t::allocate(1);
-
- //If the pointer type a has trivial constructor we can avoid this
- if(!boost::has_trivial_constructor<node_pointer>::value){
- basic_node_ptr_allocator_t node_ptr_allocator(*this);
- scoped_ptr<node_val_t, NodeDeallocator>node_deallocator(this->m_header, *this);
- basic_node_ptr_ptr_t pleft(node_ptr_allocator.address(this->m_header->left())),
- pright(node_ptr_allocator.address(this->m_header->right())),
- pparent(node_ptr_allocator.address(this->m_header->parent()));
-
- //Make sure destructors are called before memory is freed
- //if an exception is thrown
- {
- node_ptr_allocator.construct(pleft, basic_node_ptr_t());
- scoped_ptr<basic_node_ptr_t, BasicPtrDestructor>
- left_destroy(pleft, node_ptr_allocator);
-
- node_ptr_allocator.construct(pright, basic_node_ptr_t());
- scoped_ptr<basic_node_ptr_t, BasicPtrDestructor>
- right_destroy(pright, node_ptr_allocator);
-
- node_ptr_allocator.construct(pparent, basic_node_ptr_t());
-
- left_destroy.release();
- right_destroy.release();
- }
- node_deallocator.release();
- }
-*/
- //m_value is not constructed since it is not used
- //m_color is POD so we don't need to construct it.
- //used to distinguish header from root, in iterator.operator++
- this->m_end.color() = node_val_t::red_color;
- this->m_end.parent() = 0;
- this->m_end.left() = this->end_node();
- this->m_end.right() = this->end_node();
-
-/*
- //m_value is not constructed since it is not used
- //m_color is POD so we don't need to construct it
- this->m_header->color() = node_val_t::red_color; // used to distinguish header from
- // root, in iterator.operator++
- this->m_header->parent() = 0;
- this->m_header->left() = this->m_header;
- this->m_header->right() = this->m_header;
-*/
- }
-
- void uninitialize_when_empty()
- {/*
- if(this->m_header){
- //If the pointer type a has trivial destructor we can avoid this
- if(!boost::has_trivial_destructor<node_pointer>::value){
- basic_node_ptr_allocator_t node_ptr_allocator(*this);
- //Destructors must not throw
- node_ptr_allocator.destroy(node_ptr_allocator.address(this->m_header->left()));
- node_ptr_allocator.destroy(node_ptr_allocator.address(this->m_header->right()));
- node_ptr_allocator.destroy(node_ptr_allocator.address(this->m_header->parent()));
- }
- //m_color is POD so we don't need to destroy it
- //m_value was not constructed so we don't need to destroy it
- node_allocator_t::deallocate(this->m_header, 1);
- }*/
- }
-
- protected:
-
- basic_node_ptr_t end_node() const
- { return basic_node_ptr_t(const_cast<base_node_t *>(&m_end)); }
-
- base_node_t m_end;
-// node_pointer m_header;
-
-};
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-class rb_tree
- : protected rb_tree_alloc_base<Value, Alloc/*,
- has_convertible_construct<Alloc>::value*/>
-{
- private:
- typedef rb_tree_alloc_base<Value, Alloc/*,
- has_convertible_construct<Alloc>::value*/> base_t;
- typedef typename base_t::node_pointer node_pointer;
- typedef typename base_t::node_val_t node_val_t;
- typedef typename node_val_t::basic_node_pointer basic_node_pointer;
- typedef rb_tree_algo<node_val_t> rb_tree_algo_t;
- typedef rb_tree_func<node_val_t, Key,
- KeyOfValue, Compare > rb_tree_func_t;
-
- public:
- typedef Key key_type;
- typedef Value value_type;
- typedef typename base_t::value_ptr_t pointer;
- typedef typename base_t::value_cptr_t const_pointer;
- typedef typename base_t::value_ref_t reference;
- typedef typename base_t::value_cref_t const_reference;
- typedef typename base_t::value_allocator_t allocator_type;
- typedef typename allocator_type::size_type size_type;
- typedef typename allocator_type::difference_type difference_type;
- typedef rb_tree_const_iterator<node_val_t> const_iterator;
- typedef rb_tree_iterator<node_val_t> iterator;
- typedef boost::reverse_iterator<iterator> reverse_iterator;
- typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
-
- rb_tree(const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : base_t(a), m_data(comp, 0)
- { }
-
- rb_tree(const rb_tree& x)
- : base_t(x),
- m_data(x.get_compare(), 0)
- {
- if (x.root()){
- this->m_end.color() = node_val_t::red_color;
- this->root()=
- this->copy_node(node_val_t::downcast(this->m_end.parent()),
- this->end_node());
- this->leftmost() =
- rb_tree_algo_t::minimum_node(node_val_t::downcast(this->root()));
- this->rightmost() =
- rb_tree_algo_t::maximum_node(node_val_t::downcast(this->root()));
- }
-
- this->m_data.m_node_count = x.m_data.m_node_count;
- }
-
- rb_tree(const detail::moved_object<rb_tree>& x)
- : base_t(move((base_t&)x.get())),
- m_data(move(x.get().get_compare()), 0)
- {
- x.get().m_data.m_node_count = 0;
- }
-
- ~rb_tree() { this->clear(); }
-
- rb_tree& operator=(const rb_tree& x)
- {
- if (this != &x) {
- // Note that Key may be a constant type.
- this->clear();
- this->m_data.m_node_count = 0;
- this->get_compare() = x.get_compare();
- if (!x.root()) {
- this->root() = 0;
- this->leftmost() = this->end_node();
- this->rightmost() = this->end_node();
- }
- else{
- this->root() = this->copy_node(x.root(), this->end_node());
- this->leftmost() =
- rb_tree_algo_t::minimum_node(node_val_t::downcast(this->root()));
- this->rightmost() =
- rb_tree_algo_t::maximum_node(node_val_t::downcast(this->root()));
- this->m_data.m_node_count = x.m_data.m_node_count;
- }
- }
- return *this;
- }
-
- public:
- // accessors:
- Compare key_comp() const
- { return this->get_compare(); }
-
- allocator_type get_allocator() const
- { return allocator_type(*this); }
-
- iterator begin()
- { basic_node_pointer a;
- iterator b(a);
-
- return iterator(this->leftmost()); }
-
- const_iterator begin() const
- { return const_iterator(this->leftmost()); }
-
- iterator end()
- { return iterator(this->end_node()); }
-
- const_iterator end() const
- { return const_iterator(this->end_node()); }
-
- reverse_iterator rbegin()
- { return reverse_iterator(this->end()); }
-
- const_reverse_iterator rbegin() const
- { return const_reverse_iterator(this->end()); }
-
- reverse_iterator rend()
- { return reverse_iterator(this->begin()); }
-
- const_reverse_iterator rend() const
- { return const_reverse_iterator(this->begin()); }
-
- bool empty() const
- { return !this->m_data.m_node_count; }
-
- size_type size() const
- { return this->m_data.m_node_count; }
-
- size_type max_size() const
- { return base_t::max_size(); }
-
- void swap(rb_tree& t)
- {
- detail::do_swap(this->m_data.m_node_count, t.m_data.m_node_count);
- detail::do_swap(this->get_compare(), t.get_compare());
- base_t::swap(t);
- }
-
- void swap(const detail::moved_object<rb_tree>& mt)
- { this->swap(mt.get()); }
-
- public:
- // insert/erase
- std::pair<iterator,bool> insert_unique(const value_type& v)
- {
- KeyOfValue key_of_value;
- typename rb_tree_func_t::insert_unique_context context;
- if(!rb_tree_func_t::insert_unique_prepare
- (node_val_t::downcast(this->end_node()), this->m_data, key_of_value(v), context)){
- return std::pair<iterator,bool>(iterator(context.node), false);
- }
- node_pointer new_node = this->allocate_and_construct_node(v);
- ++this->m_data.m_node_count;
- rb_tree_func_t::insert_unique_commit
- (node_val_t::downcast(this->end_node()), this->m_data, new_node, context);
- return std::pair<iterator,bool>(iterator(new_node), true);
- }
-
- template<class MovableConvertible>
- std::pair<iterator,bool> insert_unique(const detail::moved_object<MovableConvertible>& mv)
- {
- MovableConvertible &v = mv.get();
- KeyOfValue key_of_value;
- typename rb_tree_func_t::insert_unique_context context;
- if(!rb_tree_func_t::insert_unique_prepare
- (node_val_t::downcast(this->end_node()), this->m_data, key_of_value(v), context)){
- return std::pair<iterator,bool>(iterator(context.node), false);
- }
- node_pointer new_node = this->allocate_and_construct_node(mv);
- ++this->m_data.m_node_count;
- rb_tree_func_t::insert_unique_commit
- (node_val_t::downcast(this->end_node()), this->m_data, new_node, context);
- return std::pair<iterator,bool>(iterator(new_node), true);
- }
-
- iterator insert_unique(iterator hint, const value_type& v)
- {
- KeyOfValue key_of_value;
- typename rb_tree_func_t::insert_unique_context context;
- if(!rb_tree_func_t::insert_unique_hint_prepare
- (node_val_t::downcast(this->end_node()), this->m_data, hint.get_ptr(),
- key_of_value(v), context)){
- return iterator(context.node);
- }
- node_pointer new_node = this->allocate_and_construct_node(v);
- ++this->m_data.m_node_count;
- rb_tree_func_t::insert_unique_commit(node_val_t::downcast(this->end_node()), this->m_data, new_node, context);
- return iterator(new_node);
- }
-
- template<class MovableConvertible>
- iterator insert_unique(iterator hint, const detail::moved_object<MovableConvertible> &mv)
- {
- MovableConvertible &v = mv.get();
- KeyOfValue key_of_value;
- typename rb_tree_func_t::insert_unique_context context;
- if(!rb_tree_func_t::insert_unique_hint_prepare
- (node_val_t::downcast(this->end_node()), this->m_data, hint.get_ptr(),
- key_of_value(v), context)){
- return iterator(context.node);
- }
- node_pointer new_node = this->allocate_and_construct_node(mv);
- ++this->m_data.m_node_count;
- rb_tree_func_t::insert_unique_commit(node_val_t::downcast(this->end_node()), this->m_data, new_node, context);
- return iterator(new_node);
- }
-
- template <class InputIterator>
- void insert_unique(InputIterator first, InputIterator last)
- {
- for ( ; first != last; ++first)
- this->insert_unique(*first);
- }
-
- iterator insert_equal(const value_type& v)
- {
- node_pointer tmp = this->allocate_and_construct_node(v);
- rb_tree_func_t::insert_equal(node_val_t::downcast(this->end_node()), this->m_data, tmp);
- ++this->m_data.m_node_count;
- return iterator(tmp);
- }
-
- template<class MovableConvertible>
- iterator insert_equal(const detail::moved_object<MovableConvertible> &mv)
- {
- node_pointer tmp = this->allocate_and_construct_node(mv);
- rb_tree_func_t::insert_equal(node_val_t::downcast(this->end_node()), this->m_data, tmp);
- ++this->m_data.m_node_count;
- return iterator(tmp);
- }
-
- iterator insert_equal(iterator hint, const value_type& v)
- {
- node_pointer tmp = this->allocate_and_construct_node(v);
- rb_tree_func_t::insert_equal_hint(node_val_t::downcast(this->end_node()), this->m_data,
- hint.get_ptr(), tmp);
- ++this->m_data.m_node_count;
- return iterator(tmp);
- }
-
- template<class MovableConvertible>
- iterator insert_equal(iterator hint, const detail::moved_object<MovableConvertible> &mv)
- {
- node_pointer tmp = this->allocate_and_construct_node(mv);
- rb_tree_func_t::insert_equal_hint(node_val_t::downcast(this->end_node()), this->m_data,
- hint.get_ptr(), tmp);
- ++this->m_data.m_node_count;
- return iterator(tmp);
- }
-
- template <class InputIterator>
- void insert_equal(InputIterator first, InputIterator last)
- {
- for ( ; first != last; ++first)
- this->insert_equal(*first);
- }
-
- iterator erase(const_iterator position)
- {
- iterator ret(position.get_ptr());
- ++ret;
- node_pointer y = node_val_t::downcast
- (rb_tree_func_t::erase_node(node_val_t::downcast(this->end_node()), position.get_ptr()));
- this->destroy_and_deallocate_node(y);
- --this->m_data.m_node_count;
- return ret;
- }
-
- size_type erase(const key_type& x)
- {
- std::pair<iterator,iterator> p = this->equal_range(x);
- size_type n = std::distance(p.first, p.second);
- this->erase(p.first, p.second);
- return n;
- }
-
- iterator erase(const_iterator first, const_iterator last)
- {
- if (first == this->begin() && last == this->end()){
- this->clear();
- return begin();
- }
- else{
- while (first != last){
- first = this->erase(first);
- }
- return iterator(last.get_ptr());
- }
- }
-
- void clear()
- {
- if (this->m_data.m_node_count) {
- this->erase_node(node_val_t::downcast(this->root()));
-/*
- this->m_end.color() = node_val_t::red_color;
- this->m_end.parent() = 0;
- this->m_end.left() = this->end_node();
- this->m_end.right() = this->end_node();
-*/
- this->m_end.color() = node_val_t::red_color;
- this->root() = 0;
- this->leftmost() = this->end_node();
- this->rightmost() = this->end_node();
-
- this->m_data.m_node_count = 0;
- }
- }
-
- // set operations:
- iterator find(const key_type& k)
- { return iterator(rb_tree_func_t::find(node_val_t::downcast(this->end_node()), this->m_data, k)); }
-
- const_iterator find(const key_type& k) const
- { return const_iterator(rb_tree_func_t::find(node_val_t::downcast(this->end_node()), this->m_data, k)); }
-
- size_type count(const key_type& k) const
- { return size_type(rb_tree_func_t::count(node_val_t::downcast(this->end_node()), this->m_data, k)); }
-
- iterator lower_bound(const key_type& k)
- { return iterator(rb_tree_func_t::lower_bound(node_val_t::downcast(this->end_node()), this->m_data, k)); }
-
- const_iterator lower_bound(const key_type& k) const
- { return const_iterator(rb_tree_func_t::lower_bound(node_val_t::downcast(this->end_node()), this->m_data, k)); }
-
- iterator upper_bound(const key_type& k)
- { return iterator (rb_tree_func_t::upper_bound(node_val_t::downcast(this->end_node()), this->m_data, k)); }
-
- const_iterator upper_bound(const key_type& k) const
- { return const_iterator (rb_tree_func_t::upper_bound(node_val_t::downcast(this->end_node()), this->m_data, k)); }
-
- std::pair<iterator,iterator> equal_range(const key_type& k)
- {
- node_pointer lower, upper;
- rb_tree_func_t::equal_range(node_val_t::downcast(this->end_node()), this->m_data, k, lower, upper);
- return std::pair<iterator, iterator>(iterator(lower), iterator(upper));
- }
-
- std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
- {
- node_pointer lower, upper;
- rb_tree_func_t::equal_range(node_val_t::downcast(this->end_node()), this->m_data, k, lower, upper);
- return std::pair<const_iterator, const_iterator>(const_iterator(lower), const_iterator(upper));
- }
-
- private:
- basic_node_pointer &root() const
- { return const_cast<basic_node_pointer &>(this->m_end.parent()); }
-
- basic_node_pointer &leftmost() const
- { return const_cast<basic_node_pointer &>(this->m_end.left()); }
-
- basic_node_pointer &rightmost() const
- { return const_cast<basic_node_pointer &>(this->m_end.right()); }
-
- node_pointer clone_node(basic_node_pointer x)
- {
- basic_node_pointer tmp = this->allocate_and_construct_node(node_val_t::downcast(x)->value());
- tmp->color() = x->color();
- tmp->left() = 0;
- tmp->right() = 0;
- return node_val_t::downcast(tmp);
- }
-
- const Compare & get_compare() const
- { return static_cast<const Compare&>(m_data); }
-
- Compare & get_compare()
- { return static_cast<Compare&>(m_data); }
-
- static const Key& get_node_key(node_pointer x)
- { return KeyOfValue()(x->value()); }
-
- node_pointer copy_node(basic_node_pointer x, basic_node_pointer p)
- {
- // structural copy. x and p must be non-null.
- node_pointer top = this->clone_node(x);
- top->parent() = p;
-
- BOOST_TRY {
- if (x->right())
- top->right() = this->copy_node(x->right(), top);
- p = top;
- x = x->left();
-
- while (x) {
- node_pointer y = this->clone_node(x);
- p->left() = y;
- y->parent() = p;
- if (x->right()){
- y->right() = this->copy_node(x->right(), y);
- }
- p = y;
- x = x->left();
- }
- }
- BOOST_CATCH(...){
- this->erase_node(top);
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
-
- return top;
- }
-
- void erase_node(node_pointer x)
- {
- // erase without rebalancing
- while (x) {
- this->erase_node(node_val_t::downcast(x->right()));
- node_pointer y = node_val_t::downcast(x->left());
- this->destroy_and_deallocate_node(x);
- x = y;
- }
- }
-
- private:
- struct Data
- : public Compare
- {
- Data(const Compare &comp, size_type node_count)
- : Compare(comp), m_node_count(node_count){}
-
- Data(const detail::moved_object<Compare> &comp, size_type node_count)
- : Compare(move(comp.get())), m_node_count(node_count){}
-
- size_type m_node_count; // keeps track of size of tree
- } m_data;
-};
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator==(const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
-{
- return x.size() == y.size() &&
- std::equal(x.begin(), x.end(), y.begin());
-}
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator<(const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
-{
- return std::lexicographical_compare(x.begin(), x.end(),
- y.begin(), y.end());
-}
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator!=(const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& y) {
- return !(x == y);
-}
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator>(const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& y) {
- return y < x;
-}
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator<=(const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& y) {
- return !(y < x);
-}
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator>=(const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& y) {
- return !(x < y);
-}
-
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline void
-swap(rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- rb_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
-{
- x.swap(y);
-}
-
-} //namespace detail {
-
-/*!This class is movable*/
-template <class T, class V, class K, class C, class A>
-struct is_movable<detail::rb_tree<T, V, K, C, A> >
-{
- enum { value = true };
-};
-
-/*!This class is movable*/
-template <class A>
-struct is_movable<detail::rb_tree_node<A> >
-{
- enum { value = true };
-};
-
-/*!This class is movable*/
-template <class T, class A>
-struct is_movable<detail::rb_tree_alloc_base<T, A/*, true*/> >
-{
- enum { value = true };
-};
-
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_TREE_HPP
-

Deleted: trunk/boost/interprocess/detail/multi_segment_services.hpp
==============================================================================
--- trunk/boost/interprocess/detail/multi_segment_services.hpp 2007-08-24 17:24:23 EDT (Fri, 24 Aug 2007)
+++ (empty file)
@@ -1,46 +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_MULTI_SEGMENT_SERVICES_HPP
-#define BOOST_INTERPROCESS_MULTI_SEGMENT_SERVICES_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-
-/*!\file
- Describes a named shared memory allocation user class.
-*/
-
-namespace boost {
-
-namespace interprocess {
-
-class multi_segment_services
-{
- public:
- virtual std::pair<void *, std::size_t> create_new_segment(std::size_t mem) = 0;
- virtual bool update_segments () = 0;
- virtual ~multi_segment_services() = 0;
-};
-
-inline multi_segment_services::~multi_segment_services()
-{}
-
-
-}} //namespace boost { namespace interprocess {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifdef BOOST_INTERPROCESS_MULTI_SEGMENT_SERVICES_HPP

Deleted: trunk/boost/interprocess/intersegment_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/intersegment_ptr.hpp 2007-08-24 17:24:23 EDT (Fri, 24 Aug 2007)
+++ (empty file)
@@ -1,904 +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_INTERSEGMENT_PTR_HPP
-#define BOOST_INTERSEGMENT_PTR_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/generic_cast.hpp>
-#include <boost/interprocess/detail/cast_tags.hpp>
-#include <boost/assert.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include <boost/type_traits/has_trivial_constructor.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/interprocess/sync/interprocess_mutex.hpp>
-#include <boost/interprocess/containers/flat_map.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <limits.h>
-
-/*!\file
-*/
-namespace boost {
-
-namespace interprocess {
-
-/*!Configures intersegment_ptr with the capability to address:
- 2^(sizeof(std::size_t)*CHAR_BIT/2) segment groups
- 2^(sizeof(std::size_t)*CHAR_BIT/2) segments per group.
- 2^(sizeof(std::size_t)*CHAR_BIT/2)-1 bytes maximum per segment.
- The mapping is implemented through flat_maps synchronized with mutexes.*/
-template <class Mutex>
-struct flat_map_intersegment
-{
- typedef flat_map_intersegment<Mutex> self_t;
- typedef std::size_t offset_t;
- typedef std::size_t segment_t;
-
- /*!Returns true if object represents null pointer*/
- bool is_null() const
- { return m_offset == ~offset_t(0); }
-
- /*!Sets the object to represent the null pointer*/
- void set_null()
- { m_offset = ~offset_t(0); }
-
- /*!Sets the object internals to represent the address pointed by ptr*/
- void set_from_pointer(const void *ptr)
- {
- if(!ptr){
- set_null();
- }
- else{
- segment_t id1, id2;
- offset_t offset1, offset2;
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- get_segment_and_offset(ptr, id1, offset1);
- get_segment_and_offset(this, id2, offset2);
- }
- m_distance = id1 - id2;
- m_offset = offset1;
- }
- }
-
- /*!Sets the object internals to represent the address pointed
- by another flat_map_intersegment*/
- void set_from_other(const self_t &other)
- {
- if(other.is_null()){
- set_null();
- }
- else{
- segment_t id1, id2;
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- offset_t off;
- get_segment_and_offset(&other, id1, off);
- get_segment_and_offset(this, id2, off);
- }
- m_distance = id1 + other.m_distance - id2;
- m_offset = other.m_offset;
- }
- }
-
- /*!Obtains the address pointed by the object*/
- void *get_pointer() const
- {
- segment_t id1;
- offset_t off;
- void * base_addr = 0;
- if(is_null()){
- return base_addr;
- }
- else{
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- get_segment_and_offset(this, id1, off);
- segment_t target_segment = segment_t(id1+m_distance);
- base_addr = get_base_address(target_segment);
- }
- return detail::char_ptr_cast(base_addr) + m_offset;
- }
- }
-
- /*!Swaps two objects efficiently*/
- void swap(self_t &other)
- {
- //This specialized swap avoids some costly operations
- segment_t id1, id2, id;
- offset_t off;
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- get_segment_and_offset(&other, id1, off);
- get_segment_and_offset(this, id2, off);
- }
- //Swap offset value
- off = m_offset; m_offset = other.m_offset; other.m_offset = off;
- //Calculate new segment distance. Let overflow do its work
- id = m_distance;
- m_distance = id1 + other.m_distance - id2;
- other.m_distance = id2 + id - id1;
- }
-
- /*!Increments internal offset*/
- void inc_offset(offset_t bytes)
- { m_offset += bytes; }
-
- /*!Decrements internal offset*/
- void dec_offset(offset_t bytes)
- { m_offset -= bytes; }
-
- /*!Calculates the distance between two basic_intersegment_ptr-s.
- This only works with two basic_intersegment_ptr pointing
- to the same segment. Otherwise undefined*/
- offset_t diff(const self_t &other) const
- { return m_offset - other.m_offset; }
-
- /*!Returns true if both point to the same object*/
- bool equal(const self_t &y) const
- {
- if(m_offset != y.m_offset){
- return false;
- }
- else{
- segment_t id1, id2;
- offset_t off;
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- get_segment_and_offset(this, id1, off);
- get_segment_and_offset(&y, id2, off);
- }
- return segment_t(id1 + m_distance) == segment_t(id2 + y.m_distance);
- }
- }
-
- /*!Returns true if *this is less than other.
- This only works with two basic_intersegment_ptr pointing
- to the same segment group. Otherwise undefined. Never throws*/
- bool less(const self_t &y) const
- {
- segment_t id1, id2;
- offset_t off;
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- get_segment_and_offset(this, id1, off);
- get_segment_and_offset(&y, id2, off);
- }
- id1 = segment_t(id1 + m_distance);
- id2 = segment_t(id2 + y.m_distance);
- return (id1 < id2) || (id1 == id2 && m_offset < y.m_offset);
- }
-
- //--------------------------------------------------------------------------
-
- static void get_group_and_id(void *addr, std::size_t &group, std::size_t &id)
- {
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- get_segment_and_offset(addr, group, id);
- }
- group = group >> s_shift;
- }
-
- /*!Returns the polymorphic multi-segment creator associated with a
- segment-group. Returns 0 if not found or an error occurs.*/
- static void* find_group_data(std::size_t group)
- {
- typedef typename mappings_t::group_to_data_t::iterator it_t;
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- it_t it(s_map.group_to_data.find(group));
- if(it == s_map.group_to_data.end()){
- return 0;
- }
- return it->second;
- }
-
- /*!Reserves a segment-group, installs the associated polymorphic
- segment-creator, and the segment passed as (base, size) as
- the segment id = 0 of the new group. Returns the group that will
- be associated with this segment. Returns 0 if there are no available
- groups or an error occurs.*/
- static std::size_t new_group(void *group_data)
- {
- typedef typename mappings_t::group_to_data_t::iterator it_t;
- typedef typename mappings_t::group_to_data_t::value_type value_type;
- typedef std::pair<it_t, bool> insert_ret;
- std::size_t group = 0;
-
- BOOST_TRY{
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- //Check if there are too many groups
- if(s_map.group_to_data.size() >= (s_max_value - 1) ){
- return 0;
- }
- //Check if there are no registered groups or the first one
- //is not group 1, assign id 1 to the new group.
- else if(s_map.group_to_data.empty() ||
- s_map.group_to_data.begin()->first != 1){
- group = 1;
- }
- //If not, take a not used number
- else{
- it_t it1(s_map.group_to_data.begin()),
- it2(it1),
- itend(s_map.group_to_data.end());
-
- for(++it2; it2 != itend; ++it1, ++it2){
- if(it2->first - it1->first > 1){
- break;
- }
- }
- group = it1->first+1;
- }
- insert_ret ret =
- s_map.group_to_data.insert(value_type(group, group_data));
- //This insertion must succeed
- assert(ret.second);
- if(!ret.second) return false;
- return group;
- }
- BOOST_CATCH(const std::bad_alloc &){}
- BOOST_CATCH_END
- return 0;
- }
-
- /*!Erases the mapping between a group and the associated polymorphic pointer.
- Returns false if the group is not found or there is an error*/
- static bool delete_group(std::size_t group)
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- typedef typename mappings_t::segment_to_ptr_t::iterator it_t;
-
- //Find the range of the group
- it_t first_of_group(s_map.segment_to_ptr.lower_bound(group << s_shift));
- it_t one_past_group(s_map.segment_to_ptr.lower_bound((group+1)<< s_shift));
-
- //Erase all info related to the group
- for(it_t it(first_of_group); it != one_past_group; ++it){
- //Erase entry from addr-segment
- if(!s_map.ptr_to_segment.erase(it->second)){
- //This can't be possible since both indexes should be synchronized
- assert(false);
- return false;
- }
- }
- //Erase all info from groups
- s_map.segment_to_ptr.erase(first_of_group, one_past_group);
-
- //Erase the group info
- bool ret = s_map.group_to_data.erase(group) == 1;
- assert(ret);
- if(!ret) return false;
- //Erase all mappings of this group
- return true;
- }
-
- /*!Associates a segment defined by group/id with a base address and size.
- Returns false if the group is not found or there is an error*/
- static bool insert_mapping(std::size_t group, std::size_t id,
- void *base_address, std::size_t size)
- {
- //Check limits
- if(group > s_max_value || id > s_max_value){
- return false;
- }
-
- BOOST_TRY{
- typedef typename mappings_t::ptr_to_segment_t::value_type ptr_to_segment_val_t;
- typedef typename mappings_t::segment_to_ptr_t::value_type segment_to_ptr_val_t;
- typedef typename mappings_t::ptr_to_segment_t::iterator ptr_to_segment_it_t;
- typedef typename mappings_t::segment_to_ptr_t::iterator segment_to_ptr_it_t;
- typedef std::pair<ptr_to_segment_it_t, bool> ptr_to_segment_ret_t;
- typedef std::pair<segment_to_ptr_it_t, bool> segment_to_ptr_ret_t;
-
- //Compose segment identification
- segment_t segment = (group << s_shift) | id;
- typename mappings_t:: segment_info_t segment_info;
- segment_info.segment = segment;
- segment_info.size = size;
-
- {
- //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- //This can throw
- ptr_to_segment_ret_t ptr_to_segment_ret =
- s_map.ptr_to_segment.insert(ptr_to_segment_val_t(base_address, segment_info));
-
- if(!ptr_to_segment_ret.second)
- return false;
-
- //Node eraser will erase the node if an exception occurs
- detail::value_eraser<typename mappings_t::ptr_to_segment_t>
- value_eraser(s_map.ptr_to_segment, ptr_to_segment_ret.first);
-
- //This can throw
- segment_to_ptr_ret_t segment_to_ptr_ret =
- s_map.segment_to_ptr.insert(segment_to_ptr_val_t(segment, base_address));
-
- if(!segment_to_ptr_ret.second){
- //This should never occur, since both maps must have
- //the same elements indexed by different key
- assert(!segment_to_ptr_ret.second);
- return false;
- }
- //Insertion ok, release value_eraser
- value_eraser.release();
- return true;
- }
- }
- BOOST_CATCH(...){
- return false;
- }
- BOOST_CATCH_END
- }
-
- static bool erase_mapping(void *base_address)
- {
- typedef typename mappings_t::ptr_to_segment_t::iterator ptr_to_segment_it_t;
- typedef typename mappings_t::segment_to_ptr_t::iterator segment_to_ptr_it_t;
-
- { //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- ptr_to_segment_it_t ptr_to_segment_it = s_map.ptr_to_segment.find(base_address);
- if(ptr_to_segment_it == s_map.ptr_to_segment.end()){
- //This group/id is not an valid entry
- assert(ptr_to_segment_it == s_map.ptr_to_segment.end());
- return false;
- }
- //Obtain segment
- segment_t segment = ptr_to_segment_it->second.segment;
- //Erase node from map
- s_map.ptr_to_segment.erase(ptr_to_segment_it);
- //Erase entry in the second map
- if(!s_map.segment_to_ptr.erase(segment)){
- //This can't be possible since both indexes should be synchronized
- assert(false);
- return false;
- }
- }
- return true;
- }
-
- static bool erase_mapping(std::size_t group, std::size_t id)
- {
- //Check limits
- if(group > s_max_value || id > s_max_value){
- return false;
- }
-
- typedef typename mappings_t::ptr_to_segment_t::iterator ptr_to_segment_it_t;
- typedef typename mappings_t::segment_to_ptr_t::iterator segment_to_ptr_it_t;
-
- //Compose segment identification
- segment_t segment = (group << s_shift) | id;
- { //------------------------------------------------------------------
- boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
- //------------------------------------------------------------------
- segment_to_ptr_it_t segment_to_ptr_it = s_map.segment_to_ptr.find(segment);
- if(segment_to_ptr_it == s_map.segment_to_ptr.end()){
- //This group/id is not an valid entry
- assert(segment_to_ptr_it != s_map.segment_to_ptr.end());
- return false;
- }
- //Obtain address
- void *address = segment_to_ptr_it->second;
- //Erase node from map
- s_map.segment_to_ptr.erase(segment_to_ptr_it);
- //Erase entry in the second map
- if(!s_map.ptr_to_segment.erase(address)){
- //This can't be possible since both indexes should be synchronized
- assert(false);
- return false;
- }
- }
- return true;
- }
-
- private:
- /*!Half of the bits are for group id and the
- other half for the index inside the group
- unsigned group : sizeof(std::size_t)/2;
- unsigned index : sizeof(std::size_t)/2;*/
- segment_t m_distance;
- offset_t m_offset;
-
- struct mappings_t : Mutex
- {
- struct segment_info_t
- {
- std::size_t size;
- segment_t segment;
- };
-
- /*!Mutex to preserve integrity in multi-threaded enviroments*/
- typedef Mutex mutex_type;
- /*!Maps base addresses and segment information
- (size and segment group and id)*/
- typedef boost::interprocess::flat_map
- <const void *
- ,segment_info_t
- ,std::less<const void *> > ptr_to_segment_t;
- /*!Maps segment group/id with base addresses*/
- typedef boost::interprocess::flat_map
- <segment_t, void *> segment_to_ptr_t;
- /*!Maps segment group with a polymorphic multi-segment creator
- that knows how to create new segments*/
- typedef boost::interprocess::flat_map
- <segment_t, void*> group_to_data_t;
-
- ptr_to_segment_t ptr_to_segment;
- segment_to_ptr_t segment_to_ptr;
- group_to_data_t group_to_data;
-
- ~mappings_t()
- {
- //Check that all mappings have been erased
- assert(ptr_to_segment.empty());
- assert(segment_to_ptr.empty());
- assert(group_to_data.empty());
- }
- };
-
- //Static members
- static mappings_t s_map;
- static const std::size_t s_shift = sizeof(std::size_t)*CHAR_BIT/2;
- static const std::size_t s_max_value = std::size_t(1) << s_shift;
-
- private:
-
- /*!Returns the segment and offset of an address*/
- static void get_segment_and_offset(const void *ptr, segment_t &segment, offset_t &offset)
- {
- if(s_map.ptr_to_segment.empty()){
- segment = 0;
- offset = detail::char_ptr_cast(ptr) - detail::char_ptr_cast();
- }
- //Find the first base address greater than ptr
- typename mappings_t::ptr_to_segment_t::iterator it
- = s_map.ptr_to_segment.upper_bound(ptr);
- if(it == s_map.ptr_to_segment.begin()){
- segment = 0;
- offset = detail::char_ptr_cast(ptr) - detail::char_ptr_cast();
- }
- //Go to the previous one
- --it;
- char * segment_base = detail::char_ptr_cast(it->first);
- std::size_t segment_size = it->second.size;
-
- if(segment_base <= detail::char_ptr_cast(ptr) &&
- (segment_base + segment_size) >= detail::char_ptr_cast(ptr)){
- segment = it->second.segment;
- offset = detail::char_ptr_cast(ptr) - segment_base;
- }
- else{
- segment = 0;
- offset = detail::char_ptr_cast(ptr) - detail::char_ptr_cast();
- }
- }
-
- /*!Returns the base address of a segment*/
- static void *get_base_address(segment_t segment)
- {
- typename mappings_t::segment_to_ptr_t::iterator it
- = s_map.segment_to_ptr.find(segment);
-
- if(it == s_map.segment_to_ptr.end()){
- return 0;
- }
- else{
- return it->second;
- }
- }
-};
-
-/*!Static map-group associated with flat_map_intersegment<>*/
-template <class Mutex>
-typename flat_map_intersegment<Mutex>::mappings_t
- flat_map_intersegment<Mutex>::s_map;
-
-/*!Static constant that shows the number of bits to shift to obtain the
- group part of segment_t type*/
-template <class Mutex>
-const std::size_t flat_map_intersegment<Mutex>::s_shift;
-
-/*!Static constant that shows the number of bits to shift to obtain the
- group part of segment_t type*/
-template <class Mutex>
-const std::size_t flat_map_intersegment<Mutex>::s_max_value;
-
-/*!
- A smart pointer that can point to a pointee that resides in another memory
- memory mapped or shared memory segment.
-*/
-template <class T/*, class PT*/>
-class intersegment_ptr : public flat_map_intersegment<interprocess_mutex> //: public PT
-{
- typedef flat_map_intersegment<interprocess_mutex> PT;
- typedef boost::interprocess::workaround::random_it<T> random_it_t;
-// typedef intersegment_ptr<T, PT> self_t;
- typedef intersegment_ptr<T> self_t;
- typedef PT base_t;
- typedef typename random_it_t::const_pointer const_pointer_t;
- typedef typename random_it_t::const_reference const_reference_t;
-
- void unspecified_bool_type_func() const {}
- typedef void (self_t::*unspecified_bool_type)() const;
-
- public:
- typedef typename random_it_t::pointer pointer;
- typedef typename random_it_t::reference reference;
- typedef typename random_it_t::value_type value_type;
- typedef typename random_it_t::difference_type difference_type;
- typedef typename random_it_t::iterator_category iterator_category;
-
- public: //Public Functions
-
- /*!Constructor from raw pointer (allows "0" pointer conversion). Never throws.*/
- intersegment_ptr(pointer ptr = 0) { base_t::set_from_pointer(ptr); }
-
- /*!Constructor from other pointer. Never throws.*/
- template <class U>
- intersegment_ptr(U *ptr){ base_t::set_from_pointer(pointer(ptr)); }
-
- /*!Constructor from other intersegment_ptr */
- intersegment_ptr(const intersegment_ptr& ptr)
- { base_t::set_from_other(ptr); }
-
- /*!Constructor from other intersegment_ptr. If pointers of pointee types are
- convertible, intersegment_ptrs will be convertibles. Never throws.*/
- template<class T2>
- intersegment_ptr(const intersegment_ptr<T2/*, PT*/> &ptr)
- { pointer p(ptr.get()); (void)p; base_t::set_from_other(ptr); }
-
- /*!Emulates static_cast operator. Never throws. */
- template<class U>
- intersegment_ptr(const intersegment_ptr<U/*, PT*/> &r, detail::static_cast_tag)
- //{ base_t::set_from_pointer(static_cast<T*>(r.get())); }
- {
- if(r.is_null()){
- base_t::set_from_pointer(0);
- }
- else{
- //Some dirty tricks to safe segment operations.
- //Calculate pointer adjustment and adjust offset.
- pointer ptr = reinterpret_cast<pointer>(this);
- std::ptrdiff_t difference = detail::char_ptr_cast(static_cast<T*>(ptr)) -
- detail::char_ptr_cast(ptr);
- base_t::set_from_other(r);
- base_t::inc_offset(difference*sizeof(T));
- }
- }
-
- /*!Emulates const_cast operator. Never throws.*/
- template<class U>
- intersegment_ptr(const intersegment_ptr<U/*, PT*/> &r, detail::const_cast_tag)
- { base_t::set_from_pointer(const_cast<T*>(r.get())); }
- /*
- {
- //Make sure const conversion is correct
- pointer p = const_cast<pointer>((U*)0); (void)p;
- base_t::set_from_other(r);
- }*/
-
- /*!Emulates dynamic_cast operator. Never throws.*/
- template<class U>
- intersegment_ptr(const intersegment_ptr<U/*, PT*/> &r, detail::dynamic_cast_tag)
- { base_t::set_from_pointer(dynamic_cast<T*>(r.get())); }
-
- /*!Emulates reinterpret_cast operator. Never throws.*/
- template<class U>
- intersegment_ptr(const intersegment_ptr<U/*, PT*/> &r, detail::reinterpret_cast_tag)
- { base_t::set_from_pointer(reinterpret_cast<T*>(r.get())); }
-
- /*!Obtains raw pointer from offset. Never throws.*/
- pointer get()const
- { return (pointer)base_t::get_pointer(); }
-
- /*!Pointer-like -> operator. It can return 0 pointer. Never throws.*/
- pointer operator->() const
- { return self_t::get(); }
-
- /*!Dereferencing operator, if it is a null intersegment_ptr behavior
- is undefined. Never throws.*/
- reference operator* () const
- { return *(self_t::get()); }
-
- /*!Indexing operator. Never throws.*/
- reference operator[](std::ptrdiff_t idx) const
- { return self_t::get()[idx]; }
-
- /*!Assignment from pointer (saves extra conversion). Never throws.*/
- intersegment_ptr& operator= (pointer from)
- { base_t::set_from_pointer(from); return *this; }
-
- /*!Assignment from other intersegment_ptr. Never throws.*/
- intersegment_ptr& operator= (const intersegment_ptr &ptr)
- { base_t::set_from_other(ptr); return *this; }
-
- /*!Assignment from related intersegment_ptr. If pointers of pointee types
- are assignable, intersegment_ptrs will be assignable. Never throws.*/
- template <class T2>
- intersegment_ptr& operator= (const intersegment_ptr<T2/*, PT*/> & ptr)
- {
- pointer p(ptr.get()); (void)p;
- base_t::set_from_other(ptr); return *this;
- }
-
- /*!intersegment_ptr + std::ptrdiff_t. Never throws.*/
- intersegment_ptr operator+ (std::ptrdiff_t idx) const
- {
- intersegment_ptr result (*this);
- result.inc_offset(idx*sizeof(T));
- return result;
- }
-
- /*!intersegment_ptr - std::ptrdiff_t. Never throws.*/
- intersegment_ptr operator- (std::ptrdiff_t idx) const
- {
- intersegment_ptr result (*this);
- result.dec_offset(idx*sizeof(T));
- return result;
- }
-
- /*!intersegment_ptr += std::ptrdiff_t. Never throws.*/
- intersegment_ptr &operator+= (std::ptrdiff_t offset)
- { base_t::inc_offset(offset*sizeof(T)); return *this; }
-
- /*!intersegment_ptr -= std::ptrdiff_t. Never throws.*/
- intersegment_ptr &operator-= (std::ptrdiff_t offset)
- { base_t::dec_offset(offset*sizeof(T)); return *this; }
-
- /*!++intersegment_ptr. Never throws.*/
- intersegment_ptr& operator++ (void)
- { base_t::inc_offset(sizeof(T)); return *this; }
-
- /*!intersegment_ptr++. Never throws.*/
- intersegment_ptr operator++ (int)
- { intersegment_ptr temp(*this); ++*this; return temp; }
-
- /*!--intersegment_ptr. Never throws.*/
- intersegment_ptr& operator-- (void)
- { base_t::dec_offset(sizeof(T)); return *this; }
-
- /*!intersegment_ptr--. Never throws.*/
- intersegment_ptr operator-- (int)
- { intersegment_ptr temp(*this); --*this; return temp; }
-
- /*!Safe bool conversion operator. Never throws.*/
- operator unspecified_bool_type() const
- { return base_t::is_null()? 0 : &self_t::unspecified_bool_type_func; }
-
- /*!Not operator. Not needed in theory, but improves portability.
- Never throws.*/
- bool operator! () const
- { return base_t::is_null(); }
-
- /*!Swaps two intersegment_ptr-s. More efficient than std::swap.
- Never throws.*/
- void swap(intersegment_ptr &other)
- { base_t::swap(other); }
-
- /*!Calculates the distance between two intersegment_ptr-s.
- This only works with two basic_intersegment_ptr pointing
- to the same segment. Otherwise undefined*/
- template <class T2>
- bool _diff(const intersegment_ptr<T2/*, PT*/> &other) const
- { return base_t::less(other); }
-
- /*!Returns true if both point to the same object*/
- template <class T2>
- bool _equal(const intersegment_ptr<T2/*, PT*/> &other) const
- { return base_t::equal(other); }
-
- /*!Returns true if *this is less than other.
- This only works with two basic_intersegment_ptr pointing
- to the same segment group. Otherwise undefined. Never throws*/
- template <class T2>
- bool _less(const intersegment_ptr<T2/*, PT*/> &other) const
- { return base_t::less(other); }
-};
-
-/*!Compares the equality of two intersegment_ptr-s.
- Never throws.*/
-template <class T1, class T2/*, class PT1*/> inline
-bool operator ==(const intersegment_ptr<T1/*, PT1*/> &left,
- const intersegment_ptr<T2/*, PT1*/> &right)
-{
- //Make sure both pointers can be compared
- bool e = typename intersegment_ptr<T1/*, PT1*/>::pointer(0) ==
- typename intersegment_ptr<T2/*, PT1*/>::pointer(0);
- (void)e;
- return left._equal(right);
-}
-
-/*!Returns true if *this is less than other.
- This only works with two basic_intersegment_ptr pointing
- to the same segment group. Otherwise undefined. Never throws*/
-template <class T1, class T2/*, class PT1*/> inline
-bool operator <(const intersegment_ptr<T1/*, PT1*/> &left,
- const intersegment_ptr<T2/*, PT1*/> &right)
-{
- //Make sure both pointers can be compared
- bool e = typename intersegment_ptr<T1/*, PT1*/>::pointer(0) <
- typename intersegment_ptr<T2/*, PT1*/>::pointer(0);
- (void)e;
- return left._less(right);
-}
-
-template<class T1, class T2/*, class PT*/> inline
-bool operator!= (const intersegment_ptr<T1/*, PT*/> &pt1,
- const intersegment_ptr<T2/*, PT*/> &pt2)
-{ return !(pt1 ==pt2); }
-
-/*!intersegment_ptr<T1> <= intersegment_ptr<T2, PT>. Never throws.*/
-template<class T1, class T2/*, class PT*/> inline
-bool operator<= (const intersegment_ptr<T1/*, PT*/> &pt1,
- const intersegment_ptr<T2/*, PT*/> &pt2)
-{ return !(pt1 > pt2); }
-
-/*!intersegment_ptr<T1> > intersegment_ptr<T2, PT>. Never throws.*/
-template<class T1, class T2/*, class PT*/> inline
-bool operator> (const intersegment_ptr<T1/*, PT*/> &pt1,
- const intersegment_ptr<T2/*, PT*/> &pt2)
-{ return (pt2 < pt1); }
-
-/*!intersegment_ptr<T1> >= intersegment_ptr<T2, PT>. Never throws.*/
-template<class T1, class T2/*, class PT*/> inline
-bool operator>= (const intersegment_ptr<T1/*, PT*/> &pt1,
- const intersegment_ptr<T2/*, PT*/> &pt2)
-{ return !(pt1 < pt2); }
-
-/*!operator<< */
-template<class E, class T, class U/*, class PT*/> inline
-std::basic_ostream<E, T> & operator<<
- (std::basic_ostream<E, T> & os, const intersegment_ptr<U/*, PT*/> & p)
-{ return os << p.get(); }
-
-/*!operator>> */
-template<class E, class T, class U/*, class PT*/> inline
-std::basic_istream<E, T> & operator>>
- (std::basic_istream<E, T> & os, intersegment_ptr<U/*, PT*/> & p)
-{ U * tmp; return os >> tmp; p = tmp; }
-
-/*!std::ptrdiff_t + intersegment_ptr.
- The result is another pointer of the same segment */
-template<class T/*, class PT*/> inline
-intersegment_ptr<T/*, PT*/> operator+
- (std::ptrdiff_t diff, const intersegment_ptr<T/*, PT*/>& right)
-{ return right + diff; }
-
-/*!intersegment_ptr - intersegment_ptr.
- This only works with two intersegment_ptr-s that point to the
- same segment*/
-template <class T, class T2/*, class PT*/> inline
-std::ptrdiff_t operator- (const intersegment_ptr<T/*, PT*/> &pt,
- const intersegment_ptr<T2/*, PT*/> &pt2)
-{ return pt._diff(pt2); }
-
-/*! swap specialization */
-template<class T/*, class PT*/> inline
-void swap (boost::interprocess::intersegment_ptr<T/*, PT*/> &pt,
- boost::interprocess::intersegment_ptr<T/*, PT*/> &pt2)
-{ pt.swap(pt2); }
-
-/*!get_pointer() enables boost::mem_fn to recognize intersegment_ptr.
- Never throws.*/
-template<class T/*, class PT*/> inline
-T * get_pointer(boost::interprocess::intersegment_ptr<T/*, PT*/> const & p)
-{ return p.get(); }
-
-/*!Simulation of static_cast between pointers. Never throws.*/
-template<class T, class U/*, class PT*/> inline
-boost::interprocess::intersegment_ptr<T/*, PT*/> static_pointer_cast(const boost::interprocess::intersegment_ptr<U/*, PT*/> &r)
-{ return boost::interprocess::intersegment_ptr<T/*, PT*/>(r, boost::interprocess::detail::static_cast_tag()); }
-
-/*!Simulation of const_cast between pointers. Never throws.*/
-template<class T, class U/*, class PT*/> inline
-boost::interprocess::intersegment_ptr<T/*, PT*/> const_pointer_cast(const boost::interprocess::intersegment_ptr<U/*, PT*/> &r)
-{ return boost::interprocess::intersegment_ptr<T/*, PT*/>(r, boost::interprocess::detail::const_cast_tag()); }
-
-/*!Simulation of dynamic_cast between pointers. Never throws.*/
-template<class T, class U/*, class PT*/> inline
-boost::interprocess::intersegment_ptr<T/*, PT*/> dynamic_pointer_cast(const boost::interprocess::intersegment_ptr<U/*, PT*/> &r)
-{ return boost::interprocess::intersegment_ptr<T/*, PT*/>(r, boost::interprocess::detail::dynamic_cast_tag()); }
-
-/*!Simulation of reinterpret_cast between pointers. Never throws.*/
-template<class T, class U/*, class PT*/> inline
-boost::interprocess::intersegment_ptr<T/*, PT*/> reinterpret_pointer_cast(const boost::interprocess::intersegment_ptr<U/*, PT*/> &r)
-{ return boost::interprocess::intersegment_ptr<T/*, PT*/>(r, boost::interprocess::detail::reinterpret_cast_tag()); }
-
-/*!Trait class to detect if an smart pointer has
- multi-segment addressing capabilities.*/
-template <class T/*, class PT*/>
-struct is_multisegment_ptr
- <boost::interprocess::intersegment_ptr<T/*, PT*/> >
-{
- enum { value = true };
-};
-
-} //namespace interprocess {
-
-
-/*!has_trivial_constructor<> == true_type specialization for optimizations*/
-template <class T/*, class PT*/>
-struct has_trivial_constructor
- < boost::interprocess::intersegment_ptr<T/*, PT*/> >
- : public true_type{};
-
-/*!has_trivial_destructor<> == true_type specialization for optimizations*/
-template <class T/*, class PT*/>
-struct has_trivial_destructor
- < boost::interprocess::intersegment_ptr<T/*, PT*/> >
- : public true_type{};
-
-} //namespace boost {
-
-namespace boost{
-namespace interprocess{
-
-/*!Simulation of cast operators between pointers.*/
-template<class T>
-class cast_to< intersegment_ptr<T> >
-{
- public:
- template<class S>
- static intersegment_ptr<T> using_static_cast(const intersegment_ptr<S> &s)
- { return intersegment_ptr<T>(s, detail::static_cast_tag()); }
-
- template<class S>
- static intersegment_ptr<T> using_reinterpret_cast(const intersegment_ptr<S> &s)
- { return intersegment_ptr<T>(s, detail::reinterpret_cast_tag()); }
-
- template<class S>
- static intersegment_ptr<T> using_const_cast(const intersegment_ptr<S> &s)
- { return intersegment_ptr<T>(s, detail::const_cast_tag()); }
-
- template<class S>
- static intersegment_ptr<T> using_dynamic_cast(const intersegment_ptr<S> &s)
- { return intersegment_ptr<T>(s, detail::dynamic_cast_tag()); }
-};
-
-} //namespace interprocess{
-} //namespace boost{
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERSEGMENT_PTR_HPP
-

Deleted: trunk/boost/interprocess/managed_multi_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_multi_shared_memory.hpp 2007-08-24 17:24:23 EDT (Fri, 24 Aug 2007)
+++ (empty file)
@@ -1,374 +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_MANAGED_MULTI_SHARED_MEMORY_HPP
-#define BOOST_INTERPROCESS_MANAGED_MULTI_SHARED_MEMORY_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/detail/managed_memory_impl.hpp>
-#include <boost/interprocess/detail/creation_tags.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-//#include <boost/interprocess/detail/multi_segment_services.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <list>
-#include <new>
-#include <boost/interprocess/containers/string.hpp>
-#include <boost/interprocess/streams/vectorstream.hpp>
-#include <memory>
-
-/*!\file
- Describes a named shared memory object allocation user class.
-*/
-
-namespace boost {
-
-namespace interprocess {
-
-/*!A basic shared memory named object creation class. Initializes the
- shared memory segment. Inherits all basic functionality from
- basic_managed_memory_impl<CharType, MemoryAlgorithm, IndexType>*/
-template
- <
- class CharType,
- class MemoryAlgorithm,
- template<class IndexConfig> class IndexType
- >
-class basic_managed_multi_shared_memory
- : public detail::basic_managed_memory_impl
- <CharType, MemoryAlgorithm, IndexType>
-{
-
- typedef basic_managed_multi_shared_memory
- <CharType, MemoryAlgorithm, IndexType> self_t;
- typedef typename self_t::void_pointer void_pointer;
- ////////////////////////////////////////////////////////////////////////
- //
- // Some internal helper structs/functors
- //
- ////////////////////////////////////////////////////////////////////////
- /*!This class defines an operator() that creates a shared memory
- of the requested size. The rest of the parameters are
- passed in the constructor. The class a template parameter
- to be used with create_from_file/create_from_istream functions
- of basic_named_object classes*/
-/*
- class segment_creator
- {
- public:
- segment_creator(shared_memory &shmem,
- const char *mem_name,
- const void *addr)
- : m_shmem(shmem), m_mem_name(mem_name), m_addr(addr){}
-
- void *operator()(std::size_t size)
- {
- if(!m_shmem.create(m_mem_name, size, m_addr))
- return 0;
- return m_shmem.get_address();
- }
- private:
- shared_memory &m_shmem;
- const char *m_mem_name;
- const void *m_addr;
- };
-*/
- class group_services
- {
- public:
- typedef std::pair<void *, std::size_t> result_type;
- typedef basic_managed_multi_shared_memory frontend_t;
- typedef typename
- basic_managed_multi_shared_memory::void_pointer void_pointer;
- group_services(frontend_t *const frontend)
- : mp_frontend(frontend), m_group(0), m_min_segment_size(0){}
-
- virtual std::pair<void *, std::size_t> create_new_segment(std::size_t alloc_size)
- {
- //We should allocate an extra byte so that the
- //[base_addr + alloc_size] byte belongs to this segment
- alloc_size += 1;
-
- //If requested size is less than minimum, update that
- alloc_size = (m_min_segment_size > alloc_size) ?
- m_min_segment_size : alloc_size;
- if(mp_frontend->priv_new_segment(create_open_func::DoCreate,
- alloc_size, 0)){
- shmem_list_t::value_type &p_shm = *mp_frontend->m_shmem_list.rbegin();
- return result_type(p_shm->get_address(), p_shm->get_size()-1);
- }
- return result_type(0, 0);
- }
-
- virtual ~group_services(){}
-
- void set_group(std::size_t group)
- { m_group = group; }
-
- std::size_t get_group() const
- { return m_group; }
-
- void set_min_segment_size(std::size_t min_segment_size)
- { m_min_segment_size = min_segment_size; }
-
- std::size_t get_min_segment_size() const
- { return m_min_segment_size; }
-
- private:
-
- frontend_t * const mp_frontend;
- std::size_t m_group;
- std::size_t m_min_segment_size;
- };
-
- /*!Functor to execute atomically when opening or creating a shared memory
- segment.*/
- struct create_open_func
- {
- enum type_t { DoCreate, DoOpen, DoOpenOrCreate };
- typedef typename
- basic_managed_multi_shared_memory::void_pointer void_pointer;
-
- create_open_func(self_t * const frontend,
- type_t type, std::size_t segment_number)
- : mp_frontend(frontend), m_type(type), m_segment_number(segment_number){}
-
- bool operator()(void *addr, std::size_t size, bool created) const
- {
- if(((m_type == DoOpen) && created) ||
- ((m_type == DoCreate) && !created))
- return false;
- std::size_t group = mp_frontend->m_group_services.get_group();
- bool mapped = false;
- bool impl_done = false;
-
- //Associate this newly created segment as the
- //segment id = 0 of this group
- if((mapped = void_pointer::insert_mapping(group, m_segment_number, addr, size))){
- //Check if this is the master segment
- if(!m_segment_number){
- //Create or open the Interprocess machinery
- if(impl_done = created ?
- mp_frontend->create_impl(addr, size) : mp_frontend->open_impl(addr, size)){
- return true;
- }
- }
- else{
- return true;
- }
- }
-
- //This is the cleanup part
- //---------------
- if(impl_done){
- mp_frontend->close_impl();
- }
- if(mapped){
- bool ret = void_pointer::erase_mapping(group, 0);
- assert(ret);(void)ret;
- }
- return false;
- }
- self_t * const mp_frontend;
- type_t m_type;
- std::size_t m_segment_number;
- };
-
- /*!Functor to execute atomically when closing a shared memory segment.*/
- struct close_func
- {
- typedef typename
- basic_managed_multi_shared_memory::void_pointer void_pointer;
-
- close_func(self_t * const frontend)
- : mp_frontend(frontend){}
-
- void operator()(const mapped_region &region, bool last) const
- {
- if(last) mp_frontend->destroy_impl();
- else mp_frontend->close_impl();
- }
- self_t * const mp_frontend;
- };
-
- typedef detail::basic_managed_memory_impl
- <CharType, MemoryAlgorithm, IndexType> base_t;
-
- //Friend declarations
- friend struct basic_managed_multi_shared_memory::create_open_func;
- friend struct basic_managed_multi_shared_memory::close_func;
- friend class basic_managed_multi_shared_memory::group_services;
-
- typedef std::list<shared_memory*> shmem_list_t;
-
- basic_managed_multi_shared_memory *get_this_pointer()
- { return this; }
-
- public:
-
- basic_managed_multi_shared_memory(detail::create_only_t,
- const char *name,
- std::size_t size)
- : m_group_services(get_this_pointer())
- {
- priv_open_or_create(create_open_func::DoCreate,name, size);
- }
-
- basic_managed_multi_shared_memory(detail::open_or_create_t,
- const char *name,
- std::size_t size)
- : m_group_services(get_this_pointer())
- {
- priv_open_or_create(create_open_func::DoOpenOrCreate, name, size);
- }
-
- basic_managed_multi_shared_memory(detail::open_only_t,
- const char *name)
- : m_group_services(get_this_pointer())
- {
- priv_open_or_create(create_open_func::DoOpen, name, 0);
- }
-
- ~basic_managed_multi_shared_memory()
- { this->priv_close(); }
-
- private:
- bool priv_open_or_create(typename create_open_func::type_t type,
- const char *name,
- std::size_t size)
- {
- if(!m_shmem_list.empty())
- return false;
- std::size_t group = 0;
- BOOST_TRY{
- m_root_name = name;
- //Insert multi segment services and get a group identifier
- group = void_pointer::new_group(static_cast<void*>(&m_group_services));
- m_group_services.set_group(group);
- m_group_services.set_min_segment_size(size);
-
- if(group){
- if(this->priv_new_segment(type, size, 0)){
- return true;
- }
- }
- }
- BOOST_CATCH(const std::bad_alloc&){
- }
- BOOST_CATCH_END
- if(group){
- void_pointer::delete_group(group);
- }
- return false;
- }
-
- bool priv_new_segment(typename create_open_func::type_t type,
- std::size_t size,
- const void *addr)
- {
- BOOST_TRY{
- //Get the number of groups of this multi_segment group
- std::size_t segment_id = m_shmem_list.size();
- //Format the name of the shared memory: append segment number.
- boost::interprocess::basic_ovectorstream<boost::interprocess::string> formatter;
- formatter.seekp(std::ios::beg);
- //Pre-reserve string size
- std::size_t str_size = m_root_name.length()+10;
- if(formatter.vector().size() < str_size){
- //This can throw.
- formatter.reserve(str_size);
- }
- //Format segment's name
- formatter << m_root_name
- << static_cast<unsigned int>(segment_id) << std::ends;
- //This functor will be executed when constructing
- create_open_func func(this, type, segment_id);
- const char *name = formatter.vector().c_str();
- //This can throw.
- std::auto_ptr<shared_memory> shm;
-
- switch(type){
- case create_open_func::DoCreate:
- shm.reset(new shared_memory(create_only, name, size
- ,read_write, addr, func));
- break;
-
- case create_open_func::DoOpen:
- shm.reset(new shared_memory(open_only, name
- ,read_write, addr, func));
- break;
-
- case create_open_func::DoOpenOrCreate:
- shm.reset(new shared_memory( boost::interprocess::open_or_create
- , name, size, read_write
- , addr, func));
- break;
-
- default:
- return false;
- break;
- }
- //This can throw.
- m_shmem_list.push_back(shm.get());
- //Anti-exception rollback
- detail::value_eraser<shmem_list_t>
- value_eraser(m_shmem_list, --m_shmem_list.end());
- shm.release();
- value_eraser.release();
- return true;
- }
- BOOST_CATCH(const std::bad_alloc&){
- }
- BOOST_CATCH_END
- return false;
- }
-
- /*!Frees resources. Never throws.*/
- void priv_close()
- {
- if(!m_shmem_list.empty()){
- bool ret;
- //Obtain group identifier
- std::size_t group = m_group_services.get_group();
- //Erase main segment and its resources
- shmem_list_t::iterator itbeg = m_shmem_list.begin(),
- itend = m_shmem_list.end(),
- it = itbeg;
- //(*itbeg)->close_with_func(close_func(this));
- //Delete group. All mappings are erased too.
- ret = void_pointer::delete_group(group);
- assert(ret);
- //Now destroy all shared_memory segments so they
- //are unmapped from the process
- for(it = itbeg; it != itend; ++it) delete *it;
- m_shmem_list.clear();
- }
- }
-
- private:
- shmem_list_t m_shmem_list;
- group_services m_group_services;
- std::string m_root_name;
-};
-
-} //namespace interprocess {
-
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_MANAGED_MULTI_SHARED_MEMORY_HPP
-

Deleted: trunk/boost/interprocess/mem_algo/multi_simple_seq_fit.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/multi_simple_seq_fit.hpp 2007-08-24 17:24:23 EDT (Fri, 24 Aug 2007)
+++ (empty file)
@@ -1,61 +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_MULTI_SIMPLE_SEQ_FIT_HPP
-#define BOOST_INTERPROCESS_MULTI_SIMPLE_SEQ_FIT_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp>
-#include <boost/interprocess/intersegment_ptr.hpp>
-
-/*!\file
- Describes sequential fit algorithm used to allocate objects in shared memory.
-*/
-
-namespace boost {
-
-namespace interprocess {
-
-/*!This class implements the simple sequential fit algorithm with a simply
- linked list of free buffers.*/
-template<class MutexFamily, class VoidPtr>
-class multi_simple_seq_fit
- : public detail::simple_seq_fit_impl<MutexFamily, VoidPtr>
-{
- typedef detail::simple_seq_fit_impl<MutexFamily, VoidPtr> base_t;
- public:
- /*!Constructor. "size" is the total size of the managed memory segment,
- "extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(multi_simple_seq_fit)
- offset that the allocator should not use at all.*/
- multi_simple_seq_fit (std::size_t size, std::size_t extra_hdr_bytes)
- : base_t(size, extra_hdr_bytes){}
-
- /*!Allocates bytes from existing segments. If there is no memory, it uses
- the growing functor associated with the group to allocate a new segment.
- If this fails, returns 0.*/
- void* allocate (std::size_t nbytes)
- { return base_t::multi_allocate(nbytes); }
-};
-
-} //namespace interprocess {
-
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_MULTI_SIMPLE_SEQ_FIT_HPP
-


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk