Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.81/180: Рейтинг темы: голосов - 180, средняя оценка - 4.81
Эксперт С++
3210 / 1458 / 73
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
1

Compile-time алгоритмы. сборник

21.06.2011, 12:31. Показов 33352. Ответов 33
Метки нет (Все метки)

всем привет.
предлагаю в этой теме обсуждать/реализовывать/выкладывать compile-time алгоритмы. под CUT'ом.

подсчет FNV1a-хеш суммы строк:
code

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
 
template<size_t N, size_t I=0>
struct hash_calc {
    static constexpr size_t apply (const char (&s)[N]) {
       return  (hash_calc<N, I+1>::apply(s) ^ s[I]) * 16777619u;
    };
};
 
template<size_t N>
struct hash_calc<N,N> {
    static constexpr size_t apply (const char (&s)[N]) {
       return  2166136261u;
    };
};
 
template<size_t N>
constexpr size_t hash ( const char (&s)[N] ) {
    return hash_calc<N>::apply(s);
}
 
int main() {
   constexpr char a[] = "12345678";
 
   enum { h1 = hash(a) };
   enum { h2 = hash("12345678") };
 
   std::cout << std::hex << h1 << std::endl;
   std::cout << std::hex << h2 << std::endl;
}

http://melpon.org/wandbox/perm... uJjtxP90wD
9
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.06.2011, 12:31
Ответы с готовыми решениями:

Что такое compile-time алгоритмы и для чего они нужны?
А есть от них хоть какая-то практическая польза? По-моему нет

Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time
Привет! Хочу как-то регистрировать все ф-ции, объявляемые в файле, например есть вот это ...

Compile - time алгоритмы
мне итересно, с появлением constexpr надобность в шаблонных компиле-тайм алгоритмах полностью...

Compile-time и run-time методы и функции
Добрый день. Есть две функции, которые делают идентичную работу: template&lt;bool leftShift,...

33
Эксперт С++
340 / 304 / 36
Регистрация: 16.06.2009
Сообщений: 486
29.08.2012, 14:40 21
Реализация compile-time алгоритма split для строки. Так как оставлять сообщения в теме https://www.cyberforum.ru/cpp-... 23714.html не могу (как и в разделе в целом), запилю сюда. Может кому интересно будет..)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <iostream>
 
#include <boost/mpl/string.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp> 
#include <boost/mpl/if.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/contains.hpp>
 
namespace mpl = boost::mpl;
 
template <
   typename Character,
   typename Word,
   typename Cond
>
struct AddToWord {
   typedef typename
      mpl::if_ <
         Cond,
         Word,
         typename mpl::push_back <
            Word,
            mpl::char_ <
               Character::value
            >
         >::type
      >::type type;
};
 
template <
   typename Word,
   typename Cond
>
struct ClearWord {
   typedef typename
      mpl::if_ <
         Cond,
         typename mpl::clear <Word>::type,
         Word
      >::type type;
};
 
template <
   typename Word,
   typename Seq,
   typename Cond
>
struct AddToSeq {
   typedef typename
      mpl::if_ <
         Cond,
         typename mpl::if_ <
            typename mpl::equal_to <
               typename mpl::size <Word>::type,
               mpl::int_ <0>
            >::type,
            Seq,
            typename mpl::push_back <
               Seq,
               Word
            >::type
         >::type,
         Seq
      >::type type;
};
 
template <typename Seq, typename Character>
struct ChInSeq {
   typedef typename
      mpl::contains <
         Seq,
         Character
      >::type type;
};
 
template <
   typename Word,
   typename Vec,
   typename Seq,
   typename Tokens,
   int I,
   int N
>
struct Split {
   typedef typename
      mpl::at_c <Seq, I>::type Character;
 
   typedef typename
      AddToWord <
         Character,
         Word,
         typename ChInSeq <Tokens, Character>::type
      >::type word;
      
   typedef typename
      Split <
         typename ClearWord <
            word,
            typename ChInSeq <Tokens, Character>::type
         >::type,
         typename AddToSeq <
            word,
            Vec,
            typename ChInSeq <Tokens, Character>::type
         >::type,
         Seq,
         Tokens,
         I + 1,
         N
      >::type type;
};
 
template <
   typename Word,
   typename Vec,
   typename Seq,
   typename Tokens,
   int N
>
struct Split <Word, Vec, Seq, Tokens, N, N> {
   typedef typename
      mpl::if_ <
         typename ChInSeq <
            Tokens,
            typename mpl::at_c <Seq, N - 1>::type
         >::type,
         Vec,
         typename mpl::push_back <
            Vec,
            Word
         >::type  
      >::type type;
};
 
template <typename Seq, typename Tokens>
struct SplitSeq {
   typedef typename
      Split <
         mpl::string <>,
         mpl::vector <>,
         Seq,
         Tokens,
         0,
         mpl::size <Seq>::value
      >::type v_words;   
};
 
int main() {
   typedef SplitSeq <
      mpl::string <'cat;', ':bad', '  ,', 'word', ': be', 'be..' >,
      mpl::string <' ,.;', ':'>
   >::v_words words;
   
   typedef boost::mpl::reverse_fold <
      words,
      mpl::string <>,
      mpl::copy <mpl::_1, mpl::back_inserter <mpl::_2>>
   >::type str_result;
 
   std::cout << mpl::c_str <str_result>::value;
}
http://melpon.org/wandbox/perm... 0Ae8ar2BnG
6
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.08.2012, 21:35 22
nameless, А вообще офигенно, спасибо!
0
Эксперт С++
340 / 304 / 36
Регистрация: 16.06.2009
Сообщений: 486
30.08.2012, 23:21 23
Получение среза (slice) последовательности.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include <iostream>
 
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp> 
#include <boost/mpl/if.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/greater_equal.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
 
namespace mpl = boost::mpl;
 
struct PrintSeq {
   template <typename T>
   void operator()(T val) {
      std::cout << val << " ";
   }
};
 
template <typename Index>
struct GetToken {
   typedef typename
      mpl::if_ <
         typename mpl::greater_equal <
            Index,
            mpl::int_ <0>   
         >::type,
         mpl::true_,
         mpl::false_
      >::type type;
};
 
template <
   typename Index,
   typename IndexToken,
   typename Seq
>
struct GetIndex {
   typedef typename
      mpl::if_ <
         typename mpl::equal_to <
            IndexToken,
            mpl::true_
         >::type,
         Index,
         typename mpl::plus <
            Index,
            typename mpl::size <Seq>::type
         >::type
      >::type type;
};
 
template <typename Seq, typename NewSeq, int Start, int End>
struct Slice {
   typedef typename
      Slice <
         Seq,
         typename mpl::push_back <
            NewSeq,
            typename mpl::at_c <Seq, Start>::type
         >::type,
         Start + 1,
         End
      >::type type;
};
 
template <typename Seq, typename NewSeq, int End>
struct Slice <Seq, NewSeq, End, End> {
   typedef NewSeq type;
};
 
template <typename Seq, int Start, int End>
struct SliceSeq {
   typedef mpl::int_ <Start> StartType;
   typedef mpl::int_ <End> EndType;
   
   typedef typename
      GetIndex <
         StartType,
         typename GetToken <StartType>::type,
         Seq
      >::type StartNew;
   
   typedef typename
      GetIndex <
         EndType,
         typename GetToken <EndType>::type,
         Seq
      >::type EndNew;
   
   typedef typename
      Slice <
         Seq,
         mpl::vector <>,
         mpl::if_ <
            typename mpl::less <
               StartNew,
               EndNew
            >::type,
            StartNew,
            EndNew
         >::type::value,
         EndNew::value
      >::type type;
};
 
int main() {
    typedef mpl::vector_c <int, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10> input_vector;
 
   mpl::for_each <
      SliceSeq <
         input_vector,
         0,
         5
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         2,
         7
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         4,
         4
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         -6,
         -2
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         -3,
         8
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         -3,
         0
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         -2,
         -7
      >::type
   >(PrintSeq());
   std::cout << "\n";
}
Bash
1
2
3
4
5
6
7
nameless@l49-53-61:~/cpp/mpl_slice$ g++ main.cpp -o main
nameless@l49-53-61:~/cpp/mpl_slice$ ./main
1 2 3 4 5 
3 4 5 6 7 
 
5 6 7 8 
8

Не по теме:

liveworkspace перестал загружаться у меня, ни с того ни сего ..

4
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
31.08.2012, 14:14 24
join.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/greater_equal.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/vector.hpp>
 
#include <iostream>
 
