Line data Source code
1 : //
2 : // Author: Vladimir Migashko <migashko@wamba.com>, (C) 2013
3 : //
4 : // Copyright: See COPYING file that comes with this distribution
5 : //
6 :
7 : #ifndef COMPARATORS_COMPARE_LIST_HPP
8 : #define COMPARATORS_COMPARE_LIST_HPP
9 :
10 : #include <fas/type_list/type_list.hpp>
11 : #include <fas/type_list/type_list_n.hpp>
12 : #include <fas/type_list/empty_list.hpp>
13 : #include <fas/type_list/head.hpp>
14 : #include <fas/type_list/tail.hpp>
15 : #include <fas/type_list/erase_c.hpp>
16 : #include <fas/type_list/push_back.hpp>
17 :
18 : namespace vset{
19 :
20 : template<typename CompareList>
21 : struct compare_list_impl;
22 :
23 : template<typename CompareList>
24 : struct compare_list2_impl;
25 :
26 :
27 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
28 :
29 : /**
30 : * @brief Создает композитный компаратор на основе списка компараторов
31 : * @tparam Args... список компараторов, например vset::compare_member
32 : * @details может использоваться для определения компаратора сложных структур.
33 : */
34 : template<typename... Args>
35 2 : struct compare_list: compare_list_impl< typename fas::type_list_n<Args...>::type > {};
36 :
37 : /**
38 : * @brief Создает композитный компаратор на основе списка компараторов
39 : * @tparam Args... список компараторов, например vset::compare_member
40 : * @details может использоваться для определения компаратора сложных структур.
41 : */
42 : template<typename... Args>
43 : struct compare_list2: compare_list2_impl< typename fas::type_list_n<Args...>::type > {};
44 :
45 : #else
46 :
47 : /**
48 : * @brief Создает композитный компаратор на основе списка компараторов
49 : * @tparam CompareList список компараторов (fas::type_list), например из vset::compare_member
50 : * @details может использоваться для определения компаратора сложных структур.
51 : */
52 : template<typename CompareList>
53 : struct compare_list: compare_list_impl< CompareList > {};
54 :
55 : /**
56 : * @brief Создает композитный компаратор на основе списка компараторов
57 : * @tparam CompareList список компараторов (fas::type_list), например из vset::compare_member
58 : * @details может использоваться для определения компаратора сложных структур.
59 : */
60 : template<typename CompareList>
61 : struct compare_list2: compare_list2_impl< CompareList > {};
62 :
63 : #endif
64 :
65 : template<typename CompareList>
66 2 : struct compare_list_impl
67 : {
68 : template<typename D>
69 451 : bool operator()(const D& l, const D& r) const
70 : {
71 451 : return _( CompareList(), l, r);
72 : }
73 :
74 : template< typename L, typename D>
75 770 : bool _( L, const D& l, const D& r) const
76 : {
77 : typedef typename fas::head<L>::type head;
78 : typedef typename fas::tail<L>::type tail;
79 :
80 1540 : return head()(l, r)
81 : ? true
82 1360 : : head()(r, l)
83 : ? false
84 2130 : : _(tail(), l, r);
85 : }
86 :
87 : template< typename D>
88 150 : static bool _( fas::empty_list, const D& , const D& )
89 : {
90 150 : return false;
91 : }
92 : };
93 :
94 : template<typename CompareList>
95 : struct compare_list2_impl
96 : {
97 : template<typename D>
98 : bool operator()(const D& l, const D& r) const
99 : {
100 : return _1_( fas::empty_list(), CompareList(), l, r);
101 : }
102 :
103 : template< typename L, typename R, typename D>
104 : static bool _1_( L, R, const D& l, const D& r)
105 : {
106 : typedef typename fas::push_back< typename fas::head<R>::type, L >::type left;
107 : typedef typename fas::erase_c< 0, R >::type right;
108 : return _2_( left(), l, r) || _1_( left(), right(), l, r );
109 : }
110 :
111 : template< typename L, typename D>
112 : static bool _1_( L, fas::empty_list, const D& , const D& )
113 : {
114 : return false;
115 : }
116 :
117 : template< typename H, typename T, typename D>
118 : static bool _2_( fas::type_list<H, T>, const D& l, const D& r)
119 : {
120 : return !H()(r, l) && _2_( T(), l, r);
121 : }
122 :
123 : template< typename H, typename D>
124 : static bool _2_( fas::type_list<H, fas::empty_list>, const D& l, const D& r)
125 : {
126 : return H()(l, r);
127 : }
128 : };
129 :
130 : }
131 :
132 : #endif
133 :
|