1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
10 #define _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
12 #include <__cxx03/__algorithm/equal.h>
13 #include <__cxx03/__algorithm/min.h>
14 #include <__cxx03/__config>
15 #include <__cxx03/__random/is_seed_sequence.h>
16 #include <__cxx03/cstddef>
17 #include <__cxx03/cstdint>
18 #include <__cxx03/iosfwd>
19 #include <__cxx03/limits>
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 # pragma GCC system_header
26 #include <__cxx03/__undef_macros>
28 _LIBCPP_BEGIN_NAMESPACE_STD
30 template <class _UIntType
,
44 class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine
;
46 template <class _UInt
,
60 _LIBCPP_HIDE_FROM_ABI
bool
61 operator==(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
62 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
64 template <class _UInt
,
78 _LIBCPP_HIDE_FROM_ABI
bool
79 operator!=(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
80 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
82 template <class _CharT
,
98 _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
99 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
100 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
102 template <class _CharT
,
118 _LIBCPP_HIDE_FROM_ABI basic_istream
<_CharT
, _Traits
>&
119 operator>>(basic_istream
<_CharT
, _Traits
>& __is
,
120 mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
122 template <class _UIntType
,
136 class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine
{
139 typedef _UIntType result_type
;
142 result_type __x_
[__n
];
145 static_assert(0 < __m
, "mersenne_twister_engine invalid parameters");
146 static_assert(__m
<= __n
, "mersenne_twister_engine invalid parameters");
147 static _LIBCPP_CONSTEXPR
const result_type _Dt
= numeric_limits
<result_type
>::digits
;
148 static_assert(__w
<= _Dt
, "mersenne_twister_engine invalid parameters");
149 static_assert(2 <= __w
, "mersenne_twister_engine invalid parameters");
150 static_assert(__r
<= __w
, "mersenne_twister_engine invalid parameters");
151 static_assert(__u
<= __w
, "mersenne_twister_engine invalid parameters");
152 static_assert(__s
<= __w
, "mersenne_twister_engine invalid parameters");
153 static_assert(__t
<= __w
, "mersenne_twister_engine invalid parameters");
154 static_assert(__l
<= __w
, "mersenne_twister_engine invalid parameters");
157 static _LIBCPP_CONSTEXPR
const result_type _Min
= 0;
158 static _LIBCPP_CONSTEXPR
const result_type _Max
=
159 __w
== _Dt
? result_type(~0) : (result_type(1) << __w
) - result_type(1);
160 static_assert(_Min
< _Max
, "mersenne_twister_engine invalid parameters");
161 static_assert(__a
<= _Max
, "mersenne_twister_engine invalid parameters");
162 static_assert(__b
<= _Max
, "mersenne_twister_engine invalid parameters");
163 static_assert(__c
<= _Max
, "mersenne_twister_engine invalid parameters");
164 static_assert(__d
<= _Max
, "mersenne_twister_engine invalid parameters");
165 static_assert(__f
<= _Max
, "mersenne_twister_engine invalid parameters");
167 // engine characteristics
168 static _LIBCPP_CONSTEXPR
const size_t word_size
= __w
;
169 static _LIBCPP_CONSTEXPR
const size_t state_size
= __n
;
170 static _LIBCPP_CONSTEXPR
const size_t shift_size
= __m
;
171 static _LIBCPP_CONSTEXPR
const size_t mask_bits
= __r
;
172 static _LIBCPP_CONSTEXPR
const result_type xor_mask
= __a
;
173 static _LIBCPP_CONSTEXPR
const size_t tempering_u
= __u
;
174 static _LIBCPP_CONSTEXPR
const result_type tempering_d
= __d
;
175 static _LIBCPP_CONSTEXPR
const size_t tempering_s
= __s
;
176 static _LIBCPP_CONSTEXPR
const result_type tempering_b
= __b
;
177 static _LIBCPP_CONSTEXPR
const size_t tempering_t
= __t
;
178 static _LIBCPP_CONSTEXPR
const result_type tempering_c
= __c
;
179 static _LIBCPP_CONSTEXPR
const size_t tempering_l
= __l
;
180 static _LIBCPP_CONSTEXPR
const result_type initialization_multiplier
= __f
;
181 _LIBCPP_HIDE_FROM_ABI
static _LIBCPP_CONSTEXPR result_type
min() { return _Min
; }
182 _LIBCPP_HIDE_FROM_ABI
static _LIBCPP_CONSTEXPR result_type
max() { return _Max
; }
183 static _LIBCPP_CONSTEXPR
const result_type default_seed
= 5489u;
185 // constructors and seeding functions
186 #ifndef _LIBCPP_CXX03_LANG
187 _LIBCPP_HIDE_FROM_ABI
mersenne_twister_engine() : mersenne_twister_engine(default_seed
) {}
188 _LIBCPP_HIDE_FROM_ABI
explicit mersenne_twister_engine(result_type __sd
) { seed(__sd
); }
190 _LIBCPP_HIDE_FROM_ABI
explicit mersenne_twister_engine(result_type __sd
= default_seed
) { seed(__sd
); }
192 template <class _Sseq
, __enable_if_t
<__is_seed_sequence
<_Sseq
, mersenne_twister_engine
>::value
, int> = 0>
193 _LIBCPP_HIDE_FROM_ABI
explicit mersenne_twister_engine(_Sseq
& __q
) {
196 _LIBCPP_HIDE_FROM_ABI
void seed(result_type __sd
= default_seed
);
197 template <class _Sseq
, __enable_if_t
<__is_seed_sequence
<_Sseq
, mersenne_twister_engine
>::value
, int> = 0>
198 _LIBCPP_HIDE_FROM_ABI
void seed(_Sseq
& __q
) {
199 __seed(__q
, integral_constant
<unsigned, 1 + (__w
- 1) / 32>());
202 // generating functions
203 _LIBCPP_HIDE_FROM_ABI result_type
operator()();
204 _LIBCPP_HIDE_FROM_ABI
void discard(unsigned long long __z
) {
209 template <class _UInt
,
223 friend bool operator==(
224 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
225 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
227 template <class _UInt
,
241 friend bool operator!=(
242 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
243 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
245 template <class _CharT
,
261 friend basic_ostream
<_CharT
, _Traits
>& operator<<(
262 basic_ostream
<_CharT
, _Traits
>& __os
,
263 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
265 template <class _CharT
,
281 friend basic_istream
<_CharT
, _Traits
>&
282 operator>>(basic_istream
<_CharT
, _Traits
>& __is
,
283 mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
286 template <class _Sseq
>
287 _LIBCPP_HIDE_FROM_ABI
void __seed(_Sseq
& __q
, integral_constant
<unsigned, 1>);
288 template <class _Sseq
>
289 _LIBCPP_HIDE_FROM_ABI
void __seed(_Sseq
& __q
, integral_constant
<unsigned, 2>);
291 template <size_t __count
,
292 __enable_if_t
<__count
< __w
, int> = 0> _LIBCPP_HIDE_FROM_ABI
static result_type
__lshift(result_type __x
) {
293 return (__x
<< __count
) & _Max
;
296 template <size_t __count
, __enable_if_t
<(__count
>= __w
), int> = 0>
297 _LIBCPP_HIDE_FROM_ABI
static result_type
__lshift(result_type
) {
298 return result_type(0);
301 template <size_t __count
,
302 __enable_if_t
<__count
< _Dt
, int> = 0> _LIBCPP_HIDE_FROM_ABI
static result_type
__rshift(result_type __x
) {
303 return __x
>> __count
;
306 template <size_t __count
, __enable_if_t
<(__count
>= _Dt
), int> = 0>
307 _LIBCPP_HIDE_FROM_ABI
static result_type
__rshift(result_type
) {
308 return result_type(0);
312 template <class _UIntType
,
326 _LIBCPP_CONSTEXPR
const size_t
327 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::word_size
;
329 template <class _UIntType
,
343 _LIBCPP_CONSTEXPR
const size_t
344 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::state_size
;
346 template <class _UIntType
,
360 _LIBCPP_CONSTEXPR
const size_t
361 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::shift_size
;
363 template <class _UIntType
,
377 _LIBCPP_CONSTEXPR
const size_t
378 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::mask_bits
;
380 template <class _UIntType
,
394 _LIBCPP_CONSTEXPR
const typename mersenne_twister_engine
<
409 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::xor_mask
;
411 template <class _UIntType
,
425 _LIBCPP_CONSTEXPR
const size_t
426 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::tempering_u
;
428 template <class _UIntType
,
442 _LIBCPP_CONSTEXPR
const typename mersenne_twister_engine
<
457 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::tempering_d
;
459 template <class _UIntType
,
473 _LIBCPP_CONSTEXPR
const size_t
474 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::tempering_s
;
476 template <class _UIntType
,
490 _LIBCPP_CONSTEXPR
const typename mersenne_twister_engine
<
505 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::tempering_b
;
507 template <class _UIntType
,
521 _LIBCPP_CONSTEXPR
const size_t
522 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::tempering_t
;
524 template <class _UIntType
,
538 _LIBCPP_CONSTEXPR
const typename mersenne_twister_engine
<
553 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::tempering_c
;
555 template <class _UIntType
,
569 _LIBCPP_CONSTEXPR
const size_t
570 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::tempering_l
;
572 template <class _UIntType
,
586 _LIBCPP_CONSTEXPR
const typename mersenne_twister_engine
<
601 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::
602 initialization_multiplier
;
604 template <class _UIntType
,
618 _LIBCPP_CONSTEXPR
const typename mersenne_twister_engine
<
633 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::default_seed
;
635 template <class _UIntType
,
649 void mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::seed(
650 result_type __sd
) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{ // __w >= 2
651 __x_
[0] = __sd
& _Max
;
652 for (size_t __i
= 1; __i
< __n
; ++__i
)
653 __x_
[__i
] = (__f
* (__x_
[__i
- 1] ^ __rshift
<__w
- 2>(__x_
[__i
- 1])) + __i
) & _Max
;
657 template <class _UIntType
,
671 template <class _Sseq
>
672 void mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::__seed(
673 _Sseq
& __q
, integral_constant
<unsigned, 1>) {
674 const unsigned __k
= 1;
675 uint32_t __ar
[__n
* __k
];
676 __q
.generate(__ar
, __ar
+ __n
* __k
);
677 for (size_t __i
= 0; __i
< __n
; ++__i
)
678 __x_
[__i
] = static_cast<result_type
>(__ar
[__i
] & _Max
);
679 const result_type __mask
= __r
== _Dt
? result_type(~0) : (result_type(1) << __r
) - result_type(1);
681 if ((__x_
[0] & ~__mask
) == 0) {
682 for (size_t __i
= 1; __i
< __n
; ++__i
)
685 __x_
[0] = result_type(1) << (__w
- 1);
689 template <class _UIntType
,
703 template <class _Sseq
>
704 void mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::__seed(
705 _Sseq
& __q
, integral_constant
<unsigned, 2>) {
706 const unsigned __k
= 2;
707 uint32_t __ar
[__n
* __k
];
708 __q
.generate(__ar
, __ar
+ __n
* __k
);
709 for (size_t __i
= 0; __i
< __n
; ++__i
)
710 __x_
[__i
] = static_cast<result_type
>((__ar
[2 * __i
] + ((uint64_t)__ar
[2 * __i
+ 1] << 32)) & _Max
);
711 const result_type __mask
= __r
== _Dt
? result_type(~0) : (result_type(1) << __r
) - result_type(1);
713 if ((__x_
[0] & ~__mask
) == 0) {
714 for (size_t __i
= 1; __i
< __n
; ++__i
)
717 __x_
[0] = result_type(1) << (__w
- 1);
721 template <class _UIntType
,
736 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::operator()() {
737 const size_t __j
= (__i_
+ 1) % __n
;
738 const result_type __mask
= __r
== _Dt
? result_type(~0) : (result_type(1) << __r
) - result_type(1);
739 const result_type __yp
= (__x_
[__i_
] & ~__mask
) | (__x_
[__j
] & __mask
);
740 const size_t __k
= (__i_
+ __m
) % __n
;
741 __x_
[__i_
] = __x_
[__k
] ^ __rshift
<1>(__yp
) ^ (__a
* (__yp
& 1));
742 result_type __z
= __x_
[__i_
] ^ (__rshift
<__u
>(__x_
[__i_
]) & __d
);
744 __z
^= __lshift
<__s
>(__z
) & __b
;
745 __z
^= __lshift
<__t
>(__z
) & __c
;
746 return __z
^ __rshift
<__l
>(__z
);
749 template <class _UInt
,
763 _LIBCPP_HIDE_FROM_ABI
bool
764 operator==(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
765 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
) {
766 if (__x
.__i_
== __y
.__i_
)
767 return std::equal(__x
.__x_
, __x
.__x_
+ _Np
, __y
.__x_
);
768 if (__x
.__i_
== 0 || __y
.__i_
== 0) {
769 size_t __j
= std::min(_Np
- __x
.__i_
, _Np
- __y
.__i_
);
770 if (!std::equal(__x
.__x_
+ __x
.__i_
, __x
.__x_
+ __x
.__i_
+ __j
, __y
.__x_
+ __y
.__i_
))
773 return std::equal(__x
.__x_
+ __j
, __x
.__x_
+ _Np
, __y
.__x_
);
774 return std::equal(__x
.__x_
, __x
.__x_
+ (_Np
- __j
), __y
.__x_
+ __j
);
776 if (__x
.__i_
< __y
.__i_
) {
777 size_t __j
= _Np
- __y
.__i_
;
778 if (!std::equal(__x
.__x_
+ __x
.__i_
, __x
.__x_
+ (__x
.__i_
+ __j
), __y
.__x_
+ __y
.__i_
))
780 if (!std::equal(__x
.__x_
+ (__x
.__i_
+ __j
), __x
.__x_
+ _Np
, __y
.__x_
))
782 return std::equal(__x
.__x_
, __x
.__x_
+ __x
.__i_
, __y
.__x_
+ (_Np
- (__x
.__i_
+ __j
)));
784 size_t __j
= _Np
- __x
.__i_
;
785 if (!std::equal(__y
.__x_
+ __y
.__i_
, __y
.__x_
+ (__y
.__i_
+ __j
), __x
.__x_
+ __x
.__i_
))
787 if (!std::equal(__y
.__x_
+ (__y
.__i_
+ __j
), __y
.__x_
+ _Np
, __x
.__x_
))
789 return std::equal(__y
.__x_
, __y
.__x_
+ __y
.__i_
, __x
.__x_
+ (_Np
- (__y
.__i_
+ __j
)));
792 template <class _UInt
,
806 inline _LIBCPP_HIDE_FROM_ABI
bool
807 operator!=(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
808 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
) {
809 return !(__x
== __y
);
812 template <class _CharT
,
828 _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
829 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
830 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
) {
831 __save_flags
<_CharT
, _Traits
> __lx(__os
);
832 typedef basic_ostream
<_CharT
, _Traits
> _Ostream
;
833 __os
.flags(_Ostream::dec
| _Ostream::left
);
834 _CharT __sp
= __os
.widen(' ');
836 __os
<< __x
.__x_
[__x
.__i_
];
837 for (size_t __j
= __x
.__i_
+ 1; __j
< _Np
; ++__j
)
838 __os
<< __sp
<< __x
.__x_
[__j
];
839 for (size_t __j
= 0; __j
< __x
.__i_
; ++__j
)
840 __os
<< __sp
<< __x
.__x_
[__j
];
844 template <class _CharT
,
860 _LIBCPP_HIDE_FROM_ABI basic_istream
<_CharT
, _Traits
>&
861 operator>>(basic_istream
<_CharT
, _Traits
>& __is
,
862 mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
) {
863 __save_flags
<_CharT
, _Traits
> __lx(__is
);
864 typedef basic_istream
<_CharT
, _Traits
> _Istream
;
865 __is
.flags(_Istream::dec
| _Istream::skipws
);
867 for (size_t __i
= 0; __i
< _Np
; ++__i
)
870 for (size_t __i
= 0; __i
< _Np
; ++__i
)
871 __x
.__x_
[__i
] = __t
[__i
];
877 typedef mersenne_twister_engine
<
893 typedef mersenne_twister_engine
<
899 0xb5026f5aa96619e9ULL
,
901 0x5555555555555555ULL
,
903 0x71d67fffeda60000ULL
,
905 0xfff7eee000000000ULL
,
907 6364136223846793005ULL>
910 _LIBCPP_END_NAMESPACE_STD
914 #endif // _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H