]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*-----------------------------------------------------------------------------+ |
2 | Copyright (c) 2008-2009: Joachim Faulhaber | |
3 | +------------------------------------------------------------------------------+ | |
4 | Distributed under the Boost Software License, Version 1.0. | |
5 | (See accompanying file LICENCE.txt or copy at | |
6 | http://www.boost.org/LICENSE_1_0.txt) | |
7 | +-----------------------------------------------------------------------------*/ | |
8 | #ifndef BOOST_ICL_IS_COMBINABLE_HPP_JOFA_090115 | |
9 | #define BOOST_ICL_IS_COMBINABLE_HPP_JOFA_090115 | |
10 | ||
11 | #include <boost/mpl/bool.hpp> | |
12 | #include <boost/mpl/if.hpp> | |
13 | #include <boost/mpl/and.hpp> | |
14 | #include <boost/mpl/or.hpp> | |
15 | #include <boost/mpl/not.hpp> | |
16 | #include <boost/type_traits/is_same.hpp> | |
17 | #include <boost/icl/type_traits/is_concept_equivalent.hpp> | |
18 | #include <boost/icl/type_traits/is_interval_container.hpp> | |
19 | ||
20 | namespace boost{namespace icl | |
21 | { | |
22 | ||
23 | template<class Type> | |
24 | struct is_overloadable | |
25 | { | |
26 | typedef is_overloadable<Type> type; | |
27 | BOOST_STATIC_CONSTANT(bool, value = | |
28 | (boost::is_same<Type, typename Type::overloadable_type>::value) | |
29 | ); | |
30 | }; | |
31 | ||
32 | ||
33 | //------------------------------------------------------------------------------ | |
34 | template<class LeftT, class RightT> | |
35 | struct is_codomain_equal | |
36 | { | |
37 | typedef is_codomain_equal<LeftT, RightT> type; | |
38 | BOOST_STATIC_CONSTANT(bool, value = | |
39 | (boost::is_same<typename LeftT::codomain_type, | |
40 | typename RightT::codomain_type>::value) | |
41 | ); | |
42 | }; | |
43 | ||
44 | //NOTE: Equality of compare order implies the equality of the domain_types | |
45 | template<class LeftT, class RightT> | |
46 | struct is_key_compare_equal | |
47 | { | |
48 | typedef is_key_compare_equal<LeftT, RightT> type; | |
49 | BOOST_STATIC_CONSTANT(bool, value = | |
50 | (boost::is_same<typename LeftT::key_compare, | |
51 | typename RightT::key_compare>::value) | |
52 | ); | |
53 | }; | |
54 | ||
55 | template<class LeftT, class RightT> | |
56 | struct is_codomain_type_equal | |
57 | { | |
58 | typedef is_codomain_type_equal<LeftT, RightT> type; | |
59 | BOOST_STATIC_CONSTANT(bool, value = | |
60 | (mpl::and_<is_key_compare_equal<LeftT, RightT>, | |
61 | is_codomain_equal<LeftT, RightT> >::value) | |
62 | ); | |
63 | }; | |
64 | ||
65 | ||
66 | // For equal containers concepts, domain order and codomain type must match. | |
67 | template<template<class>class IsConcept, class LeftT, class RightT> | |
68 | struct is_concept_compatible | |
69 | { | |
70 | typedef is_concept_compatible<IsConcept, LeftT, RightT> type; | |
71 | BOOST_STATIC_CONSTANT(bool, value = | |
72 | (mpl::and_< | |
73 | IsConcept<LeftT> | |
74 | , IsConcept<RightT> | |
75 | , is_codomain_type_equal<LeftT, RightT> | |
76 | >::value) | |
77 | ); | |
78 | }; | |
79 | ||
80 | template<template<class>class LeftConcept, | |
81 | template<class>class RightConcept, | |
82 | class LeftT, class RightT> | |
83 | struct is_concept_combinable | |
84 | { | |
85 | typedef is_concept_combinable<LeftConcept, RightConcept, LeftT, RightT> type; | |
86 | BOOST_STATIC_CONSTANT(bool, value = | |
87 | (mpl::and_< | |
88 | LeftConcept<LeftT> | |
89 | , RightConcept<RightT> | |
90 | , is_key_compare_equal<LeftT, RightT> | |
91 | >::value) | |
92 | ); | |
93 | }; | |
94 | ||
95 | template<class LeftT, class RightT> | |
96 | struct is_intra_combinable | |
97 | { | |
98 | typedef is_intra_combinable<LeftT, RightT> type; | |
99 | BOOST_STATIC_CONSTANT(bool, value = | |
100 | (mpl::or_< | |
101 | is_concept_compatible<is_interval_set, LeftT, RightT> | |
102 | , is_concept_compatible<is_interval_map, LeftT, RightT> | |
103 | >::value) | |
104 | ); | |
105 | }; | |
106 | ||
107 | //------------------------------------------------------------------------------ | |
108 | ||
109 | ||
110 | //------------------------------------------------------------------------------ | |
111 | template<class LeftT, class RightT> | |
112 | struct is_cross_combinable | |
113 | { | |
114 | typedef is_cross_combinable<LeftT, RightT> type; | |
115 | BOOST_STATIC_CONSTANT(bool, value = | |
116 | (mpl::or_< | |
117 | is_concept_combinable<is_interval_set, is_interval_map, LeftT, RightT> | |
118 | , is_concept_combinable<is_interval_map, is_interval_set, LeftT, RightT> | |
119 | >::value) | |
120 | ); | |
121 | }; | |
122 | ||
123 | template<class LeftT, class RightT> | |
124 | struct is_inter_combinable | |
125 | { | |
126 | typedef is_inter_combinable<LeftT, RightT> type; | |
127 | BOOST_STATIC_CONSTANT(bool, value = | |
128 | (mpl::or_<is_intra_combinable<LeftT,RightT>, | |
129 | is_cross_combinable<LeftT,RightT> >::value) | |
130 | ); | |
131 | }; | |
132 | ||
133 | //------------------------------------------------------------------------------ | |
134 | // is_fragment_of | |
135 | //------------------------------------------------------------------------------ | |
136 | template<class FragmentT, class Type> | |
137 | struct is_fragment_of | |
138 | { | |
139 | typedef is_fragment_of type; | |
140 | BOOST_STATIC_CONSTANT(bool, value = false); | |
141 | }; | |
142 | ||
143 | template<class Type> | |
144 | struct is_fragment_of<typename Type::element_type, Type> | |
145 | { | |
146 | typedef is_fragment_of type; | |
147 | BOOST_STATIC_CONSTANT(bool, value = true); | |
148 | }; | |
149 | ||
150 | template<class Type> | |
151 | struct is_fragment_of<typename Type::segment_type, Type> | |
152 | { | |
153 | typedef is_fragment_of type; | |
154 | BOOST_STATIC_CONSTANT(bool, value = true); | |
155 | }; | |
156 | ||
157 | //------------------------------------------------------------------------------ | |
158 | // is_key_of | |
159 | //------------------------------------------------------------------------------ | |
160 | template<class KeyT, class Type> | |
161 | struct is_key_of | |
162 | { | |
163 | typedef is_key_of type; | |
164 | BOOST_STATIC_CONSTANT(bool, value = false); | |
165 | }; | |
166 | ||
167 | template<class Type> | |
168 | struct is_key_of<typename Type::domain_type, Type> | |
169 | { | |
170 | typedef is_key_of type; | |
171 | BOOST_STATIC_CONSTANT(bool, value = true); | |
172 | }; | |
173 | ||
174 | template<class Type> | |
175 | struct is_key_of<typename Type::interval_type, Type> | |
176 | { | |
177 | typedef is_key_of type; | |
178 | BOOST_STATIC_CONSTANT(bool, value = true); | |
179 | }; | |
180 | ||
181 | //------------------------------------------------------------------------------ | |
182 | // is_interval_set_derivative | |
183 | //------------------------------------------------------------------------------ | |
184 | template<class Type, class AssociateT> | |
185 | struct is_interval_set_derivative; | |
186 | ||
187 | template<class Type> | |
188 | struct is_interval_set_derivative<Type, typename Type::domain_type> | |
189 | { | |
190 | typedef is_interval_set_derivative type; | |
191 | BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); | |
192 | }; | |
193 | ||
194 | template<class Type> | |
195 | struct is_interval_set_derivative<Type, typename Type::interval_type> | |
196 | { | |
197 | typedef is_interval_set_derivative type; | |
198 | BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); | |
199 | }; | |
200 | ||
201 | template<class Type, class AssociateT> | |
202 | struct is_interval_set_derivative | |
203 | { | |
204 | typedef is_interval_set_derivative<Type, AssociateT> type; | |
205 | BOOST_STATIC_CONSTANT(bool, value = false); | |
206 | }; | |
207 | ||
208 | //------------------------------------------------------------------------------ | |
209 | // is_interval_map_derivative | |
210 | //------------------------------------------------------------------------------ | |
211 | template<class Type, class AssociateT> | |
212 | struct is_interval_map_derivative; | |
213 | ||
214 | template<class Type> | |
215 | struct is_interval_map_derivative<Type, typename Type::domain_mapping_type> | |
216 | { | |
217 | typedef is_interval_map_derivative type; | |
218 | BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); | |
219 | }; | |
220 | ||
221 | template<class Type> | |
222 | struct is_interval_map_derivative<Type, typename Type::interval_mapping_type> | |
223 | { | |
224 | typedef is_interval_map_derivative type; | |
225 | BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); | |
226 | }; | |
227 | ||
228 | template<class Type> | |
229 | struct is_interval_map_derivative<Type, typename Type::value_type> | |
230 | { | |
231 | typedef is_interval_map_derivative type; | |
232 | BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); | |
233 | }; | |
234 | ||
235 | template<class Type, class AssociateT> | |
236 | struct is_interval_map_derivative | |
237 | { | |
238 | typedef is_interval_map_derivative<Type, AssociateT> type; | |
239 | BOOST_STATIC_CONSTANT(bool, value = false); | |
240 | }; | |
241 | ||
242 | //------------------------------------------------------------------------------ | |
243 | // is_intra_derivative | |
244 | //------------------------------------------------------------------------------ | |
245 | template<class Type, class AssociateT> | |
246 | struct is_intra_derivative | |
247 | { | |
248 | typedef is_intra_derivative<Type, AssociateT> type; | |
249 | BOOST_STATIC_CONSTANT(bool, value = | |
250 | (mpl::or_ | |
251 | < | |
252 | mpl::and_<is_interval_set<Type>, | |
253 | is_interval_set_derivative<Type, AssociateT> > | |
254 | , mpl::and_<is_interval_map<Type>, | |
255 | is_interval_map_derivative<Type, AssociateT> > | |
256 | >::value) | |
257 | ); | |
258 | }; | |
259 | ||
260 | template<class Type, class AssociateT> | |
261 | struct is_cross_derivative | |
262 | { | |
263 | typedef is_cross_derivative<Type, AssociateT> type; | |
264 | BOOST_STATIC_CONSTANT(bool, value = | |
265 | (mpl::and_< | |
266 | is_interval_map<Type> | |
267 | , is_interval_set_derivative<Type, AssociateT> | |
268 | >::value) | |
269 | ); | |
270 | }; | |
271 | ||
272 | template<class Type, class AssociateT> | |
273 | struct is_inter_derivative | |
274 | { | |
275 | typedef is_inter_derivative<Type, AssociateT> type; | |
276 | BOOST_STATIC_CONSTANT(bool, value = | |
277 | (mpl::or_< | |
278 | is_intra_derivative<Type, AssociateT> | |
279 | , is_cross_derivative<Type, AssociateT> | |
280 | >::value) | |
281 | ); | |
282 | }; | |
283 | ||
284 | //------------------------------------------------------------------------------ | |
285 | //- right combinable | |
286 | //------------------------------------------------------------------------------ | |
287 | ||
288 | template<class GuideT, class CompanionT> | |
289 | struct is_interval_set_right_combinable | |
290 | { | |
291 | typedef is_interval_set_right_combinable<GuideT, CompanionT> type; | |
292 | BOOST_STATIC_CONSTANT(bool, value = | |
293 | (mpl::and_ | |
294 | < | |
295 | is_interval_set<GuideT> | |
296 | , mpl::or_ | |
297 | < | |
298 | is_interval_set_derivative<GuideT, CompanionT> | |
299 | , is_concept_compatible<is_interval_set, GuideT, CompanionT> | |
300 | > | |
301 | >::value) | |
302 | ); | |
303 | }; | |
304 | ||
305 | template<class GuideT, class CompanionT> | |
306 | struct is_interval_map_right_intra_combinable //NOTE equivalent to is_fragment_type_of | |
307 | { | |
308 | typedef is_interval_map_right_intra_combinable<GuideT, CompanionT> type; | |
309 | BOOST_STATIC_CONSTANT(bool, value = | |
310 | (mpl::and_ | |
311 | < | |
312 | is_interval_map<GuideT> | |
313 | , mpl::or_ | |
314 | < | |
315 | is_interval_map_derivative<GuideT, CompanionT> | |
316 | , is_concept_compatible<is_interval_map, GuideT, CompanionT> | |
317 | > | |
318 | >::value) | |
319 | ); | |
320 | }; | |
321 | ||
322 | template<class GuideT, class CompanionT> | |
323 | struct is_interval_map_right_cross_combinable //NOTE equivalent to key_type_of<Comp, Guide> | |
324 | { | |
325 | typedef is_interval_map_right_cross_combinable<GuideT, CompanionT> type; | |
326 | BOOST_STATIC_CONSTANT(bool, value = | |
327 | (mpl::and_ | |
328 | < | |
329 | is_interval_map<GuideT> | |
330 | , mpl::or_ | |
331 | < | |
332 | is_cross_derivative<GuideT, CompanionT> | |
333 | , is_concept_combinable<is_interval_map, is_interval_set, GuideT, CompanionT> | |
334 | > | |
335 | >::value) | |
336 | ); | |
337 | }; | |
338 | ||
339 | template<class GuideT, class CompanionT> | |
340 | struct is_interval_map_right_inter_combinable | |
341 | { | |
342 | typedef is_interval_map_right_inter_combinable<GuideT, CompanionT> type; | |
343 | BOOST_STATIC_CONSTANT(bool, value = | |
344 | (mpl::or_< | |
345 | is_interval_map_right_intra_combinable<GuideT, CompanionT> | |
346 | , is_interval_map_right_cross_combinable<GuideT, CompanionT> | |
347 | >::value) | |
348 | ); | |
349 | }; | |
350 | ||
351 | ||
352 | template<class GuideT, class CompanionT> | |
353 | struct is_right_intra_combinable | |
354 | { | |
355 | typedef is_right_intra_combinable<GuideT, CompanionT> type; | |
356 | BOOST_STATIC_CONSTANT(bool, value = | |
357 | (mpl::or_ | |
358 | < | |
359 | is_interval_set_right_combinable<GuideT, CompanionT> | |
360 | , is_interval_map_right_intra_combinable<GuideT, CompanionT> | |
361 | >::value) | |
362 | ); | |
363 | }; | |
364 | ||
365 | template<class GuideT, class CompanionT> | |
366 | struct is_right_inter_combinable | |
367 | { | |
368 | typedef is_right_inter_combinable<GuideT, CompanionT> type; | |
369 | BOOST_STATIC_CONSTANT(bool, value = | |
370 | (mpl::or_ | |
371 | < | |
372 | is_interval_set_right_combinable<GuideT, CompanionT> | |
373 | , is_interval_map_right_inter_combinable<GuideT, CompanionT> | |
374 | >::value) | |
375 | ); | |
376 | }; | |
377 | ||
378 | template<class GuideT, class IntervalSetT> | |
379 | struct combines_right_to_interval_set | |
380 | { | |
381 | typedef combines_right_to_interval_set<GuideT, IntervalSetT> type; | |
382 | BOOST_STATIC_CONSTANT(bool, value = | |
383 | (is_concept_combinable<is_interval_container, is_interval_set, | |
384 | GuideT, IntervalSetT>::value) | |
385 | ); | |
386 | }; | |
387 | ||
388 | template<class GuideT, class IntervalMapT> | |
389 | struct combines_right_to_interval_map | |
390 | { | |
391 | typedef combines_right_to_interval_map<GuideT, IntervalMapT> type; | |
392 | BOOST_STATIC_CONSTANT(bool, value = | |
393 | (is_concept_compatible<is_interval_map, GuideT, IntervalMapT>::value) ); | |
394 | }; | |
395 | ||
396 | template<class GuideT, class IntervalContainerT> | |
397 | struct combines_right_to_interval_container | |
398 | { | |
399 | typedef combines_right_to_interval_container<GuideT, IntervalContainerT> type; | |
400 | BOOST_STATIC_CONSTANT(bool, value = | |
401 | (mpl::or_<combines_right_to_interval_set<GuideT, IntervalContainerT>, | |
402 | combines_right_to_interval_map<GuideT, IntervalContainerT> >::value) | |
403 | ); | |
404 | }; | |
405 | ||
406 | ||
407 | ||
408 | //------------------------------------------------------------------------------ | |
409 | //- segmentational_fineness | |
410 | //------------------------------------------------------------------------------ | |
411 | template<class Type> struct unknown_fineness | |
412 | { | |
413 | typedef unknown_fineness<Type> type; | |
414 | static const int value = 0; | |
415 | }; | |
416 | ||
417 | template<class Type> struct known_fineness | |
418 | { | |
419 | typedef known_fineness<Type> type; | |
420 | static const int value = Type::fineness; | |
421 | }; | |
422 | ||
423 | template<class Type>struct segmentational_fineness | |
424 | { | |
425 | typedef segmentational_fineness<Type> type; | |
426 | static const int value = | |
427 | mpl::if_<is_interval_container<Type>, | |
428 | known_fineness<Type>, | |
429 | unknown_fineness<Type> | |
430 | >::type::value; | |
431 | }; | |
432 | ||
433 | ||
434 | //------------------------------------------------------------------------------ | |
435 | // is_interval_set_companion | |
436 | //------------------------------------------------------------------------------ | |
437 | ||
438 | // CompanionT is either an interval_set or a derivative of set level: | |
439 | // element_type=domain_type, segment_type=interval_type | |
440 | template<class GuideT, class CompanionT> struct is_interval_set_companion | |
441 | { | |
442 | typedef is_interval_set_companion<GuideT,CompanionT> type; | |
443 | BOOST_STATIC_CONSTANT(bool, value = | |
444 | (mpl::or_ | |
445 | < | |
446 | combines_right_to_interval_set<GuideT,CompanionT> | |
447 | , is_interval_set_derivative<GuideT,CompanionT> | |
448 | >::value) | |
449 | ); | |
450 | }; | |
451 | ||
452 | ||
453 | //------------------------------------------------------------------------------ | |
454 | // is_interval_map_companion | |
455 | //------------------------------------------------------------------------------ | |
456 | ||
457 | template<class GuideT, class CompanionT> struct is_interval_map_companion | |
458 | { | |
459 | typedef is_interval_map_companion<GuideT,CompanionT> type; | |
460 | BOOST_STATIC_CONSTANT(bool, value = | |
461 | (mpl::or_ | |
462 | < | |
463 | combines_right_to_interval_map<GuideT,CompanionT> | |
464 | , is_interval_map_derivative<GuideT,CompanionT> | |
465 | >::value) | |
466 | ); | |
467 | }; | |
468 | ||
469 | ||
470 | //------------------------------------------------------------------------------ | |
471 | //- is_coarser_interval_{set,map}_companion | |
472 | //------------------------------------------------------------------------------ | |
473 | template<class GuideT, class CompanionT> | |
474 | struct is_coarser_interval_set_companion | |
475 | { | |
476 | typedef is_coarser_interval_set_companion<GuideT, CompanionT> type; | |
477 | BOOST_STATIC_CONSTANT(bool, value = | |
478 | (mpl::and_ | |
479 | < | |
480 | is_interval_set_companion<GuideT, CompanionT> | |
481 | , mpl::bool_<( segmentational_fineness<GuideT>::value | |
482 | > segmentational_fineness<CompanionT>::value)> | |
483 | >::value) | |
484 | ); | |
485 | }; | |
486 | ||
487 | template<class GuideT, class CompanionT> | |
488 | struct is_coarser_interval_map_companion | |
489 | { | |
490 | typedef is_coarser_interval_map_companion<GuideT, CompanionT> type; | |
491 | BOOST_STATIC_CONSTANT(bool, value = | |
492 | (mpl::and_ | |
493 | < | |
494 | is_interval_map_companion<GuideT, CompanionT> | |
495 | , mpl::bool_<( segmentational_fineness<GuideT>::value | |
496 | > segmentational_fineness<CompanionT>::value)> | |
497 | >::value) | |
498 | ); | |
499 | }; | |
500 | ||
501 | //------------------------------------------------------------------------------ | |
502 | // is_binary_interval_{set,map}_combinable | |
503 | //------------------------------------------------------------------------------ | |
504 | template<class GuideT, class CompanionT> | |
505 | struct is_binary_interval_set_combinable | |
506 | { | |
507 | typedef is_binary_interval_set_combinable<GuideT,CompanionT> type; | |
508 | static const int value = | |
509 | mpl::and_< is_interval_set<GuideT> | |
510 | , is_coarser_interval_set_companion<GuideT, CompanionT> | |
511 | >::value; | |
512 | }; | |
513 | ||
514 | template<class GuideT, class CompanionT> | |
515 | struct is_binary_interval_map_combinable | |
516 | { | |
517 | typedef is_binary_interval_map_combinable<GuideT,CompanionT> type; | |
518 | static const int value = | |
519 | mpl::and_< is_interval_map<GuideT> | |
520 | , is_coarser_interval_map_companion<GuideT, CompanionT> | |
521 | >::value; | |
522 | }; | |
523 | ||
524 | template<class GuideT, class CompanionT> | |
525 | struct is_binary_intra_combinable | |
526 | { | |
527 | typedef is_binary_intra_combinable<GuideT,CompanionT> type; | |
528 | BOOST_STATIC_CONSTANT(bool, value = | |
529 | (mpl::or_<is_binary_interval_set_combinable<GuideT, CompanionT>, | |
530 | is_binary_interval_map_combinable<GuideT, CompanionT> | |
531 | >::value) | |
532 | ); | |
533 | }; | |
534 | ||
535 | template<class GuideT, class CompanionT> | |
536 | struct is_binary_cross_combinable | |
537 | { | |
538 | typedef is_binary_cross_combinable<GuideT,CompanionT> type; | |
539 | BOOST_STATIC_CONSTANT(bool, value = | |
540 | (mpl::and_ | |
541 | < is_interval_map<GuideT> | |
542 | , mpl::or_< is_coarser_interval_map_companion<GuideT, CompanionT> | |
543 | , is_interval_set_companion<GuideT, CompanionT> > | |
544 | >::value) | |
545 | ); | |
546 | }; | |
547 | ||
548 | template<class GuideT, class CompanionT> | |
549 | struct is_binary_inter_combinable | |
550 | { | |
551 | typedef is_binary_inter_combinable<GuideT,CompanionT> type; | |
552 | BOOST_STATIC_CONSTANT(bool, value = | |
553 | (mpl::or_ | |
554 | < | |
555 | mpl::and_<is_interval_map<GuideT>, | |
556 | is_binary_cross_combinable<GuideT, CompanionT> > | |
557 | , mpl::and_<is_interval_set<GuideT>, | |
558 | is_binary_intra_combinable<GuideT, CompanionT> > | |
559 | >::value) | |
560 | ); | |
561 | }; | |
562 | ||
563 | ||
564 | }} // namespace icl boost | |
565 | ||
566 | #endif | |
567 | ||
568 |