basic/Library_sb.mk          |    7 
 basic/source/sbx/sbxbool.cxx |  199 ++++-----
 basic/source/sbx/sbxbyte.cxx |  309 ---------------
 basic/source/sbx/sbxchar.cxx |  295 --------------
 basic/source/sbx/sbxconv.hxx |  163 ++++----
 basic/source/sbx/sbxcurr.cxx |  122 ++----
 basic/source/sbx/sbxdate.cxx |  278 +++++--------
 basic/source/sbx/sbxdbl.cxx  |  265 -------------
 basic/source/sbx/sbxdec.cxx  |  296 ++++++--------
 basic/source/sbx/sbxdec.hxx  |   32 +
 basic/source/sbx/sbxint.cxx  |  868 ++++++++-----------------------------------
 basic/source/sbx/sbxlng.cxx  |  285 --------------
 basic/source/sbx/sbxsng.cxx  |  279 -------------
 basic/source/sbx/sbxuint.cxx |  281 -------------
 basic/source/sbx/sbxulng.cxx |  266 -------------
 15 files changed, 661 insertions(+), 3284 deletions(-)

New commits:
commit 2143c0a6949ee80c34ec6a8e2028fea2930dd947
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Jun 3 18:09:30 2025 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Sat Jun 7 12:30:17 2025 +0200

    Simplify getter/setter implementations
    
    For numeric types, they are made unified templates. In many cases,
    gotos were dropped, and the code was streamlined. Hopefully, this
    would make it at least a bit manageable.
    
    Change-Id: I63154d61fa6629d1431157ac382ec758f4f50074
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186234
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/basic/Library_sb.mk b/basic/Library_sb.mk
index dae083a34864..aa1de14b01f8 100644
--- a/basic/Library_sb.mk
+++ b/basic/Library_sb.mk
@@ -113,25 +113,18 @@ $(eval $(call gb_Library_add_exception_objects,sb,\
        basic/source/runtime/runtime \
        basic/source/sbx/sbxarray \
        basic/source/sbx/sbxbool \
-       basic/source/sbx/sbxbyte \
-       basic/source/sbx/sbxchar \
        basic/source/sbx/sbxcoll \
        basic/source/sbx/sbxcurr \
        basic/source/sbx/sbxbase \
        basic/source/sbx/sbxdate \
-       basic/source/sbx/sbxdbl \
        basic/source/sbx/sbxdec \
        basic/source/sbx/sbxexec \
        basic/source/sbx/sbxform \
        basic/source/sbx/sbxint \
-       basic/source/sbx/sbxlng \
        basic/source/sbx/sbxobj \
        basic/source/sbx/sbxres \
        basic/source/sbx/sbxscan \
-       basic/source/sbx/sbxsng \
        basic/source/sbx/sbxstr \
-       basic/source/sbx/sbxuint \
-       basic/source/sbx/sbxulng \
        basic/source/sbx/sbxvalue \
        basic/source/sbx/sbxvar \
 ))
diff --git a/basic/source/sbx/sbxbool.cxx b/basic/source/sbx/sbxbool.cxx
index c6d9c2fbd166..6cdcb9ed464a 100644
--- a/basic/source/sbx/sbxbool.cxx
+++ b/basic/source/sbx/sbxbool.cxx
@@ -24,116 +24,100 @@
 
 enum SbxBOOL ImpGetBool( const SbxValues* p )
 {
-    enum SbxBOOL nRes;
+    auto SbxBoolFrom = [](auto val) { return val != 0 ? SbxTRUE : SbxFALSE; };
     switch( +p->eType )
     {
-        case SbxNULL:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            [[fallthrough]];
         case SbxEMPTY:
-            nRes = SbxFALSE; break;
+            return SbxFALSE;
         case SbxCHAR:
-            nRes = p->nChar ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nChar);
+        case SbxBYREF | SbxCHAR:
+            return SbxBoolFrom(*p->pChar);
         case SbxBYTE:
-            nRes = p->nByte ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nByte);
+        case SbxBYREF | SbxBYTE:
+            return SbxBoolFrom(*p->pByte);
         case SbxINTEGER:
         case SbxBOOL:
-            nRes = p->nInteger ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nInteger);
+        case SbxBYREF | SbxINTEGER:
+        case SbxBYREF | SbxBOOL:
+            return SbxBoolFrom(*p->pInteger);
         case SbxERROR:
         case SbxUSHORT:
-            nRes = p->nUShort ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nUShort);
+        case SbxBYREF | SbxERROR:
+        case SbxBYREF | SbxUSHORT:
+            return SbxBoolFrom(*p->pUShort);
         case SbxLONG:
-            nRes = p->nLong ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nLong);
+        case SbxBYREF | SbxLONG:
+            return SbxBoolFrom(*p->pLong);
         case SbxULONG:
-            nRes = p->nULong ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nULong);
+        case SbxBYREF | SbxULONG:
+            return SbxBoolFrom(*p->pULong);
         case SbxSINGLE:
-            nRes = p->nSingle ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nSingle);
+        case SbxBYREF | SbxSINGLE:
+            return SbxBoolFrom(*p->pSingle);
         case SbxDATE:
         case SbxDOUBLE:
-            nRes = p->nDouble ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nDouble);
+        case SbxBYREF | SbxDATE:
+        case SbxBYREF | SbxDOUBLE:
+            return SbxBoolFrom(*p->pDouble);
         case SbxDECIMAL:
         case SbxBYREF | SbxDECIMAL:
-            {
-            double dVal = 0.0;
             if( p->pDecimal )
-                p->pDecimal->getDouble( dVal );
-            nRes = dVal ? SbxTRUE : SbxFALSE;
-            }
-            break;
+                return SbxBoolFrom(p->pDecimal->getWithOverflow<double>());
+            return SbxFALSE;
         case SbxSALINT64:
         case SbxCURRENCY:
-            nRes = p->nInt64 ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->nInt64);
+        case SbxBYREF | SbxSALINT64:
+        case SbxBYREF | SbxCURRENCY:
+            return SbxBoolFrom(*p->pnInt64);
         case SbxSALUINT64:
-            nRes = p->uInt64 ? SbxTRUE : SbxFALSE; break;
+            return SbxBoolFrom(p->uInt64);
+        case SbxBYREF | SbxSALUINT64:
+            return SbxBoolFrom(*p->puInt64);
+
         case SbxBYREF | SbxSTRING:
         case SbxSTRING:
         case SbxLPSTR:
-            nRes = SbxFALSE;
             if ( p->pOUString )
             {
                 if( p->pOUString->equalsIgnoreAsciiCase( GetSbxRes( 
StringId::True ) ) )
-                    nRes = SbxTRUE;
-                else if( !p->pOUString->equalsIgnoreAsciiCase( GetSbxRes( 
StringId::False ) ) )
+                    return SbxTRUE;
+                if( p->pOUString->equalsIgnoreAsciiCase( GetSbxRes( 
StringId::False ) ) )
+                    return SbxFALSE;
+
+                // it can be convertible to a number
+                double n;
+                SbxDataType t;
+                sal_Int32 nLen = 0;
+                if( ImpScan( *p->pOUString, n, t, &nLen ) == ERRCODE_NONE )
                 {
-                    // it can be convertible to a number
-                    bool bError = true;
-                    double n;
-                    SbxDataType t;
-                    sal_Int32 nLen = 0;
-                    if( ImpScan( *p->pOUString, n, t, &nLen ) == ERRCODE_NONE )
+                    if( nLen == p->pOUString->getLength() )
                     {
-                        if( nLen == p->pOUString->getLength() )
-                        {
-                            bError = false;
-                            if( n != 0.0 )
-                                nRes = SbxTRUE;
-                        }
+                        return SbxBoolFrom(n);
                     }
-                    if( bError )
-                        SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
                 }
+                SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
             }
-            break;
+            return SbxFALSE;
+
         case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                nRes = pVal->GetBool() ? SbxTRUE : SbxFALSE;
-            else
-            {
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = SbxFALSE;
-            }
-            break;
-        }
+            if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
+                return SbxBoolFrom(pVal->GetBool());
+            SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
+            return SbxFALSE;
 
-        case SbxBYREF | SbxCHAR:
-            nRes = *p->pChar ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxBYTE:
-            nRes = *p->pByte ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            nRes = *p->pInteger ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxLONG:
-            nRes = *p->pLong ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxULONG:
-            nRes = *p->pULong ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            nRes = *p->pUShort ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxSINGLE:
-            nRes = ( *p->pSingle != 0 ) ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            nRes = ( *p->pDouble != 0 ) ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxCURRENCY:
-        case SbxBYREF | SbxSALINT64:
-            nRes = ( *p->pnInt64 ) ? SbxTRUE : SbxFALSE; break;
-        case SbxBYREF | SbxSALUINT64:
-            nRes = ( *p->puInt64 ) ? SbxTRUE : SbxFALSE; break;
         default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = SbxFALSE;
+            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
+            return SbxFALSE;
     }
-    return nRes;
 }
 
 void ImpPutBool( SbxValues* p, sal_Int16 n )
@@ -144,28 +128,53 @@ void ImpPutBool( SbxValues* p, sal_Int16 n )
     {
         case SbxCHAR:
             p->nChar = static_cast<sal_Unicode>(n); break;
-        case SbxUINT:
+        case SbxBYREF | SbxCHAR:
+            *p->pChar = static_cast<sal_Unicode>(n); break;
+        case SbxBYTE:
             p->nByte = static_cast<sal_uInt8>(n); break;
+        case SbxBYREF | SbxBYTE:
+            *p->pByte = static_cast<sal_uInt8>(n); break;
         case SbxINTEGER:
         case SbxBOOL:
             p->nInteger = n; break;
+        case SbxBYREF | SbxINTEGER:
+        case SbxBYREF | SbxBOOL:
+            *p->pInteger = n; break;
+        case SbxERROR:
+        case SbxUSHORT:
+            p->nUShort = static_cast<sal_uInt16>(n); break;
+        case SbxBYREF | SbxERROR:
+        case SbxBYREF | SbxUSHORT:
+            *p->pUShort = static_cast<sal_uInt16>(n); break;
         case SbxLONG:
             p->nLong = n; break;
+        case SbxBYREF | SbxLONG:
+            *p->pLong = n; break;
         case SbxULONG:
             p->nULong = static_cast<sal_uInt32>(n); break;
-        case SbxERROR:
-        case SbxUSHORT:
-            p->nUShort = static_cast<sal_uInt16>(n); break;
+        case SbxBYREF | SbxULONG:
+            *p->pULong = static_cast<sal_uInt32>(n); break;
         case SbxSINGLE:
             p->nSingle = n; break;
+        case SbxBYREF | SbxSINGLE:
+            *p->pSingle = n; break;
         case SbxDATE:
         case SbxDOUBLE:
             p->nDouble = n; break;
+        case SbxBYREF | SbxDATE:
+        case SbxBYREF | SbxDOUBLE:
+            *p->pDouble = n; break;
         case SbxCURRENCY:
         case SbxSALINT64:
-            p->nInt64 = static_cast<sal_Int64>(n); break;
+            p->nInt64 = n; break;
+        case SbxBYREF | SbxCURRENCY:
+        case SbxBYREF | SbxSALINT64:
+            *p->pnInt64 = n; break;
         case SbxSALUINT64:
             p->uInt64 = static_cast<sal_uInt64>(n); break;
+        case SbxBYREF | SbxSALUINT64:
+            *p->puInt64 = static_cast<sal_uInt64>(n); break;
+
         case SbxDECIMAL:
         case SbxBYREF | SbxDECIMAL:
             ImpCreateDecimal( p )->setInt( n );
@@ -181,38 +190,12 @@ void ImpPutBool( SbxValues* p, sal_Int16 n )
             break;
 
         case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
+            if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
                 pVal->PutBool( n != 0 );
             else
                 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
             break;
-        }
-        case SbxBYREF | SbxCHAR:
-            *p->pChar = static_cast<sal_Unicode>(n); break;
-        case SbxBYREF | SbxBYTE:
-            *p->pByte = static_cast<sal_uInt8>(n); break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            *p->pInteger = n; break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            *p->pUShort = static_cast<sal_uInt16>(n); break;
-        case SbxBYREF | SbxLONG:
-            *p->pLong = n; break;
-        case SbxBYREF | SbxULONG:
-            *p->pULong = static_cast<sal_uInt32>(n); break;
-        case SbxBYREF | SbxSINGLE:
-            *p->pSingle = n; break;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            *p->pDouble = n; break;
-        case SbxBYREF | SbxCURRENCY:
-        case SbxBYREF | SbxSALINT64:
-            *p->pnInt64 = static_cast<sal_Int64>(n); break;
-        case SbxBYREF | SbxSALUINT64:
-            *p->puInt64 = static_cast<sal_uInt64>(n); break;
+
         default:
             SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
     }
