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

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

21.06.2011, 12:31. Показов 35092. Ответов 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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru