Remove CDS_RVALUE_SUPPORT, CDS_MOVE_SEMANTICS_SUPPORT macros and emulating code
[libcds.git] / cds / container / striped_set / std_set.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H
4 #define __CDS_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H
5
6 #include <cds/container/striped_set/adapter.h>
7 #include <set>
8
9 //@cond
10 namespace cds { namespace container {
11     namespace striped_set {
12
13         // Copy policy for std::set
14         template <typename T, typename Traits, typename Alloc>
15         struct copy_item_policy< std::set< T, Traits, Alloc > >
16         {
17             typedef std::set< T, Traits, Alloc > set_type;
18             typedef typename set_type::iterator iterator;
19
20             void operator()( set_type& set, iterator itWhat )
21             {
22                 set.insert( *itWhat );
23             }
24         };
25
26         template <typename T, typename Traits, typename Alloc>
27         struct swap_item_policy< std::set< T, Traits, Alloc > >: public copy_item_policy< std::set< T, Traits, Alloc > >
28         {};
29
30         // Move policy for std::set
31         template <typename T, typename Traits, typename Alloc>
32         struct move_item_policy< std::set< T, Traits, Alloc > >
33         {
34             typedef std::set< T, Traits, Alloc > set_type;
35             typedef typename set_type::iterator iterator;
36
37             void operator()( set_type& set, iterator itWhat )
38             {
39                 set.insert( std::move( *itWhat ) );
40             }
41         };
42     }   // namespace striped_set
43 }} // namespace cds::container
44
45 namespace cds { namespace intrusive { namespace striped_set {
46
47     /// std::set adapter for hash set bucket
48     template <typename T, class Traits, class Alloc, CDS_SPEC_OPTIONS>
49     class adapt< std::set<T, Traits, Alloc>, CDS_OPTIONS >
50     {
51     public:
52         typedef std::set<T, Traits, Alloc>     container_type          ;   ///< underlying container type
53
54     private:
55         /// Adapted container type
56         class adapted_container: public cds::container::striped_set::adapted_container
57         {
58         public:
59             typedef typename container_type::value_type value_type  ;   ///< value type stored in the container
60             typedef typename container_type::iterator      iterator ;   ///< container iterator
61             typedef typename container_type::const_iterator const_iterator ;    ///< container const iterator
62
63             static bool const has_find_with = false;
64             static bool const has_erase_with = false;
65
66         private:
67             //@cond
68             typedef typename cds::opt::select<
69                 typename cds::opt::value<
70                     typename cds::opt::find_option<
71                         cds::opt::copy_policy< cds::container::striped_set::move_item >
72                         , CDS_OPTIONS
73                     >::type
74                 >::copy_policy
75                 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
76                 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
77                 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
78             >::type copy_item;
79             //@endcond
80
81         private:
82             //@cond
83             container_type  m_Set;
84             //@endcond
85
86         public:
87
88             template <typename Q, typename Func>
89             bool insert( const Q& val, Func f )
90             {
91                 std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
92                 if ( res.second )
93                     ::cds::unref(f)( const_cast<value_type&>(*res.first) );
94                 return res.second;
95             }
96
97 #       ifdef CDS_EMPLACE_SUPPORT
98             template <typename... Args>
99             bool emplace( Args&&... args )
100             {
101 #           if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40800 || CDS_COMPILER == CDS_COMPILER_CLANG && !defined(__LIBCPP_VERSION)
102                 // GCC < 4.8: std::set has no "emplace" member function. Emulate it
103                 std::pair<iterator, bool> res = m_Set.insert( value_type( std::forward<Args>(args)...));
104 #           else
105                 std::pair<iterator, bool> res = m_Set.emplace( std::forward<Args>(args)... );
106 #           endif
107                 return res.second;
108             }
109 #       endif
110
111             template <typename Q, typename Func>
112             std::pair<bool, bool> ensure( const Q& val, Func func )
113             {
114                 std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
115                 ::cds::unref(func)( res.second, const_cast<value_type&>(*res.first), val );
116                 return std::make_pair( true, res.second );
117             }
118
119             template <typename Q, typename Func>
120             bool erase( const Q& key, Func f )
121             {
122                 iterator it = m_Set.find( value_type(key) );
123                 if ( it == m_Set.end() )
124                     return false;
125                 ::cds::unref(f)( const_cast<value_type&>(*it) );
126                 m_Set.erase( it );
127                 return true;
128             }
129
130             template <typename Q, typename Func>
131             bool find( Q& val, Func f )
132             {
133                 iterator it = m_Set.find( value_type(val) );
134                 if ( it == m_Set.end() )
135                     return false;
136                 ::cds::unref(f)( const_cast<value_type&>(*it), val );
137                 return true;
138             }
139
140             void clear()
141             {
142                 m_Set.clear();
143             }
144
145             iterator begin()                { return m_Set.begin(); }
146             const_iterator begin() const    { return m_Set.begin(); }
147             iterator end()                  { return m_Set.end(); }
148             const_iterator end() const      { return m_Set.end(); }
149
150             void move_item( adapted_container& /*from*/, iterator itWhat )
151             {
152                 assert( m_Set.find( *itWhat ) == m_Set.end() );
153                 copy_item()( m_Set, itWhat );
154             }
155
156             size_t size() const
157             {
158                 return m_Set.size();
159             }
160         };
161
162     public:
163         typedef adapted_container type ; ///< Result of \p adapt metafunction
164
165     };
166 }}} // namespace cds::intrusive::striped_set
167
168
169 //@endcond
170
171 #endif // #ifndef __CDS_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H