Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#ifdef _DEBUG
DWORD dataOffset;
__asm
{
mov eax, oracle::occi::Number::data
mov [dataOffset], eax
}
ASSERT (dataOffset == 0);
#endif
#define private public
OCINumber* extractOCINumber(oracle::occi::Number& );
#define private public
// подключаем необходимый заголовочный файл
OCINumber* extractOCINumber(oracle::occi::Number& foo)
{
return &foo.data;
}
//и ничего более
//и ичего более
#undef private
__int64 OCCINumberToInt64 (const oracle::occi::Number &number, OCIError *hError, bool bSigned)
{
const OCINumber *ociNumber = (const OCINumber*)&number;
__int64 result;
OCINumberToInt (hError, ociNumber, 8, bSigned ? OCI_NUMBER_SIGNED : OCI_NUMBER_UNSIGNED, &result);
return result;
}
// в случае C++11
#include <type_traits>
template<typename T>
T OCCINumberToInt(const oracle::occi::Number &number, OCIError *hError)
{
// тут можно нанаставлять статик ассертов для лимитации типов по размерам
const OCINumber *ociNumber = reinterpret_cast<const OCINumber*>(&number);
T result;
// Если C++11
//const static bool bSigned = std::is_signed<T>::value;
// Если нет:
const static bool bSigned = T(-1) < T(0);
OCINumberToInt (hError, ociNumber, sizeof(T), bSigned ? OCI_NUMBER_SIGNED : OCI_NUMBER_UNSIGNED, &result);
return result;
}
uint64_t unsignedValue64 = OCCINumberToInt<uint64_t>(ociNumber, err);
int64_t signedValue64 = OCCINumberToInt<int64_t>(ociNumber, err);
вы тут сохраняете в знаковый int64 как знаковые, так и беззнаковые значения. Судя по всему тестировали только на положительных числах?
причём не только для 64бит, но внимательно посмотреть и статических ассертов добавить на допустимые длины.
bSigned тут вычислится один раз для каждого типа.
OCINumberToInt (hError, ociNumber, sizeof(T), T(-1) < T(0) ? OCI_NUMBER_SIGNED : OCI_NUMBER_UNSIGNED, &result);
А для чего вы определили ее вообще? Можно ведь написать так:
const static bool bSigned = T(-1) < T(0);
const static uword flags = bSigned ? OCI_NUMBER_SIGNED : OCI_NUMBER_UNSIGNED;
// в случае C++11 можно и одной строчкой: из контекста и так понятно что происходит, а что такое T(-1) < T(0) сто пудов не сходу вспомнится:
//constexpr static uword flags = std::is_signed<T>::value ? OCI_NUMBER_SIGNED : OCI_NUMBER_UNSIGNED;
...
OCINumberToInt (hError, ociNumber, sizeof(T), flags, &result);
Чтение 64-битных целых чисел из Oracle на OCCI (MSVC)