issue#11: cds: changed __CDS_ guard prefix to CDSLIB_ for all .h files
[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> ensure( const Q& val, Func func )
106             {
107                 std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
108                 func( res.second, const_cast<value_type&>(*res.first), val );
109                 return std::make_pair( true, res.second );
110             }
111
112             template <typename Q, typename Func>
113             bool erase( const Q& key, Func f )
114             {
115                 iterator it = m_Set.find( value_type(key) );
116                 if ( it == m_Set.end() )
117                     return false;
118                 f( const_cast<value_type&>(*it) );
119                 m_Set.erase( it );
120                 return true;
121             }
122
123             template <typename Q, typename Func>
124             bool find( Q& val, Func f )
125             {
126                 iterator it = m_Set.find( value_type(val) );
127                 if ( it == m_Set.end() )
128                     return false;
129                 f( const_cast<value_type&>(*it), val );
130                 return true;
131             }
132
133             void clear()
134             {
135                 m_Set.clear();
136             }
137
138             iterator begin()                { return m_Set.begin(); }
139             const_iterator begin() const    { return m_Set.begin(); }
140             iterator end()                  { return m_Set.end(); }
141             const_iterator end() const      { return m_Set.end(); }
142
143             void move_item( adapted_container& /*from*/, iterator itWhat )
144             {
145                 assert( m_Set.find( *itWhat ) == m_Set.end() );
146                 copy_item()( m_Set, itWhat );
147             }
148
149             size_t size() const
150             {
151                 return m_Set.size();
152             }
153         };
154
155     public:
156         typedef adapted_container type ; ///< Result of \p adapt metafunction
157
158     };
159 }}} // namespace cds::intrusive::striped_set
160
161
162 //@endcond
163
164 #endif // #ifndef CDSLIB_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H