1/////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2014-2014
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// See http://www.boost.org/libs/intrusive for documentation.
10//
11/////////////////////////////////////////////////////////////////////////////
12
13#ifndef BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP
14#define BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP
15
16#ifndef BOOST_CONFIG_HPP
17# include <boost/config.hpp>
18#endif
19
20#if defined(BOOST_HAS_PRAGMA_ONCE)
21# pragma once
22#endif
23
24#include <boost/intrusive/detail/mpl.hpp>
25#include <boost/intrusive/detail/ebo_functor_holder.hpp>
26
27namespace boost {
28namespace intrusive {
29namespace detail {
30
31template<class KeyValueCompare, class ValueTraits>
32struct key_nodeptr_comp
33 //Use public inheritance to avoid MSVC bugs with closures
34 : public ebo_functor_holder<KeyValueCompare>
35{
36 typedef ValueTraits value_traits;
37 typedef typename value_traits::value_type value_type;
38 typedef typename value_traits::node_ptr node_ptr;
39 typedef typename value_traits::const_node_ptr const_node_ptr;
40 typedef ebo_functor_holder<KeyValueCompare> base_t;
41
42 key_nodeptr_comp(KeyValueCompare kcomp, const ValueTraits *traits)
43 : base_t(kcomp), traits_(traits)
44 {}
45
46 template<class T>
47 struct is_node_ptr
48 {
49 static const bool value = is_same<T, const_node_ptr>::value || is_same<T, node_ptr>::value;
50 };
51
52 //key_forward
53 template<class T>
54 const value_type & key_forward
55 (const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const
56 { return *traits_->to_value_ptr(node); }
57
58 template<class T>
59 const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const
60 { return key; }
61
62 //operator() 1 arg
63 template<class KeyType>
64 bool operator()(const KeyType &key1) const
65 { return base_t::get()(this->key_forward(key1)); }
66
67 template<class KeyType>
68 bool operator()(const KeyType &key1)
69 { return base_t::get()(this->key_forward(key1)); }
70
71 //operator() 2 arg
72 template<class KeyType, class KeyType2>
73 bool operator()(const KeyType &key1, const KeyType2 &key2) const
74 { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); }
75
76 template<class KeyType, class KeyType2>
77 bool operator()(const KeyType &key1, const KeyType2 &key2)
78 { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); }
79
80 const ValueTraits *const traits_;
81};
82
83} //namespace detail{
84} //namespace intrusive{
85} //namespace boost{
86
87#endif //BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP
88