namespace mpl = boost::mpl;
 
template<typename Begin,
         typename End,
         typename Delims,
         typename OutString>
struct Join_impl
{
   typedef typename mpl::deref<Begin>::type Current;
   typedef typename mpl::insert_range
   <
    Current,
    typename mpl::end<Current>::type,
    Delims
   >::type CurrentWithDels;
   typedef typename mpl::insert_range
   <
    OutString,
    typename mpl::end<OutString>::type,
    CurrentWithDels
   >::type NewString;
   typedef typename Join_impl
   <
    typename mpl::next<Begin>::type,
    End,
    Delims,
    NewString
   >::type type;
};
 
template<typename End,
         typename Delims,
         typename OutString>
struct Join_impl<End, End, Delims, OutString>
{
   typedef typename mpl::if_
   <
    mpl::greater_equal
    <
     mpl::size<OutString>,
     mpl::size<Delims>
    >,
    typename mpl::advance
    <
     typename mpl::end<OutString>::type,
     mpl::int_<-mpl::size<Delims>::value>
    >::type,
    typename mpl::end<OutString>::type
   >::type LastPos;
   typedef typename mpl::erase
   <
    OutString,
    LastPos,
    typename mpl::end<OutString>::type
   >::type type;
};
 
template<typename Sequence, typename Delims>
struct Join
{
   typedef typename Join_impl
   <
    typename mpl::begin<Sequence>::type,
    typename mpl::end<Sequence>::type,
    Delims,
    mpl::string<>
   >::type type;
};
 
int main()
{
   typedef mpl::vector<mpl::string<'a', 'b'>, mpl::string<'c', 'd'>, mpl::string<'e', 'f'> > sequence;
   typedef mpl::string<',', '.'> delims;
   typedef Join<sequence, delims>::type result;
   std::cout << mpl::c_str<result>::value << std::endl;
}
http://melpon.org/wandbox/perm... BTKdi0F7uz

Добавлено через 23 минуты
Вцелом терминальный случай можно сделать вразы проще.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
 
#include <iostream>
 
namespace mpl = boost::mpl;
 
template<typename Begin,
         typename End,
         typename Delims,
         typename Out>
struct Join_impl
{
   typedef typename mpl::deref<Begin>::type Current;
   typedef typename mpl::insert_range
   <
    Current,
    typename mpl::end<Current>::type,
    Delims
   >::type CurrentWithDels;
   typedef typename mpl::insert_range
   <
    Out,
    typename mpl::end<Out>::type,
    CurrentWithDels
   >::type NewOut;
   typedef typename Join_impl
   <
    typename mpl::next<Begin>::type,
    End,
    Delims,
    NewOut
   >::type type;
};
 
template<typename End,
         typename Delims,
         typename Out>
struct Join_impl<typename mpl::advance<End, mpl::int_<-1>>::type, End, Delims, Out>
{
   typedef typename mpl::advance<End, mpl::int_<-1>>::type Current;
   typedef typename mpl::insert_range
   <
    Out,
    typename mpl::end<Out>::type,
    typename mpl::deref<Current>::type
   >::type type;
};
 
template<typename Sequence, typename Delims, typename Out>
struct Join
{
   static_assert(!mpl::empty<Sequence>::value, "Can't join empty sequence");
   typedef typename Join_impl
   <
    typename mpl::begin<Sequence>::type,
    typename mpl::end<Sequence>::type,
    Delims,
    Out
   >::type type;
};
 
struct Printer
{
   template<typename T>
   void operator () (const T& c)
   {
      std::cout << c;
   }
};
 
int main()
{
   typedef mpl::vector<mpl::string<'a', 'b'>, mpl::string<'c', 'd'> > sequence;
   typedef mpl::string<',', '.'> delims;
   typedef Join<sequence, delims, mpl::string<>>::type result;
   std::cout << mpl::c_str<result>::value << std::endl;
   typedef Join<sequence, delims, mpl::vector<>>::type result_type;
   mpl::for_each<result_type>(Printer());
   std::cout << std::endl;
}
http://melpon.org/wandbox/perm... djFPsclrd5

Добавлено через 2 часа 5 минут
Split с возможностью сохранения разделителей.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/for_each.hpp>
 
#include <iostream>
 
namespace mpl = boost::mpl;
 
template<typename Sequence,
         typename Elem,
         typename Cond>
struct AppendIf
{
   typedef typename mpl::if_
   <
    Cond,
    typename mpl::push_back<Sequence, Elem>::type,
    Sequence
   >::type type;
};
 
template<typename Begin,
         typename End,
         typename Delims,
         typename Policy,
         typename DelimsSaved,
         typename Out>
struct Split_impl
{
   typedef typename mpl::deref<Begin>::type Current;
   typedef typename mpl::contains<Delims, Current>::type IsInDelims;
   typedef typename mpl::if_
   <
    IsInDelims,
    typename AppendIf
    <
     DelimsSaved,
     Current,
     mpl::bool_<Policy::need_save_delims()>
    >::type,
    DelimsSaved
   >::type NewDelims;
   typedef typename mpl::if_
   <
    mpl::not_<IsInDelims>,
    typename mpl::push_back<Out, Current>::type,
    Out
   >::type NewOut;
   typedef Split_impl
   <
    typename mpl::next<Begin>::type,
    End,
    Delims,
    Policy,
    NewDelims,
    NewOut
   > split_type;
   typedef typename split_type::type type;
   typedef typename split_type::delims delims;
};
 
template<typename End,
         typename Delims,
         typename Policy,
         typename DelimsSaved,
         typename Out>
struct Split_impl<End, End, Delims, Policy, DelimsSaved, Out>
{
   typedef Out type;
   typedef DelimsSaved delims;
};
 
template<typename Sequence,
         typename Delims,
         typename Policy>
struct Split
{
   static_assert(!mpl::empty<Sequence>::value, "Can't split empty sequence");
   typedef Split_impl
   <
    typename mpl::begin<Sequence>::type,
    typename mpl::end<Sequence>::type,
    Delims,
    Policy,
    mpl::string<>,
    mpl::string<>
   > split_type;
   typedef typename split_type::type type;
   typedef typename split_type::delims delims;
};
 
template<bool Value>
struct keep_seps
{
   static constexpr bool need_save_delims() { return Value; }
};
 
int main()
{
   typedef mpl::string<'a', '.', ',', 'd', '!', 'e'> string;
   typedef mpl::string<',', '.', '!'> delims;
   typedef Split<string, delims, keep_seps<true>> f_split_type;
   std::cout << mpl::c_str<f_split_type::type>::value << std::endl;
   std::cout << mpl::c_str<f_split_type::delims>::value << std::endl;
   typedef Split<string, delims, keep_seps<false>> s_split_type;
   std::cout << mpl::c_str<s_split_type::delims>::value << std::endl;
}
http://melpon.org/wandbox/perm... gw0Rkqpnxs
4
Эксперт С++
340 / 304 / 36
Регистрация: 16.06.2009
Сообщений: 486
31.08.2012, 14:39 25
Цитата Сообщение от ForEveR Посмотреть сообщение
Split с возможностью сохранения разделителей.
0
Эксперт С++
340 / 304 / 36
Регистрация: 16.06.2009
Сообщений: 486
02.09.2012, 15:50 26
Слегка модифицированный вариант slice. 3 параметр - step.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#include <iostream>
 
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp> 
#include <boost/mpl/if.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/greater_equal.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/or.hpp>
 
namespace mpl = boost::mpl;
 
struct PrintSeq {
   template <typename T>
   void operator()(T val) {
      std::cout << val << " ";
   }
};
 
template <
   typename Index,
   typename IndexToken,
   typename Seq
>
struct GetIndex {
   typedef typename
      mpl::if_ <
         typename mpl::equal_to <
            IndexToken,
            mpl::true_
         >::type,
         Index,
         typename mpl::plus <
            Index,
            typename mpl::size <Seq>::type
         >::type
      >::type type;
};
 
template <typename Start, typename Step, typename Size>
struct CorrectStart {
   typedef mpl::int_ <Size::value - 1> SizeStart;
   typedef typename
      mpl::if_ <
         typename mpl::and_ <
            typename mpl::less <Step, mpl::int_ <0>>::type,
            typename mpl::greater <Start, SizeStart>::type
         >::type,
         SizeStart,
         Start
      >::type type;
};
 
