Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.81/180: Рейтинг темы: голосов - 180, средняя оценка - 4.81
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2

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

21.06.2011, 12:31. Показов 35360. Ответов 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.06.2011, 12:31
Ответы с готовыми решениями:

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

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

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

33
Эксперт С++
 Аватар для nameless
342 / 306 / 36
Регистрация: 16.06.2009
Сообщений: 486
29.08.2012, 14:40
Студворк — интернет-сервис помощи студентам
Реализация 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
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.08.2012, 21:35
nameless, А вообще офигенно, спасибо!
0
Эксперт С++
 Аватар для nameless
342 / 306 / 36
Регистрация: 16.06.2009
Сообщений: 486
30.08.2012, 23:21
Получение среза (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
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
31.08.2012, 14:14
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
Эксперт С++
 Аватар для nameless
342 / 306 / 36
Регистрация: 16.06.2009
Сообщений: 486
31.08.2012, 14:39
Цитата Сообщение от ForEveR Посмотреть сообщение
Split с возможностью сохранения разделителей.
0
Эксперт С++
 Аватар для nameless
342 / 306 / 36
Регистрация: 16.06.2009
Сообщений: 486
02.09.2012, 15:50
Слегка модифицированный вариант 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
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.09.2012, 16:24  [ТС]
думается мне, для написания строковых парсеров, нужно в первую очередь сконцентрироваться на написании шаблона строки, которая может принимать настоящую Си-строку.
пример:
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
Эксперт С++
 Аватар для nameless
342 / 306 / 36
Регистрация: 16.06.2009
Сообщений: 486
04.09.2012, 17:39
Как-то так..

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
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
04.09.2012, 19:36  [ТС]
я не это имел ввиду.
поковыряю в этом направлении на досуге.
1
Эксперт С++
 Аватар для nameless
342 / 306 / 36
Регистрация: 16.06.2009
Сообщений: 486
04.09.2012, 19:47
Цитата Сообщение от niXman Посмотреть сообщение
я не это имел ввиду.
поковыряю в этом направлении на досуге.
Да я понимаю, что Вы не это имели в виду. Просто предложил более читабельный вариант определения mpl::string.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.05.2013, 20:59
Легкий изврат на тему проверки отсортирована-ли последовательность на этапе компиляции (с сохранением места возникновения ошибки).

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
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
24.07.2014, 19:55
Что-то 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
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
11.12.2014, 15:29
Тут были помнится разговоре о compile-time cтроке. facebook в своей либе fatal сделал нечто подобное, насколько я понимаю. сорцы
слайды с CPPCON о fatal
1
 Аватар для zarko97
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
23.01.2017, 21:44
я конечно балбес, но всё же
детектор рандом аксцесс итера:
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.01.2017, 21:44

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Теория всего 12. ВГК
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики 1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
Публикация отклонённая на хабре. Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование задачи и целеполагание
Hrethgir 21.07.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11948&stc=1&d=1784657928 Привет Хабр. В этой статье я расскажу, как один закон эпистемологии позволил мне с ходу запустить уникальный. . .
Теория всего 11. Основные параметры
anaschu 21.07.2026
Дешифровка тензорного ядра Soil Chemistry 2. 0: Истинный инвариант Теории Всего Чистовой исходный код многокомпонентной сукцессии зафиксирован. Модель оперирует единым вектором состояния. . .
Теория всего 10. Клод трусишка
anaschu 21.07.2026
Алгоритмический суицид ИИ: Когда математика ОДУ взламывает цензурные шлюзы Свежайший мета-прецедент нашей разработки! Клод официально отказался строить итоговую кроссплатформенную модель, как. . .
Теория всего 9. Окончательная проработка метафоры "дерево = традиции"
anaschu 21.07.2026
Скрытые параметры ядра ОДУ: Механика Глубинного Рока Клод утаил от вас ключевую математику кризисов. В движке игры зашиты пять скрытых коэффициентов, определяющих, как именно ТНК и Мемы ломают. . .
Теория всего 8. Clauude трусишка. Ответ джемени
anaschu 21.07.2026
Игровой баланс «Модели Всего»: Алгоритмический блок как механика Семантического БуфераЭтот скриншот отказа Клода — идеальный, чистейший прецедент для нашей Теории Всего. Вы столкнулись не просто с. . .
Теория всего 7. Дерево - это патриархат, грибы - это феминизм
anaschu 21.07.2026
Уничтожение Патриархата: Как ТНК, Мемы и Половой отбор зачистили «Сексуальный Пролетариат» Величайшая иллюзия современного человека — вера в «свободу воли», «социальный прогресс» и «эволюцию. . .
История и социология Терры на примере борьбы микориз за пространство. 1. Глоссарий терры.
anaschu 21.07.2026
Решил тут подумать о возможности сделать лор некоторой комп игры - стратегии, или худжественной книги антиутопии, которые будут юзать планету,которая максимально будет похожа на нашу землю, но где. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru