Merge branch 'dev' of github.com:khizmax/libcds into dev
[libcds.git] / cds / container / striped_set / std_set.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H
4 #define CDSLIB_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, typename... Options>
49     class adapt< std::set<T, Traits, Alloc>, 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                         , 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                     f( const_cast<value_type&>(*res.first) );
94                 return res.second;
95             }
96
97             template <typename... Args>
98             bool emplace( Args&&... args )
99             {
100                 std::pair<iterator, bool> res = m_Set.emplace( std::forward<Args>(args)... );
101                 return res.second;
102             }
103
104             template <typename Q, typename Func>
105             std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
106             {
107                 if ( bAllowInsert ) {
108                     std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
109                     func( res.second, const_cast<value_type&>(*res.first), val );
110                     return std::make_pair( true, res.second );
111                 }
112                 else {
113                     auto it = m_Set.find(value_type(val));
114                     if ( it == m_Set.end() )
115                         return std::make_pair( false, false );
116                     func( false, const_cast<value_type&>(*it), val );
117                     return std::make_pair( true, false );
118                 }
119             }
120
121             template <typename Q, typename Func>
122             bool erase( const Q& key, Func f )
123             {
124                 iterator it = m_Set.find( value_type(key) );
125                 if ( it == m_Set.end() )
126                     return false;
127                 f( const_cast<value_type&>(*it) );
128                 m_Set.erase( it );
129                 return true;
130             }
131
132             template <typename Q, typename Func>
133             bool find( Q& val, Func f )
134             {
135                 iterator it = m_Set.find( value_type(val) );
136                 if ( it == m_Set.end() )
137                     return false;
138                 f( const_cast<value_type&>(*it), val );
139                 return true;
140             }
141
142             void clear()
143             {
144                 m_Set.clear();
145             }
146
147             iterator begin()                { return m_Set.begin(); }
148             const_iterator begin() const    { return m_Set.begin(); }
149             iterator end()                  { return m_Set.end(); }
150             const_iterator end() const      { return m_Set.end(); }
151
152             void move_item( adapted_container& /*from*/, iterator itWhat )
153             {
154                 assert( m_Set.find( *itWhat ) == m_Set.end() );
155                 copy_item()( m_Set, itWhat );
156             }
157
158             size_t size() const
159             {
160                 return m_Set.size();
161             }
162         };
163
164     public:
165         typedef adapted_container type ; ///< Result of \p adapt metafunction
166
167     };
168 }}} // namespace cds::intrusive::striped_set
169
170
171 //@endcond
172
173 #endif // #ifndef CDSLIB_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H