template <typename End, typename Step, typename Size>
struct CorrectEnd {
   typedef mpl::int_ <Size::value - 1> SizeEnd;
   typedef typename
      mpl::if_ <
         typename mpl::and_ <
            typename mpl::greater <Step, mpl::int_ <0>>::type,
            typename mpl::greater <End, SizeEnd>::type
         >::type,
         mpl::int_ <Size::value>,
         End
      >::type type;
};
 
template <typename Start, typename End, typename Step>
struct CorrectStep {
   typedef mpl::int_ <Start::value + Step::value> SumStartStep;
   typedef mpl::int_ <End::value - Start::value> DiffStartStep;
 
   typedef typename
      mpl::if_ <
         typename mpl::or_ <
            typename mpl::and_ <
               typename mpl::less <Step, mpl::int_ <0>>::type,
               typename mpl::less <SumStartStep, End>::type
            >::type,
            typename mpl::and_ <
               typename mpl::greater <Step, mpl::int_ <0>>::type,
               typename mpl::greater <SumStartStep, End>::type
            >::type
         >::type,
         DiffStartStep,
         Step
      >::type type;
};
 
template <typename Seq, typename NewSeq, int Start, int End, int Step>
struct Slice {
   typedef typename
      CorrectStart <
         mpl::int_ <Start>,
         mpl::int_ <Step>,
         typename mpl::size <Seq>::type
      >::type NewStart;
      
   typedef typename
      CorrectEnd <
         mpl::int_ <End>,
         mpl::int_ <Step>,
         typename mpl::size <Seq>::type
      >::type NewEnd;  
      
   typedef typename
      CorrectStep <
         NewStart,
         NewEnd,
         mpl::int_ <Step>
      >::type NewStep;  
           
   typedef typename
      Slice <
         Seq,
         typename mpl::push_back <
            NewSeq,
            typename mpl::at_c <Seq, NewStart::value>::type
         >::type,
         NewStart::value + NewStep::value,
         NewEnd::value,
         NewStep::value
      >::type type;
};
 
template <typename Seq, typename NewSeq, int End, int Step>
struct Slice <Seq, NewSeq, End, End, Step> {
   typedef NewSeq type;
};
 
template <typename Seq, int Start, int End, int Step = 1>
struct SliceSeq {
   static_assert(Step, "Slice step cannot be zero");
   typedef mpl::int_ <Start> StartType;
   typedef mpl::int_ <End> EndType;
   
   typedef typename
      GetIndex <
         StartType,
         typename mpl::greater_equal <StartType, mpl::int_ <0>>::type,
         Seq
      >::type StartNew;
   
   typedef typename
      GetIndex <
         EndType,
         typename mpl::greater_equal <EndType, mpl::int_ <0>>::type,
         Seq
      >::type EndNew;
   
   typedef typename
      Slice <
         Seq,
         mpl::vector <>,
         mpl::if_ <
            typename mpl::or_ <
               typename mpl::and_ <
                  typename mpl::less <StartNew, EndNew>::type,
                  typename mpl::greater <mpl::int_ <Step>, mpl::int_ <0>>::type
               >::type,
               typename mpl::and_ <
                  typename mpl::greater <StartNew, EndNew>::type,
                  typename mpl::less <mpl::int_ <Step>, mpl::int_ <0>>::type
               >::type
            >::type,
            StartNew,
            EndNew
         >::type::value,
         EndNew::value,
         Step
      >::type type;
};
 
int main() {
   typedef mpl::vector_c <int, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10> input_vector;
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         0,
         8,
         2
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         7,
         -1,
         3
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         0,
         0,
         -3
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         20,
         3,
         -4
      >::type
   >(PrintSeq());
   std::cout << "\n";
    
   mpl::for_each <
      SliceSeq <
         input_vector,
         -1,
         2,
         -2
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         -3,
         12,
         2
      >::type
   >(PrintSeq());
   std::cout << "\n";
   
   mpl::for_each <
      SliceSeq <
         input_vector,
         0,
         20,
         32
      >::type
   >(PrintSeq());
   std::cout << "\n";
}
http://melpon.org/wandbox/perm... O6afSev7xZ
4
Эксперт С++
3210 / 1458 / 73
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.09.2012, 16:24  [ТС] 27
думается мне, для написания строковых парсеров, нужно в первую очередь сконцентрироваться на написании шаблона строки, которая может принимать настоящую Си-строку.
пример:
C++
1
2
3
4
constexpr auto str = create_string("some string");
constexpr auto strings = split(str, ' ');
constexpr auto orig = join(strings, ' ');
static_assert(is_equal(str, orig), "error!");
в моем представлении это возможно.

