Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
#1

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

21.06.2011, 12:31. Просмотров 31828. Ответов 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/permlink/ibMdmMuJjtxP90wD
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.06.2011, 12:31     Compile-time алгоритмы. сборник
Посмотрите здесь:

Compile C++
C++ Что такое compile-time алгоритмы и для чего они нужны?
C++ Не могу разобраться с заданием "Создайте класс Time с конструкторами Time(), Time( int hour)......"
C++ Compile - time алгоритмы
C++ Класс Time через time(0)
Напишите конструктор для инициализации объекта класса Time, который может использовать текущее время, возвращаемое функцией time (). C++
Класс "Время". Двусмысленность между time и std:time(long*) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nameless
Эксперт C++
296 / 295 / 14
Регистрация: 16.06.2009
Сообщений: 486
29.08.2012, 14:40     Compile-time алгоритмы. сборник #21
Реализация compile-time алгоритма split для строки. Так как оставлять сообщения в теме http://www.cyberforum.ru/cpp-experts/thread323714.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/permlink/nIQ7bX0Ae8ar2BnG
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
29.08.2012, 21:35     Compile-time алгоритмы. сборник #22
nameless, А вообще офигенно, спасибо!
nameless
Эксперт C++
296 / 295 / 14
Регистрация: 16.06.2009
Сообщений: 486
30.08.2012, 23:21     Compile-time алгоритмы. сборник #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 перестал загружаться у меня, ни с того ни сего ..

ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
31.08.2012, 14:14     Compile-time алгоритмы. сборник #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/permlink/dIIWuTBTKdi0F7uz

Добавлено через 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/permlink/L4HfJVdjFPsclrd5

Добавлено через 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/permlink/gJaUVdgw0Rkqpnxs
nameless
Эксперт C++
296 / 295 / 14
Регистрация: 16.06.2009
Сообщений: 486
31.08.2012, 14:39     Compile-time алгоритмы. сборник #25
Цитата Сообщение от ForEveR Посмотреть сообщение
Split с возможностью сохранения разделителей.
nameless
Эксперт C++
296 / 295 / 14
Регистрация: 16.06.2009
Сообщений: 486
02.09.2012, 15:50     Compile-time алгоритмы. сборник #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/permlink/Zq0AlxO6afSev7xZ
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.09.2012, 16:24  [ТС]     Compile-time алгоритмы. сборник #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>
nameless
Эксперт C++
296 / 295 / 14
Регистрация: 16.06.2009
Сообщений: 486
04.09.2012, 17:39     Compile-time алгоритмы. сборник #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/permlink/RUcuWZEvbLP5TZk8
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
04.09.2012, 19:36  [ТС]     Compile-time алгоритмы. сборник #29
я не это имел ввиду.
поковыряю в этом направлении на досуге.
nameless
Эксперт C++
296 / 295 / 14
Регистрация: 16.06.2009
Сообщений: 486
04.09.2012, 19:47     Compile-time алгоритмы. сборник #30
Цитата Сообщение от niXman Посмотреть сообщение
я не это имел ввиду.
поковыряю в этом направлении на досуге.
Да я понимаю, что Вы не это имели в виду. Просто предложил более читабельный вариант определения mpl::string.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
09.05.2013, 20:59     Compile-time алгоритмы. сборник #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> >();
}
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
24.07.2014, 19:55     Compile-time алгоритмы. сборник #32
Что-то compile-time алгоритмы совсем затихли, посему выложу то, что меня сегодня крайне заинтересовало. Ссылка на SO: http://stackoverflow.com/questions/2...37715#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.com/a/7e8ac56a53738fca

Вряд ли сие кому пригодится, но пусть будет, я думаю.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
11.12.2014, 15:29     Compile-time алгоритмы. сборник #33
Тут были помнится разговоре о compile-time cтроке. facebook в своей либе fatal сделал нечто подобное, насколько я понимаю. сорцы
слайды с CPPCON о fatal
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.01.2017, 21:44     Compile-time алгоритмы. сборник
Еще ссылки по теме:

C++ Что за ошибка: "E2015 Ambiguity between 'time' and 'std::time"?
C++ Что за ошибка: "E2015 Ambiguity between 'time' and 'std::time"?
C++ Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time
C++ Compile-time и run-time методы и функции
C++ Выделение памяти объёмом, известном в compile-time

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

Или воспользуйтесь поиском по форуму:
zarko97
246 / 27 / 0
Регистрация: 11.10.2015
Сообщений: 150
23.01.2017, 21:44     Compile-time алгоритмы. сборник #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 << ")";
}
кстати такое дело вроде в хана есть
Yandex
Объявления
23.01.2017, 21:44     Compile-time алгоритмы. сборник
Ответ Создать тему
Опции темы

Текущее время: 15:08. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru