/* Copyright 2003-2005 Joaquín M López Muñoz.
* 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/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <functional>
namespace boost{
namespace multi_index{
namespace detail{
/* singly-linked node for use by hashed_index */
struct hashed_index_node_impl
{
hashed_index_node_impl*& next(){return next_;}
hashed_index_node_impl*const & next()const{return next_;}
/* interoperability with hashed_index_proxy */
static hashed_index_node_impl* end(hashed_index_node_impl* header)
{
return header;
}
/* algorithmic stuff */
static void increment(
hashed_index_node_impl*& x,
hashed_index_node_impl* bbegin,hashed_index_node_impl* bbend)
{
std::less_equal<hashed_index_node_impl*> leq;
x=x->next();
if(leq(bbegin,x)&&leq(x,bbend)){ /* bucket node */
do{
++x;
}while(x->next()==x);
x=x->next();
}
}
static void link(
hashed_index_node_impl* x,hashed_index_node_impl* pos)
{
x->next()=pos->next();
pos->next()=x;
};
static void unlink(hashed_index_node_impl* x)
{
hashed_index_node_impl* y=x->next();
while(y->next()!=x){y=y->next();}
y->next()=x->next();
}
static hashed_index_node_impl* prev(hashed_index_node_impl* x)
{
hashed_index_node_impl* y=x->next();
while(y->next()!=x){y=y->next();}
return y;
}
static void unlink_next(hashed_index_node_impl* x)
{
x->next()=x->next()->next();
}
private:
hashed_index_node_impl();
hashed_index_node_impl* next_;
};
template<typename Super>
struct hashed_index_node_trampoline:hashed_index_node_impl{};
template<typename Super>
struct hashed_index_node:Super,hashed_index_node_trampoline<Super>
{
hashed_index_node_impl* impl()
{return static_cast<impl_type*>(this);}
const hashed_index_node_impl* impl()const
{return static_cast<const impl_type*>(this);}
static hashed_index_node* from_impl(hashed_index_node_impl *x)
{return static_cast<hashed_index_node*>(static_cast<impl_type*>(x));}
static const hashed_index_node* from_impl(
const hashed_index_node_impl* x)
{
return static_cast<const hashed_index_node*>(
static_cast<const impl_type*>(x));
}
static void increment(
hashed_index_node*& x,
hashed_index_node_impl* bbegin,hashed_index_node_impl* bend)
{
hashed_index_node_impl* xi=x->impl();
impl_type::increment(xi,bbegin,bend);
x=from_impl(xi);
}
/* interoperability with hashed_index_proxy */
static hashed_index_node* end(hashed_index_node* header)
{
return from_impl(impl_type::end(header->impl()));
}
private:
typedef hashed_index_node_trampoline<Super> impl_type;
};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif