Removed trailing spaces
[libcds.git] / cds / container / striped_set / std_set.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSLIB_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H
32 #define CDSLIB_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H
33
34 #include <cds/container/striped_set/adapter.h>
35 #include <set>
36
37 //@cond
38 namespace cds { namespace container {
39     namespace striped_set {
40
41         // Copy policy for std::set
42         template <typename T, typename Traits, typename Alloc>
43         struct copy_item_policy< std::set< T, Traits, Alloc > >
44         {
45             typedef std::set< T, Traits, Alloc > set_type;
46             typedef typename set_type::iterator iterator;
47
48             void operator()( set_type& set, iterator itWhat )
49             {
50                 set.insert( *itWhat );
51             }
52         };
53
54         template <typename T, typename Traits, typename Alloc>
55         struct swap_item_policy< std::set< T, Traits, Alloc > >: public copy_item_policy< std::set< T, Traits, Alloc > >
56         {};
57
58         // Move policy for std::set
59         template <typename T, typename Traits, typename Alloc>
60         struct move_item_policy< std::set< T, Traits, Alloc > >
61         {
62             typedef std::set< T, Traits, Alloc > set_type;
63             typedef typename set_type::iterator iterator;
64
65             void operator()( set_type& set, iterator itWhat )
66             {
67                 set.insert( std::move( *itWhat ) );
68             }
69         };
70     }   // namespace striped_set
71 }} // namespace cds::container
72
73 namespace cds { namespace intrusive { namespace striped_set {
74
75     /// std::set adapter for hash set bucket
76     template <typename T, class Traits, class Alloc, typename... Options>
77     class adapt< std::set<T, Traits, Alloc>, Options... >
78     {
79     public:
80         typedef std::set<T, Traits, Alloc>     container_type          ;   ///< underlying container type
81
82     private:
83         /// Adapted container type
84         class adapted_container: public cds::container::striped_set::adapted_container
85         {
86         public:
87             typedef typename container_type::value_type value_type  ;   ///< value type stored in the container
88             typedef typename container_type::iterator      iterator ;   ///< container iterator
89             typedef typename container_type::const_iterator const_iterator ;    ///< container const iterator
90
91             static bool const has_find_with = false;
92             static bool const has_erase_with = false;
93
94         private:
95             //@cond
96             typedef typename cds::opt::select<
97                 typename cds::opt::value<
98                     typename cds::opt::find_option<
99                         cds::opt::copy_policy< cds::container::striped_set::move_item >
100                         , Options...
101                     >::type
102                 >::copy_policy
103                 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
104                 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
105                 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
106             >::type copy_item;
107             //@endcond
108
109         private:
110             //@cond
111             container_type  m_Set;
112             //@endcond
113
114         public:
115
116             template <typename Q, typename Func>
117             bool insert( const Q& val, Func f )
118             {
119                 std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
120                 if ( res.second )
121                     f( const_cast<value_type&>(*res.first) );
122                 return res.second;
123             }
124
125             template <typename... Args>
126             bool emplace( Args&&... args )
127             {
128                 std::pair<iterator, bool> res = m_Set.emplace( std::forward<Args>(args)... );
129                 return res.second;
130             }
131
132             template <typename Q, typename Func>
133             std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
134             {
135                 if ( bAllowInsert ) {
136                     std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
137                     func( res.second, const_cast<value_type&>(*res.first), val );
138                     return std::make_pair( true, res.second );
139                 }
140                 else {
141                     auto it = m_Set.find(value_type(val));
142                     if ( it == m_Set.end() )
143                         return std::make_pair( false, false );
144                     func( false, const_cast<value_type&>(*it), val );
145                     return std::make_pair( true, false );
146                 }
147             }
148
149             template <typename Q, typename Func>
150             bool erase( const Q& key, Func f )
151             {
152                 iterator it = m_Set.find( value_type(key) );
153                 if ( it == m_Set.end() )
154                     return false;
155                 f( const_cast<value_type&>(*it) );
156                 m_Set.erase( it );
157                 return true;
158             }
159
160             template <typename Q, typename Func>
161             bool find( Q& val, Func f )
162             {
163                 iterator it = m_Set.find( value_type(val) );
164                 if ( it == m_Set.end() )
165                     return false;
166                 f( const_cast<value_type&>(*it), val );
167                 return true;
168             }
169
170             void clear()
171             {
172                 m_Set.clear();
173             }
174
175             iterator begin()                { return m_Set.begin(); }
176             const_iterator begin() const    { return m_Set.begin(); }
177             iterator end()                  { return m_Set.end(); }
178             const_iterator end() const      { return m_Set.end(); }
179
180             void move_item( adapted_container& /*from*/, iterator itWhat )
181             {
182                 assert( m_Set.find( *itWhat ) == m_Set.end() );
183                 copy_item()( m_Set, itWhat );
184             }
185
186             size_t size() const
187             {
188                 return m_Set.size();
189             }
190         };
191
192     public:
193         typedef adapted_container type ; ///< Result of \p adapt metafunction
194
195     };
196 }}} // namespace cds::intrusive::striped_set
197
198
199 //@endcond
200
201 #endif // #ifndef CDSLIB_CONTAINER_STRIPED_SET_STD_SET_ADAPTER_H