1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Andrey Semashev 2018.
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 #include <boost/intrusive/options.hpp>
14 #include <boost/intrusive/set.hpp>
15 #include <boost/intrusive/set_hook.hpp>
16 #include <boost/config.hpp>
17 #include <boost/core/lightweight_test.hpp>
18 #include <functional> // std::less
19
20 // The test verifies that the set implementation does not use void* as auxiliary arguments for SFINAE
21 // in internal functions, which would make overload resolution ambiguous if user's key type is also void*.
22
23 typedef boost::intrusive::set_base_hook<
24 boost::intrusive::link_mode< boost::intrusive::safe_link >,
25 boost::intrusive::tag< struct for_set_element_lookup_by_key >,
26 boost::intrusive::optimize_size< true >
27 > set_element_hook_t;
28
29 struct set_element :
30 public set_element_hook_t
31 {
32 struct order_by_key
33 {
34 typedef bool result_type;
35
operator ()set_element::order_by_key36 result_type operator() (set_element const& left, set_element const& right) const
37 {
38 return std::less< void* >()(left.m_key, right.m_key);
39 }
operator ()set_element::order_by_key40 result_type operator() (void* left, set_element const& right) const
41 {
42 return std::less< void* >()(left, right.m_key);
43 }
operator ()set_element::order_by_key44 result_type operator() (set_element const& left, void* right) const
45 {
46 return std::less< void* >()(left.m_key, right);
47 }
48 };
49
50 void* m_key;
51
set_elementset_element52 explicit set_element(void* key) : m_key(key) {}
53
54 BOOST_DELETED_FUNCTION(set_element(set_element const&))
55 BOOST_DELETED_FUNCTION(set_element& operator=(set_element const&))
56 };
57
58 typedef boost::intrusive::set<
59 set_element,
60 boost::intrusive::base_hook< set_element_hook_t >,
61 boost::intrusive::compare< set_element::order_by_key >,
62 boost::intrusive::constant_time_size< true >
63 > set_t;
64
test_set()65 void test_set()
66 {
67 int v1 = 0, v2 = 1, v3 = 2;
68 set_element e1(&v1), e2(&v2), e3(&v3);
69
70 set_t s;
71 s.insert(e1);
72 s.insert(e2);
73
74 set_t::iterator it = s.find(e1);
75 BOOST_TEST(it != s.end() && &*it == &e1);
76
77 it = s.find((void*)&v2, set_element::order_by_key());
78 BOOST_TEST(it != s.end() && &*it == &e2);
79
80 it = s.find(e3);
81 BOOST_TEST(it == s.end());
82
83 it = s.find((void*)&v3, set_element::order_by_key());
84 BOOST_TEST(it == s.end());
85
86 s.clear();
87 }
88
main()89 int main()
90 {
91 test_set();
92
93 return boost::report_errors();
94 }
95