/// Destructor ~cstring_range() stlsoft_throw_0() { // This is a constraint to ensure that this template is not used // for any non-character types. STLSOFT_STATIC_ASSERT(0 != is_integral_type<value_type>::value); STLSOFT_STATIC_ASSERT(0 == is_numeric_type<value_type>::value); STLSOFT_STATIC_ASSERT(0 == is_bool_type<value_type>::value); }
static pantheios::sint64_t pan_get_tid_() { #if defined(PLATFORMSTL_OS_IS_UNIX) # ifdef PANTHEIOS_MT union { pantheios::sint64_t u64; pthread_t self; } u; STLSOFT_STATIC_ASSERT(sizeof(::pthread_self()) <= sizeof(pantheios::sint64_t)); u.u64 = 0; u.self = ::pthread_self(); return u.u64; # else /* ? PANTHEIOS_MT */ return 1; # endif /* PANTHEIOS_MT */ #elif defined(PLATFORMSTL_OS_IS_WINDOWS) return static_cast<pantheios::sint64_t>(::GetCurrentThreadId()); #else /* ? OS */ # error Not discriminated for platforms other than UNIX and Windows #endif /* OS */ }
inline bool truncation_test_helper_runtime_test(FROM from, no_type, TO ) // The use of the dummy variable is to fix a bug with VC++ 5-7.0 { #ifdef _DEBUG # if defined(STLSOFT_COMPILER_IS_MSVC) int const flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); _CrtSetDbgFlag(flags & ~(_CRTDBG_ALLOC_MEM_DF)); # endif /* VC++ */ char const* TO_ = typeid(TO).name(); char const* FROM_ = typeid(FROM).name(); STLSOFT_SUPPRESS_UNUSED(TO_); STLSOFT_SUPPRESS_UNUSED(FROM_); # if defined(STLSOFT_COMPILER_IS_MSVC) _CrtSetDbgFlag(flags); # endif /* VC++ */ #endif /* _DEBUG */ // Types are different // Next test for same sign enum { TO_is_signed = is_signed_type<TO>::value }; enum { FROM_is_signed = is_signed_type<FROM>::value }; enum { types_have_same_sign = int(TO_is_signed) == int(FROM_is_signed) }; const ss_size_t sizeofFROM = sizeof(FROM); const ss_size_t sizeofTO = sizeof(TO); STLSOFT_STATIC_ASSERT(sizeofFROM >= sizeofTO || FROM_is_signed); typedef ss_typename_param_k value_to_yesno_type<types_have_same_sign>::type same_sign_yesno_t; return truncation_test_helper_runtime_test_same_sign<TO>(from, same_sign_yesno_t(), TO()); }
int be_fprintf_Context::rawLogEntry( int severity4 , int /* severityX */ , const pan_slice_t (&ar)[rawLogArrayDimension] , size_t /* cchTotal */ ) { PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_INTERNAL(severity4 >= 0, "severity must be >= 0"); PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_INTERNAL(severity4 < 16, "severity must be < 16"); // select the stream: stdout for debug/info/notice; stderr for everything else FILE* const stm = deduce_stm_(severity4); const PAN_CHAR_T fmt[] = PANTHEIOS_LITERAL_STRING("%.*s%.*s%.*s%.*s%.*s%.*s%.*s%.*s%.*s%.*s\n"); STLSOFT_STATIC_ASSERT(4 * rawLogArrayDimension + 2 == STLSOFT_NUM_ELEMENTS(fmt)); // fprintf the array of slices #define PAN_BE_GET_SLICE_4_PRINTF(x) int(x.len), x.ptr return pan_fprintf_(stm, fmt , PAN_BE_GET_SLICE_4_PRINTF(ar[0]) , PAN_BE_GET_SLICE_4_PRINTF(ar[1]) , PAN_BE_GET_SLICE_4_PRINTF(ar[2]) , PAN_BE_GET_SLICE_4_PRINTF(ar[3]) , PAN_BE_GET_SLICE_4_PRINTF(ar[4]) , PAN_BE_GET_SLICE_4_PRINTF(ar[5]) , PAN_BE_GET_SLICE_4_PRINTF(ar[6]) , PAN_BE_GET_SLICE_4_PRINTF(ar[7]) , PAN_BE_GET_SLICE_4_PRINTF(ar[8]) , PAN_BE_GET_SLICE_4_PRINTF(ar[9])); }
inline bool truncation_test_helper_runtime_test_same_sign(FROM from, no_type, TO) { #ifdef _DEBUG # if defined(STLSOFT_COMPILER_IS_MSVC) int const flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); _CrtSetDbgFlag(flags & ~(_CRTDBG_ALLOC_MEM_DF)); # endif /* VC++ */ char const* TO_ = typeid(TO).name(); char const* FROM_ = typeid(FROM).name(); STLSOFT_SUPPRESS_UNUSED(TO_); STLSOFT_SUPPRESS_UNUSED(FROM_); # if defined(STLSOFT_COMPILER_IS_MSVC) _CrtSetDbgFlag(flags); # endif /* VC++ */ #endif /* _DEBUG */ enum { TO_is_signed = is_signed_type<TO>::value }; enum { FROM_is_signed = is_signed_type<FROM>::value }; const ss_size_t sizeofFROM = sizeof(FROM); const ss_size_t sizeofTO = sizeof(TO); STLSOFT_SUPPRESS_UNUSED(sizeofFROM); STLSOFT_SUPPRESS_UNUSED(sizeofTO); STLSOFT_STATIC_ASSERT((0 == int(TO_is_signed)) != (0 == int(FROM_is_signed))); typedef ss_typename_param_k value_to_yesno_type<FROM_is_signed>::type same_sign_yesno_t; return truncation_test_helper_runtime_test_different_sign_FROM_is_signed<TO>(from, same_sign_yesno_t(), TO()); }
inline bool truncation_test_helper_runtime_test_different_sign_FROM_is_signed(FROM from, no_type, TO) { #ifdef _DEBUG # if defined(STLSOFT_COMPILER_IS_MSVC) int const flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); _CrtSetDbgFlag(flags & ~(_CRTDBG_ALLOC_MEM_DF)); # endif /* VC++ */ char const* TO_ = typeid(TO).name(); char const* FROM_ = typeid(FROM).name(); STLSOFT_SUPPRESS_UNUSED(TO_); STLSOFT_SUPPRESS_UNUSED(FROM_); # if defined(STLSOFT_COMPILER_IS_MSVC) _CrtSetDbgFlag(flags); # endif /* VC++ */ #endif /* _DEBUG */ enum { TO_is_signed = is_signed_type<TO>::value }; enum { FROM_is_signed = is_signed_type<FROM>::value }; const ss_size_t sizeofFROM = sizeof(FROM); const ss_size_t sizeofTO = sizeof(TO); STLSOFT_SUPPRESS_UNUSED(sizeofFROM); STLSOFT_SUPPRESS_UNUSED(sizeofTO); STLSOFT_STATIC_ASSERT((0 == int(TO_is_signed)) != (0 == int(FROM_is_signed))); STLSOFT_STATIC_ASSERT(0 == int(FROM_is_signed)); STLSOFT_STATIC_ASSERT(0 != int(TO_is_signed)); // FROM is unsigned // TO is signed // // Truncation occurs if from > toMax FROM toMax = static_cast<FROM>(limit_traits<TO>::maximum()); if(from > toMax) { return false; } else { return true; } }
inline C const* integer_to_string(C (&buf)[N], ss_sint16_t i) { STLSOFT_STATIC_ASSERT(!(N < 7)); return signed_integer_to_string(buf, N, i); }
inline C const* integer_to_string(C (&buf)[N], ss_uint32_t i) { STLSOFT_STATIC_ASSERT(!(N < 11)); return unsigned_integer_to_string(buf, N, i); }
inline transform_iterator<filter_iterator<I, FP>, TF> make_transform_filter_iterator(I from, I to, TF fn, FP pr) { typedef ss_typename_param_k FP::result_type predicate_result_t; // If this fires, you've either specified the transforming function and // the filtering predicate in the wrong order, or your predicate has a // non-integral return type (which would be decidedly odd). STLSOFT_STATIC_ASSERT(0 != is_integral_type<predicate_result_t>::value); return transformer(filter(from, to, pr), fn); }
inline ximpl_integer::ff_to_i_r_t_ to_i( I const& value ) { STLSOFT_STATIC_ASSERT(stlsoft::is_integral_type<I>::value); return #if !defined(FASTFORMAT_NO_NAMESPACE) ::fastformat::inserters:: #endif /* !FASTFORMAT_NO_NAMESPACE */ ximpl_integer::integer_helper_3(value, ximpl_integer::default_width_sentinel_(), ximpl_integer::default_precision_sentinel_()); }
inline C const* integer_to_string(C (&buf)[N], ss_uint64_t const& i) { STLSOFT_STATIC_ASSERT(!(N < 21)); #ifdef STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT if(i < 0x80000000) { return unsigned_integer_to_string(buf, N, static_cast<ss_uint32_t>(i)); } #endif // STLSOFT_INTEGER_TO_STRING_OPTIMISE_64BIT return unsigned_integer_to_string(buf, N, i); }
inline ximpl_integer::ff_to_i_r_t_ to_i( I const& value , int minimumWidth , int precision ) { STLSOFT_STATIC_ASSERT(stlsoft::is_integral_type<I>::value); return #if !defined(FASTFORMAT_NO_NAMESPACE) ::fastformat::inserters:: #endif /* !FASTFORMAT_NO_NAMESPACE */ ximpl_integer::integer_helper_3(value, minimumWidth, precision); }
inline ss_size_t format_thousands( C *dest , ss_size_t cchDest , C const *picture , I const &number , C fmtSep , C outputSep ) { C szRawNumber[21]; // 21 is large enough for any 64-bit number (signed or unsigned) C const* rawNumber = integer_to_string(szRawNumber, STLSOFT_NUM_ELEMENTS(szRawNumber), static_cast<unsigned int>(number)); STLSOFT_STATIC_ASSERT(sizeof(C) <= 8); return translate_thousands(dest, cchDest, picture, rawNumber, fmtSep, outputSep); }
inline bool truncation_test_helper_runtime_test_same_sign(FROM from, yes_type, TO) // The use of the dummy variable is to fix a bug with VC++ 5-7.0 { #ifdef STLSOFT_DEBUG # if defined(STLSOFT_COMPILER_IS_MSVC) int const flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); _CrtSetDbgFlag(flags & ~(_CRTDBG_ALLOC_MEM_DF)); # endif /* VC++ */ char const* TO_ = typeid(TO).name(); char const* FROM_ = typeid(FROM).name(); STLSOFT_SUPPRESS_UNUSED(TO_); STLSOFT_SUPPRESS_UNUSED(FROM_); # if defined(STLSOFT_COMPILER_IS_MSVC) _CrtSetDbgFlag(flags); # endif /* VC++ */ #endif /* STLSOFT_DEBUG */ const ss_size_t sizeofFROM = sizeof(FROM); const ss_size_t sizeofTO = sizeof(TO); STLSOFT_STATIC_ASSERT(sizeofTO < sizeofFROM); STLSOFT_SUPPRESS_UNUSED(sizeofTO); STLSOFT_SUPPRESS_UNUSED(sizeofFROM); // This is a fully runtime test: does FROM fit into TO's limits? // // To do this we elicit TO's min and max. The values are held in // FROM, which involves no truncation because sizeof(FROM) > sizeof(TO) FROM toMax = static_cast<FROM>(limit_traits<TO>::maximum()); FROM toMin = static_cast<FROM>(limit_traits<TO>::minimum()); if( from < toMin || from > toMax) { return false; } else { return true; } }
inline ss_bool_t operator !=(T const& lhs, NULL_v const& rhs) { STLSOFT_STATIC_ASSERT(sizeof(lhs) == 4); return !rhs.equal(lhs); }
inline ss_bool_t operator ==(NULL_v const& lhs, T const& rhs) { STLSOFT_STATIC_ASSERT(sizeof(rhs) == 4); return lhs.equal(rhs); }
void pointer::construct_() { PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(0 == m_sz[0], "cannot construct if value is non-empty"); PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(0 == m_len, "cannot construct if length is non-0"); if(static_cast<void const*>(0) == m_value) { static const pan_char_t s_null[] = PANTHEIOS_LITERAL_STRING("(null)"); STLSOFT_STATIC_ASSERT(sizeof(m_sz) >= sizeof(s_null)); ::memcpy(&m_sz[0], &s_null[0], sizeof(s_null)); m_len = STLSOFT_NUM_ELEMENTS(s_null) - 1; } else { pan_char_t szFmt[101]; int width; pan_char_t const* zeroX; pan_char_t const* leadingMinus; pan_char_t const* zeroPad; if(m_minWidth < 0) { width = -m_minWidth; leadingMinus = PANTHEIOS_LITERAL_STRING("-"); } else { width = m_minWidth; leadingMinus = PANTHEIOS_LITERAL_STRING(""); } zeroX = (m_format & fmt::zeroXPrefix) ? PANTHEIOS_LITERAL_STRING("0x") : PANTHEIOS_LITERAL_STRING(""); zeroPad = (m_format & fmt::zeroPad) ? PANTHEIOS_LITERAL_STRING("0") : PANTHEIOS_LITERAL_STRING(""); if( 0 != width && fmt::zeroXPrefix == (m_format & (fmt::zeroXPrefix | fmt::zeroPad))) { // Special case pan_char_t szTemp[23]; // 23 is always big enough, since the width is 21 PANTHEIOS_CONTRACT_ENFORCE_ASSUMPTION(0 == (m_format & fmt::zeroPad)); // Determine ptr-sized integer type #if defined(STLSOFT_COMPILER_IS_GCC) typedef unsigned long intptr_t_; #else /* ? compiler */ typedef stlsoft::int_size_traits<sizeof(void*)>::unsigned_type intptr_t_; #endif /* compiler */ int r = pantheios_util_snprintf( &szTemp[0] , STLSOFT_NUM_ELEMENTS(szTemp) , PANTHEIOS_LITERAL_STRING("0x%lx") , static_cast<intptr_t_>(stlsoft::union_cast<intptr_t_>(m_value)) ); if(r < 0) { return; } else { size_t n = static_cast<size_t>(r); PANTHEIOS_CONTRACT_ENFORCE_POSTCONDITION_RETURN_INTERNAL((n + 2) <= STLSOFT_NUM_ELEMENTS(szTemp), "snprintf() overwrote the local buffer capacity"); width += 2; if(static_cast<size_t>(width) > n) { if(m_minWidth < 0) { PANTHEIOS_char_copy(&m_sz[0], szTemp, n); std::fill_n(&m_sz[0] + n, size_t(width - n), ' '); m_sz[width] = '\0'; } else { std::fill_n(&m_sz[0], size_t(width - n), ' '); PANTHEIOS_char_copy(&m_sz[0] + (size_t(width) - n), szTemp, (n + 1)); } m_len = static_cast<size_t>(width); } else { PANTHEIOS_char_copy(&m_sz[0], szTemp, (n + 1)); m_len = n; } } } else { pantheios_util_snprintf(&szFmt[0] , STLSOFT_NUM_ELEMENTS(szFmt) , PANTHEIOS_LITERAL_STRING("%s%%%s%s%dx") , zeroX , leadingMinus , zeroPad , width); m_len = static_cast<size_t>(pantheios_util_snprintf(&m_sz[0], STLSOFT_NUM_ELEMENTS(m_sz), szFmt, m_value)); } } PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(0 != m_sz[0], "failed to set value to non-empty"); PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(m_len > 0, "failed to set length"); PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(m_len < 23, "pantheios::pointer string too long"); }
inline C const* signed_integer_to_string(C *buf, ss_size_t cchBuf, I i) { #ifndef STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT // If the compiler does not evaluate -9 % 10 to equal -9, then we need to work // with it as if an unsigned, and prepend the -ve typedef limit_traits<I> limit_traits_t; typedef sign_traits<I> sign_traits_t; typedef ss_typename_type_k sign_traits_t::signed_type signed_type_t; typedef ss_typename_type_k sign_traits_t::unsigned_type unsigned_type_t; // If this fires, something has happened to invoke this function on an // unsigned type. STLSOFT_STATIC_ASSERT((0 != is_same_type<signed_type_t, I>::value)); C const* psz; if(i == limit_traits_t::minimum()) { STLSOFT_ASSERT(i == -i); // Special case of the (signed) minimum, since the maximum -ve value // of a signed integer cannot be negated. // // We instead take the equivalent value as an unsigned integer, // convert that (as unsigned), and prepend a '-' psz = unsigned_integer_to_string(buf, cchBuf, static_cast<unsigned_type_t>(limit_traits_t::minimum())); *const_cast<C*>(--psz) = C('-'); } else { // Just using the unsigned version here for the absence of // sign. Perversely, The invoked function is still a signed // specialisation. psz = unsigned_integer_to_string(buf, cchBuf, i); if(i < 0) { *const_cast<C*>(--psz) = C('-'); } } return psz; #else /* ? STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT */ // Compiler evaluates -9 % 10 to equal -9, so use the full -ve algorithm. This // is chosen because it is more efficient on most compilers than calling the // unsigned peer and converting. #if defined(STLSOFT_COMPILER_IS_MSVC) typedef I rem_t; #else /* ? compiler */ typedef ss_sint_t rem_t; #endif /* compiler */ C *psz = buf + cchBuf - 1; // Set pointer to last character. *psz = 0; // Set the terminating null character. if(i < 0) { do { rem_t lsd = static_cast<rem_t>(i % 10); // Determine the least significant digit. i = static_cast<I>(i / 10); // Deal with next most significant. --psz; // Move back. #ifdef STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS *psz = get_digit_character(static_cast<C*>(NULL))[lsd]; #else /* ? STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */ *psz = get_digit_character<C>()[lsd]; #endif /* STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */ } while(i != 0); *(--psz) = C('-'); // Prepend the minus sign. } else { do { rem_t lsd = static_cast<rem_t>(i % 10); // Determine the least significant digit. i = static_cast<I>(i / 10); // Deal with next most significant. --psz; // Move back. #ifdef STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS *psz = get_digit_character(static_cast<C*>(NULL))[lsd]; #else /* ? STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */ *psz = get_digit_character<C>()[lsd]; #endif /* STLSOFT_CF_TEMPLATE_TYPE_REQUIRED_IN_ARGS */ } while(i != 0); } STLSOFT_ASSERT(!(psz < buf)); return psz; #endif /* !STLSOFT_CF_NEGATIVE_MODULUS_POSITIVE_GIVES_NEGATIVE_RESULT */ }
inline bool truncation_test_(FROM from, TO dummy = TO()) // The use of the dummy variable is to fix a bug with VC++ 5-7.0 { #ifdef _DEBUG # if defined(STLSOFT_COMPILER_IS_MSVC) int const flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); _CrtSetDbgFlag(flags & ~(_CRTDBG_ALLOC_MEM_DF)); # endif /* VC++ */ char const* TO_ = typeid(TO).name(); char const* FROM_ = typeid(FROM).name(); STLSOFT_SUPPRESS_UNUSED(TO_); STLSOFT_SUPPRESS_UNUSED(FROM_); # if defined(STLSOFT_COMPILER_IS_MSVC) _CrtSetDbgFlag(flags); # endif /* VC++ */ #endif /* _DEBUG */ // First, we must check that the types are compatible, with constraints // Both types must be integral STLSOFT_STATIC_ASSERT(0 != is_integral_type<TO>::value); STLSOFT_STATIC_ASSERT(0 != is_integral_type<FROM>::value); // Now calculate the sizes const ss_size_t sizeofFROM = sizeof(FROM); const ss_size_t sizeofTO = sizeof(TO); // Now determine the signs enum { TO_is_signed = is_signed_type<TO>::value }; enum { FROM_is_signed = is_signed_type<FROM>::value }; // We know at compile time that FROM fits into TO if: // // - they have the same sign, and sizeof(FROM) <= sizeof(TO), OR // - FROM is unsigned (and TO is signed), and sizeof(FROM) < sizeof(TO) // // If either of these hold, then the answer is true: the yes_type overload // of truncation_test_helper_runtime_test() is selected. // // If not, then a runtime test is required: the no_type overload // of truncation_test_helper_runtime_test() is selected. enum { types_are_statically_compatible = ( int(TO_is_signed) == int(FROM_is_signed) && sizeofFROM <= sizeofTO) || ( !FROM_is_signed && sizeofFROM < sizeofTO) }; typedef ss_typename_param_k value_to_yesno_type<types_are_statically_compatible>::type yesno_t; # if defined(STLSOFT_COMPILER_IS_MSVC) && \ defined(_Wp64) && \ !defined(_WIN64) # pragma warning(push) # pragma warning(disable : 4267) # endif /* VC++ + Win32 + _Wp32 */ return truncation_test_helper_runtime_test<TO>(from, yesno_t(), dummy); # if defined(STLSOFT_COMPILER_IS_MSVC) && \ defined(_Wp64) && \ !defined(_WIN64) # pragma warning(pop) # endif /* VC++ + Win32 + _Wp32 */ }
bool truncation_test_v3_is_statically_determined(FROM from, TO, no_type) { #ifdef _DEBUG char const *TO_ = typeid(TO).name(); char const *FROM_ = typeid(FROM).name(); STLSOFT_SUPPRESS_UNUSED(TO_); STLSOFT_SUPPRESS_UNUSED(FROM_); #endif /* _DEBUG */ enum { fromIsSigned = stlsoft::is_signed_type<FROM>::value }; enum { toIsSigned = stlsoft::is_signed_type<TO>::value }; STLSOFT_STATIC_ASSERT(sizeof(FROM) >= sizeof(TO) || fromIsSigned); if(fromIsSigned) { if(toIsSigned) { if(sizeof(FROM) <= sizeof(TO)) { return true; // 1a, 1b } else { // 1c // FROM is larger than TO, so have to test value FROM toMin = static_cast<FROM>(stlsoft::limit_traits<TO>::minimum()); FROM toMax = static_cast<FROM>(stlsoft::limit_traits<TO>::maximum()); if( from < toMin || from > toMax) { return false; } else { return true; } } } else { // 3a, 3b, 3c if(from < 0) // GCC: comparison is always false due to limited range of data type { return false; } else { if(sizeof(FROM) <= sizeof(TO)) { return true; // 3a, 3b } else { FROM toMax = static_cast<FROM>(stlsoft::limit_traits<TO>::maximum()); // 3c return from <= toMax; } } } } else { if(toIsSigned) { if(sizeof(FROM) < sizeof(TO)) { return true; // 2a } else { FROM toMax = static_cast<FROM>(stlsoft::limit_traits<TO>::maximum()); return from <= toMax; // 2b, 2c } } else { if(sizeof(FROM) <= sizeof(TO)) { return true; // 4a, 4b } else { // 4c FROM toMax = static_cast<FROM>(stlsoft::limit_traits<TO>::maximum()); return from <= toMax; } } } }
inline int stlsoft_meta_n_types_size_checker() { STLSOFT_STATIC_ASSERT(sizeof(one_type) < sizeof(two_type)); STLSOFT_STATIC_ASSERT(sizeof(two_type) < sizeof(three_type)); STLSOFT_STATIC_ASSERT(sizeof(three_type) < sizeof(four_type)); STLSOFT_STATIC_ASSERT(sizeof(four_type) < sizeof(five_type)); STLSOFT_STATIC_ASSERT(sizeof(five_type) < sizeof(six_type)); STLSOFT_STATIC_ASSERT(sizeof(six_type) < sizeof(seven_type)); STLSOFT_STATIC_ASSERT(sizeof(seven_type) < sizeof(eight_type)); STLSOFT_STATIC_ASSERT(sizeof(eight_type) < sizeof(nine_type)); STLSOFT_STATIC_ASSERT(sizeof(nine_type) < sizeof(ten_type)); STLSOFT_STATIC_ASSERT(sizeof(ten_type) < sizeof(eleven_type)); STLSOFT_STATIC_ASSERT(sizeof(eleven_type) < sizeof(twelve_type)); STLSOFT_STATIC_ASSERT(sizeof(twelve_type) < sizeof(thirteen_type)); STLSOFT_STATIC_ASSERT(sizeof(thirteen_type) < sizeof(fourteen_type)); STLSOFT_STATIC_ASSERT(sizeof(fourteen_type) < sizeof(fifteen_type)); STLSOFT_STATIC_ASSERT(sizeof(fifteen_type) < sizeof(sixteen_type)); STLSOFT_STATIC_ASSERT(sizeof(sixteen_type) < sizeof(seventeen_type)); STLSOFT_STATIC_ASSERT(sizeof(seventeen_type) < sizeof(eighteen_type)); STLSOFT_STATIC_ASSERT(sizeof(eighteen_type) < sizeof(nineteen_type)); STLSOFT_STATIC_ASSERT(sizeof(nineteen_type) < sizeof(twenty_type)); return 1; }
inline ws_uint64_t load_text_file_impl(S1 const& fileName, S2 &contents) { typedef string_traits<S1> string_traits_t; STLSOFT_STATIC_ASSERT(sizeof(string_traits_t)); // Fires if S1 does not have a traits specialisation defined typedef string_traits<S2> string_traits2_t; STLSOFT_STATIC_ASSERT(sizeof(string_traits2_t)); // Fires if S2 does not have a traits specialisation defined typedef ss_typename_type_k string_traits_t::char_type C; STLSOFT_STATIC_ASSERT(sizeof(C)); // Fires if the traits is not correctly defined typedef ss_typename_type_k string_traits2_t::char_type char_2_type; STLSOFT_STATIC_ASSERT(sizeof(char_2_type)); // Fires if the traits is not correctly defined typedef filesystem_traits<C> filesys_traits_t; STLSOFT_STATIC_ASSERT(sizeof(filesys_traits_t)); // Fires if no corresponding filesystem_traits defined scoped_handle<HANDLE> h( filesys_traits_t::create_file( stlsoft_ns_qual(c_str_ptr)(fileName) , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , 0 , NULL) , (void (STLSOFT_CDECL *)(HANDLE))&filesys_traits_t::close_handle // This cast required by VC++ 5 , INVALID_HANDLE_VALUE); if(INVALID_HANDLE_VALUE == h.get()) { STLSOFT_THROW_X(windows_exception("File does not exist", ::GetLastError())); } ws_uint64_t size = filesys_traits_t::get_file_size(h.get()); if( 0 != size && static_cast<ws_uint64_t>(~0) != size) { if(size > 0xFFFFFFFF) { STLSOFT_THROW_X(winstl_ns_qual_std(out_of_range)("Cannot read in files larger than 4GB")); } else { // TODO: Catch the out-of-memory exception and translate to a std::out_of_range() typedef ::stlsoft::auto_buffer_old< char_2_type , processheap_allocator<char_2_type> , 1024 > buffer_t; buffer_t buffer(static_cast<ss_typename_type_k buffer_t::size_type>(size)); DWORD dw; if(!::ReadFile(h.get(), &buffer[0], buffer.size(), &dw, NULL)) { STLSOFT_THROW_X(windows_exception("Read operation failed", ::GetLastError())); } else { contents.assign(&buffer[0], dw); return size; } } } return 0; }