131
|
1 // PR c++/84684
|
|
2 // { dg-do compile { target c++17 } }
|
|
3
|
|
4 typedef decltype (sizeof (0)) size_t;
|
|
5
|
|
6 namespace std {
|
|
7 template<class _E>
|
|
8 struct initializer_list
|
|
9 {
|
|
10 typedef _E value_type;
|
|
11 typedef const _E& reference;
|
|
12 typedef const _E& const_reference;
|
|
13 typedef size_t size_type;
|
|
14 typedef const _E* iterator;
|
|
15 typedef const _E* const_iterator;
|
|
16 iterator _M_array;
|
|
17 size_type _M_len;
|
|
18 constexpr initializer_list(const_iterator __a, size_type __l) : _M_array(__a), _M_len(__l) { }
|
|
19 constexpr initializer_list() noexcept : _M_array(0), _M_len(0) { }
|
|
20 constexpr size_type size() const noexcept { return _M_len; }
|
|
21 constexpr const_iterator begin() const noexcept { return _M_array; }
|
|
22 constexpr const_iterator end() const noexcept { return begin() + size(); }
|
|
23 };
|
|
24 }
|
|
25
|
|
26 template <typename E, size_t N>
|
|
27 struct array
|
|
28 {
|
|
29 constexpr E &operator[](size_t n) noexcept { return elems[n]; }
|
|
30 constexpr const E &operator[](size_t n) const noexcept { return elems[n]; }
|
|
31 constexpr size_t size() const { return N; }
|
|
32 E elems[N];
|
|
33 };
|
|
34
|
|
35 template<typename T>
|
|
36 constexpr
|
|
37 inline T
|
|
38 max (std::initializer_list<T> i)
|
|
39 {
|
|
40 const T *b = i.begin ();
|
|
41 const T *e = i.end ();
|
|
42 if (b == e) return *b;
|
|
43 const T *r = b;
|
|
44 while (++b != e)
|
|
45 if (*r < *b)
|
|
46 r = b;
|
|
47 return *r;
|
|
48 }
|
|
49
|
|
50 template <typename alphabet_type>
|
|
51 constexpr char to_char(alphabet_type const alph)
|
|
52 {
|
|
53 return alph.to_char();
|
|
54 }
|
|
55
|
|
56 template <typename ...alphabet_types>
|
|
57 struct union_composition
|
|
58 {
|
|
59 static constexpr size_t value_size = (alphabet_types::value_size + ... );
|
|
60 unsigned char _value;
|
|
61 template <size_t fixed_size, typename alphabet_t>
|
|
62 static constexpr auto value_to_char_helper(alphabet_t alphabet)
|
|
63 {
|
|
64 array<char, fixed_size> value_to_char{};
|
|
65 for (size_t i = 0u; i < alphabet_t::value_size; ++i)
|
|
66 value_to_char[i] = to_char(alphabet.assign_rank(i));
|
|
67 return value_to_char;
|
|
68 }
|
|
69
|
|
70 static constexpr auto make_value_to_char()
|
|
71 {
|
|
72 constexpr auto N = sizeof...(alphabet_types);
|
|
73 constexpr array<size_t, N> alphabet_sizes { alphabet_types::value_size... };
|
|
74 constexpr size_t fixed_size = max({alphabet_types::value_size...});
|
|
75 array value_to_char_tables = array<array<char, fixed_size>, N> {
|
|
76 value_to_char_helper<fixed_size>(alphabet_types{})...
|
|
77 };
|
|
78 array<char, value_size> value_to_char{};
|
|
79 for (size_t i = 0u, value = 0u; i < N; ++i)
|
|
80 for (size_t k = 0u; k < alphabet_sizes[i]; ++k, ++value)
|
|
81 value_to_char[value] = value_to_char_tables[i][k];
|
|
82 return value_to_char;
|
|
83 }
|
|
84 };
|
|
85
|
|
86 struct gap
|
|
87 {
|
|
88 constexpr char to_char() const noexcept { return '-'; }
|
|
89 constexpr gap & assign_rank([[maybe_unused]] bool const i) noexcept { return *this; }
|
|
90 static constexpr size_t value_size{1};
|
|
91 };
|
|
92
|
|
93 struct dna4
|
|
94 {
|
|
95 constexpr char to_char() const noexcept { return value_to_char[_value]; }
|
|
96 constexpr dna4 & assign_rank(unsigned char const c) { _value = c; return *this; }
|
|
97 static constexpr size_t value_size{4};
|
|
98 static constexpr char value_to_char[value_size] { 'A', 'C', 'G', 'T' };
|
|
99 unsigned char _value;
|
|
100 };
|
|
101
|
|
102 struct dna5
|
|
103 {
|
|
104 constexpr char to_char() const noexcept { return value_to_char[_value]; }
|
|
105 constexpr dna5 & assign_rank(unsigned char const c) { _value = c; return *this; }
|
|
106 static constexpr size_t value_size{5};
|
|
107 static constexpr char value_to_char[value_size] { 'A', 'C', 'G', 'T', 'N' };
|
|
108 unsigned char _value;
|
|
109 };
|
|
110
|
|
111 constexpr array value_to_char1 = union_composition<dna4>::make_value_to_char();
|
|
112 static_assert(value_to_char1.size() == 4u);
|
|
113 static_assert(value_to_char1[0] == 'A');
|
|
114 static_assert(value_to_char1[1] == 'C');
|
|
115 static_assert(value_to_char1[2] == 'G');
|
|
116 static_assert(value_to_char1[3] == 'T');
|
|
117
|
|
118 constexpr array value_to_char2 = union_composition<dna4, gap>::make_value_to_char();
|
|
119 static_assert(value_to_char2.size() == 5u);
|
|
120 static_assert(value_to_char2[0] == 'A');
|
|
121 static_assert(value_to_char2[1] == 'C');
|
|
122 static_assert(value_to_char2[2] == 'G');
|
|
123 static_assert(value_to_char2[3] == 'T');
|
|
124 static_assert(value_to_char2[4] == '-');
|
|
125
|
|
126 constexpr array value_to_char3 = union_composition<dna4, gap, dna5>::make_value_to_char();
|
|
127 static_assert(value_to_char3.size() == 10u);
|
|
128 static_assert(value_to_char3[0] == 'A');
|
|
129 static_assert(value_to_char3[1] == 'C');
|
|
130 static_assert(value_to_char3[2] == 'G');
|
|
131 static_assert(value_to_char3[3] == 'T');
|
|
132 static_assert(value_to_char3[4] == '-');
|
|
133 static_assert(value_to_char3[5] == 'A');
|
|
134 static_assert(value_to_char3[6] == 'C');
|
|
135 static_assert(value_to_char3[7] == 'G');
|
|
136 static_assert(value_to_char3[8] == 'T');
|
|
137 static_assert(value_to_char3[9] == 'N');
|
|
138
|
|
139 constexpr array value_to_char4 = union_composition<dna5, gap, dna4>::make_value_to_char();
|
|
140 static_assert(value_to_char4.size() == 10u);
|
|
141 static_assert(value_to_char4[0] == 'A');
|
|
142 static_assert(value_to_char4[1] == 'C');
|
|
143 static_assert(value_to_char4[2] == 'G');
|
|
144 static_assert(value_to_char4[3] == 'T');
|
|
145 static_assert(value_to_char4[4] == 'N');
|
|
146 static_assert(value_to_char4[5] == '-');
|
|
147 static_assert(value_to_char4[6] == 'A');
|
|
148 static_assert(value_to_char4[7] == 'C');
|
|
149 static_assert(value_to_char4[8] == 'G');
|
|
150 static_assert(value_to_char4[9] == 'T');
|
|
151
|
|
152 constexpr array value_to_char5 = union_composition<gap, dna4, dna5>::make_value_to_char();
|
|
153 static_assert(value_to_char5.size() == 10u);
|
|
154 static_assert(value_to_char5[0] == '-');
|
|
155 static_assert(value_to_char5[1] == 'A');
|
|
156 static_assert(value_to_char5[2] == 'C');
|
|
157 static_assert(value_to_char5[3] == 'G');
|
|
158 static_assert(value_to_char5[4] == 'T');
|
|
159 static_assert(value_to_char5[5] == 'A');
|
|
160 static_assert(value_to_char5[6] == 'C');
|
|
161 static_assert(value_to_char5[7] == 'G');
|
|
162 static_assert(value_to_char5[8] == 'T');
|
|
163 static_assert(value_to_char5[9] == 'N');
|