2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
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.
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.
31 #ifndef CDSLIB_OPT_COMPARE_H
32 #define CDSLIB_OPT_COMPARE_H
36 2011.05.05 khizmax Created
39 #include <type_traits>
42 #include <cds/opt/options.h>
44 namespace cds { namespace opt {
46 /// [type-option] Option setter for key comparing
48 The option sets a type of a functor to compare keys.
49 For comparing two keys \p k1 and \p k2 the functor must return:
50 - 1 if <tt> k1 > k2 </tt>
51 - 0 if <tt> k1 == k2 </tt>
52 - -1 if <tt> k1 < k2 </tt>
54 \p Functor is a functor with following interface:
58 int operator ()(const T& r1, const T& r2)
64 Note that the functor must return \p int, not a \p bool value.
66 There are predefined type for \p Functor:
67 - the functor \p opt::v::less_comparator that implements comparing functor through \p std::less predicate.
68 - the specialization of \p opt::v::less_comparator functor intended for the string comparison
70 You may implement your own comparing functor that satisfies \p Functor interface.
72 About relation between \p %opt::less and \p %opt::compare option setters see \p opt::less description.
74 template <typename Functor>
77 template <typename Base> struct pack: public Base
79 typedef Functor compare;
86 /// Comparator based on \p std::less predicate
88 This functor is predefined type for \p opt::compare option setter.
89 It is based on \p std::less predicate.
92 struct less_comparator {
93 /// Operator that compares two value of type \p T
94 int operator()(T const& v1, T const& v2)
96 if ( std::less<T>()( v1, v2 ))
98 if ( std::less<T>()( v2, v1 ))
104 /// Comparator specialization for \p std::string
106 This functor uses \p std::string::compare() method instead of \p std::less predicate.
108 template <typename T, typename Traits, typename Alloc>
109 struct less_comparator< std::basic_string<T, Traits, Alloc> >
112 typedef std::basic_string<T, Traits, Alloc> string_type;
113 int operator()(string_type const& v1, string_type const& v2)
115 return v1.compare( v2 );
121 /// [type-option] Option setter for \p less predicate
123 The option sets a binary predicate that tests whether a value of a specified type is less than another value of that type.
124 \p Functor interface is similar to \p std::less predicate interface.
125 The standard predicate \p std::less can act as \p Functor:
126 \code typedef cds::opt::less< std::less< int > > opt_less \endcode
128 In addition, the option setter may sets non-standard 2-type predicate (\p std::binary_function):
135 template <typename T, typename Q>
137 bool operator ()( const T& t, const Q& q )
139 bool operator ()( const Q& q, const T& t )
141 bool operator ()( const T& t1, const T& t2 )
142 { return t1.n < t2.n ; }
143 bool operator ()( const Q& q1, const Q& q2 )
147 typedef cds::opt::less< pred_less< foo, int > > opt_less;
150 Generally, the default type for \p Functor is \p std::less but it depends on the container used.
152 \par Relation between opt::less and opt::compare option setters
153 Unless otherwise specified, \p opt::compare option setter has high priority.
154 If \p %opt::compare and \p %opt::less options are specified for a container, the \p %opt::compare option is used:
156 // Suppose, a hypothetical map_type allows to specify
157 // cds::opt::less and cds::opt::compare options
159 typedef map_type< std::string, int,
160 cds::opt::compare< cds::opt::v::less_comparator< std::string > >,
161 cds::opt::less< std::less< std::string > >
164 // For my_map_type, the cds::opt::compare comparator will be used,
165 // the cds::opt::less option is ignored without any warnings.
168 template <typename Functor>
171 template <typename Base> struct pack: public Base
173 typedef Functor less;
180 template <typename Less>
181 struct make_comparator_from_less
183 typedef Less less_functor;
185 template <typename T, typename Q>
186 int operator ()( T const& t, Q const& q ) const
197 template <typename T, typename Traits, typename DefaultCmp = make_comparator_from_less< std::less<T>> >
198 struct make_comparator_from
200 typedef typename Traits::compare compare;
201 typedef typename Traits::less less;
203 typedef typename std::conditional<
204 std::is_same< compare, opt::none >::value,
205 typename std::conditional<
206 std::is_same< less, opt::none >::value,
208 make_comparator_from_less< less >
215 template <typename T, typename Traits, bool Forced = true >
216 using make_comparator = make_comparator_from< T, Traits,
217 typename std::conditional<
219 make_comparator_from_less< std::less<T>>,
223 template <typename T, typename... Options>
224 struct make_comparator_from_option_list
226 struct default_traits {
227 typedef opt::none compare;
228 typedef opt::none less;
231 typedef typename make_comparator< T,
232 typename opt::make_options<
233 typename opt::find_type_traits< default_traits, Options... >::type
238 } // namespace details
241 /// [type-option] Option setter for \p opt::equal_to predicate
243 The option sets a binary predicate that tests whether a value of a specified type is equal to another value of that type.
244 \p Functor interface is similar to \p std::equal_to predicate interface.
245 The standard predicate \p std::equal_to can act as \p Functor:
246 \code typedef cds::opt::equal_to< std::equal_to< int > > opt_equal_to \endcode
248 In addition, the option setter may sets non-standard 2-type (or even N-type) predicate (\p std::binary_function):
255 template <typename T, typename Q>
256 struct pred_equal_to {
257 bool operator ()( const T& t, const Q& q )
258 { return t.n == q ; }
259 bool operator ()( const Q& q, const T& t )
260 { return q == t.n ; }
261 bool operator ()( const T& t1, const T& t2 )
262 { return t1.n == t2.n ; }
263 bool operator ()( const Q& q1, const Q& q2 )
264 { return q1 == q2 ; }
267 typedef cds::opt::equal_to< pred_equal_to< foo, int > > opt_equal_to;
270 Generally, the default type for \p Functor is \p std::equal_to but it depends on the container used.
272 template <typename Functor>
275 template <typename Base> struct pack: public Base
277 typedef Functor equal_to;
284 template <typename Compare>
285 struct make_equal_to_from_compare
287 typedef Compare compare_functor;
289 template <typename T, typename Q>
290 bool operator()( T const& t, Q const& q ) const
292 return compare_functor()(t, q) == 0;
296 template <typename Less>
297 struct make_equal_to_from_less
299 typedef Less less_functor;
301 template <typename T, typename Q>
302 bool operator()( T const& t, Q const& q ) const
305 return !less(t, q) && !less(q, t);
309 template <typename T, typename Traits, bool Forced = true>
312 typedef typename Traits::equal_to equal_to;
313 typedef typename Traits::compare compare;
314 typedef typename Traits::less less;
316 typedef typename std::conditional<
317 std::is_same< equal_to, opt::none >::value,
318 typename std::conditional<
319 std::is_same< compare, opt::none >::value,
320 typename std::conditional<
321 std::is_same< less, opt::none >::value,
322 typename std::conditional<
326 make_equal_to_from_less< less > >::type,
327 make_equal_to_from_compare< compare > >::type,
334 }} // namespace cds::opt
336 #endif // #ifndef CDSLIB_OPT_COMPARE_H