/* Copyright 2003-2008 Joaquin M Lopez Munoz. | |
* 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_INDEX_NODE_BASE_HPP | |
#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_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 <boost/type_traits/aligned_storage.hpp> | |
#include <boost/type_traits/alignment_of.hpp> | |
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) | |
#include <boost/archive/archive_exception.hpp> | |
#include <boost/serialization/access.hpp> | |
#include <boost/throw_exception.hpp> | |
#endif | |
namespace boost{ | |
namespace multi_index{ | |
namespace detail{ | |
/* index_node_base tops the node hierarchy of multi_index_container. It holds | |
* the value of the element contained. | |
*/ | |
template<typename Value> | |
struct pod_value_holder | |
{ | |
typename aligned_storage< | |
sizeof(Value), | |
alignment_of<Value>::value | |
>::type space; | |
}; | |
template<typename Value,typename Allocator> | |
struct index_node_base:private pod_value_holder<Value> | |
{ | |
typedef index_node_base base_type; /* used for serialization purposes */ | |
typedef Value value_type; | |
typedef Allocator allocator_type; | |
value_type& value() | |
{ | |
return *static_cast<value_type*>( | |
static_cast<void*>(&this->space)); | |
} | |
const value_type& value()const | |
{ | |
return *static_cast<const value_type*>( | |
static_cast<const void*>(&this->space)); | |
} | |
static index_node_base* from_value(const value_type* p) | |
{ | |
return static_cast<index_node_base *>( | |
reinterpret_cast<pod_value_holder<Value>*>( /* std 9.2.17 */ | |
const_cast<value_type*>(p))); | |
} | |
private: | |
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) | |
friend class boost::serialization::access; | |
/* nodes do not emit any kind of serialization info. They are | |
* fed to Boost.Serialization so that pointers to nodes are | |
* tracked correctly. | |
*/ | |
template<class Archive> | |
void serialize(Archive&,const unsigned int) | |
{ | |
} | |
#endif | |
}; | |
template<typename Node,typename Value> | |
Node* node_from_value( | |
const Value* p | |
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node)) | |
{ | |
typedef typename Node::allocator_type allocator_type; | |
return static_cast<Node*>( | |
index_node_base<Value,allocator_type>::from_value(p)); | |
} | |
} /* namespace multi_index::detail */ | |
} /* namespace multi_index */ | |
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) | |
/* Index nodes never get constructed directly by Boost.Serialization, | |
* as archives are always fed pointers to previously existent | |
* nodes. So, if this is called it means we are dealing with a | |
* somehow invalid archive. | |
*/ | |
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
namespace serialization{ | |
#else | |
namespace multi_index{ | |
namespace detail{ | |
#endif | |
template<class Archive,typename Value,typename Allocator> | |
inline void load_construct_data( | |
Archive&,boost::multi_index::detail::index_node_base<Value,Allocator>*, | |
const unsigned int) | |
{ | |
throw_exception( | |
archive::archive_exception(archive::archive_exception::other_exception)); | |
} | |
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
} /* namespace serialization */ | |
#else | |
} /* namespace multi_index::detail */ | |
} /* namespace multi_index */ | |
#endif | |
#endif | |
} /* namespace boost */ | |
#endif |