///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. // (C) Copyright Ion Gaztanaga 2006-2013. // // 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/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// #ifndef BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP #define BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP #include #include #include #include #include "nonhook_node.hpp" #include "int_holder.hpp" #include #include namespace boost{ namespace intrusive{ struct testvalue_filler { void *dummy_[3]; }; template struct testvalue : testvalue_filler , Hooks::base_hook_type , Hooks::auto_base_hook_type { typename Hooks::member_hook_type node_; typename Hooks::auto_member_hook_type auto_node_; typename Hooks::nonhook_node_member_type nhn_member_; int_holder value_; testvalue() {} explicit testvalue(int i) : value_(i) {} testvalue (const testvalue& src) : value_(src.value_) {} // testvalue is used in boost::container::vector and thus prev and next // have to be handled appropriately when copied: testvalue & operator= (const testvalue& src) { Hooks::base_hook_type::operator=(static_cast(src)); Hooks::auto_base_hook_type::operator=(static_cast(src)); this->node_ = src.node_; this->auto_node_ = src.auto_node_; this->nhn_member_ = src.nhn_member_; value_ = src.value_; return *this; } void swap_nodes(testvalue &other) { Hooks::base_hook_type::swap_nodes(static_cast(other)); Hooks::auto_base_hook_type::swap_nodes(static_cast(other)); node_.swap_nodes(other.node_); auto_node_.swap_nodes(other.auto_node_); nhn_member_.swap_nodes(other.nhn_member_); } bool is_linked() const { return Hooks::base_hook_type::is_linked() || Hooks::auto_base_hook_type::is_linked() || node_.is_linked() || auto_node_.is_linked() || nhn_member_.is_linked(); } const int_holder &get_int_holder() const { return value_; } int int_value() const { return value_.int_value(); } ~testvalue() {} bool operator< (const testvalue &other) const { return value_ < other.value_; } bool operator> (const testvalue &other) const { return value_ > other.value_; } bool operator==(const testvalue &other) const { return value_ == other.value_; } bool operator!=(const testvalue &other) const { return value_ != other.value_; } friend bool operator< (int other1, const testvalue &other2) { return other1 < other2.value_.int_; } friend bool operator> (int other1, const testvalue &other2) { return other1 > other2.value_.int_; } friend bool operator< (const testvalue &other1, int other2) { return other1.value_.int_ < other2; } friend bool operator> (const testvalue &other1, int other2) { return other1.value_.int_ > other2; } friend bool operator== (int other1, const testvalue &other2) { return other1 == other2.value_.int_; } friend bool operator== (const testvalue &other1, int other2) { return other1.value_.int_ == other2; } friend bool operator!= (int other1, const testvalue &other2) { return other1 != other2.value_.int_; } friend bool operator!= (const testvalue &other1, int other2) { return other1.value_.int_ != other2; } friend std::size_t hash_value(const testvalue&t) { boost::hash hasher; return hasher((&t)->int_value()); } }; template std::size_t priority_hash(const T &t) { return boost::hash()((&t)->int_value()); } std::size_t priority_hash(int i) { return boost::hash()(i); } template bool priority_order(const T& t1, const U& t2) { std::size_t hash1 = (priority_hash)(t1); boost::hash_combine(hash1, -hash1); std::size_t hash2 = (priority_hash)(t2); boost::hash_combine(hash2, -hash2); return hash1 < hash2; } template < typename Node_Algorithms, class Hooks> void swap_nodes(testvalue& lhs, testvalue& rhs) { lhs.swap_nodes(rhs); } template std::ostream& operator<< (std::ostream& s, const testvalue& t) { return s << t.value_.int_value(); } struct even_odd { template < typename key_type_1, typename key_type_2 > bool operator() (const key_type_1& v1 ,const key_type_2& v2) const { if (((&v1)->int_value() & 1) == ((&v2)->int_value() & 1)) return (&v1)->int_value() < (&v2)->int_value(); else return (&v2)->int_value() & 1; } }; struct is_even { template bool operator() (const key_type& v1) const { return ((&v1)->int_value() & 1) == 0; } }; struct is_odd { template bool operator() (const key_type& v1) const { return ((&v1)->int_value() & 1) != 0; } }; template struct ValueContainer; template < class Hooks> struct ValueContainer< testvalue > { typedef boost::container::vector< testvalue > type; }; template < typename Pointer > class heap_node_holder { typedef typename pointer_traits::element_type element_type; typedef Pointer pointer; typedef typename pointer_rebind::type const_pointer; public: heap_node_holder() : m_ptr(pointer_traits::pointer_to(*new element_type)) {} ~heap_node_holder() { delete &*m_ptr; } const_pointer get_node() const { return m_ptr; } pointer get_node() { return m_ptr; } private: pointer m_ptr; }; template struct testvalue_traits : public Hooks { typedef testvalue< Hooks > value_type; //base typedef typename detail::get_base_value_traits < value_type , typename Hooks::base_hook_type >::type base_value_traits; //auto-base typedef typename detail::get_base_value_traits < value_type , typename Hooks::auto_base_hook_type >::type auto_base_value_traits; //member typedef typename detail::get_member_value_traits < member_hook < value_type , typename Hooks::member_hook_type , &value_type::node_ > >::type member_value_traits; //auto-member typedef typename detail::get_member_value_traits < member_hook < value_type , typename Hooks::auto_member_hook_type , &value_type::auto_node_ > >::type auto_member_value_traits; //nonmember typedef nonhook_node_member_value_traits < value_type , typename Hooks::nonhook_node_member_type , &value_type::nhn_member_ , safe_link > nonhook_value_traits; }; } //namespace intrusive{ } //namespace boost{ bool priority_order(int t1, int t2) { std::size_t hash1 = boost::hash()(t1); boost::hash_combine(hash1, &t1); std::size_t hash2 = boost::hash()(t2); boost::hash_combine(hash2, &t2); return hash1 < hash2; } #endif