Добавлено через 1 минуту
т.е. здесь, create_string() возвращает шаблон типа: string<12>
0
Эксперт С++
340 / 304 / 36
Регистрация: 16.06.2009
Сообщений: 486
04.09.2012, 17:39 28
Как-то так..

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
 
#include <boost/mpl/string.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/char.hpp>
 
#include <boost/preprocessor/repetition/repeat.hpp>
 
namespace mpl = boost::mpl;
 
#define MAX_STRING_LENGTH 32
 
template <typename Seq, char Character, bool StateEnd>
struct AppendToString {
   typedef typename
      mpl::push_back <
         Seq,
         mpl::char_ <Character>
      >::type type;
};
      
template <typename Seq, char  Character>
struct AppendToString <Seq, Character, true> {
   typedef Seq type;
};
 
template <std::size_t Length, typename T>
constexpr T GetElement(const T (&seq)[Length], std::size_t index) {
   return index >= Length ? 0 : seq[index];
}
 
#define GENERATE_MPL_STRING(z, n, unused) \
   AppendToString < \
 
#define ADD_CHARACTER(z, n, str) \
      , \
      GetElement <sizeof(str)>(str, n), \
      (n >= sizeof(str) - 1) \
   >::type
   
#define STRING(s) \
   BOOST_PP_REPEAT( \
      MAX_STRING_LENGTH, \
      GENERATE_MPL_STRING, \
      ~ \
   ) \
   mpl::string <> \
   BOOST_PP_REPEAT( \
      MAX_STRING_LENGTH, \
      ADD_CHARACTER, \
      s \
   )
   
int main() {
   std::cout << mpl::c_str <STRING("string")>::value << std::endl;
}
http://melpon.org/wandbox/perm... EvbLP5TZk8
3
Эксперт С++
3210 / 1458 / 73
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
04.09.2012, 19:36  [ТС] 29
я не это имел ввиду.
поковыряю в этом направлении на досуге.
1
Эксперт С++
340 / 304 / 36
Регистрация: 16.06.2009
Сообщений: 486
04.09.2012, 19:47 30
Цитата Сообщение от niXman Посмотреть сообщение
я не это имел ввиду.
поковыряю в этом направлении на досуге.
Да я понимаю, что Вы не это имели в виду. Просто предложил более читабельный вариант определения mpl::string.
0
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.05.2013, 20:59 31
Легкий изврат на тему проверки отсортирована-ли последовательность на этапе компиляции (с сохранением места возникновения ошибки).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
 
#include <boost/mpl/vector.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/prior.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/less_equal.hpp>
#include <boost/mpl/distance.hpp>
 
namespace mpl = boost::mpl;
 
template<typename Begin, typename Current, typename End,
template<typename, typename> class Compare, bool CurrentResult>
struct is_sorted_helper
{
private:
    typedef Current current_impl_t;
    typedef typename mpl::prior<Current>::type prior_impl_t;
    typedef typename boost::is_same<Begin, current_impl_t>::type current_eq_begin;
    typedef typename mpl::if_<current_eq_begin,
        current_impl_t, prior_impl_t>::type current_prior_t;
    typedef typename mpl::deref<current_prior_t>::type current_p_d;
    typedef typename mpl::deref<current_impl_t>::type current_d;
    typedef Compare<current_p_d, current_d> compare_t;
    typedef typename mpl::next<current_impl_t>::type next_impl_t;
    typedef is_sorted_helper<Begin, next_impl_t, End, Compare,
        compare_t::type::value> impl_t;
public:
    typedef Begin begin_t;
    typedef typename impl_t::current_t current_t;
    typedef typename impl_t::next_t next_t;
    typedef typename impl_t::prior_t prior_t;
    static const bool value = CurrentResult &&
        impl_t::value;
};
 
template<typename Begin, typename Current, typename End,
template <typename, typename> class Compare>
struct is_sorted_helper<Begin, Current, End, Compare, false>
{
private:
    typedef typename mpl::prior<Current>::type prior_impl_t;
    typedef typename boost::is_same<Begin, Current>::type prior_less_eq_current_t;
public:
    typedef Begin begin_t;
    typedef typename mpl::prior<Current>::type current_t;
    typedef typename mpl::prior<current_t>::type prior_t;
    typedef mpl::next<current_t> next_t;
    static const bool value = false;
};
 