diff --git a/basic/source/sbx/sbxbyte.cxx b/basic/source/sbx/sbxbyte.cxx
deleted file mode 100644
index 3e95c5124219..000000000000
--- a/basic/source/sbx/sbxbyte.cxx
+++ /dev/null
@@ -1,309 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <sal/config.h>
-
-#include <o3tl/safeint.hxx>
-#include <comphelper/errcode.hxx>
-//#include <basic/sbx.hxx>
-#include <basic/sberrors.hxx>
-#include "sbxconv.hxx"
-
-#include <rtl/math.hxx>
-
-sal_uInt8 ImpGetByte( const SbxValues* p )
-{
-    SbxValues aTmp;
-    sal_uInt8 nRes;
-start:
-    switch( +p->eType )
-    {
-        case SbxNULL:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            [[fallthrough]];
-        case SbxEMPTY:
-            nRes = 0; break;
-        case SbxCHAR:
-            if( p->nChar > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(p->nChar);
-            break;
-        case SbxBYTE:
-            nRes = p->nByte;    break;
-        case SbxINTEGER:
-        case SbxBOOL:
-            if( p->nInteger > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else if( p->nInteger < 0 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(p->nInteger);
-            break;
-        case SbxERROR:
-        case SbxUSHORT:
-            if( p->nUShort > o3tl::make_unsigned(SbxMAXBYTE) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(p->nUShort);
-            break;
-        case SbxLONG:
-            if( p->nLong > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else if( p->nLong < 0 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(p->nLong);
-            break;
-        case SbxULONG:
-            if( p->nULong > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(p->nULong);
-            break;
-        case SbxCURRENCY:
-            nRes = CurTo<sal_uInt8>(p->nInt64);
-            break;
-        case SbxSALINT64:
-            if (sal_Int64 val = p->nInt64; val > SbxMAXBYTE)
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else if (val < 0)
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(val);
-            break;
-        case SbxSALUINT64:
-            if( p->uInt64 > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(p->uInt64);
-            break;
-        case SbxSINGLE:
-            if( p->nSingle > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else if( p->nSingle < 0 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(rtl::math::round( p->nSingle ));
-            break;
-        case SbxDATE:
-        case SbxDOUBLE:
-        case SbxDECIMAL:
-        case SbxBYREF | SbxDECIMAL:
-            {
-            double dVal;
-            if( p->eType == SbxDECIMAL )
-            {
-                dVal = 0.0;
-                if( p->pDecimal )
-                    p->pDecimal->getDouble( dVal );
-            }
-            else
-                dVal = p->nDouble;
-
-            if( dVal > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-            }
-            else if( dVal < 0 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(rtl::math::round( dVal ));
-            break;
-            }
-        case SbxBYREF | SbxSTRING:
-        case SbxSTRING:
-        case SbxLPSTR:
-            if( !p->pOUString )
-                nRes = 0;
-            else
-            {
-                double d;
-                SbxDataType t;
-                if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE )
-                    nRes = 0;
-                else if( d > SbxMAXBYTE )
-                {
-                    SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXBYTE;
-                }
-                else if( d < 0 )
-                {
-                    SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 0;
-                }
-                else
-                    nRes = static_cast<sal_uInt8>( d + 0.5 );
-            }
-            break;
-        case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                nRes = pVal->GetByte();
-            else
-            {
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
-            }
-            break;
-        }
-
-        case SbxBYREF | SbxBYTE:
-            nRes = p->nByte; break;
-
-        // from here on will be tested
-        case SbxBYREF | SbxCHAR:
-            aTmp.nChar = *p->pChar; goto ref;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            aTmp.nInteger = *p->pInteger; goto ref;
-        case SbxBYREF | SbxLONG:
-            aTmp.nLong = *p->pLong; goto ref;
-        case SbxBYREF | SbxULONG:
-            aTmp.nULong = *p->pULong; goto ref;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            aTmp.nUShort = *p->pUShort; goto ref;
-        case SbxBYREF | SbxSINGLE:
-            aTmp.nSingle = *p->pSingle; goto ref;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            aTmp.nDouble = *p->pDouble; goto ref;
-        case SbxBYREF | SbxCURRENCY:
-        case SbxBYREF | SbxSALINT64:
-            aTmp.nInt64 = *p->pnInt64; goto ref;
-        case SbxBYREF | SbxSALUINT64:
-            aTmp.uInt64 = *p->puInt64; goto ref;
-        ref:
-            aTmp.eType = SbxDataType( p->eType & 0x0FFF );
-            p = &aTmp; goto start;
-
-        default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
-    }
-    return nRes;
-}
-
-void ImpPutByte( SbxValues* p, sal_uInt8 n )
-{
-    switch( +p->eType )
-    {
-        case SbxBYTE:
-            p->nByte = n; break;
-        case SbxINTEGER:
-        case SbxBOOL:
-            p->nInteger = n; break;
-        case SbxERROR:
-        case SbxUSHORT:
-            p->nUShort = n; break;
-        case SbxLONG:
-            p->nLong = n; break;
-        case SbxULONG:
-            p->nULong = n; break;
-        case SbxSINGLE:
-            p->nSingle = n; break;
-        case SbxDATE:
-        case SbxDOUBLE:
-            p->nDouble = n; break;
-        case SbxCURRENCY:
-            p->nInt64 = CurFrom(n); break;
-        case SbxSALINT64:
-            p->nInt64 = n; break;
-        case SbxSALUINT64:
-            p->uInt64 = n; break;
-        case SbxDECIMAL:
-        case SbxBYREF | SbxDECIMAL:
-            ImpCreateDecimal( p )->setByte( n );
-            break;
-
-        case SbxCHAR:
-            p->nChar = static_cast<sal_Unicode>(n); break;
-
-        case SbxBYREF | SbxSTRING:
-        case SbxSTRING:
-        case SbxLPSTR:
-            if( !p->pOUString )
-                p->pOUString = new OUString;
-            ImpCvtNum( static_cast<double>(n), 0, *p->pOUString );
-            break;
-        case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                pVal->PutByte( n );
-            else
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
-            break;
-        }
-        case SbxBYREF | SbxCHAR:
-            *p->pChar = static_cast<sal_Unicode>(n); break;
-        case SbxBYREF | SbxBYTE:
-            *p->pByte = n; break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            *p->pInteger = n; break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            *p->pUShort = n; break;
-        case SbxBYREF | SbxLONG:
-            *p->pLong = n; break;
-        case SbxBYREF | SbxULONG:
-            *p->pULong = n; break;
-        case SbxBYREF | SbxSINGLE:
-            *p->pSingle = n; break;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            *p->pDouble = n; break;
-        case SbxBYREF | SbxCURRENCY:
-            p->nInt64 = CurFrom(n); break;
-        case SbxBYREF | SbxSALINT64:
-            *p->pnInt64 = n; break;
-        case SbxBYREF | SbxSALUINT64:
-            *p->puInt64 = n; break;
-
-        default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-    }
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/sbx/sbxchar.cxx b/basic/source/sbx/sbxchar.cxx
deleted file mode 100644
index 6bc44b4e138a..000000000000
--- a/basic/source/sbx/sbxchar.cxx
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <comphelper/errcode.hxx>
-#include <basic/sberrors.hxx>
-#include "sbxconv.hxx"
-
-#include <rtl/math.hxx>
-
-sal_Unicode ImpGetChar( const SbxValues* p )
-{
-    SbxValues aTmp;
-    sal_Unicode nRes = 0;
-start:
-    switch( +p->eType )
-    {
-        case SbxNULL:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            [[fallthrough]];
-        case SbxEMPTY:
-            nRes = 0; break;
-        case SbxCHAR:
-            nRes = p->nChar; break;
-        case SbxBYTE:
-            nRes = static_cast<sal_Unicode>(p->nByte);
-            break;
-        case SbxINTEGER:
-        case SbxBOOL:
-            if( p->nInteger < SbxMINCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMINCHAR;
-            }
-            else
-                nRes = static_cast<sal_Unicode>(p->nInteger);
-            break;
-        case SbxERROR:
-        case SbxUSHORT:
-            nRes = static_cast<sal_Unicode>(p->nUShort);
-            break;
-        case SbxLONG:
-            if( p->nLong > SbxMAXCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXCHAR;
-            }
-            else if( p->nLong < SbxMINCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMINCHAR;
-            }
-            else
-                nRes = static_cast<sal_Unicode>(p->nLong);
-            break;
-        case SbxULONG:
-            if( p->nULong > SbxMAXCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXCHAR;
-            }
-            else
-                nRes = static_cast<sal_Unicode>(p->nULong);
-            break;
-        case SbxCURRENCY:
-            nRes = CurTo<sal_Unicode>(p->nInt64);
-            break;
-        case SbxSALINT64:
-            if (sal_Int64 val = p->nInt64; val > SbxMAXCHAR)
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXCHAR;
-            }
-            else if (val < SbxMINCHAR)
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMINCHAR;
-            }
-            else
-                nRes = static_cast<sal_Unicode>(val);
-            break;
-        case SbxSALUINT64:
-            if( p->uInt64 > SbxMAXCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXCHAR;
-            }
-            else
-                nRes = static_cast<sal_Unicode>(p->uInt64);
-            break;
-        case SbxSINGLE:
-            if( p->nSingle > SbxMAXCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXCHAR;
-            }
-            else if( p->nSingle < SbxMINCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMINCHAR;
-            }
-            else
-                nRes = static_cast<sal_Unicode>(rtl::math::round( p->nSingle 
));
-            break;
-        case SbxDATE:
-        case SbxDOUBLE:
-        case SbxDECIMAL:
-        case SbxBYREF | SbxDECIMAL:
-            {
-            double dVal;
-            if( p->eType == SbxDECIMAL )
-            {
-                dVal = 0.0;
-                if( p->pDecimal )
-                    p->pDecimal->getDouble( dVal );
-            }
-            else
-                dVal = p->nDouble;
-
-            if( dVal > SbxMAXCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXCHAR;
-            }
-            else if( dVal < SbxMINCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMINCHAR;
-            }
-            else
-                nRes = static_cast<sal_uInt8>(rtl::math::round( dVal ));
-            break;
-            }
-        case SbxBYREF | SbxSTRING:
-        case SbxSTRING:
-        case SbxLPSTR:
-            if ( p->pOUString )
-            {
-                double d;
-                SbxDataType t;
-                if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE )
-                    nRes = 0;
-                else if( d > SbxMAXCHAR )
-                {
-                    SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXCHAR;
-                }
-                else if( d < SbxMINCHAR )
-                {
-                    SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMINCHAR;
-                }
-                else
-                    nRes = static_cast<sal_Unicode>(rtl::math::round( d ));
-            }
-            break;
-        case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                nRes = pVal->GetChar();
-            else
-            {
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
-            }
-            break;
-        }
-
-        case SbxBYREF | SbxCHAR:
-            nRes = *p->pChar; break;
-        // from here on will be tested
-        case SbxBYREF | SbxBYTE:
-            aTmp.nByte = *p->pByte; goto ref;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            aTmp.nInteger = *p->pInteger; goto ref;
-        case SbxBYREF | SbxLONG:
-            aTmp.nLong = *p->pLong; goto ref;
-        case SbxBYREF | SbxULONG:
-            aTmp.nULong = *p->pULong; goto ref;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            aTmp.nUShort = *p->pUShort; goto ref;
-        case SbxBYREF | SbxSINGLE:
-            aTmp.nSingle = *p->pSingle; goto ref;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            aTmp.nDouble = *p->pDouble; goto ref;
-        case SbxBYREF | SbxCURRENCY:
-        case SbxBYREF | SbxSALINT64:
-            aTmp.nInt64 = *p->pnInt64; goto ref;
-        case SbxBYREF | SbxSALUINT64:
-            aTmp.uInt64 = *p->puInt64; goto ref;
-        ref:
-            aTmp.eType = SbxDataType( p->eType & 0x0FFF );
-            p = &aTmp; goto start;
-
-        default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
-    }
-    return nRes;
-}
-
-void ImpPutChar( SbxValues* p, sal_Unicode n )
-{
-    SbxValues aTmp;
-start:
-    switch( +p->eType )
-    {
-        case SbxCHAR:
-            p->nChar = n; break;
-        case SbxINTEGER:
-        case SbxBOOL:
-            p->nInteger = n; break;
-        case SbxLONG:
-            p->nLong = n; break;
-        case SbxSINGLE:
-            p->nSingle = n; break;
-        case SbxDATE:
-        case SbxDOUBLE:
-            p->nDouble = n; break;
-        case SbxCURRENCY:
-            p->nInt64 = CurFrom(n); break;
-        case SbxSALINT64:
-            p->nInt64 = n; break;
-        case SbxSALUINT64:
-            p->uInt64 = n; break;
-        case SbxBYREF | SbxDECIMAL:
-            ImpCreateDecimal( p )->setChar( n );
-            break;
-
-        // from here on will be tested
-        case SbxBYTE:
-            aTmp.pByte = &p->nByte; goto direct;
-        case SbxULONG:
-            aTmp.pULong = &p->nULong; goto direct;
-        case SbxERROR:
-        case SbxUSHORT:
-            aTmp.pUShort = &p->nUShort; goto direct;
-        direct:
-            aTmp.eType = SbxDataType( p->eType | SbxBYREF );
-            p = &aTmp; goto start;
-
-        case SbxBYREF | SbxSTRING:
-        case SbxSTRING:
-        case SbxLPSTR:
-            if ( !p->pOUString )
-                p->pOUString = new OUString( n );
-            else
-                *p->pOUString = OUString( n );
-            break;
-        case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                pVal->PutChar( n );
-            else
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
-            break;
-        }
-        case SbxBYREF | SbxCHAR:
-            *p->pChar = n; break;
-        case SbxBYREF | SbxBYTE:
-            *p->pByte = static_cast<sal_uInt8>(n); break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            *p->pInteger = n; break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            *p->pUShort = static_cast<sal_uInt16>(n); break;
-        case SbxBYREF | SbxLONG:
-            *p->pLong = static_cast<sal_Int32>(n); break;
-        case SbxBYREF | SbxULONG:
-            *p->pULong = static_cast<sal_uInt32>(n); break;
-        case SbxBYREF | SbxSINGLE:
-            *p->pSingle = static_cast<float>(n); break;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            *p->pDouble = static_cast<double>(n); break;
-        case SbxBYREF | SbxCURRENCY:
-            p->nInt64 = CurFrom(n); break;
-        case SbxBYREF | SbxSALINT64:
-            *p->pnInt64 = n; break;
-        case SbxBYREF | SbxSALUINT64:
-            *p->puInt64 = n; break;
-
-        default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-    }
-}
-
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/sbx/sbxconv.hxx b/basic/source/sbx/sbxconv.hxx
index edb0e8cd973c..b04d534f42a2 100644
--- a/basic/source/sbx/sbxconv.hxx
+++ b/basic/source/sbx/sbxconv.hxx
@@ -32,32 +32,87 @@
 
 class SbxArray;
 
-template <typename I> inline I DoubleTo(double f, I min, I max)
+template <std::integral I> I ConvertWithOverflowTo(double f)
 {
     f = rtl::math::round(f);
-    if (!o3tl::convertsToAtMost(f, max))
+    if (!o3tl::convertsToAtMost(f, std::numeric_limits<I>::max()))
     {
         SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
-        return max;
+        return std::numeric_limits<I>::max();
     }
-    if (!o3tl::convertsToAtLeast(f, min))
+    if (!o3tl::convertsToAtLeast(f, std::numeric_limits<I>::min()))
     {
         SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
-        return min;
+        return std::numeric_limits<I>::min();
     }
     return f;
 }
 
-inline auto ImpDoubleToChar(double f) { return DoubleTo<sal_Unicode>(f, 
SbxMINCHAR, SbxMAXCHAR); }
-inline auto ImpDoubleToByte(double f) { return DoubleTo<sal_uInt8>(f, 0, 
SbxMAXBYTE); }
-inline auto ImpDoubleToUShort(double f) { return DoubleTo<sal_uInt16>(f, 0, 
SbxMAXUINT); }
-inline auto ImpDoubleToInteger(double f) { return DoubleTo<sal_Int16>(f, 
SbxMININT, SbxMAXINT); }
-inline auto ImpDoubleToULong(double f) { return DoubleTo<sal_uInt32>(f, 0, 
SbxMAXULNG); }
-inline auto ImpDoubleToLong(double f) { return DoubleTo<sal_Int32>(f, 
SbxMINLNG, SbxMAXLNG); }
-inline auto ImpDoubleToSalUInt64(double d) { return DoubleTo<sal_uInt64>(d, 0, 
SAL_MAX_UINT64); }
-inline auto ImpDoubleToSalInt64(double d)
+template <std::integral To, std::integral From> To ConvertWithOverflowTo(From 
n)
+{
+    using ValidRange = o3tl::ValidRange<To>;
+    if (ValidRange::isAbove(n))
+    {
+        SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+        return std::numeric_limits<To>::max();
+    }
+    if (ValidRange::isBelow(n))
+    {
+        SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+        return std::numeric_limits<To>::min();
+    }
+    return n;
+}
+
+template <std::floating_point To, std::floating_point From> inline To 
ConvertWithOverflowTo(From n)
+{
+    if constexpr (std::numeric_limits<From>::max() > 
std::numeric_limits<To>::max())
+    {
+        if (n > std::numeric_limits<To>::max())
+        {
+            SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+            return std::numeric_limits<To>::max();
+        }
+    }
+    if constexpr (std::numeric_limits<From>::lowest() < 
std::numeric_limits<To>::lowest())
+    {
+        if (n < std::numeric_limits<To>::lowest())
+        {
+            SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+            return std::numeric_limits<To>::lowest();
+        }
+    }
+    // tests for underflow - storing value too small for precision of single
+    if constexpr (std::numeric_limits<From>::min() < 
std::numeric_limits<To>::min())
+    {
+        if (n > 0 && n < std::numeric_limits<To>::min())
+        {
+            SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+            return std::numeric_limits<To>::min();
+        }
+        if (n < 0 && n > -std::numeric_limits<To>::min())
+        {
+            SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+            return -std::numeric_limits<To>::min();
+        }
+    }
+    return n;
+}
+
+template <std::floating_point To, std::integral From> inline To 
ConvertWithOverflowTo(From n)
 {
-    return DoubleTo<sal_Int64>(d, SAL_MIN_INT64, SAL_MAX_INT64);
+    // No integral types overflow floats
+    return static_cast<To>(n);
+}
+
+template <typename T1, typename T2> void assignWithOverflowTo(T1& dest, T2 src)
+{
+    dest = ConvertWithOverflowTo<T1>(src);
+}
+
+template <typename T> void assignWithOverflowTo(T& dest, SbxDecimal& dec)
+{
+    dest = dec.getWithOverflow<T>();
 }
 
 // SBXSCAN.CXX
@@ -73,37 +128,33 @@ void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, 
sal_Unicode& rcThousandSep, sal
 
 // SBXINT.CXX
 
+sal_Unicode ImpGetChar( const SbxValues* );
+void        ImpPutChar( SbxValues*, sal_Unicode );
+sal_uInt8   ImpGetByte( const SbxValues* );
+void        ImpPutByte( SbxValues*, sal_uInt8 );
 sal_Int16   ImpGetInteger( const SbxValues* );
 void        ImpPutInteger( SbxValues*, sal_Int16 );
-
+sal_uInt16  ImpGetUShort( const SbxValues* );
+void        ImpPutUShort( SbxValues*, sal_uInt16 );
+sal_Int32   ImpGetLong( const SbxValues* );
+void        ImpPutLong( SbxValues*, sal_Int32 );
+sal_uInt32  ImpGetULong( const SbxValues* );
+void        ImpPutULong( SbxValues*, sal_uInt32 );
 sal_Int64   ImpGetInt64( const SbxValues* );
 void        ImpPutInt64( SbxValues*, sal_Int64 );
 sal_uInt64  ImpGetUInt64( const SbxValues* );
 void        ImpPutUInt64( SbxValues*, sal_uInt64 );
-
-double      ImpSalUInt64ToDouble( sal_uInt64 n );
-
-// SBXLNG.CXX
-
-sal_Int32   ImpGetLong( const SbxValues* );
-void    ImpPutLong( SbxValues*, sal_Int32 );
-
-// SBXSNG.CXX
-
-float   ImpGetSingle( const SbxValues* );
-void    ImpPutSingle( SbxValues*, float );
-
-// SBXDBL.CXX
-
-double  ImpGetDouble( const SbxValues* );
-void    ImpPutDouble( SbxValues*, double, bool bCoreString=false );
+double      ImpGetDouble( const SbxValues* );
+void        ImpPutDouble( SbxValues*, double, bool bCoreString=false );
+float       ImpGetSingle( const SbxValues* );
+void        ImpPutSingle( SbxValues*, float );
 
 // SBXCURR.CXX
 
 sal_Int64   ImpGetCurrency( const SbxValues* );
 void        ImpPutCurrency( SbxValues*, const sal_Int64 );
 
-inline  sal_Int64   ImpDoubleToCurrency( double d )
+inline sal_Int64 CurFrom(double d)
 {
     double result = d > 0 ? (d * CURRENCY_FACTOR + 0.5) : (d * CURRENCY_FACTOR 
- 0.5);
     if (result >= double(SAL_MAX_INT64)) // double(SAL_MAX_INT64) is greater 
than SAL_MAX_INT64
@@ -119,9 +170,7 @@ inline  sal_Int64   ImpDoubleToCurrency( double d )
     return result;
 }
 
-template <typename I>
-    requires std::is_integral_v<I>
-inline sal_Int64 CurFrom(I n)
+template <std::integral I> sal_Int64 CurFrom(I n)
 {
     using ValidRange = o3tl::ValidRange<sal_Int64, SAL_MIN_INT64 / 
CURRENCY_FACTOR, SAL_MAX_INT64 / CURRENCY_FACTOR>;
     if (ValidRange::isAbove(n))
@@ -137,24 +186,9 @@ inline sal_Int64 CurFrom(I n)
     return n * CURRENCY_FACTOR;
 }
 
-inline double ImpCurrencyToDouble(sal_Int64 r) { return static_cast<double>(r) 
/ CURRENCY_FACTOR; }
-
-template <typename I>
-    requires std::is_integral_v<I>
-inline I CurTo(sal_Int64 cur_val)
+template <std::integral I> I CurTo(sal_Int64 cur_val)
 {
-    sal_Int64 i = CurTo<sal_Int64>(cur_val);
-    if (o3tl::ValidRange<I>::isAbove(i))
-    {
-        SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
-        return std::numeric_limits<I>::max();
-    }
-    if (o3tl::ValidRange<I>::isBelow(i))
-    {
-        SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
-        return std::numeric_limits<I>::min();
-    }
-    return i;
+    return ConvertWithOverflowTo<I>(CurTo<sal_Int64>(cur_val));
 }
 
 template <> inline sal_Int64 CurTo<sal_Int64>(sal_Int64 cur_val)
@@ -176,6 +210,10 @@ template <> inline sal_Int64 CurTo<sal_Int64>(sal_Int64 
cur_val)
     return i;
 }
 
+template <std::floating_point F> F CurTo(sal_Int64 r)
+{
+    return ConvertWithOverflowTo<F>(static_cast<double>(r) / CURRENCY_FACTOR);
+}
 
 // SBXDEC.CXX
 
@@ -194,25 +232,6 @@ OUString     ImpGetString( const SbxValues* );
 OUString     ImpGetCoreString( const SbxValues* );
 void    ImpPutString( SbxValues*, const OUString* );
 
-// SBXCHAR.CXX
-
-sal_Unicode ImpGetChar( const SbxValues* );
-void        ImpPutChar( SbxValues*, sal_Unicode );
-
-// SBXBYTE.CXX
-sal_uInt8   ImpGetByte( const SbxValues* );
-void    ImpPutByte( SbxValues*, sal_uInt8 );
-
-// SBXUINT.CXX
-
-sal_uInt16  ImpGetUShort( const SbxValues* );
-void    ImpPutUShort( SbxValues*, sal_uInt16 );
-
-// SBXULNG.CXX
-
-sal_uInt32  ImpGetULong( const SbxValues* );
-void    ImpPutULong( SbxValues*, sal_uInt32 );
-
 // SBXBOOL.CXX
 
 enum SbxBOOL ImpGetBool( const SbxValues* );
diff --git a/basic/source/sbx/sbxcurr.cxx b/basic/source/sbx/sbxcurr.cxx
index d5fe4be9f6b7..5b452686de24 100644
--- a/basic/source/sbx/sbxcurr.cxx
+++ b/basic/source/sbx/sbxcurr.cxx
@@ -104,129 +104,98 @@ static sal_Int64 ImpStringToCurrency(const 
rtl::OUString& rStr)
         SbxBase::SetError(ERRCODE_BASIC_CONVERSION);
     }
 
-    return ImpDoubleToCurrency(fResult);
+    return CurFrom(fResult);
 }
 
 sal_Int64 ImpGetCurrency( const SbxValues* p )
 {
-    SbxValues   aTmp;
-    sal_Int64  nRes;
-start:
     switch( +p->eType )
     {
         case SbxERROR:
         case SbxNULL:
             SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            nRes = 0; break;
+            return 0;
         case SbxEMPTY:
-            nRes = 0; break;
+            return 0;
         case SbxCURRENCY:
-            nRes = p->nInt64; break;
+            return p->nInt64;
         case SbxBYTE:
-            nRes = CurFrom(p->nByte);
-            break;
+            return CurFrom(p->nByte);
         case SbxCHAR:
-            nRes = CurFrom(p->nChar);
-            break;
+            return CurFrom(p->nChar);
         case SbxBOOL:
         case SbxINTEGER:
-            nRes = CurFrom(p->nInteger);
-            break;
+            return CurFrom(p->nInteger);
         case SbxUSHORT:
-            nRes = CurFrom(p->nUShort);
-            break;
+            return CurFrom(p->nUShort);
         case SbxLONG:
-            nRes = CurFrom(p->nLong);
-            break;
+            return CurFrom(p->nLong);
         case SbxULONG:
-            nRes = CurFrom(p->nULong);
-            break;
+            return CurFrom(p->nULong);
         case SbxSALINT64:
-            nRes = CurFrom(p->nInt64);
-            break;
+            return CurFrom(p->nInt64);
         case SbxSALUINT64:
-            nRes = CurFrom(p->uInt64);
-            break;
+            return CurFrom(p->uInt64);
         case SbxSINGLE:
-            nRes = ImpDoubleToCurrency(p->nSingle);
-            break;
+            return CurFrom(p->nSingle);
 
         case SbxDATE:
         case SbxDOUBLE:
-            nRes = ImpDoubleToCurrency( p->nDouble );
-            break;
+            return CurFrom(p->nDouble);
 
         case SbxDECIMAL:
         case SbxBYREF | SbxDECIMAL:
-            {
-            double d = 0.0;
             if( p->pDecimal )
+            {
+                double d = 0.0;
                 p->pDecimal->getDouble( d );
-            nRes = ImpDoubleToCurrency( d );
-            break;
+                return CurFrom(d);
             }
-
+            return 0;
 
         case SbxBYREF | SbxSTRING:
         case SbxSTRING:
         case SbxLPSTR:
-            if( !p->pOUString )
-                nRes=0;
-            else
-                nRes = ImpStringToCurrency( *p->pOUString );
-            break;
+            if (p->pOUString)
+                return ImpStringToCurrency( *p->pOUString );
+            return 0;
         case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                nRes = pVal->GetCurrency();
-            else
-            {
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
-                nRes=0;
-            }
-            break;
-        }
+            if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
+                return pVal->GetCurrency();
+            SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
+            return 0;
 
         case SbxBYREF | SbxCHAR:
-            nRes = CurFrom(*p->pChar);
-            break;
+            return CurFrom(*p->pChar);
         case SbxBYREF | SbxBYTE:
-            nRes = CurFrom(*p->pByte);
-            break;
+            return CurFrom(*p->pByte);
         case SbxBYREF | SbxBOOL:
         case SbxBYREF | SbxINTEGER:
-            nRes = CurFrom(*p->pInteger);
-            break;
+            return CurFrom(*p->pInteger);
         case SbxBYREF | SbxERROR:
         case SbxBYREF | SbxUSHORT:
-            nRes = CurFrom(*p->pUShort);
-            break;
+            return CurFrom(*p->pUShort);
 
-        // from here on had to be tested
         case SbxBYREF | SbxLONG:
-            aTmp.nLong = *p->pLong; goto ref;
+            return CurFrom(*p->pLong);
         case SbxBYREF | SbxULONG:
-            aTmp.nULong = *p->pULong; goto ref;
+            return CurFrom(*p->pULong);
         case SbxBYREF | SbxSINGLE:
-            aTmp.nSingle = *p->pSingle; goto ref;
+            return CurFrom(*p->pSingle);
         case SbxBYREF | SbxDATE:
         case SbxBYREF | SbxDOUBLE:
-            aTmp.nDouble = *p->pDouble; goto ref;
+            return CurFrom(*p->pDouble);
         case SbxBYREF | SbxCURRENCY:
+            return *p->pnInt64;
         case SbxBYREF | SbxSALINT64:
-            aTmp.nInt64 = *p->pnInt64; goto ref;
+            return CurFrom(*p->pnInt64);
         case SbxBYREF | SbxSALUINT64:
-            aTmp.uInt64 = *p->puInt64; goto ref;
-        ref:
-            aTmp.eType = SbxDataType( p->eType & ~SbxBYREF );
-            p = &aTmp; goto start;
+            return CurFrom(*p->puInt64);
 
         default:
             SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            nRes=0;
+            return 0;
     }
-    return nRes;
 }
 
 void ImpPutCurrency( SbxValues* p, const sal_Int64 r )
@@ -235,7 +204,7 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r )
     {
         case SbxDATE:
         case SbxDOUBLE:
-            p->nDouble =  ImpCurrencyToDouble( r ); break;
+            p->nDouble =  CurTo<double>( r ); break;
         case SbxSALUINT64:
             p->uInt64 = CurTo<sal_uInt64>(r); break;
         case SbxSALINT64:
@@ -246,12 +215,9 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r )
 
         case SbxDECIMAL:
         case SbxBYREF | SbxDECIMAL:
-            {
-            SbxDecimal* pDec = ImpCreateDecimal( p );
-            if( !pDec->setDouble( ImpCurrencyToDouble( r ) ) )
+            if (!ImpCreateDecimal(p)->setDouble(CurTo<double>(r)))
                 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
             break;
-            }
         case SbxBYREF | SbxSTRING:
         case SbxSTRING:
         case SbxLPSTR:
@@ -261,14 +227,11 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r )
             *p->pOUString = ImpCurrencyToString( r );
             break;
         case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
+            if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
                 pVal->PutCurrency( r );
             else
                 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
             break;
-        }
         case SbxCHAR:
             p->nChar = CurTo<sal_Unicode>(r); break;
         case SbxBYREF | SbxCHAR:
@@ -304,11 +267,12 @@ void ImpPutCurrency( SbxValues* p, const sal_Int64 r )
         case SbxBYREF | SbxSALUINT64:
             *p->puInt64 = CurTo<sal_uInt64>(r); break;
         case SbxSINGLE:
+            p->nSingle = CurTo<float>( r ); break;
         case SbxBYREF | SbxSINGLE:
-            p->nSingle = r / float(CURRENCY_FACTOR); break;
+            *p->pSingle = CurTo<float>( r ); break;
         case SbxBYREF | SbxDATE:
         case SbxBYREF | SbxDOUBLE:
-            *p->pDouble = ImpCurrencyToDouble( r ); break;
+            *p->pDouble = CurTo<double>( r ); break;
         default:
             SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
     }
diff --git a/basic/source/sbx/sbxdate.cxx b/basic/source/sbx/sbxdate.cxx
index 057e16f09d03..c3d3a4d2a4f2 100644
--- a/basic/source/sbx/sbxdate.cxx
+++ b/basic/source/sbx/sbxdate.cxx
@@ -35,67 +35,46 @@
 
 double ImpGetDate( const SbxValues* p )
 {
-    double nRes;
-    SbxValue* pVal;
-
     switch( +p->eType )
     {
-    case SbxNULL:
-        SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-        [[fallthrough]];
     case SbxEMPTY:
-        nRes = 0;
-        break;
+        return 0;
     case SbxCHAR:
-        nRes = p->nChar;
-        break;
+        return p->nChar;
     case SbxBYTE:
-        nRes = p->nByte;
-        break;
+        return p->nByte;
     case SbxINTEGER:
     case SbxBOOL:
-        nRes = p->nInteger;
-        break;
+        return p->nInteger;
     case SbxERROR:
     case SbxUSHORT:
-        nRes = p->nUShort;
-        break;
+        return p->nUShort;
     case SbxLONG:
-        nRes = static_cast<double>(p->nLong);
-        break;
+        return p->nLong;
     case SbxULONG:
-        nRes = static_cast<double>(p->nULong);
-        break;
+        return p->nULong;
     case SbxSINGLE:
-        nRes = p->nSingle;
-        break;
+        return p->nSingle;
     case SbxDATE:
     case SbxDOUBLE:
-        nRes = p->nDouble;
-        break;
+        return p->nDouble;
     case SbxCURRENCY:
-        nRes = ImpCurrencyToDouble( p->nInt64 );
-        break;
+        return CurTo<double>(p->nInt64);
     case SbxSALINT64:
-        nRes = static_cast< double >(p->nInt64);
-        break;
+        return static_cast<double>(p->nInt64);
     case SbxSALUINT64:
-        nRes = ImpSalUInt64ToDouble( p->uInt64 );
-        break;
+        return static_cast<double>(p->uInt64);
     case SbxDECIMAL:
     case SbxBYREF | SbxDECIMAL:
-        if (!p->pDecimal || !p->pDecimal->getDouble(nRes))
-            nRes = 0.0;
-        break;
+        if (p->pDecimal)
+            if (double d; p->pDecimal->getDouble(d))
+                return d;
+        return 0;
     case SbxBYREF | SbxSTRING:
     case SbxSTRING:
     case SbxLPSTR:
 #if HAVE_FEATURE_SCRIPTING
-        if( !p->pOUString )
-        {
-            nRes = 0;
-        }
-        else
+        if (p->pOUString)
         {
             LanguageType eLangType = 
Application::GetSettings().GetLanguageTag().getLanguageType();
             std::shared_ptr<SvNumberFormatter> pFormatter;
@@ -137,135 +116,137 @@ double ImpGetDate( const SbxValues* p )
 
             pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
                                             nIndex, LANGUAGE_ENGLISH_US, 
eLangType, true);
-            bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, 
nRes );
-            if ( bSuccess )
+            if (double d; pFormatter->IsNumberFormat(*p->pOUString, nIndex, d))
             {
                 SvNumFormatType nType_ = pFormatter->GetType( nIndex );
-                if(!(nType_ & ( SvNumFormatType::DATETIME | 
SvNumFormatType::DATE |
-                                SvNumFormatType::TIME | 
SvNumFormatType::DEFINED )))
+                if(nType_ & ( SvNumFormatType::DATETIME | 
SvNumFormatType::DATE |
+                                SvNumFormatType::TIME | 
SvNumFormatType::DEFINED ))
                 {
-                    bSuccess = false;
+                    return d;
                 }
             }
 
-            if ( !bSuccess )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
-            }
+            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
         }
