Skip to content

Commit f1f707b

Browse files
committed
Implement string conversions for exe_bitset
1 parent 5fc63a2 commit f1f707b

File tree

1 file changed

+151
-26
lines changed

1 file changed

+151
-26
lines changed

nh3api/core/nh3api_std/exe_bitset.hpp

Lines changed: 151 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include "exe_string.hpp" // exe_string, exceptions
2727
#include "intrin.hpp" // bitpopcnt
2828

29+
template<size_t N>
30+
struct exe_bitset_to_string_helper;
31+
2932
#pragma pack(push, 8)
3033
/// @brief Visual C++ 6.0 std::bitset implementation used by heroes3.exe
3134
/// @tparam _N number of bits to store
@@ -111,25 +114,47 @@ class exe_bitset
111114
_A[i / _Bitsperword] |= (_Ty)1 << i % _Bitsperword;
112115
}
113116

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') )
120145
{
121146
size_t _I;
122-
if (_S.size() < _P)
147+
if (str.size() < pos)
123148
_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)
131156
set(_I);
132-
else if (_S[_P] != _zero)
157+
else if (str[pos] != zero)
133158
_Xinv();
134159
}
135160

@@ -258,16 +283,31 @@ class exe_bitset
258283
return (_V);
259284
}
260285

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
271311

272312
/*
273313
NH3API_CONSTEXPR size_t count() const NH3API_NOEXCEPT
@@ -391,6 +431,63 @@ class exe_bitset
391431
friend std::hash<this_type>;
392432
#endif
393433

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+
394491
// bit array
395492
_Ty _A[_Words + 1];
396493
};
@@ -407,4 +504,32 @@ class std::hash< exe_bitset<N> >
407504
return arg._Hash_code();
408505
}
409506
};
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

Comments
 (0)