Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / cds / container / details / split_list_base.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_DETAILS_SPLIT_LIST_BASE_H
32 #define CDSLIB_CONTAINER_DETAILS_SPLIT_LIST_BASE_H
33
34 #include <cds/intrusive/details/split_list_base.h>
35
36 namespace cds { namespace container {
37
38     // forward declaration
39     struct michael_list_tag;
40
41     /// SplitListSet related definitions
42     /** @ingroup cds_nonintrusive_helper
43     */
44     namespace split_list {
45         /// Internal statistics, see \p cds::intrusive::split_list::stat
46         template <typename Counter = cds::intrusive::split_list::stat<>::counter_type >
47         using stat = cds::intrusive::split_list::stat<Counter>;
48
49         /// Disabled internal statistics, see \p cds::intrusive::split_list::empty_stat
50         typedef cds::intrusive::split_list::empty_stat empty_stat;
51
52         /// Selector of bucket table implementation = typedef for \p intrusive::split_list::dynamic_bucket_table
53         template <bool Value>
54         using dynamic_bucket_table = cds::intrusive::split_list::dynamic_bucket_table<Value>;
55
56         using cds::intrusive::split_list::static_bucket_table;
57         using cds::intrusive::split_list::expandable_bucket_table;
58
59         //@cond
60         namespace details {
61
62             template <typename Key, typename Value, typename Traits, typename Opt>
63             struct wrap_map_traits_helper {
64                 typedef Opt key_accessor;
65             };
66
67             template <typename Key, typename Value, typename Traits >
68             struct wrap_map_traits_helper<Key, Value, Traits, opt::none>
69             {
70                 struct key_accessor
71                 {
72                     typedef Key     key_type;
73                     key_type const & operator()( std::pair<Key const, Value> const & val ) const
74                     {
75                         return val.first;
76                     }
77                 };
78             };
79
80             template <typename Key, typename Value, typename Traits>
81             struct wrap_map_traits: public Traits
82             {
83                 typedef typename wrap_map_traits_helper<Key, Value, Traits, typename Traits::key_accessor>::key_accessor    key_accessor;
84             };
85
86             template <typename Value, typename Traits, typename Opt>
87             struct wrap_set_traits_helper {
88                 typedef Opt key_accessor;
89             };
90
91             template <typename Value, typename Traits >
92             struct wrap_set_traits_helper<Value, Traits, opt::none>
93             {
94                 struct key_accessor
95                 {
96                     typedef Value     key_type;
97                     key_type const& operator()( Value const& val ) const
98                     {
99                         return val;
100                     }
101                 };
102             };
103
104             template <typename Value, typename Traits>
105             struct wrap_set_traits: public Traits
106             {
107                 typedef typename wrap_set_traits_helper<Value, Traits, typename Traits::key_accessor>::key_accessor key_accessor;
108             };
109         }  // namespace details
110         //@endcond
111
112
113         /// SplitListSet traits
114         struct traits: public intrusive::split_list::traits
115         {
116             // Ordered list implementation
117             /**
118                 Selects appropriate ordered-list implementation for split-list.
119                 Supported types are:
120                 - \p michael_list_tag - for \p MichaelList
121                 - \p lazy_list_tag - for \p LazyList
122                 - \p iterable_list_tag - for \p IterableList
123             */
124             typedef michael_list_tag    ordered_list;
125
126             // Ordered list traits
127             /**
128                 Specifyes traits for selected ordered list type, default type:
129                 - for \p michael_list_tag: \p container::michael_list::traits.
130                 - for \p lazy_list_tag: \p container::lazy_list::traits.
131                 - for \p iterable_list_tag: \p container::iterable_list::traits.
132
133                 If this type is \p opt::none, the ordered list traits is combined with default
134                 ordered list traits and split-list traits.
135             */
136             typedef opt::none           ordered_list_traits;
137
138             //@cond
139             typedef opt::none           key_accessor;
140             //@endcond
141         };
142
143         /// Option to select ordered list class for split-list
144         /**
145             This option selects appropriate ordered list class for containers based on split-list.
146             Template parameter \p Type may be \p michael_list_tag or \p lazy_list_tag.
147         */
148         template <class Type>
149         struct ordered_list
150         {
151             //@cond
152             template<class Base> struct pack: public Base
153             {
154                 typedef Type ordered_list;
155             };
156             //@endcond
157         };
158
159         /// Option to specify ordered list type traits
160         /**
161             The \p Type template parameter specifies ordered list type traits.
162             It depends on type of ordered list selected.
163         */
164         template <class Type>
165         struct ordered_list_traits
166         {
167             //@cond
168             template<class Base> struct pack: public Base
169             {
170                 typedef Type ordered_list_traits;
171             };
172             //@endcond
173         };
174
175         /// Metafunction converting option list to traits struct
176         /**
177             Available \p Options:
178             - \p split_list::ordered_list - a tag for ordered list implementation.
179             - \p split_list::ordered_list_traits - type traits for ordered list implementation.
180                 For \p MichaelList use \p container::michael_list::traits or derivatives,
181                 for \p LazyList use \p container::lazy_list::traits or derivatives.
182             - plus any option from \p intrusive::split_list::make_traits
183         */
184         template <typename... Options>
185         struct make_traits {
186             typedef typename cds::opt::make_options< traits, Options...>::type type  ;   ///< Result of metafunction
187         };
188     }   // namespace split_list
189
190     //@cond
191     // Forward declarations
192     template <class GC, class T, class Traits = split_list::traits>
193     class SplitListSet;
194
195     template <class GC, typename Key, typename Value, class Traits = split_list::traits>
196     class SplitListMap;
197     //@endcond
198
199     //@cond
200     // Forward declaration
201     namespace details {
202         template <typename GC, typename T, typename OrderedListTag, typename Traits>
203         struct make_split_list_set;
204
205         template <typename GC, typename Key, typename Value, typename OrderedListTag, typename Traits>
206         struct make_split_list_map;
207     }
208     //@endcond
209
210 }}  // namespace cds::container
211
212
213 #endif // #ifndef CDSLIB_CONTAINER_DETAILS_SPLIT_LIST_BASE_H