-#else
-        nRes = 0;
 #endif
-        break;
+        return 0;
     case SbxOBJECT:
-        pVal = dynamic_cast<SbxValue*>( p->pObj );
-        if( pVal )
-        {
-            nRes = pVal->GetDate();
-        }
-        else
-        {
-            SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
-        }
-        break;
+        if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
+            return pVal->GetDate();
+        SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
+        return 0;
     case SbxBYREF | SbxCHAR:
-        nRes = *p->pChar;
-        break;
+        return *p->pChar;
     case SbxBYREF | SbxBYTE:
-        nRes = *p->pByte;
-        break;
+        return *p->pByte;
     case SbxBYREF | SbxINTEGER:
     case SbxBYREF | SbxBOOL:
-        nRes = *p->pInteger;
-        break;
+        return *p->pInteger;
     case SbxBYREF | SbxLONG:
-        nRes = *p->pLong;
-        break;
+        return *p->pLong;
     case SbxBYREF | SbxULONG:
-        nRes = *p->pULong;
-        break;
+        return *p->pULong;
     case SbxBYREF | SbxERROR:
     case SbxBYREF | SbxUSHORT:
-        nRes = *p->pUShort;
-        break;
+        return *p->pUShort;
     case SbxBYREF | SbxSINGLE:
-        nRes = *p->pSingle;
-        break;
+        return *p->pSingle;
     case SbxBYREF | SbxDATE:
     case SbxBYREF | SbxDOUBLE:
-        nRes = *p->pDouble;
-        break;
+        return *p->pDouble;
     case SbxBYREF | SbxCURRENCY:
-        nRes = ImpCurrencyToDouble( *p->pnInt64 );
-        break;
+        return CurTo<double>(*p->pnInt64);
     case SbxBYREF | SbxSALINT64:
-        nRes = static_cast< double >(*p->pnInt64);
-        break;
+        return static_cast<double>(*p->pnInt64);
     case SbxBYREF | SbxSALUINT64:
-        nRes = ImpSalUInt64ToDouble( *p->puInt64 );
-        break;
+        return static_cast<double>(*p->puInt64);
     default:
-        SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
-        break;
+        SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
+        return 0;
     }
-    return nRes;
 }
 
 void ImpPutDate( SbxValues* p, double n )
 {
-    SbxValues aTmp;
-    SbxDecimal* pDec;
-    SbxValue* pVal;
-
-start:
     switch( +p->eType )
     {
     case SbxDATE:
     case SbxDOUBLE:
         p->nDouble = n;
         break;
-        // from here will be tested
+    case SbxBYREF | SbxDATE:
+    case SbxBYREF | SbxDOUBLE:
+        *p->pDouble = n;
+        break;
     case SbxCHAR:
-        aTmp.pChar = &p->nChar;
-        goto direct;
+        assignWithOverflowTo(p->nChar, n);
+        break;
+    case SbxBYREF | SbxCHAR:
+        assignWithOverflowTo(*p->pChar, n);
+        break;
     case SbxBYTE:
-        aTmp.pByte = &p->nByte;
-        goto direct;
+        assignWithOverflowTo(p->nByte, n);
+        break;
+    case SbxBYREF | SbxBYTE:
+        assignWithOverflowTo(*p->pByte, n);
+        break;
     case SbxINTEGER:
     case SbxBOOL:
-        aTmp.pInteger = &p->nInteger;
-        goto direct;
-    case SbxLONG:
-        aTmp.pLong = &p->nLong;
-        goto direct;
-    case SbxULONG:
-        aTmp.pULong = &p->nULong;
-        goto direct;
+        assignWithOverflowTo(p->nInteger, n);
+        break;
+    case SbxBYREF | SbxINTEGER:
+    case SbxBYREF | SbxBOOL:
+        assignWithOverflowTo(*p->pInteger, n);
+        break;
     case SbxERROR:
     case SbxUSHORT:
-        aTmp.pUShort = &p->nUShort;
-        goto direct;
-    case SbxSINGLE:
-        aTmp.pSingle = &p->nSingle;
-        goto direct;
+        assignWithOverflowTo(p->nUShort, n);
+        break;
+    case SbxBYREF | SbxERROR:
+    case SbxBYREF | SbxUSHORT:
+        assignWithOverflowTo(*p->pUShort, n);
+        break;
+    case SbxLONG:
+        assignWithOverflowTo(p->nLong, n);
+        break;
+    case SbxBYREF | SbxLONG:
+        assignWithOverflowTo(*p->pLong, n);
+        break;
+    case SbxULONG:
+        assignWithOverflowTo(p->nULong, n);
+        break;
+    case SbxBYREF | SbxULONG:
+        assignWithOverflowTo(*p->pULong, n);
+        break;
     case SbxCURRENCY:
+        assignWithOverflowTo(p->nInt64, CurFrom(n));
+        break;
+    case SbxBYREF | SbxCURRENCY:
+        assignWithOverflowTo(*p->pnInt64, CurFrom(n));
+        break;
     case SbxSALINT64:
-        aTmp.pnInt64 = &p->nInt64;
-        goto direct;
+        assignWithOverflowTo(p->nInt64, n);
+        break;
+    case SbxBYREF | SbxSALINT64:
+        assignWithOverflowTo(*p->pnInt64, n);
+        break;
     case SbxSALUINT64:
-        aTmp.puInt64 = &p->uInt64;
-        goto direct;
+        assignWithOverflowTo(p->uInt64, n);
+        break;
+    case SbxBYREF | SbxSALUINT64:
+        assignWithOverflowTo(*p->puInt64, n);
+        break;
+    case SbxSINGLE:
+        assignWithOverflowTo(p->nSingle, n);
+        break;
+    case SbxBYREF | SbxSINGLE:
+        assignWithOverflowTo(*p->pSingle, n);
+        break;
+
     case SbxDECIMAL:
     case SbxBYREF | SbxDECIMAL:
-        pDec = ImpCreateDecimal( p );
-        if( !pDec->setDouble( n ) )
-        {
-            SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-        }
+        ImpCreateDecimal(p)->setWithOverflow(n);
         break;
-    direct:
-        aTmp.eType = SbxDataType( p->eType | SbxBYREF );
-        p = &aTmp; goto start;
 
     case SbxBYREF | SbxSTRING:
     case SbxSTRING:
@@ -336,9 +317,9 @@ start:
 #endif
             break;
         }
+
     case SbxOBJECT:
-        pVal = dynamic_cast<SbxValue*>( p->pObj );
-        if( pVal )
+        if (auto pVal = dynamic_cast<SbxValue*>(p->pObj))
         {
             pVal->PutDate( n );
         }
@@ -347,58 +328,7 @@ start:
             SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
         }
         break;
-    case SbxBYREF | SbxCHAR:
-        *p->pChar = ImpDoubleToChar(n);
-        break;
-    case SbxBYREF | SbxBYTE:
-        *p->pByte = ImpDoubleToByte(n);
-        break;
-    case SbxBYREF | SbxINTEGER:
-    case SbxBYREF | SbxBOOL:
-        *p->pInteger = ImpDoubleToInteger(n);
-        break;
-    case SbxBYREF | SbxERROR:
-    case SbxBYREF | SbxUSHORT:
-        *p->pUShort = ImpDoubleToUShort(n);
-        break;
-    case SbxBYREF | SbxLONG:
-        *p->pLong = ImpDoubleToLong(n);
-        break;
-    case SbxBYREF | SbxULONG:
-        *p->pULong = ImpDoubleToULong(n);
-        break;
-    case SbxBYREF | SbxSINGLE:
-        if( n > SbxMAXSNG )
-        {
-            SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXSNG;
-        }
-        else if( n < SbxMINSNG )
-        {
-            SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINSNG;
-        }
-        *p->pSingle = static_cast<float>(n);
-        break;
-    case SbxBYREF | SbxSALINT64:
-        *p->pnInt64 = ImpDoubleToSalInt64( n );
-        break;
-    case SbxBYREF | SbxSALUINT64:
-        *p->puInt64 = ImpDoubleToSalUInt64( n );
-        break;
-    case SbxBYREF | SbxDATE:
-    case SbxBYREF | SbxDOUBLE:
-        *p->pDouble = n;
-        break;
-    case SbxBYREF | SbxCURRENCY:
-        if( n > SbxMAXCURR )
-        {
-            SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMAXCURR;
-        }
-        else if( n < SbxMINCURR )
-        {
-            SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = SbxMINCURR;
-        }
-        *p->pnInt64 = ImpDoubleToCurrency( n );
-        break;
+
     default:
         SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
         break;
diff --git a/basic/source/sbx/sbxdbl.cxx b/basic/source/sbx/sbxdbl.cxx
deleted file mode 100644
index fa6ca01d6219..000000000000
--- a/basic/source/sbx/sbxdbl.cxx
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <config_features.h>
-
-#include <comphelper/errcode.hxx>
-#include "sbxconv.hxx"
-#include <runtime.hxx>
-
-double ImpGetDouble( const SbxValues* p )
-{
-    double nRes;
-    switch( +p->eType )
-    {
-        case SbxNULL:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            [[fallthrough]];
-        case SbxEMPTY:
-            nRes = 0; break;
-        case SbxCHAR:
-            nRes = p->nChar; break;
-        case SbxBYTE:
-            nRes = p->nByte; break;
-        case SbxINTEGER:
-        case SbxBOOL:
-            nRes = p->nInteger; break;
-        case SbxERROR:
-        case SbxUSHORT:
-            nRes = p->nUShort; break;
-        case SbxLONG:
-            nRes = p->nLong; break;
-        case SbxULONG:
-            nRes = p->nULong; break;
-        case SbxSINGLE:
-            nRes = p->nSingle; break;
-        case SbxDATE:
-        case SbxDOUBLE:
-            nRes = p->nDouble; break;
-        case SbxCURRENCY:
-            nRes = ImpCurrencyToDouble( p->nInt64 ); break;
-        case SbxSALINT64:
-            nRes = static_cast< double >(p->nInt64); break;
-        case SbxSALUINT64:
-            nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
-        case SbxDECIMAL:
-        case SbxBYREF | SbxDECIMAL:
-            if (!p->pDecimal || !p->pDecimal->getDouble(nRes))
-                nRes = 0.0;
-            break;
-        case SbxBYREF | SbxSTRING:
-        case SbxSTRING:
-        case SbxLPSTR:
-            if( !p->pOUString )
-            {
-                nRes = 0;
-#if HAVE_FEATURE_SCRIPTING
-                if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
-                    SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-#endif
-            }
-            else
-            {
-                double d;
-                SbxDataType t;
-                if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE )
-                {
-                    nRes = 0;
-#if HAVE_FEATURE_SCRIPTING
-                    if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
-                        SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-#endif
-                }
-                else
-                    nRes = d;
-            }
-            break;
-        case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                nRes = pVal->GetDouble();
-            else
-            {
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
-            }
-            break;
-        }
-
-        case SbxBYREF | SbxCHAR:
-            nRes = *p->pChar; break;
-        case SbxBYREF | SbxBYTE:
-            nRes = *p->pByte; break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            nRes = *p->pInteger; break;
-        case SbxBYREF | SbxLONG:
-            nRes = *p->pLong; break;
-        case SbxBYREF | SbxULONG:
-            nRes = *p->pULong; break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            nRes = *p->pUShort; break;
-        case SbxBYREF | SbxSINGLE:
-            nRes = *p->pSingle; break;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            nRes = *p->pDouble; break;
-        case SbxBYREF | SbxCURRENCY:
-            nRes = ImpCurrencyToDouble( *p->pnInt64 ); break;
-        case SbxBYREF | SbxSALINT64:
-            nRes = static_cast< double >(*p->pnInt64); break;
-        case SbxBYREF | SbxSALUINT64:
-            nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
-
-        default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
-    }
-    return nRes;
-}
-
-void ImpPutDouble( SbxValues* p, double n, bool bCoreString )
-{
-    SbxValues aTmp;
-start:
-    switch( +p->eType )
-    {
-        // Here are tests necessary
-        case SbxCHAR:
-            aTmp.pChar = &p->nChar; goto direct;
-        case SbxBYTE:
-            aTmp.pByte = &p->nByte; goto direct;
-        case SbxINTEGER:
-        case SbxBOOL:
-            aTmp.pInteger = &p->nInteger; goto direct;
-        case SbxLONG:
-            aTmp.pLong = &p->nLong; goto direct;
-        case SbxULONG:
-            aTmp.pULong = &p->nULong; goto direct;
-        case SbxERROR:
-        case SbxUSHORT:
-            aTmp.pUShort = &p->nUShort; goto direct;
-        case SbxSINGLE:
-            aTmp.pSingle = &p->nSingle; goto direct;
-        case SbxDECIMAL:
-        case SbxBYREF | SbxDECIMAL:
-            {
-            SbxDecimal* pDec = ImpCreateDecimal( p );
-            if( !pDec->setDouble( n ) )
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-            break;
-            }
-        direct:
-            aTmp.eType = SbxDataType( p->eType | SbxBYREF );
-            p = &aTmp; goto start;
-
-        case SbxCURRENCY:
-            if( n > SbxMAXCURR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMAXCURR;
-            }
-            else if( n < SbxMINCURR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMINCURR;
-            }
-            p->nInt64 = ImpDoubleToCurrency( n );
-            break;
-
-            // from here on no longer
-        case SbxSALINT64:
-            p->nInt64 = ImpDoubleToSalInt64( n ); break;
-        case SbxSALUINT64:
-            p->uInt64 = ImpDoubleToSalUInt64( n ); break;
-        case SbxDATE:
-        case SbxDOUBLE:
-            p->nDouble = n; break;
-
-        case SbxBYREF | SbxSTRING:
-        case SbxSTRING:
-        case SbxLPSTR:
-            if( !p->pOUString )
-                p->pOUString = new OUString;
-            // tdf#107953 - show 17 significant digits
-            ImpCvtNum( n, 17, *p->pOUString, bCoreString );
-            break;
-        case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                pVal->PutDouble( n );
-            else
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
-            break;
-        }
-        case SbxBYREF | SbxCHAR:
-            *p->pChar = ImpDoubleToChar(n); break;
-        case SbxBYREF | SbxBYTE:
-            *p->pByte = ImpDoubleToByte(n); break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            *p->pInteger = ImpDoubleToInteger(n); break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            *p->pUShort = ImpDoubleToUShort(n); break;
-        case SbxBYREF | SbxLONG:
-            *p->pLong = ImpDoubleToLong(n); break;
-        case SbxBYREF | SbxULONG:
-            *p->pULong = ImpDoubleToULong(n); break;
-        case SbxBYREF | SbxSINGLE:
-            if( n > SbxMAXSNG )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMAXSNG;
-            }
-            else if( n < SbxMINSNG )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMINSNG;
-            }
-            else if( n > 0 && n < SbxMAXSNG2 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMAXSNG2;
-            }
-            else if( n < 0 && n > SbxMINSNG2 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMINSNG2;
-            }
-            *p->pSingle = static_cast<float>(n); break;
-        case SbxBYREF | SbxSALINT64:
-            *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
-        case SbxBYREF | SbxSALUINT64:
-            *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            *p->pDouble = n; break;
-        case SbxBYREF | SbxCURRENCY:
-            if( n > SbxMAXCURR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMAXCURR;
-            }
-            else if( n < SbxMINCURR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMINCURR;
-            }
-            *p->pnInt64 = ImpDoubleToCurrency( n ); break;
-
-        default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-    }
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/sbx/sbxdec.cxx b/basic/source/sbx/sbxdec.cxx
index cad5601f2f7b..e6a8837fe7ee 100644
--- a/basic/source/sbx/sbxdec.cxx
+++ b/basic/source/sbx/sbxdec.cxx
@@ -157,6 +157,11 @@ void SbxDecimal::setLong( sal_Int32 val )
     VarDecFromI4(static_cast<LONG>(val), &maDec);
 }
 
+bool SbxDecimal::setHyper( sal_Int64 val )
+{
+    return SUCCEEDED(VarDecFromI8(static_cast<LONG64>(val), &maDec));
+}
+
 void SbxDecimal::setUShort( sal_uInt16 val )
 {
     VarDecFromUI2( val, &maDec );
@@ -167,6 +172,11 @@ void SbxDecimal::setULong( sal_uInt32 val )
     VarDecFromUI4( static_cast<ULONG>(val), &maDec );
 }
 
+bool SbxDecimal::setUHyper( sal_uInt64 val )
+{
+    return SUCCEEDED(VarDecFromUI8( static_cast<ULONG64>(val), &maDec ));
+}
+
 bool SbxDecimal::setSingle( float val )
 {
     bool bRet = ( VarDecFromR4( val, &maDec ) == S_OK );
@@ -241,6 +251,12 @@ bool SbxDecimal::getChar( sal_Unicode& rVal )
     return bRet;
 }
 
+bool SbxDecimal::getByte( sal_uInt8& rVal )
+{
+    bool bRet = ( VarUI1FromDec( &maDec, &rVal ) == S_OK );
+    return bRet;
+}
+
 bool SbxDecimal::getShort( sal_Int16& rVal )
 {
     bool bRet = ( VarI2FromDec( &maDec, &rVal ) == S_OK );
@@ -253,6 +269,12 @@ bool SbxDecimal::getLong( sal_Int32& rVal )
     return bRet;
 }
 
+bool SbxDecimal::getHyper( sal_Int64& rVal )
+{
+    bool bRet = ( VarI8FromDec( &maDec, &rVal ) == S_OK );
+    return bRet;
+}
+
 bool SbxDecimal::getUShort( sal_uInt16& rVal )
 {
     bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
@@ -265,6 +287,12 @@ bool SbxDecimal::getULong( sal_uInt32& rVal )
     return bRet;
 }
 
+bool SbxDecimal::getUHyper( sal_uInt64& rVal )
+{
+    bool bRet = ( VarUI8FromDec( &maDec, &rVal ) == S_OK );
+    return bRet;
+}
+
 bool SbxDecimal::getSingle( float& rVal )
 {
     bool bRet = ( VarR4FromDec( &maDec, &rVal ) == S_OK );
@@ -319,8 +347,10 @@ void SbxDecimal::setChar( SAL_UNUSED_PARAMETER sal_Unicode 
) {}
 void SbxDecimal::setByte( SAL_UNUSED_PARAMETER sal_uInt8 ) {}
 void SbxDecimal::setShort( SAL_UNUSED_PARAMETER sal_Int16 ) {}
 void SbxDecimal::setLong( SAL_UNUSED_PARAMETER sal_Int32 ) {}
+bool SbxDecimal::setHyper( SAL_UNUSED_PARAMETER sal_Int64 ) { return false; }
 void SbxDecimal::setUShort( SAL_UNUSED_PARAMETER sal_uInt16 ) {}
 void SbxDecimal::setULong( SAL_UNUSED_PARAMETER sal_uInt32 ) {}
+bool SbxDecimal::setUHyper( SAL_UNUSED_PARAMETER sal_uInt64 ) { return false; }
 bool SbxDecimal::setSingle( SAL_UNUSED_PARAMETER float ) { return false; }
 bool SbxDecimal::setDouble( SAL_UNUSED_PARAMETER double ) { return false; }
 void SbxDecimal::setInt( SAL_UNUSED_PARAMETER int ) {}
@@ -328,10 +358,13 @@ void SbxDecimal::setUInt( SAL_UNUSED_PARAMETER unsigned 
int ) {}
 bool SbxDecimal::setString( SAL_UNUSED_PARAMETER OUString* ) { return false; }
 
 bool SbxDecimal::getChar( SAL_UNUSED_PARAMETER sal_Unicode& ) { return false; }
+bool SbxDecimal::getByte( SAL_UNUSED_PARAMETER sal_uInt8& ) { return false; }
 bool SbxDecimal::getShort( SAL_UNUSED_PARAMETER sal_Int16& ) { return false; }
 bool SbxDecimal::getLong( SAL_UNUSED_PARAMETER sal_Int32& ) { return false; }
+bool SbxDecimal::getHyper( SAL_UNUSED_PARAMETER sal_Int64& ) { return false; }
 bool SbxDecimal::getUShort( SAL_UNUSED_PARAMETER sal_uInt16& ) { return false; 
}
 bool SbxDecimal::getULong( SAL_UNUSED_PARAMETER sal_uInt32& ) { return false; }
+bool SbxDecimal::getUHyper( SAL_UNUSED_PARAMETER sal_uInt64& ) { return false; 
}
 bool SbxDecimal::getSingle( SAL_UNUSED_PARAMETER float& ) { return false; }
 bool SbxDecimal::getDouble( SAL_UNUSED_PARAMETER double& ) { return false; }
 
@@ -373,6 +406,12 @@ void SbxDecimal::getString( OUString& rString )
 #endif
 }
 
+void SbxDecimal::HandleFailure(bool isSuccess)
+{
+    if (!isSuccess)
+        SbxBase::SetError(ERRCODE_BASIC_MATH_OVERFLOW);
+}
+
 SbxDecimal* ImpCreateDecimal( SbxValues* p )
 {
     if( !p )
@@ -389,25 +428,18 @@ SbxDecimal* ImpCreateDecimal( SbxValues* p )
 
 SbxDecimal* ImpGetDecimal( const SbxValues* p )
 {
-    SbxValues aTmp;
-    SbxDecimal* pnDecRes;
-
     SbxDataType eType = p->eType;
     if( eType == SbxDECIMAL && p->pDecimal )
     {
-        pnDecRes = new SbxDecimal( *p->pDecimal );
+        SbxDecimal* pnDecRes = new SbxDecimal( *p->pDecimal );
         pnDecRes->addRef();
         return pnDecRes;
     }
-    pnDecRes = new SbxDecimal();
+    SbxDecimal* pnDecRes = new SbxDecimal();
     pnDecRes->addRef();
 
-start:
     switch( +eType )
     {
-        case SbxNULL:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            [[fallthrough]];
         case SbxEMPTY:
             pnDecRes->setShort( 0 ); break;
         case SbxCHAR:
@@ -425,35 +457,37 @@ start:
         case SbxULONG:
             pnDecRes->setULong( p->nULong ); break;
         case SbxSINGLE:
-            if( !pnDecRes->setSingle( p->nSingle ) )
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
+            pnDecRes->setWithOverflow(p->nSingle);
+            break;
+        case SbxBYREF | SbxSINGLE:
+            pnDecRes->setWithOverflow(*p->pSingle);
             break;
         case SbxCURRENCY:
-            {
-                if( !pnDecRes->setDouble( ImpCurrencyToDouble( p->nInt64 ) ) )
-                    SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                break;
-            }
+            pnDecRes->setWithOverflow(CurTo<double>(p->nInt64));
+            break;
+        case SbxBYREF | SbxCURRENCY:
+            pnDecRes->setWithOverflow(CurTo<double>(*p->pnInt64));
+            break;
         case SbxSALINT64:
-            {
-                if( !pnDecRes->setDouble( static_cast<double>(p->nInt64) ) )
-                    SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                break;
-            }
+            pnDecRes->setWithOverflow(p->nInt64);
+            break;
+        case SbxBYREF | SbxSALINT64:
+            pnDecRes->setWithOverflow(*p->pnInt64);
+            break;
         case SbxSALUINT64:
-            {
-                if( !pnDecRes->setDouble( static_cast<double>(p->uInt64) ) )
-                    SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                break;
-            }
+            pnDecRes->setWithOverflow(p->uInt64);
+            break;
+        case SbxBYREF | SbxSALUINT64:
+            pnDecRes->setWithOverflow(*p->puInt64);
+            break;
         case SbxDATE:
         case SbxDOUBLE:
-        {
-            double dVal = p->nDouble;
-            if( !pnDecRes->setDouble( dVal ) )
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
+            pnDecRes->setWithOverflow(p->nDouble);
+            break;
+        case SbxBYREF | SbxDATE:
+        case SbxBYREF | SbxDOUBLE:
+            pnDecRes->setWithOverflow(*p->pDouble);
             break;
-        }
         case SbxLPSTR:
         case SbxSTRING:
         case SbxBYREF | SbxSTRING:
@@ -461,9 +495,7 @@ start:
                 pnDecRes->setString( p->pOUString );
             break;
         case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
+            if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
                 pnDecRes->setDecimal( pVal->GetDecimal() );
             else
             {
@@ -471,7 +503,6 @@ start:
                 pnDecRes->setShort( 0 );
             }
             break;
-        }
 
         case SbxBYREF | SbxCHAR:
             pnDecRes->setChar( *p->pChar ); break;
@@ -488,21 +519,6 @@ start:
         case SbxBYREF | SbxUSHORT:
             pnDecRes->setUShort( *p->pUShort ); break;
 
-        // from here on had to be tested
-        case SbxBYREF | SbxSINGLE:
-            aTmp.nSingle = *p->pSingle; goto ref;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            aTmp.nDouble = *p->pDouble; goto ref;
-        case SbxBYREF | SbxCURRENCY:
-        case SbxBYREF | SbxSALINT64:
-            aTmp.nInt64 = *p->pnInt64; goto ref;
-        case SbxBYREF | SbxSALUINT64:
-            aTmp.uInt64 = *p->puInt64; goto ref;
-        ref:
-            aTmp.eType = SbxDataType( p->eType & 0x0FFF );
-            p = &aTmp; goto start;
-
         default:
             SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); pnDecRes->setShort( 
0 );
     }
