Add std::hash specialization for VECTOR2I

This commit is contained in:
Marek Roszko 2022-01-01 20:28:28 -05:00
parent a365afde3c
commit 589a03afcd
3 changed files with 59 additions and 1 deletions

View File

@ -21,6 +21,7 @@ set( KIMATH_SRCS
src/geometry/shape_segment.cpp
src/math/vector2.cpp
src/math/util.cpp
)

View File

@ -627,12 +627,29 @@ std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
return aStream;
}
/* Default specializations */
typedef VECTOR2<double> VECTOR2D;
typedef VECTOR2<int> VECTOR2I;
typedef VECTOR2<unsigned int> VECTOR2U;
/* STL specializations */
namespace std
{
// Required to enable correct use in std::map/unordered_map
template <>
struct hash<VECTOR2I>
{
size_t operator()( const VECTOR2I& k ) const;
};
// Required to enable use of std::hash with maps
template <>
struct less<VECTOR2I>
{
bool operator()( const VECTOR2I& aA, const VECTOR2I& aB ) const;
};
}
/* Compatibility typedefs */
// FIXME should be removed to avoid multiple typedefs for the same type
typedef VECTOR2<double> DPOINT;

View File

@ -0,0 +1,40 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <math/vector2d.h>
size_t std::hash<VECTOR2I>::operator()( const VECTOR2I& k ) const
{
auto xhash = std::hash<int>()( k.x );
// 0x9e3779b9 is 2^33 / ( 1 + sqrt(5) )
// Adding this value ensures that consecutive bits of y will not be close to each other
// decreasing the likelihood of hash collision in similar values of x and y
return xhash ^ ( std::hash<int>()( k.y ) + 0x9e3779b9 + ( xhash << 6 ) + ( xhash >> 2 ) );
}
bool std::less<VECTOR2I>::operator()( const VECTOR2I& aA, const VECTOR2I& aB ) const
{
if( aA.x == aB.x )
return aA.y < aB.y;
return aA.x < aB.x;
}