• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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