@@ -514,39 +530,69 @@ void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec )
     if( !pDec )
         return;
 
-    SbxValues aTmp;
-start:
     switch( +p->eType )
     {
-        // here had to be tested
         case SbxCHAR:
-            aTmp.pChar = &p->nChar; goto direct;
+            assignWithOverflowTo(p->nChar, *pDec);
+            break;
+        case SbxBYREF | SbxCHAR:
+            assignWithOverflowTo(*p->pChar, *pDec);
+            break;
         case SbxBYTE:
-            aTmp.pByte = &p->nByte; goto direct;
-        case SbxULONG:
-            aTmp.pULong = &p->nULong; goto direct;
-        case SbxERROR:
-        case SbxUSHORT:
-            aTmp.pUShort = &p->nUShort; goto direct;
+            assignWithOverflowTo(p->nByte, *pDec);
+            break;
+        case SbxBYREF | SbxBYTE:
+            assignWithOverflowTo(*p->pByte, *pDec);
+            break;
         case SbxINTEGER:
         case SbxBOOL:
-            aTmp.pInteger = &p->nInteger; goto direct;
+            assignWithOverflowTo(p->nInteger, *pDec);
+            break;
+        case SbxBYREF | SbxINTEGER:
+        case SbxBYREF | SbxBOOL:
+            assignWithOverflowTo(*p->pInteger, *pDec);
+            break;
+        case SbxERROR:
+        case SbxUSHORT:
+            assignWithOverflowTo(p->nUShort, *pDec);
+            break;
+        case SbxBYREF | SbxERROR:
+        case SbxBYREF | SbxUSHORT:
+            assignWithOverflowTo(*p->pUShort, *pDec);
+            break;
         case SbxLONG:
-            aTmp.pLong = &p->nLong; goto direct;
+            assignWithOverflowTo(p->nLong, *pDec);
+            break;
+        case SbxBYREF | SbxLONG:
+            assignWithOverflowTo(*p->pLong, *pDec);
+            break;
+        case SbxULONG:
+            assignWithOverflowTo(p->nULong, *pDec);
+            break;
+        case SbxBYREF | SbxULONG:
+            assignWithOverflowTo(*p->pULong, *pDec);
+            break;
         case SbxCURRENCY:
+            p->nInt64 = CurFrom(pDec->getWithOverflow<double>());
+            break;
+        case SbxBYREF | SbxCURRENCY:
+            *p->pnInt64 = CurFrom(pDec->getWithOverflow<double>());
+            break;
         case SbxSALINT64:
-            aTmp.pnInt64 = &p->nInt64; goto direct;
+            assignWithOverflowTo(p->nInt64, *pDec);
+            break;
+        case SbxBYREF | SbxSALINT64:
+            assignWithOverflowTo(*p->pnInt64, *pDec);
+            break;
         case SbxSALUINT64:
-            aTmp.puInt64 = &p->uInt64; goto direct;
-
-        direct:
-            aTmp.eType = SbxDataType( p->eType | SbxBYREF );
-            p = &aTmp; goto start;
+            assignWithOverflowTo(p->uInt64, *pDec);
+            break;
+        case SbxBYREF | SbxSALUINT64:
+            assignWithOverflowTo(*p->puInt64, *pDec);
+            break;
 
-        // from here on no longer
         case SbxDECIMAL:
         case SbxBYREF | SbxDECIMAL:
-        {
             if( pDec != p->pDecimal )
             {
                 releaseDecimalPtr( p->pDecimal );
@@ -555,22 +601,20 @@ start:
                     pDec->addRef();
             }
             break;
-        }
         case SbxSINGLE:
-        {
-            float f(0.0);
-            pDec->getSingle( f );
-            p->nSingle = f;
+            assignWithOverflowTo(p->nSingle, *pDec);
+            break;
+        case SbxBYREF | SbxSINGLE:
+            assignWithOverflowTo(*p->pSingle, *pDec);
             break;
-        }
         case SbxDATE:
         case SbxDOUBLE:
-        {
-            double d(0.0);
-            pDec->getDouble( d );
-            p->nDouble = d;
+            assignWithOverflowTo(p->nDouble, *pDec);
+            break;
+        case SbxBYREF | SbxDATE:
+        case SbxBYREF | SbxDOUBLE:
+            assignWithOverflowTo(*p->pDouble, *pDec);
             break;
-        }
 
         case SbxLPSTR:
         case SbxSTRING:
@@ -580,100 +624,12 @@ start:
             pDec->getString( *p->pOUString );
             break;
         case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
+            if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
                 pVal->PutDecimal( pDec );
             else
                 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
             break;
-        }
 
-        case SbxBYREF | SbxCHAR:
-            if( !pDec->getChar( *p->pChar ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pChar = 0;
-            }
-            break;
-        case SbxBYREF | SbxBYTE:
-            if( !pDec->getChar( *p->pChar ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pByte = 0;
-            }
-            break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            if( !pDec->getShort( *p->pInteger ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pInteger = 0;
-            }
-            break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            if( !pDec->getUShort( *p->pUShort ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pUShort = 0;
-            }
-            break;
-        case SbxBYREF | SbxLONG:
-            if( !pDec->getLong( *p->pLong ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pLong = 0;
-            }
-            break;
-        case SbxBYREF | SbxULONG:
-            if( !pDec->getULong( *p->pULong ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pULong = 0;
-            }
-            break;
-        case SbxBYREF | SbxCURRENCY:
-            {
-            double d(0.0);
-            if( !pDec->getDouble( d ) )
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-            *p->pnInt64 = ImpDoubleToCurrency( d );
-            }
-            break;
-        case SbxBYREF | SbxSALINT64:
-            {
-            double d(0.0);
-            if( !pDec->getDouble( d ) )
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-            else
-                *p->pnInt64 = ImpDoubleToSalInt64( d );
-            }
-            break;
-        case SbxBYREF | SbxSALUINT64:
-            {
-            double d(0.0);
-            if( !pDec->getDouble( d ) )
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-            else
-                *p->puInt64 = ImpDoubleToSalUInt64( d );
-            }
-            break;
-        case SbxBYREF | SbxSINGLE:
-            if( !pDec->getSingle( *p->pSingle ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pSingle = 0;
-            }
-            break;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            if( !pDec->getDouble( *p->pDouble ) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW );
-                *p->pDouble = 0;
-            }
-            break;
         default:
             SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
     }
diff --git a/basic/source/sbx/sbxdec.hxx b/basic/source/sbx/sbxdec.hxx
index 756fdc9f9273..a7af21fa4f28 100644
--- a/basic/source/sbx/sbxdec.hxx
+++ b/basic/source/sbx/sbxdec.hxx
@@ -55,8 +55,10 @@ public:
     void setByte( sal_uInt8 val );
     void setShort( sal_Int16 val );
     void setLong( sal_Int32 val );
+    bool setHyper( sal_Int64 val );
     void setUShort( sal_uInt16 val );
     void setULong( sal_uInt32 val );
+    bool setUHyper( sal_uInt64 val );
     bool setSingle( float val );
     bool setDouble( double val );
     void setInt( int val );
@@ -72,15 +74,31 @@ public:
 #endif
     }
 
+    void setWithOverflow(float val) { HandleFailure(setSingle(val)); }
+    void setWithOverflow(double val) { HandleFailure(setDouble(val)); }
+    void setWithOverflow(sal_Int64 val) { HandleFailure(setHyper(val)); }
+    void setWithOverflow(sal_uInt64 val) { HandleFailure(setUHyper(val)); }
+
     bool getChar( sal_Unicode& rVal );
+    bool getByte( sal_uInt8& rVal );
     bool getShort( sal_Int16& rVal );
     bool getLong( sal_Int32& rVal );
+    bool getHyper( sal_Int64& rVal );
     bool getUShort( sal_uInt16& rVal );
     bool getULong( sal_uInt32& rVal );
+    bool getUHyper( sal_uInt64& rVal );
     bool getSingle( float& rVal );
     bool getDouble( double& rVal );
     void getString( OUString& rString );
 
+    // Only handles types, which have corresponding getWithOverflow_impl
+    template <typename T> T getWithOverflow()
+    {
+        T n = 0;
+        HandleFailure(getWithOverflow_impl(n));
+        return n;
+    }
+
     bool operator -= ( const SbxDecimal &r );
     bool operator += ( const SbxDecimal &r );
     bool operator /= ( const SbxDecimal &r );
@@ -92,6 +110,20 @@ public:
     // must match the return values of the Microsoft VarDecCmp Automation 
function
     enum class CmpResult { LT, EQ, GT };
     friend CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal 
&rRight );
+
+private:
+    bool getWithOverflow_impl(sal_Unicode& n) { return getChar(n); }
+    bool getWithOverflow_impl(sal_uInt8& n) { return getByte(n); }
+    bool getWithOverflow_impl(sal_Int16& n) { return getShort(n); }
+    bool getWithOverflow_impl(sal_uInt16& n) { return getUShort(n); }
+    bool getWithOverflow_impl(sal_Int32& n) { return getLong(n); }
+    bool getWithOverflow_impl(sal_uInt32& n) { return getULong(n); }
+    bool getWithOverflow_impl(sal_Int64& n) { return getHyper(n); }
+    bool getWithOverflow_impl(sal_uInt64& n) { return getUHyper(n); }
+    bool getWithOverflow_impl(float& n) { return getSingle(n); }
+    bool getWithOverflow_impl(double& n) { return getDouble(n); }
+
+    void HandleFailure(bool isSuccess);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/sbx/sbxint.cxx b/basic/source/sbx/sbxint.cxx
index 6a6721eb7840..a0693635a302 100644
--- a/basic/source/sbx/sbxint.cxx
+++ b/basic/source/sbx/sbxint.cxx
@@ -19,786 +19,266 @@
 
 #include <sal/config.h>
 
+#include <config_features.h>
+
 #include <o3tl/safeint.hxx>
 #include <comphelper/errcode.hxx>
 #include <basic/sberrors.hxx>
 #include "sbxconv.hxx"
+#include <runtime.hxx>
 
 #include <rtl/math.hxx>
 
-sal_Int16 ImpGetInteger( const SbxValues* p )
+namespace
+{
+template <class T>
+concept number = std::is_arithmetic_v<T>;
+
+template <SbxDataType MySbxType, number N> N ImpGet(const SbxValues* p)
 {
-    SbxValues aTmp;
-    sal_Int16 nRes;
-start:
-    switch( +p->eType )
+    switch (+p->eType)
     {
-        case SbxNULL:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
-            [[fallthrough]];
         case SbxEMPTY:
-            nRes = 0; break;
+            return 0;
         case SbxCHAR:
-            nRes = p->nChar; break;
+            return ConvertWithOverflowTo<N>(p->nChar);
+        case SbxBYREF | SbxCHAR:
+            return ConvertWithOverflowTo<N>(*p->pChar);
         case SbxBYTE:
-            nRes = p->nByte; break;
+            return ConvertWithOverflowTo<N>(p->nByte);
+        case SbxBYREF | SbxBYTE:
+            return ConvertWithOverflowTo<N>(*p->pByte);
         case SbxINTEGER:
         case SbxBOOL:
-            nRes = p->nInteger; break;
+            return ConvertWithOverflowTo<N>(p->nInteger);
+        case SbxBYREF | SbxINTEGER:
+        case SbxBYREF | SbxBOOL:
+            return ConvertWithOverflowTo<N>(*p->pInteger);
         case SbxERROR:
         case SbxUSHORT:
-            if( p->nUShort > o3tl::make_unsigned(SbxMAXINT) )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXINT;
-            }
-            else
-                nRes = static_cast<sal_Int16>(p->nUShort);
-            break;
+            return ConvertWithOverflowTo<N>(p->nUShort);
+        case SbxBYREF | SbxERROR:
+        case SbxBYREF | SbxUSHORT:
+            return ConvertWithOverflowTo<N>(*p->pUShort);
         case SbxLONG:
-            if( p->nLong > SbxMAXINT )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXINT;
-            }
-            else if( p->nLong < SbxMININT )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMININT;
-            }
-            else
-                nRes = static_cast<sal_Int16>(p->nLong);
-            break;
+            return ConvertWithOverflowTo<N>(p->nLong);
+        case SbxBYREF | SbxLONG:
+            return ConvertWithOverflowTo<N>(*p->pLong);
         case SbxULONG:
-            if( p->nULong > SbxMAXINT )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXINT;
-            }
-            else
-                nRes = static_cast<sal_Int16>(p->nULong);
-            break;
-        case SbxSINGLE:
-            nRes = ImpDoubleToInteger(p->nSingle);
-            break;
+            return ConvertWithOverflowTo<N>(p->nULong);
+        case SbxBYREF | SbxULONG:
+            return ConvertWithOverflowTo<N>(*p->pULong);
         case SbxCURRENCY:
-            nRes = CurTo<sal_Int16>(p->nInt64);
-            break;
+            return CurTo<N>(p->nInt64);
+        case SbxBYREF | SbxCURRENCY:
+            return CurTo<N>(*p->pnInt64);
         case SbxSALINT64:
-            if( p->nInt64 > SbxMAXINT )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXINT;
-            }
-            else if( p->nInt64 < SbxMININT )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMININT;
-            }
-            else
-                nRes = static_cast<sal_Int16>(p->nInt64);
-            break;
+            return ConvertWithOverflowTo<N>(p->nInt64);
+        case SbxBYREF | SbxSALINT64:
+            return ConvertWithOverflowTo<N>(*p->pnInt64);
         case SbxSALUINT64:
