00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00048 #ifndef WINSTL_INCL_WINSTL_CONVERSION_HPP_INT_TO_STRING
00049 #define WINSTL_INCL_WINSTL_CONVERSION_HPP_INT_TO_STRING
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_MAJOR 2
00053 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_MINOR 1
00054 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_REVISION 4
00055 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_EDIT 41
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00073 # include <winstl/winstl.h>
00074 #endif
00075 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_INT_TO_STRING
00076 # include <stlsoft/conversion/integer_to_string.hpp>
00077 #endif
00078 #ifndef WINSTL_INCL_WINSTL_SYNCH_HPP_THREAD_MUTEX
00079 # include <winstl/synch/thread_mutex.hpp>
00080 #endif
00081 #ifndef WINSTL_INCL_WINSTL_SYNCH_HPP_SPIN_MUTEX
00082 # include <winstl/synch/spin_mutex.hpp>
00083 #endif
00084 #ifndef STLSOFT_INCL_STLSOFT_SYNCH_HPP_LOCK_SCOPE
00085 # include <stlsoft/synch/lock_scope.hpp>
00086 #endif
00087 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_SAP_CAST
00088 # include <stlsoft/conversion/sap_cast.hpp>
00089 #endif
00090
00091
00092
00093
00094
00095 #ifndef _WINSTL_NO_NAMESPACE
00096 # if defined(_STLSOFT_NO_NAMESPACE) || \
00097 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00098
00099 namespace winstl
00100 {
00101 # else
00102
00103
00104 namespace stlsoft
00105 {
00106
00107 namespace winstl_project
00108 {
00109
00110 # endif
00111 #endif
00112
00113
00114
00115
00116
00117 #if defined(_WINSTL_INT_TO_STRING_USE_DECLSPECTHREAD_FOR_EXES)
00118 # if defined(_DLL) || \
00119 defined(__DLL__) || \
00120 defined(_WINDLL) || \
00121 defined(_USRDLL) || \
00122 defined(_AFXDLL)
00123 # pragma message("Using _WINSTL_INT_TO_STRING_USE_DECLSPECTHREAD_FOR_EXES when building DLLs will result in their not being loadable dynamically (via LoadLibrary())")
00124 # endif
00125 #endif
00126
00127
00128
00129
00130
00131 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00132
00133 #ifdef STLSOFT_CF_NAMESPACE_SUPPORT
00134 namespace int_to_string_tls
00135 {
00136 #endif
00137
00138
00139
00140
00141 struct thread_mx_
00142 : public thread_mutex
00143 {
00144 public:
00145 thread_mx_()
00146 {}
00147
00148 void* operator new(ws_size_t , void* p)
00149 {
00150 return p;
00151 }
00152
00153 #if !defined(STLSOFT_COMPILER_IS_BORLAND) && \
00154 ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
00155 _MSC_VER >= 1200)
00156 void operator delete(void* , void* )
00157 {}
00158 #endif
00159 void operator delete(void*)
00160 {}
00161 };
00162
00163
00164 template< ss_typename_param_k C
00165 , ws_size_t CCH
00166 >
00167 struct Slot
00168 {
00169 Slot(Slot* next)
00170 : next(next)
00171 {}
00172 ~Slot() stlsoft_throw_0()
00173 {
00174 delete next;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 void* operator new(ws_size_t cb)
00191 {
00192 return ::HeapAlloc(::GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, cb);
00193 }
00194 void operator delete(void* pv)
00195 {
00196 ::HeapFree(::GetProcessHeap(), 0, pv);
00197 }
00198
00199 C buff[CCH];
00200 Slot* next;
00201 };
00202
00203 template< ss_typename_param_k C
00204 , ws_size_t CCH
00205 >
00206 struct Key
00207 {
00208 typedef Slot<C, CCH> Slot;
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 Key()
00221 {
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 spin_mutex smx(&m_ctor);
00235 stlsoft_ns_qual(lock_scope)<spin_mutex, spin_mutex_lock_traits> lock(smx);
00236
00237 if(0 == m_init++)
00238 {
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 new (&mx()) thread_mx_();
00252
00253 m_index = ::TlsAlloc();
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 if(TLS_OUT_OF_INDEXES == m_index)
00264 {
00265 ::RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, 0);
00266 }
00267 }
00268 }
00269
00270 ~Key() stlsoft_throw_0()
00271 {
00272 if(0 == ::InterlockedDecrement((LPLONG)&m_init))
00273 {
00274
00275
00276 delete m_top;
00277
00278
00279 ::TlsFree(m_index);
00280
00281
00282 mx().~thread_mutex();
00283 }
00284 }
00285
00286 Slot* GetSlot()
00287 {
00288
00289 return sap_cast<Slot*>(::TlsGetValue(m_index));
00290 }
00291
00292 Slot* AllocSlot()
00293 {
00294 Slot* next;
00295
00296 {
00297 stlsoft_ns_qual(lock_scope)<thread_mutex, thread_mutex_lock_traits> lock(mx());
00298
00299 m_top = next = new Slot(m_top);
00300 }
00301
00302 ::TlsSetValue(m_index, next);
00303
00304 return next;
00305 }
00306
00307
00308 private:
00309 thread_mutex &mx()
00310 {
00311 return *static_cast<thread_mutex*>(static_cast<void*>(&m__mx.bytes[0]));
00312 }
00313
00314 private:
00315 #if 0
00316
00317 ws_dword_t m_index;
00318 Slot* m_top;
00319 thread_mutex m_mx;
00320 #else
00321
00322 ws_dword_t m_index;
00323 Slot* m_top;
00324 union
00325 {
00326 ws_byte_t bytes[sizeof(thread_mutex)];
00327 long double ld;
00328 } m__mx;
00329 ws_sint32_t m_init;
00330 ws_sint32_t m_ctor;
00331 #endif
00332 };
00333
00334 #ifdef STLSOFT_CF_NAMESPACE_SUPPORT
00335 }
00336 #endif
00337
00338
00339 template< ss_typename_param_k C
00340 , ws_size_t CCH
00341 >
00342 inline C* i2str_get_tss_buffer()
00343 {
00344 #if defined(_WINSTL_INT_TO_STRING_USE_DECLSPECTHREAD_FOR_EXES)
00345 __declspec(thread) static C s_buffer[CCH];
00346
00347 return s_buffer;
00348 #else
00349
00350 #ifdef STLSOFT_CF_NAMESPACE_SUPPORT
00351 typedef int_to_string_tls::Key<C, CCH> Key;
00352 typedef int_to_string_tls::Slot<C, CCH> Slot;
00353 #else
00354 typedef Key<C, CCH> Key;
00355 typedef Slot<C, CCH> Slot;
00356 #endif
00357
00358 static Key s_index;
00359 Slot* slot = s_index.GetSlot();
00360
00361 if(NULL == slot)
00362 {
00363 slot = s_index.AllocSlot();
00364 }
00365
00366 return slot->buff;
00367 #endif
00368 }
00369
00370 #endif
00371
00388 template<ss_typename_param_k C>
00389 inline C const* int_to_string(ws_sint8_t value)
00390 {
00391 const ws_size_t CCH = 21;
00392 C* buffer = i2str_get_tss_buffer<C, CCH>();
00393
00394 return stlsoft::integer_to_string(buffer, CCH, value);
00395 }
00396
00413 template<ss_typename_param_k C>
00414 inline C const* int_to_string(ws_uint8_t value)
00415 {
00416 const ws_size_t CCH = 21;
00417 C* buffer = i2str_get_tss_buffer<C, CCH>();
00418
00419 return stlsoft::integer_to_string(buffer, CCH, value);
00420 }
00421
00438 template<ss_typename_param_k C>
00439 inline C const* int_to_string(ws_sint16_t value)
00440 {
00441 const ws_size_t CCH = 21;
00442 C* buffer = i2str_get_tss_buffer<C, CCH>();
00443
00444 return stlsoft::integer_to_string(buffer, CCH, value);
00445 }
00446
00463 template<ss_typename_param_k C>
00464 inline C const* int_to_string(ws_uint16_t value)
00465 {
00466 const ws_size_t CCH = 21;
00467 C* buffer = i2str_get_tss_buffer<C, CCH>();
00468
00469 return stlsoft::integer_to_string(buffer, CCH, value);
00470 }
00471
00488 template<ss_typename_param_k C>
00489 inline C const* int_to_string(ws_sint32_t value)
00490 {
00491 const ws_size_t CCH = 21;
00492 C* buffer = i2str_get_tss_buffer<C, CCH>();
00493
00494 return stlsoft::integer_to_string(buffer, CCH, value);
00495 }
00496
00513 template<ss_typename_param_k C>
00514 inline C const* int_to_string(ws_uint32_t value)
00515 {
00516 const ws_size_t CCH = 21;
00517 C* buffer = i2str_get_tss_buffer<C, CCH>();
00518
00519 return stlsoft::integer_to_string(buffer, CCH, value);
00520 }
00521
00538 template<ss_typename_param_k C>
00539 inline C const* int_to_string(ws_sint64_t const& value)
00540 {
00541 const ws_size_t CCH = 21;
00542 C* buffer = i2str_get_tss_buffer<C, CCH>();
00543
00544 return stlsoft::integer_to_string(buffer, CCH, value);
00545 }
00546
00563 template<ss_typename_param_k C>
00564 inline C const* int_to_string(ws_uint64_t const& value)
00565 {
00566 const ws_size_t CCH = 21;
00567 C* buffer = i2str_get_tss_buffer<C, CCH>();
00568
00569 return stlsoft::integer_to_string(buffer, CCH, value);
00570 }
00571
00572
00573 #ifdef STLSOFT_CF_INT_DISTINCT_INT_TYPE
00574
00575 template<ss_typename_param_k C>
00576 inline C const* int_to_string(int const& value)
00577 {
00578 const ws_size_t CCH = 21;
00579 C* buffer = i2str_get_tss_buffer<C, CCH>();
00580
00581 return stlsoft::integer_to_string(buffer, CCH, value);
00582 }
00583
00584 template<ss_typename_param_k C>
00585 inline C const* int_to_string(unsigned int const& value)
00586 {
00587 const ws_size_t CCH = 21;
00588 C* buffer = i2str_get_tss_buffer<C, CCH>();
00589
00590 return stlsoft::integer_to_string(buffer, CCH, value);
00591 }
00592
00593 #endif
00594
00595 #ifdef STLSOFT_CF_LONG_DISTINCT_INT_TYPE
00596
00597 template<ss_typename_param_k C>
00598 inline C const* int_to_string(long const& value)
00599 {
00600 const ws_size_t CCH = 21;
00601 C* buffer = i2str_get_tss_buffer<C, CCH>();
00602
00603 return stlsoft::integer_to_string(buffer, CCH, value);
00604 }
00605
00606 template<ss_typename_param_k C>
00607 inline C const* int_to_string(unsigned long const& value)
00608 {
00609 const ws_size_t CCH = 21;
00610 C* buffer = i2str_get_tss_buffer<C, CCH>();
00611
00612 return stlsoft::integer_to_string(buffer, CCH, value);
00613 }
00614
00615 #endif
00616
00618
00619
00620 #ifdef STLSOFT_UNITTEST
00621 # include "./unittest/int_to_string_unittest_.h"
00622 #endif
00623
00624
00625
00626 #ifndef _WINSTL_NO_NAMESPACE
00627 # if defined(_STLSOFT_NO_NAMESPACE) || \
00628 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00629 }
00630 # else
00631 }
00632 }
00633 # endif
00634 #endif
00635
00636
00637
00638 #endif
00639
00640