template<typename Begin, typename End, template<typename, typename> class Compare>
struct is_sorted_helper<Begin, End, End, Compare, true>
{
    typedef Begin begin_t;
    typedef End current_t;
    typedef mpl::prior<current_t> prior_t;
    typedef End next_t;
    static const bool value = true;
};
 
template<typename Begin, typename End, template<typename, typename> class Compare>
struct is_sorted_range
{
    typedef is_sorted_helper<Begin, Begin, End, Compare, true> result_t;
    typedef typename result_t::begin_t begin_t;
    typedef typename result_t::current_t current_t;
    typedef typename result_t::prior_t prior_t;
    static const bool value = result_t::value;
};
 
template<typename Sequence, template<typename, typename> class Compare>
struct is_sorted_sequence
{
    typedef is_sorted_range<typename mpl::begin<Sequence>::type, typename mpl::end<Sequence>::type, Compare> result_t;
    typedef typename result_t::begin_t begin_t;
    typedef typename result_t::current_t current_t;
    typedef typename result_t::prior_t prior_t;
    static const bool value = result_t::value;
};
 
 
template<typename Result, bool>
struct trace_helper
{
    static void apply()
    {
        std::cout << "Sorted sequence" << std::endl;
    }
};
 
template<typename Result>
struct trace_helper<Result, false>
{
    static void apply()
    {
        typedef typename mpl::deref<Result::prior_t>::type prior_t;
        typedef typename mpl::deref<Result::current_t>::type current_t;
        typedef typename mpl::distance<Result::begin_t, Result::prior_t>::type p_distance_t;
        typedef typename mpl::distance<Result::begin_t, Result::current_t>::type c_distance_t;
        std::cout << "Condition failure between " << p_distance_t::value + 1 << " and " << c_distance_t::value + 1
            << " elements: " << prior_t::value << " > " << current_t::value << std::endl;
    }
};
 
template<typename Result>
void trace()
{
    trace_helper<Result, Result::value>::apply();
}
 
int main()
{
    typedef mpl::vector<mpl::int_<1>, mpl::int_<2>, mpl::int_<3> >::type sorted_vector;
    trace<is_sorted_sequence<sorted_vector, mpl::less_equal> >();
    typedef mpl::vector<mpl::int_<4>, mpl::int_<2>, mpl::int_<3> >::type not_sorted_vector;
    trace<is_sorted_sequence<not_sorted_vector, mpl::less_equal> >();
    typedef mpl::vector<mpl::int_<1> >::type one_el_vector;
    trace<is_sorted_sequence<one_el_vector, mpl::less_equal> >();
    typedef mpl::vector<>::type empty_vector;
    trace<is_sorted_sequence<empty_vector, mpl::less_equal> >();
    typedef mpl::vector<mpl::int_<1>, mpl::int_<3>, mpl::int_<2> >::type not_sorted_vector2;
    trace<is_sorted_sequence<not_sorted_vector2, mpl::less_equal> >();
}
4
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
24.07.2014, 19:55 32
Что-то compile-time алгоритмы совсем затихли, посему выложу то, что меня сегодня крайне заинтересовало. Ссылка на SO: http://stackoverflow.com/quest... 5#24937715
Было очень интересно как это сделать, пытался по разному, в итоге на работе так и не додумался, а пока ехал домой подумал еще раз и приехав домой написал - отработало.
Вкратце, перевод LOKI typelist в std::tuple.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
template<typename T, typename... Args>
struct tuple_push;
 
template<typename T, typename... Args>
struct tuple_push<T, std::tuple<Args...>>
{
    typedef std::tuple<Args..., T> type;
};
 
template<typename TL>
struct typelist_to_tuple;
 
template<typename H, typename T>
struct typelist_to_tuple<typelist<H, T>>
{
    typedef typename tuple_push<H, typename typelist_to_tuple<T>::type>::type type;
};
 
template<typename H>
struct typelist_to_tuple<typelist<H, null_typelist>>
{
    typedef std::tuple<H> type;
};
 
int main()
{
    typedef typelist<Int, typelist<Float, typelist<Int, null_typelist>>> list;
    typedef typelist_to_tuple<list>::type tuple;
    tuple v = 1;
}
Выдаст ошибку вида, нельзя присвоить 1 значению типа std::tuple<Int, Float, Int>.

Полный вариант с некоторыми извратами со SFINAE на coliru: http://coliru.stacked-crooked.... 6a53738fca

Вряд ли сие кому пригодится, но пусть будет, я думаю.
1
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
11.12.2014, 15:29 33
Тут были помнится разговоре о compile-time cтроке. facebook в своей либе fatal сделал нечто подобное, насколько я понимаю. сорцы
слайды с CPPCON о fatal
1
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
23.01.2017, 21:44 34
я конечно балбес, но всё же
детектор рандом аксцесс итера:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
namespace detail {
    
    template<class ...>
    struct param_tester
    {
        using type = void;
    };
 
    template<class... Args>
    using void_t = typename param_tester<Args...>::type;
 
    template<class Iter>
    struct has_iterator
    {
        static constexpr bool value_t = std::is_copy_constructible<Iter>::value &&
                                        std::is_copy_assignable<Iter>::value && 
                                        std::is_destructible<Iter>::value //&&
                                        /*std::is_swappable<Iter>::value*/;
    };
 
    template<class It, class voider = void_t<>>
    struct is_iterator : std::false_type {};
 
    template<class It>
    struct is_iterator<It,
        void_t
        <
        decltype(++std::declval<It&>()),
        decltype(--std::declval<It&>()),
        decltype(*std::declval<It&>()),
        decltype(std::ptrdiff_t(std::declval<It&>().operator[](std::declval<std::ptrdiff_t>()))),
        decltype(std::declval<It&>() + std::declval<std::ptrdiff_t>()),
        decltype(std::declval<It&>() - std::declval<std::ptrdiff_t>()),
        decltype(std::ptrdiff_t(std::declval<It&>() - std::declval<It const&>())),
        decltype(std::declval<It&>() += std::declval<std::ptrdiff_t>()),
        decltype(std::declval<It&>() -= std::declval<std::ptrdiff_t>()),
        decltype(std::declval<It&>() == std::declval<It const&>()),
        decltype(std::declval<It&>() = std::declval<It const&>())
        >
    > : std::integral_constant<bool, has_iterator<It>::value_t || std::is_pointer<It>::value> {};
 
    template<class It>
    struct is_iterator<It*> : std::true_type {};
 
    template<class It>
    struct is_iterator<It const*> : std::true_type {};
    
    template<class It>
    using is_iterator_t = typename is_iterator<It>::type;
}
PS Может кто подскажет как сваппбле реализовать (он только в 17 стандарте есть)?

Добавлено через 2 минуты
вывод элементов кортежа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<std::size_t Index = 0, std::size_t Maximum, class... Args>
static constexpr typename std::enable_if_t<Index == sizeof...(Args), std::ostream&>
for_each(const std::tuple<Args...>&, std::ostream& os) 
{
    return os;
}
 
template<std::size_t Index = 0, std::size_t Maximum, class... Args>
static constexpr typename std::enable_if_t<Index != sizeof...(Args), std::ostream&>
for_each(const std::tuple<Args...>& tuple, std::ostream& os)
{
    return for_each<Index + 1, Maximum, Args...>(tuple, os) << std::get<Index>(tuple) << (Index == std::size_t{} ? "" : ",");
}
 
template<class... Args>
auto operator<<(std::ostream& os, const std::tuple<Args...>& tuple) -> std::ostream&
{
    os << "(";
    for_each<std::size_t{}, sizeof...(Args), Args...>(tuple, os);
    return os << ")";
}
кстати такое дело вроде в хана есть
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.01.2017, 21:44

Выделение памяти объёмом, известном в compile-time
Правда ли, что, скажем new int Произойдёт существенно быстрее, чем int length =...

Не могу разобраться с заданием "Создайте класс Time с конструкторами Time(), Time( int hour)......"
/* Создайте класс Time с конструкторами Time(), Time( int hour), Time(int hour, int min),...

Const в delay.h: compile time integer constant
Есть такая библиотека, delay.h. В ней есть функция _delay_us(double __us): _delay_us(double...

Ошибка compile-time constant для аргумента по умолчанию
Имеется два метода class MyFile { public static string ReadAll(string filename, Encoding enc...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.