-            if( p->uInt64 > SbxMAXINT )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); nRes = 
SbxMAXINT;
-            }
-            else
-                nRes = static_cast<sal_Int16>(p->uInt64);
-            break;
+            return ConvertWithOverflowTo<N>(p->uInt64);
+        case SbxBYREF | SbxSALUINT64:
+            return ConvertWithOverflowTo<N>(*p->puInt64);
+        case SbxSINGLE:
+            return ConvertWithOverflowTo<N>(p->nSingle);
+        case SbxBYREF | SbxSINGLE:
+            return ConvertWithOverflowTo<N>(*p->pSingle);
         case SbxDATE:
         case SbxDOUBLE:
+            return ConvertWithOverflowTo<N>(p->nDouble);
+        case SbxBYREF | SbxDATE:
+        case SbxBYREF | SbxDOUBLE:
+            return ConvertWithOverflowTo<N>(*p->pDouble);
         case SbxDECIMAL:
         case SbxBYREF | SbxDECIMAL:
-        {
-            double dVal = 0.0;
-            if( p->eType == SbxDECIMAL )
-            {
-                if( p->pDecimal )
-                    p->pDecimal->getDouble( dVal );
-            }
-            else
-                dVal = p->nDouble;
-
-            nRes = ImpDoubleToInteger(dVal);
-            break;
-            }
-        case SbxLPSTR:
-        case SbxSTRING:
+            if (p->pDecimal)
+                return p->pDecimal->getWithOverflow<N>();
+            return 0;
         case SbxBYREF | SbxSTRING:
-            if( !p->pOUString )
-                nRes = 0;
-            else
+        case SbxSTRING:
+        case SbxLPSTR:
+            if (p->pOUString)
             {
                 double d;
                 SbxDataType t;
-                if( ImpScan( *p->pOUString, d, t, nullptr ) != ERRCODE_NONE )
-                    nRes = 0;
-                else
-                    nRes = ImpDoubleToInteger(d);
-            }
-            break;
+                if (ImpScan(*p->pOUString, d, t, nullptr) == ERRCODE_NONE)
+                    return ConvertWithOverflowTo<N>(d);
+            }
+#if HAVE_FEATURE_SCRIPTING
+            if (SbiRuntime::isVBAEnabled()) // VBA only behaviour
+                SbxBase::SetError(ERRCODE_BASIC_CONVERSION);
+#endif
+            return 0;
         case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                nRes = pVal->GetInteger();
-            else
+            if (SbxValue* pVal = dynamic_cast<SbxValue*>(p->pObj))
             {
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); nRes = 0;
+                SbxValues aObjVal(MySbxType);
+                pVal->Get(aObjVal);
+                return ImpGet<MySbxType, N>(&aObjVal);
             }
-            break;
-        }
-
-        case SbxBYREF | SbxCHAR:
-            nRes = *p->pChar; break;
-        case SbxBYREF | SbxBYTE:
-            nRes = *p->pByte; break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            nRes = *p->pInteger; break;
-
-        // from here had to be tested
-        case SbxBYREF | SbxLONG:
-            aTmp.nLong = *p->pLong; goto ref;
-        case SbxBYREF | SbxULONG:
-            aTmp.nULong = *p->pULong; goto ref;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            aTmp.nUShort = *p->pUShort; goto ref;
-        case SbxBYREF | SbxSINGLE:
-            aTmp.nSingle = *p->pSingle; goto ref;
-        case SbxBYREF | SbxDATE:
-        case SbxBYREF | SbxDOUBLE:
-            aTmp.nDouble = *p->pDouble; goto ref;
-        case SbxBYREF | SbxCURRENCY:
-        case SbxBYREF | SbxSALINT64:
-            aTmp.nInt64 = *p->pnInt64; goto ref;
-        case SbxBYREF | SbxSALUINT64:
-            aTmp.uInt64 = *p->puInt64; goto ref;
-        ref:
-            aTmp.eType = SbxDataType( p->eType & 0x0FFF );
-            p = &aTmp; goto start;
+            SbxBase::SetError(ERRCODE_BASIC_NO_OBJECT);
+            return 0;
 
         default:
-            SbxBase::SetError( ERRCODE_BASIC_CONVERSION ); nRes = 0;
+            SbxBase::SetError(ERRCODE_BASIC_CONVERSION);
+            return 0;
     }
-    return nRes;
 }
 
-void ImpPutInteger( SbxValues* p, sal_Int16 n )
+template <typename T> void assignTo(SbxDecimal& dest, T n); // not defined
+template <> void assignTo<sal_uInt8>(SbxDecimal& dest, sal_uInt8 n) { 
dest.setByte(n); }
+template <> void assignTo<sal_Unicode>(SbxDecimal& dest, sal_Unicode n) { 
dest.setChar(n); }
+template <> void assignTo<sal_Int16>(SbxDecimal& dest, sal_Int16 n) { 
dest.setShort(n); }
+template <> void assignTo<sal_uInt16>(SbxDecimal& dest, sal_uInt16 n) { 
dest.setUShort(n); }
+template <> void assignTo<sal_Int32>(SbxDecimal& dest, sal_Int32 n) { 
dest.setLong(n); }
+template <> void assignTo<sal_uInt32>(SbxDecimal& dest, sal_uInt32 n) { 
dest.setULong(n); }
+template <> void assignTo<sal_Int64>(SbxDecimal& dest, sal_Int64 n) { 
dest.setWithOverflow(n); }
+template <> void assignTo<sal_uInt64>(SbxDecimal& dest, sal_uInt64 n) { 
dest.setWithOverflow(n); }
+template <> void assignTo<double>(SbxDecimal& dest, double n) { 
dest.setWithOverflow(n); }
+template <> void assignTo<float>(SbxDecimal& dest, float n) { 
dest.setWithOverflow(n); }
+
+template <std::integral I> void assignTo(OUString& dest, I n, bool) { dest = 
OUString::number(n); }
+void assignTo(OUString& dest, double n, bool bCoreString)
 {
-    SbxValues aTmp;
-start:
-    switch( +p->eType )
-    {
-        // here had to be tested
-        case SbxCHAR:
-            aTmp.pChar = &p->nChar; goto direct;
-        case SbxBYTE:
-            aTmp.pByte = &p->nByte; goto direct;
-        case SbxULONG:
-            aTmp.pULong = &p->nULong; goto direct;
-        case SbxERROR:
-        case SbxUSHORT:
-            aTmp.pUShort = &p->nUShort; goto direct;
-        case SbxSALUINT64:
-            aTmp.puInt64 = &p->uInt64; goto direct;
-        direct:
-            aTmp.eType = SbxDataType( p->eType | SbxBYREF );
-            p = &aTmp; goto start;
-
-        // from here no tests needed
-        case SbxINTEGER:
-        case SbxBOOL:
-            p->nInteger = n; break;
-        case SbxLONG:
-            p->nLong = n; break;
-        case SbxSINGLE:
-            p->nSingle = n; break;
-        case SbxDATE:
-        case SbxDOUBLE:
-            p->nDouble = n; break;
-        case SbxCURRENCY:
-            p->nInt64 = CurFrom(n); break;
-        case SbxSALINT64:
-            p->nInt64 = n; break;
-        case SbxDECIMAL:
-        case SbxBYREF | SbxDECIMAL:
-            ImpCreateDecimal( p )->setInt( n );
-            break;
-
-        case SbxLPSTR:
-        case SbxSTRING:
-        case SbxBYREF | SbxSTRING:
-            if( !p->pOUString )
-                p->pOUString = new OUString;
-            ImpCvtNum( static_cast<double>(n), 0, *p->pOUString );
-            break;
-        case SbxOBJECT:
-        {
-            SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
-            if( pVal )
-                pVal->PutInteger( n );
-            else
-                SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
-            break;
-        }
-        case SbxBYREF | SbxCHAR:
-            if( n < SbxMINCHAR )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMINCHAR;
-            }
-            *p->pChar = static_cast<char>(n); break;
-        case SbxBYREF | SbxBYTE:
-            if( n > SbxMAXBYTE )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 
SbxMAXBYTE;
-            }
-            else if( n < 0 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
-            }
-            *p->pByte = static_cast<sal_uInt8>(n); break;
-        case SbxBYREF | SbxINTEGER:
-        case SbxBYREF | SbxBOOL:
-            *p->pInteger = n; break;
-        case SbxBYREF | SbxERROR:
-        case SbxBYREF | SbxUSHORT:
-            if( n < 0 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
-            }
-            *p->pUShort = static_cast<sal_uInt16>(n); break;
-        case SbxBYREF | SbxLONG:
-            *p->pLong = static_cast<sal_Int32>(n); break;
-        case SbxBYREF | SbxULONG:
-            if( n < 0 )
-            {
-                SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW ); n = 0;
-            }
-            *p->pULong = static_cast<sal_uInt32>(n); break;
-        case SbxBYREF | SbxCURRENCY:
-            *p->pnInt64 = CurFrom(n); break;
-        case SbxBYREF | SbxSALINT64:
-            *p->pnInt64 = n; break;
-e 
... etc. - the rest is truncated

Reply via email to