26
26
#include " exe_string.hpp" // exe_string, exceptions
27
27
#include " intrin.hpp" // bitpopcnt
28
28
29
+ template <size_t N>
30
+ struct exe_bitset_to_string_helper ;
31
+
29
32
#pragma pack(push, 8)
30
33
// / @brief Visual C++ 6.0 std::bitset implementation used by heroes3.exe
31
34
// / @tparam _N number of bits to store
@@ -111,25 +114,47 @@ class exe_bitset
111
114
_A[i / _Bitsperword] |= (_Ty)1 << i % _Bitsperword;
112
115
}
113
116
114
- template <typename _StringType>
115
- exe_bitset (const _StringType& _S,
116
- size_t _P = 0 ,
117
- size_t _L = _StringType::npos,
118
- typename _StringType::value_type _zero = typename _StringType::value_type (' 0' ),
119
- typename _StringType::value_type _one = typename _StringType::value_type(' 1' ) )
117
+ template <class T , class CharTraits , class Allocator >
118
+ exe_bitset (const std::basic_string<T, CharTraits, Allocator>& str,
119
+ size_t pos = 0 ,
120
+ size_t n = std::basic_string<T, CharTraits, Allocator>::npos,
121
+ typename std::basic_string<T, CharTraits, Allocator>::value_type zero = typename std::basic_string<T, CharTraits, Allocator>::value_type(' 0' ),
122
+ typename std::basic_string<T, CharTraits, Allocator>::value_type one = typename std::basic_string<T, CharTraits, Allocator>::value_type(' 1' ) )
123
+ {
124
+ size_t _I;
125
+ if (str.size () < pos)
126
+ _Xran ();
127
+ if (str.size () - pos < n)
128
+ n = str.size () - pos;
129
+ if (_N < n)
130
+ n = _N;
131
+ _Tidy (), pos += n;
132
+ for (_I = 0 ; _I < n; ++_I)
133
+ if (str[--pos] == one)
134
+ set (_I);
135
+ else if (str[pos] != zero)
136
+ _Xinv ();
137
+ }
138
+
139
+ template <class T , class CharTraits , class Allocator >
140
+ exe_bitset (const exe_basic_string<T, CharTraits, Allocator>& str,
141
+ size_t pos = 0 ,
142
+ size_t n = exe_basic_string<T, CharTraits, Allocator>::npos,
143
+ typename exe_basic_string<T, CharTraits, Allocator>::value_type zero = typename exe_basic_string<T, CharTraits, Allocator>::value_type(' 0' ),
144
+ typename exe_basic_string<T, CharTraits, Allocator>::value_type one = typename exe_basic_string<T, CharTraits, Allocator>::value_type(' 1' ) )
120
145
{
121
146
size_t _I;
122
- if (_S .size () < _P )
147
+ if (str .size () < pos )
123
148
_Xran ();
124
- if (_S .size () - _P < _L )
125
- _L = _S .size () - _P ;
126
- if (_N < _L )
127
- _L = _N;
128
- _Tidy (), _P += _L ;
129
- for (_I = 0 ; _I < _L ; ++_I)
130
- if (_S [--_P ] == _one )
149
+ if (str .size () - pos < n )
150
+ n = str .size () - pos ;
151
+ if (_N < n )
152
+ n = _N;
153
+ _Tidy (), pos += n ;
154
+ for (_I = 0 ; _I < n ; ++_I)
155
+ if (str [--pos ] == one )
131
156
set (_I);
132
- else if (_S[_P ] != _zero )
157
+ else if (str[pos ] != zero )
133
158
_Xinv ();
134
159
}
135
160
@@ -258,16 +283,31 @@ class exe_bitset
258
283
return (_V);
259
284
}
260
285
261
- exe_string to_string (char _zero = ' 0' , char _one = ' 1' ) const
262
- {
263
- exe_string _S (_N, _zero);
264
- // use const_char and c_str explicitly to avoid invoking exe_string::_Freeze
265
- // as an optimization
266
- char * _Data = const_cast <char *>(_S.c_str ());
267
- for (size_t i = _N; 0 < i; ++_Data )
268
- *_Data = _At (--i) ? _one : _zero;
269
- return (_S);
270
- }
286
+ #if NH3API_STD_DEFAULT_TEMPLATE_ARGUMENTS
287
+ template <typename CharT = char , typename CharTraits = std::char_traits<CharT>, typename Allocator = exe_allocator<CharT>>
288
+ exe_basic_string<CharT, CharTraits, Allocator>
289
+ to_string (CharT zero = CharT(' 0' ), CharT one = CharT(' 1' )) const
290
+ { return _To_exe_string<CharT, CharTraits, Allocator>(); }
291
+
292
+ #else
293
+ template <typename CharT, typename CharTraits, typename Allocator>
294
+ exe_basic_string<CharT, CharTraits, Allocator>
295
+ to_string (CharT zero = CharT(' 0' ), CharT one = CharT(' 1' )) const
296
+ { return _To_exe_string<CharT, CharTraits, Allocator>(); }
297
+
298
+ template <typename CharT, typename CharTraits>
299
+ exe_basic_string<CharT, CharTraits>
300
+ to_string (CharT zero = CharT(' 0' ), CharT one = CharT(' 1' )) const
301
+ { return _To_exe_string<CharT, CharTraits>(); }
302
+
303
+ template <typename CharT>
304
+ exe_basic_string<CharT>
305
+ to_string (CharT zero = CharT(' 0' ), CharT one = CharT(' 1' )) const
306
+ { return _To_exe_string<CharT>(); }
307
+
308
+ exe_string to_string (char zero = ' 0' , char one = ' 1' ) const
309
+ { return _To_exe_string<char >(zero, one); }
310
+ #endif
271
311
272
312
/*
273
313
NH3API_CONSTEXPR size_t count() const NH3API_NOEXCEPT
@@ -391,6 +431,63 @@ class exe_bitset
391
431
friend std::hash<this_type>;
392
432
#endif
393
433
434
+ template <class CharT
435
+ #if NH3API_STD_DEFAULT_TEMPLATE_ARGUMENTS
436
+ , class CharTraits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>
437
+ #endif
438
+ > NH3API_FORCEINLINE
439
+ std::basic_string<CharT,
440
+ #if NH3API_STD_DEFAULT_TEMPLATE_ARGUMENTS
441
+ CharTraits, Allocator
442
+ #else
443
+ std::char_traits<CharT>, std::allocator<CharT>
444
+ #endif
445
+ > _To_std_string (CharT zero = CharT(' 0' ), CharT one = CharT(' 1' )) const
446
+ {
447
+ std::basic_string<CharT,
448
+ #if NH3API_STD_DEFAULT_TEMPLATE_ARGUMENTS
449
+ CharTraits, Allocator
450
+ #else
451
+ std::char_traits<CharT>, std::allocator<CharT>
452
+ #endif
453
+ >
454
+ result (_N, zero);
455
+ CharT* dst = const_cast <CharT*>(result.c_str ());
456
+ for (size_t i = _N; 0 < i; ++dst )
457
+ *dst = _At (--i) ? one : zero;
458
+ return result;
459
+ }
460
+
461
+ template <class CharT
462
+ #if NH3API_STD_DEFAULT_TEMPLATE_ARGUMENTS
463
+ , class CharTraits = std::char_traits<CharT>, class Allocator = exe_allocator<CharT>
464
+ #endif
465
+ > NH3API_FORCEINLINE
466
+ exe_basic_string<CharT,
467
+ #if NH3API_STD_DEFAULT_TEMPLATE_ARGUMENTS
468
+ CharTraits, Allocator
469
+ #else
470
+ std::char_traits<CharT>, exe_allocator<CharT>
471
+ #endif
472
+ > _To_exe_string (CharT zero = CharT(' 0' ), CharT one = CharT(' 1' )) const
473
+ {
474
+ exe_basic_string<CharT,
475
+ #if NH3API_STD_DEFAULT_TEMPLATE_ARGUMENTS
476
+ CharTraits, Allocator
477
+ #else
478
+ std::char_traits<CharT>, exe_allocator<CharT>
479
+ #endif
480
+ >
481
+ result (_N, zero);
482
+ // use const_char and c_str explicitly to avoid invoking exe_string::_Freeze
483
+ // as an optimization
484
+ CharT* dst = const_cast <CharT*>(result.c_str ());
485
+ for (size_t i = _N; 0 < i; ++dst )
486
+ *dst = _At (--i) ? one : zero;
487
+ return result;
488
+ }
489
+ friend exe_bitset_to_string_helper<_N>;
490
+
394
491
// bit array
395
492
_Ty _A[_Words + 1 ];
396
493
};
@@ -407,4 +504,32 @@ class std::hash< exe_bitset<N> >
407
504
return arg._Hash_code ();
408
505
}
409
506
};
410
- #endif
507
+ #endif
508
+
509
+ template <size_t N>
510
+ struct exe_bitset_to_string_helper
511
+ {
512
+ template <typename StringT> NH3API_FORCEINLINE
513
+ static StringT to_std_basic_string (const exe_bitset<N>& arg, char zero = ' 0' , char one = ' 1' )
514
+ { return arg._To_std_string (zero, one); }
515
+
516
+ template <typename StringT> NH3API_FORCEINLINE
517
+ static StringT to_exe_basic_string (const exe_bitset<N>& arg, char zero = ' 0' , char one = ' 1' )
518
+ { return arg._To_exe_string (zero, one); }
519
+ };
520
+
521
+ template <size_t N>
522
+ std::string to_std_string (const exe_bitset<N>& arg, char zero = ' 0' , char one = ' 1' )
523
+ { return exe_bitset_to_string_helper<N>::template to_std_basic_string<std::string>(arg, zero, one); }
524
+
525
+ template <size_t N>
526
+ std::wstring to_std_wstring (const exe_bitset<N>& arg, wchar_t zero = L' 0' , wchar_t one = L' 1' )
527
+ { return exe_bitset_to_string_helper<N>::template to_std_basic_string<std::wstring>(arg, zero, one); }
528
+
529
+ template <size_t N>
530
+ exe_string to_exe_string (const exe_bitset<N>& arg, char zero = ' 0' , char one = ' 1' )
531
+ { return exe_bitset_to_string_helper<N>::template to_exe_basic_string<exe_string>(arg, zero, one); }
532
+
533
+ template <size_t N>
534
+ exe_wstring to_exe_wstring (const exe_bitset<N>& arg, wchar_t zero = L' 0' , wchar_t one = L' 1' )
535
+ { return exe_bitset_to_string_helper<N>::template to_exe_basic_string<exe_wstring>(arg, zero, one); }
0 commit comments