sc: make ScAddress constexpr and clean-up
- remove the inlines which are implicit anyway - make compile type tests of the class - move inline methods into body Change-Id: If2656c1b750a300bc0ed589bc7ea6aec27b3237a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190255 Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Tested-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
committed by
Tomaž Vajngerl
parent
827648dabe
commit
4ad007de60
@@ -0,0 +1,35 @@
|
||||
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
|
||||
#*************************************************************************
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
#*************************************************************************
|
||||
|
||||
$(eval $(call gb_CppunitTest_CppunitTest,sc_basic_types_test))
|
||||
|
||||
$(eval $(call gb_CppunitTest_add_exception_objects,sc_basic_types_test,\
|
||||
sc/qa/unit/ScAddressTest \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_external,sc_basic_types_test,boost_headers))
|
||||
|
||||
$(eval $(call gb_CppunitTest_set_include,sc_basic_types_test,\
|
||||
-I$(SRCDIR)/sc/source/ui/inc \
|
||||
-I$(SRCDIR)/sc/source/core/inc \
|
||||
-I$(SRCDIR)/sc/inc \
|
||||
$$(INCLUDE) \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_libraries,sc_basic_types_test,\
|
||||
sal \
|
||||
))
|
||||
|
||||
# Needed for include/test/cppunitasserthelper.hxx
|
||||
$(eval $(call gb_CppunitTest_use_sdk_api,sc_basic_types_test))
|
||||
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
@@ -61,6 +61,7 @@ $(eval $(call gb_Module_add_check_targets,sc,\
|
||||
CppunitTest_sc_filters_test \
|
||||
CppunitTest_sc_mark_test \
|
||||
CppunitTest_sc_core \
|
||||
CppunitTest_sc_basic_types_test \
|
||||
CppunitTest_sc_dataprovider \
|
||||
CppunitTest_sc_cache_test \
|
||||
CppunitTest_sc_parallelism \
|
||||
|
||||
+119
-114
@@ -248,77 +248,107 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
ScAddress() :
|
||||
constexpr ScAddress() :
|
||||
nRow(0), nCol(0), nTab(0)
|
||||
{}
|
||||
ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP ) :
|
||||
|
||||
constexpr ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP ) :
|
||||
nRow(nRowP), nCol(nColP), nTab(nTabP)
|
||||
{}
|
||||
|
||||
/** coverity[uninit_member] - Yes, it is what it seems to be: Uninitialized.
|
||||
May be used for performance reasons if it is initialized by other means. */
|
||||
ScAddress( Uninitialized )
|
||||
constexpr ScAddress( Uninitialized )
|
||||
{}
|
||||
ScAddress( InitializeInvalid ) :
|
||||
|
||||
constexpr ScAddress( InitializeInvalid ) :
|
||||
nRow(-1), nCol(-1), nTab(-1)
|
||||
{}
|
||||
ScAddress( const ScAddress& rAddress ) :
|
||||
|
||||
constexpr ScAddress( const ScAddress& rAddress ) :
|
||||
nRow(rAddress.nRow), nCol(rAddress.nCol), nTab(rAddress.nTab)
|
||||
{}
|
||||
inline ScAddress& operator=( const ScAddress& rAddress );
|
||||
|
||||
inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
|
||||
constexpr ScAddress& operator=(const ScAddress& rAddress)
|
||||
{
|
||||
nCol = rAddress.nCol;
|
||||
nRow = rAddress.nRow;
|
||||
nTab = rAddress.nTab;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SCROW Row() const
|
||||
constexpr void Set(SCCOL nColP, SCROW nRowP, SCTAB nTabP)
|
||||
{
|
||||
nCol = nColP;
|
||||
nRow = nRowP;
|
||||
nTab = nTabP;
|
||||
}
|
||||
|
||||
constexpr SCROW Row() const
|
||||
{
|
||||
return nRow;
|
||||
}
|
||||
|
||||
SCCOL Col() const
|
||||
constexpr SCCOL Col() const
|
||||
{
|
||||
return nCol;
|
||||
}
|
||||
SCTAB Tab() const
|
||||
|
||||
constexpr SCTAB Tab() const
|
||||
{
|
||||
return nTab;
|
||||
}
|
||||
void SetRow( SCROW nRowP )
|
||||
|
||||
constexpr void SetRow( SCROW nRowP )
|
||||
{
|
||||
nRow = nRowP;
|
||||
}
|
||||
void SetCol( SCCOL nColP )
|
||||
|
||||
constexpr void SetCol( SCCOL nColP )
|
||||
{
|
||||
nCol = nColP;
|
||||
}
|
||||
void SetTab( SCTAB nTabP )
|
||||
|
||||
constexpr void SetTab( SCTAB nTabP )
|
||||
{
|
||||
nTab = nTabP;
|
||||
}
|
||||
void SetInvalid()
|
||||
|
||||
constexpr void SetInvalid()
|
||||
{
|
||||
nRow = -1;
|
||||
nCol = -1;
|
||||
nTab = -1;
|
||||
}
|
||||
bool IsValid() const
|
||||
|
||||
constexpr bool IsValid() const
|
||||
{
|
||||
return (nRow >= 0) && (nCol >= 0) && (nTab >= 0);
|
||||
}
|
||||
|
||||
inline void PutInOrder( ScAddress& rAddress );
|
||||
constexpr void PutInOrder(ScAddress& rAddress)
|
||||
{
|
||||
::PutInOrder(nCol, rAddress.nCol);
|
||||
::PutInOrder(nRow, rAddress.nRow);
|
||||
::PutInOrder(nTab, rAddress.nTab);
|
||||
}
|
||||
|
||||
void IncRow( SCROW nDelta = 1 )
|
||||
constexpr void IncRow( SCROW nDelta = 1 )
|
||||
{
|
||||
nRow = sal::static_int_cast<SCROW>(nRow + nDelta);
|
||||
nRow = static_cast<SCROW>(nRow + nDelta);
|
||||
}
|
||||
void IncCol( SCCOL nDelta = 1 )
|
||||
|
||||
constexpr void IncCol( SCCOL nDelta = 1 )
|
||||
{
|
||||
nCol = sal::static_int_cast<SCCOL>(nCol + nDelta);
|
||||
nCol = static_cast<SCCOL>(nCol + nDelta);
|
||||
}
|
||||
void IncTab( SCTAB nDelta = 1 )
|
||||
|
||||
constexpr void IncTab( SCTAB nDelta = 1 )
|
||||
{
|
||||
nTab = sal::static_int_cast<SCTAB>(nTab + nDelta);
|
||||
nTab = static_cast<SCTAB>(nTab + nDelta);
|
||||
}
|
||||
void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
|
||||
|
||||
constexpr void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
|
||||
{
|
||||
nColP = nCol;
|
||||
nRowP = nRow;
|
||||
@@ -358,13 +388,72 @@ public:
|
||||
[[nodiscard]] SC_DLLPUBLIC bool Move( SCCOL nDeltaX, SCROW nDeltaY, SCTAB nDeltaZ,
|
||||
ScAddress& rErrorPos, const ScDocument& rDoc );
|
||||
|
||||
inline bool operator==( const ScAddress& rAddress ) const;
|
||||
inline bool operator!=( const ScAddress& rAddress ) const;
|
||||
inline bool operator<( const ScAddress& rAddress ) const;
|
||||
inline bool operator<=( const ScAddress& rAddress ) const;
|
||||
inline bool lessThanByRow( const ScAddress& rAddress ) const;
|
||||
constexpr bool operator==( const ScAddress& rAddress ) const
|
||||
{
|
||||
return nRow == rAddress.nRow && nCol == rAddress.nCol && nTab == rAddress.nTab;
|
||||
}
|
||||
|
||||
inline size_t hash() const;
|
||||
/** Less than ordered by tab,col,row. */
|
||||
constexpr bool operator<(const ScAddress& rAddress) const
|
||||
{
|
||||
if (nTab == rAddress.nTab)
|
||||
{
|
||||
if (nCol == rAddress.nCol)
|
||||
return nRow < rAddress.nRow;
|
||||
else
|
||||
return nCol < rAddress.nCol;
|
||||
}
|
||||
else
|
||||
return nTab < rAddress.nTab;
|
||||
}
|
||||
|
||||
constexpr bool operator<=( const ScAddress& rAddress ) const
|
||||
{
|
||||
return operator<(rAddress) || operator==(rAddress);
|
||||
}
|
||||
|
||||
constexpr bool operator>(const ScAddress& rAddress) const
|
||||
{
|
||||
return !(operator<=(rAddress));
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const ScAddress& rAddress) const
|
||||
{
|
||||
return !(operator<(rAddress));
|
||||
}
|
||||
|
||||
/** Less than ordered by tab,row,col as needed by row-wise import/export */
|
||||
bool lessThanByRow(const ScAddress& rAddress) const
|
||||
{
|
||||
if (nTab == rAddress.nTab)
|
||||
{
|
||||
if (nRow == rAddress.nRow)
|
||||
return nCol < rAddress.nCol;
|
||||
else
|
||||
return nRow < rAddress.nRow;
|
||||
}
|
||||
else
|
||||
return nTab < rAddress.nTab;
|
||||
}
|
||||
|
||||
size_t hash() const
|
||||
{
|
||||
#if SAL_TYPES_SIZEOFPOINTER == 8
|
||||
// 16 bits for the columns, and 20 bits for the rows
|
||||
return (static_cast<size_t>(nTab) << 36) ^
|
||||
(static_cast<size_t>(nCol) << 20) ^
|
||||
static_cast<size_t>(nRow);
|
||||
#else
|
||||
// Assume that there are not that many addresses with row > 2^16 AND column
|
||||
// > 2^8 AND sheet > 2^8 so we won't have too many collisions.
|
||||
if (nRow <= 0xffff)
|
||||
return (static_cast<size_t>(nTab) << 24) ^
|
||||
(static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
|
||||
else
|
||||
return (static_cast<size_t>(nTab) << 28) ^
|
||||
(static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a human-readable string representation of the cell address. You
|
||||
@@ -390,90 +479,6 @@ inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT,
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline void ScAddress::PutInOrder( ScAddress& rAddress )
|
||||
{
|
||||
::PutInOrder(nCol, rAddress.nCol);
|
||||
::PutInOrder(nRow, rAddress.nRow);
|
||||
::PutInOrder(nTab, rAddress.nTab);
|
||||
}
|
||||
|
||||
inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
|
||||
{
|
||||
nCol = nColP;
|
||||
nRow = nRowP;
|
||||
nTab = nTabP;
|
||||
}
|
||||
|
||||
inline ScAddress& ScAddress::operator=( const ScAddress& rAddress )
|
||||
{
|
||||
nCol = rAddress.nCol;
|
||||
nRow = rAddress.nRow;
|
||||
nTab = rAddress.nTab;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool ScAddress::operator==( const ScAddress& rAddress ) const
|
||||
{
|
||||
return nRow == rAddress.nRow && nCol == rAddress.nCol && nTab == rAddress.nTab;
|
||||
}
|
||||
|
||||
inline bool ScAddress::operator!=( const ScAddress& rAddress ) const
|
||||
{
|
||||
return !operator==( rAddress );
|
||||
}
|
||||
|
||||
/** Less than ordered by tab,col,row. */
|
||||
inline bool ScAddress::operator<( const ScAddress& rAddress ) const
|
||||
{
|
||||
if (nTab == rAddress.nTab)
|
||||
{
|
||||
if (nCol == rAddress.nCol)
|
||||
return nRow < rAddress.nRow;
|
||||
else
|
||||
return nCol < rAddress.nCol;
|
||||
}
|
||||
else
|
||||
return nTab < rAddress.nTab;
|
||||
}
|
||||
|
||||
inline bool ScAddress::operator<=( const ScAddress& rAddress ) const
|
||||
{
|
||||
return operator<( rAddress ) || operator==( rAddress );
|
||||
}
|
||||
|
||||
/** Less than ordered by tab,row,col as needed by row-wise import/export */
|
||||
inline bool ScAddress::lessThanByRow( const ScAddress& rAddress ) const
|
||||
{
|
||||
if (nTab == rAddress.nTab)
|
||||
{
|
||||
if (nRow == rAddress.nRow)
|
||||
return nCol < rAddress.nCol;
|
||||
else
|
||||
return nRow < rAddress.nRow;
|
||||
}
|
||||
else
|
||||
return nTab < rAddress.nTab;
|
||||
}
|
||||
|
||||
inline size_t ScAddress::hash() const
|
||||
{
|
||||
#if SAL_TYPES_SIZEOFPOINTER == 8
|
||||
// 16 bits for the columns, and 20 bits for the rows
|
||||
return (static_cast<size_t>(nTab) << 36) ^
|
||||
(static_cast<size_t>(nCol) << 20) ^
|
||||
static_cast<size_t>(nRow);
|
||||
#else
|
||||
// Assume that there are not that many addresses with row > 2^16 AND column
|
||||
// > 2^8 AND sheet > 2^8 so we won't have too many collisions.
|
||||
if (nRow <= 0xffff)
|
||||
return (static_cast<size_t>(nTab) << 24) ^
|
||||
(static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
|
||||
else
|
||||
return (static_cast<size_t>(nTab) << 28) ^
|
||||
(static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct ScAddressHashFunctor
|
||||
{
|
||||
size_t operator()( const ScAddress & rAddress ) const
|
||||
@@ -482,7 +487,7 @@ struct ScAddressHashFunctor
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] inline bool ValidAddress( const ScAddress& rAddress, SCCOL nMaxCol, SCROW nMaxRow )
|
||||
[[nodiscard]] constexpr bool ValidAddress(const ScAddress& rAddress, SCCOL nMaxCol, SCROW nMaxRow)
|
||||
{
|
||||
return ValidCol(rAddress.Col(), nMaxCol) && ValidRow(rAddress.Row(), nMaxRow) && ValidTab(rAddress.Tab());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/* -*- 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/.
|
||||
*/
|
||||
|
||||
#include <address.hxx>
|
||||
|
||||
#include <cppunit/plugin/TestPlugIn.h>
|
||||
|
||||
// Compile time tests for ScAddress
|
||||
|
||||
static_assert(ScAddress() == ScAddress(0, 0, 0));
|
||||
static_assert(ScAddress().IsValid() == true);
|
||||
static_assert(ScAddress(ScAddress::INITIALIZE_INVALID).IsValid() == false);
|
||||
|
||||
// Equal, not Equal
|
||||
|
||||
// Format is Col, Row, Tab and Col has priority over Row
|
||||
static_assert(ScAddress(0, 0, 0) != ScAddress(1, 0, 0)); // A1 != B1
|
||||
static_assert(ScAddress(0, 0, 0) != ScAddress(0, 1, 0)); // A1 != A2
|
||||
static_assert(ScAddress(0, 0, 0) != ScAddress(0, 0, 1)); // Sheet1:A1 != Sheet2:A1
|
||||
static_assert(ScAddress(0, 0, 0) == ScAddress(0, 0, 0)); // A1 == A1
|
||||
|
||||
// Less
|
||||
|
||||
static_assert(!(ScAddress(1, 0, 0) < ScAddress(1, 0, 0))); // B1 < B1
|
||||
static_assert(!(ScAddress(0, 1, 0) < ScAddress(0, 1, 0))); // A2 < A2
|
||||
static_assert(!(ScAddress(0, 0, 1) < ScAddress(0, 0, 1))); // Sheet2:A1 < Sheet2:A1
|
||||
|
||||
static_assert(ScAddress(0, 0, 0) < ScAddress(1, 0, 0)); // A1 < B1
|
||||
static_assert(ScAddress(0, 1, 0) < ScAddress(1, 0, 0)); // A2 < B1
|
||||
static_assert(ScAddress(0, 10000, 0) < ScAddress(1, 0, 0)); // A10000 < B1
|
||||
static_assert(ScAddress(0, 10000, 0) < ScAddress(1, 10000, 0)); // A10000 < B10000
|
||||
static_assert(ScAddress(1, 0, 0) < ScAddress(1, 0, 1)); // Sheet1:A1 < Sheet2:A1
|
||||
|
||||
// Less or Equal
|
||||
|
||||
static_assert(ScAddress(1, 0, 0) <= ScAddress(1, 0, 0)); // B1 <= B1
|
||||
static_assert(ScAddress(0, 1, 0) <= ScAddress(0, 1, 0)); // A2 <= A2
|
||||
static_assert(ScAddress(0, 0, 1) <= ScAddress(0, 0, 1)); // Sheet2:A1 <= Sheet2:A1
|
||||
|
||||
static_assert(ScAddress(0, 0, 0) <= ScAddress(1, 0, 0)); // A1 <= B1
|
||||
static_assert(ScAddress(0, 1, 0) <= ScAddress(1, 0, 0)); // A2 <= B1
|
||||
static_assert(ScAddress(0, 10000, 0) <= ScAddress(1, 0, 0)); // A10000 <= B1
|
||||
static_assert(ScAddress(0, 10000, 0) <= ScAddress(1, 10000, 0)); // A10000 <= B10000
|
||||
static_assert(ScAddress(1, 0, 0) <= ScAddress(1, 0, 1)); // Sheet1:A1 <= Sheet2:A1
|
||||
|
||||
// More
|
||||
|
||||
static_assert(!(ScAddress(1, 0, 0) > ScAddress(1, 0, 0))); // B1 > B1
|
||||
static_assert(!(ScAddress(0, 1, 0) > ScAddress(0, 1, 0))); // A2 > A2
|
||||
static_assert(!(ScAddress(0, 0, 1) > ScAddress(0, 0, 1))); // Sheet1:A1 > Sheet2:A1
|
||||
|
||||
static_assert(ScAddress(1, 0, 0) > ScAddress(0, 0, 0)); // B1 > A1
|
||||
static_assert(ScAddress(1, 0, 0) > ScAddress(0, 1, 0)); // B1 > A2
|
||||
static_assert(ScAddress(1, 0, 0) > ScAddress(0, 10000, 0)); // B1 > A10000
|
||||
static_assert(ScAddress(1, 10000, 0) > ScAddress(0, 10000, 0)); // B10000 > A10000
|
||||
static_assert(ScAddress(1, 0, 1) > ScAddress(1, 0, 0)); // Sheet2:A1 > Sheet1:A1
|
||||
|
||||
// More or Equal
|
||||
|
||||
static_assert(ScAddress(1, 0, 0) >= ScAddress(1, 0, 0)); // B1 >= B1
|
||||
static_assert(ScAddress(0, 1, 0) >= ScAddress(0, 1, 0)); // A2 >= A2
|
||||
static_assert(ScAddress(0, 0, 1) >= ScAddress(0, 0, 1)); // Sheet1:A1 >= Sheet2:A1
|
||||
|
||||
static_assert(ScAddress(1, 0, 0) >= ScAddress(0, 0, 0)); // B1 >= A1
|
||||
static_assert(ScAddress(1, 0, 0) >= ScAddress(0, 1, 0)); // B1 >= A2
|
||||
static_assert(ScAddress(1, 0, 0) >= ScAddress(0, 10000, 0)); // B1 >= A10000
|
||||
static_assert(ScAddress(1, 10000, 0) >= ScAddress(0, 10000, 0)); // B10000 >= A10000
|
||||
static_assert(ScAddress(1, 0, 1) >= ScAddress(1, 0, 0)); // Sheet2:A1 >= Sheet1:A1
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
Reference in New Issue
Block a user