3 #ifndef CDSLIB_OPT_COMPARE_H
4 #define CDSLIB_OPT_COMPARE_H
8 2011.05.05 khizmax Created
11 #include <type_traits>
14 #include <cds/opt/options.h>
16 namespace cds { namespace opt {
18 /// [type-option] Option setter for key comparing
20 The option sets a type of a functor to compare keys.
21 For comparing two keys \p k1 and \p k2 the functor must return:
22 - 1 if <tt> k1 > k2 </tt>
23 - 0 if <tt> k1 == k2 </tt>
24 - -1 if <tt> k1 < k2 </tt>
26 \p Functor is a functor with following interface:
30 int operator ()(const T& r1, const T& r2)
36 Note that the functor must return \p int, not a \p bool value.
38 There are predefined type for \p Functor:
39 - the functor \p opt::v::less_comparator that implements comparing functor through \p std::less predicate.
40 - the specialization of \p opt::v::less_comparator functor intended for the string comparison
42 You may implement your own comparing functor that satisfies \p Functor interface.
44 About relation between \p %opt::less and \p %opt::compare option setters see \p opt::less description.
46 template <typename Functor>
49 template <typename Base> struct pack: public Base
51 typedef Functor compare;
58 /// Comparator based on \p std::less predicate
60 This functor is predefined type for \p opt::compare option setter.
61 It is based on \p std::less predicate.
64 struct less_comparator {
65 /// Operator that compares two value of type \p T
66 int operator()(T const& v1, T const& v2)
68 if ( std::less<T>()( v1, v2 ) )
70 if ( std::less<T>()( v2, v1 ))
76 /// Comparator specialization for \p std::string
78 This functor uses \p std::string::compare() method instead of \p std::less predicate.
80 template <typename T, typename Traits, typename Alloc>
81 struct less_comparator< std::basic_string<T, Traits, Alloc> >
84 typedef std::basic_string<T, Traits, Alloc> string_type;
85 int operator()(string_type const& v1, string_type const& v2)
87 return v1.compare( v2 );
93 /// [type-option] Option setter for \p less predicate
95 The option sets a binary predicate that tests whether a value of a specified type is less than another value of that type.
96 \p Functor interface is similar to \p std::less predicate interface.
97 The standard predicate \p std::less can act as \p Functor:
98 \code typedef cds::opt::less< std::less< int > > opt_less \endcode
100 In addition, the option setter may sets non-standard 2-type predicate (\p std::binary_function):
107 template <typename T, typename Q>
109 bool operator ()( const T& t, const Q& q )
111 bool operator ()( const Q& q, const T& t )
113 bool operator ()( const T& t1, const T& t2 )
114 { return t1.n < t2.n ; }
115 bool operator ()( const Q& q1, const Q& q2 )
119 typedef cds::opt::less< pred_less< foo, int > > opt_less;
122 Generally, the default type for \p Functor is \p std::less but it depends on the container used.
124 \par Relation between opt::less and opt::compare option setters
125 Unless otherwise specified, \p opt::compare option setter has high priority.
126 If \p %opt::compare and \p %opt::less options are specified for a container, the \p %opt::compare option is used:
128 // Suppose, a hypothetical map_type allows to specify
129 // cds::opt::less and cds::opt::compare options
131 typedef map_type< std::string, int,
132 cds::opt::compare< cds::opt::v::less_comparator< std::string > >,
133 cds::opt::less< std::less< std::string > >
136 // For my_map_type, the cds::opt::compare comparator will be used,
137 // the cds::opt::less option is ignored without any warnings.
140 template <typename Functor>
143 template <typename Base> struct pack: public Base
145 typedef Functor less;
152 template <typename Less>
153 struct make_comparator_from_less
155 typedef Less less_functor;
157 template <typename T, typename Q>
158 int operator ()( T const& t, Q const& q ) const
169 template <typename T, typename Traits, typename DefaultCmp = make_comparator_from_less< std::less<T>> >
170 struct make_comparator_from
172 typedef typename Traits::compare compare;
173 typedef typename Traits::less less;
175 typedef typename std::conditional<
176 std::is_same< compare, opt::none >::value,
177 typename std::conditional<
178 std::is_same< less, opt::none >::value,
180 make_comparator_from_less< less >
187 template <typename T, typename Traits, bool Forced = true >
188 using make_comparator = make_comparator_from< T, Traits,
189 typename std::conditional<
191 make_comparator_from_less< std::less<T>>,
195 template <typename T, typename... Options>
196 struct make_comparator_from_option_list
198 struct default_traits {
199 typedef opt::none compare;
200 typedef opt::none less;
203 typedef typename make_comparator< T,
204 typename opt::make_options<
205 typename opt::find_type_traits< default_traits, Options... >::type
210 } // namespace details
213 /// [type-option] Option setter for \p opt::equal_to predicate
215 The option sets a binary predicate that tests whether a value of a specified type is equal to another value of that type.
216 \p Functor interface is similar to \p std::equal_to predicate interface.
217 The standard predicate \p std::equal_to can act as \p Functor:
218 \code typedef cds::opt::equal_to< std::equal_to< int > > opt_equal_to \endcode
220 In addition, the option setter may sets non-standard 2-type (or even N-type) predicate (\p std::binary_function):
227 template <typename T, typename Q>
228 struct pred_equal_to {
229 bool operator ()( const T& t, const Q& q )
230 { return t.n == q ; }
231 bool operator ()( const Q& q, const T& t )
232 { return q == t.n ; }
233 bool operator ()( const T& t1, const T& t2 )
234 { return t1.n == t2.n ; }
235 bool operator ()( const Q& q1, const Q& q2 )
236 { return q1 == q2 ; }
239 typedef cds::opt::equal_to< pred_equal_to< foo, int > > opt_equal_to;
242 Generally, the default type for \p Functor is \p std::equal_to but it depends on the container used.
244 template <typename Functor>
247 template <typename Base> struct pack: public Base
249 typedef Functor equal_to;
256 template <typename Compare>
257 struct make_equal_to_from_compare
259 typedef Compare compare_functor;
261 template <typename T, typename Q>
262 bool operator()( T const& t, Q const& q ) const
264 return compare_functor()(t, q) == 0;
268 template <typename Less>
269 struct make_equal_to_from_less
271 typedef Less less_functor;
273 template <typename T, typename Q>
274 bool operator()( T const& t, Q const& q ) const
277 return !less(t, q) && !less(q, t);
281 template <typename T, typename Traits, bool Forced = true>
284 typedef typename Traits::equal_to equal_to;
285 typedef typename Traits::compare compare;
286 typedef typename Traits::less less;
288 typedef typename std::conditional<
289 std::is_same< equal_to, opt::none >::value,
290 typename std::conditional<
291 std::is_same< compare, opt::none >::value,
292 typename std::conditional<
293 std::is_same< less, opt::none >::value,
294 typename std::conditional<
298 make_equal_to_from_less< less > >::type,
299 make_equal_to_from_compare< compare > >::type,
306 }} // namespace cds::opt
308 #endif // #ifndef CDSLIB_OPT_COMPARE_H