Updated copyright
[libcds.git] / cds / container / striped_map / std_map.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-2017
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_MAP_STD_MAP_ADAPTER_H
32 #define CDSLIB_CONTAINER_STRIPED_MAP_STD_MAP_ADAPTER_H
33
34 #include <cds/container/striped_set/adapter.h>
35 #include <map>
36
37 //@cond
38 namespace cds { namespace container {
39     namespace striped_set {
40
41         // Copy policy for map
42         template <typename Key, typename T, typename Traits, typename Alloc>
43         struct copy_item_policy< std::map< Key, T, Traits, Alloc > >
44         {
45             typedef std::map< Key, T, Traits, Alloc > map_type;
46             typedef typename map_type::value_type pair_type;
47             typedef typename map_type::iterator    iterator;
48
49             void operator()( map_type& map, iterator itWhat )
50             {
51                 map.insert( *itWhat );
52             }
53         };
54
55         // Swap item policy
56         template <typename Key, typename T, typename Traits, typename Alloc>
57         struct swap_item_policy< std::map< Key, T, Traits, Alloc > >
58         {
59             typedef std::map< Key, T, Traits, Alloc > map_type;
60             typedef typename map_type::value_type pair_type;
61             typedef typename map_type::iterator    iterator;
62
63             void operator()( map_type& map, iterator itWhat )
64             {
65                 std::pair< typename map_type::iterator, bool > ret = map.insert( pair_type( itWhat->first, typename pair_type::second_type()));
66                 assert( ret.second )    ;   // successful insertion
67                 std::swap( ret.first->second, itWhat->second );
68             }
69         };
70
71         // Move policy for map
72         template <typename Key, typename T, typename Traits, typename Alloc>
73         struct move_item_policy< std::map< Key, T, Traits, Alloc > >
74         {
75             typedef std::map< Key, T, Traits, Alloc > map_type;
76             typedef typename map_type::value_type pair_type;
77             typedef typename map_type::iterator    iterator;
78
79             void operator()( map_type& map, iterator itWhat  )
80             {
81                 map.insert( std::move( *itWhat ));
82             }
83         };
84     }   // namespace striped_set
85 }} // namespace cds::container
86
87 namespace cds { namespace intrusive { namespace striped_set {
88
89     /// std::set adapter for hash set bucket
90     template <typename Key, typename T, class Traits, class Alloc, typename... Options>
91     class adapt< std::map< Key, T, Traits, Alloc>, Options... >
92     {
93     public:
94         typedef std::map< Key, T, Traits, Alloc>     container_type          ;   ///< underlying container type
95
96     private:
97         /// Adapted container type
98         class adapted_container: public cds::container::striped_set::adapted_container
99         {
100         public:
101             typedef typename container_type::value_type     value_type  ;   ///< value type stored in the container
102             typedef typename container_type::key_type       key_type;
103             typedef typename container_type::mapped_type    mapped_type;
104             typedef typename container_type::iterator       iterator ;   ///< container iterator
105             typedef typename container_type::const_iterator const_iterator ;    ///< container const iterator
106
107             static bool const has_find_with = false;
108             static bool const has_erase_with = false;
109
110         private:
111             //@cond
112             typedef typename cds::opt::select<
113                 typename cds::opt::value<
114                     typename cds::opt::find_option<
115                         cds::opt::copy_policy< cds::container::striped_set::move_item >
116                         , Options...
117                     >::type
118                 >::copy_policy
119                 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
120                 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
121                 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
122             >::type copy_item;
123             //@endcond
124
125         private:
126             //@cond
127             container_type  m_Map;
128             //@endcond
129
130         public:
131
132             template <typename Q, typename Func>
133             bool insert( const Q& key, Func f )
134             {
135                 std::pair<iterator, bool> res = m_Map.insert( value_type( key_type( key ), mapped_type()));
136                 if ( res.second )
137                     f( *res.first );
138                 return res.second;
139             }
140
141             template <typename Q, typename... Args>
142             bool emplace( Q&& key, Args&&... args )
143             {
144                 std::pair<iterator, bool> res = m_Map.emplace( key_type( std::forward<Q>( key )), mapped_type( std::forward<Args>( args )...));
145                 return res.second;
146             }
147
148             template <typename Q, typename Func>
149             std::pair<bool, bool> update( const Q& key, Func func, bool bAllowInsert )
150             {
151                 if ( bAllowInsert ) {
152                     std::pair<iterator, bool> res = m_Map.insert( value_type( key_type( key ), mapped_type()));
153                     func( res.second, *res.first );
154                     return std::make_pair( true, res.second );
155                 }
156                 else {
157                     auto it = m_Map.find( key_type( key ));
158                     if ( it == end())
159                         return std::make_pair( false, false );
160                     func( false, *it );
161                     return std::make_pair( true, false );
162                 }
163             }
164
165             template <typename Q, typename Func>
166             bool erase( const Q& key, Func f )
167             {
168                 iterator it = m_Map.find( key_type( key ));
169                 if ( it == m_Map.end())
170                     return false;
171                 f( *it );
172                 m_Map.erase( it );
173                 return true;
174             }
175
176             template <typename Q, typename Func>
177             bool find( Q& key, Func f )
178             {
179                 iterator it = m_Map.find( key_type( key ));
180                 if ( it == m_Map.end())
181                     return false;
182                 f( *it, key );
183                 return true;
184             }
185
186             /// Clears the container
187             void clear()
188             {
189                 m_Map.clear();
190             }
191
192             iterator begin()                { return m_Map.begin(); }
193             const_iterator begin() const    { return m_Map.begin(); }
194             iterator end()                  { return m_Map.end(); }
195             const_iterator end() const      { return m_Map.end(); }
196
197             void move_item( adapted_container& /*from*/, iterator itWhat )
198             {
199                 assert( m_Map.find( itWhat->first ) == m_Map.end());
200                 copy_item()( m_Map, itWhat );
201             }
202
203             size_t size() const
204             {
205                 return m_Map.size();
206             }
207         };
208
209     public:
210         typedef adapted_container type ; ///< Result of \p adapt metafunction
211     };
212 }}} // namespace cds::intrusive::striped_set
213
214 //@endcond
215
216 #endif // #ifndef CDSLIB_CONTAINER_STRIPED_MAP_STD_MAP_ADAPTER_H