KiCad PCB EDA Suite
util.h File Reference
#include <config.h>
#include <cmath>
#include <cstdint>
#include <limits>
#include <typeinfo>
#include <type_traits>

Go to the source code of this file.

Functions

void kimathLogDebug (const char *aFormatString,...)
 Helper to avoid directly including wx/log.h for the templated functions in kimath. More...
 
void kimathLogOverflow (double v, const char *aTypeName)
 Workaround to avoid the empty-string conversion issue in wxWidgets. More...
 
template<typename T >
constexpr T Clamp (const T &lower, const T &value, const T &upper)
 Limit value within the range lower <= value <= upper. More...
 
template<typename fp_type , typename ret_type = int>
constexpr ret_type KiROUND (fp_type v)
 Round a floating point number to an integer using "round halfway cases away from zero". More...
 
template<typename T >
rescale (T aNumerator, T aValue, T aDenominator)
 Scale a number (value) by rational (numerator/denominator). More...
 
template<typename T >
int sign (T val)
 
template<>
int rescale (int aNumerator, int aValue, int aDenominator)
 
template<>
int64_t rescale (int64_t aNumerator, int64_t aValue, int64_t aDenominator)
 
template<class T >
std::enable_if< std::is_floating_point< T >::value, bool >::type equals (T aFirst, T aSecond, T aEpsilon=std::numeric_limits< T >::epsilon())
 Template to compare two floating point values for equality within a required epsilon. More...
 

Function Documentation

◆ Clamp()

template<typename T >
constexpr T Clamp ( const T &  lower,
const T &  value,
const T &  upper 
)
inlineconstexpr

Limit value within the range lower <= value <= upper.

It will work on temporary expressions, since they are evaluated only once, and it should work on most if not all numeric types, string types, or any type for which "operator < ()" is present. The arguments are accepted in this order so you can remember the expression as a memory aid:

result is: lower <= value <= upper

Definition at line 64 of file util.h.

65{
66 if( value < lower )
67 return lower;
68 else if( upper < value )
69 return upper;
70 return value;
71}

Referenced by LSET::AllCuMask(), DIALOG_PAGES_SETTINGS::GetCustomSizeMilsFromDialog(), SCH_SEXPR_PARSER::parseEDA_TEXT(), SCH_SEXPR_PARSER::parseFill(), SCH_SEXPR_PARSER::parseJunction(), STROKE_PARAMS_PARSER::ParseStroke(), DRAWING_SHEET_PARSER::parseText(), BRDITEMS_PLOTTER::plotOneDrillMark(), PCB_PLOT_PARAMS::SetSvgPrecision(), and DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample().

◆ equals()

template<class T >
std::enable_if< std::is_floating_point< T >::value, bool >::type equals ( aFirst,
aSecond,
aEpsilon = std::numeric_limits<T>::epsilon() 
)

Template to compare two floating point values for equality within a required epsilon.

Parameters
aFirstvalue to compare.
aSecondvalue to compare.
aEpsilonallowed error.
Returns
true if the values considered equal within the specified epsilon, otherwise false.

Definition at line 147 of file util.h.

148{
149 T diff = std::abs( aFirst - aSecond );
150
151 if( diff < aEpsilon )
152 {
153 return true;
154 }
155
156 aFirst = std::abs( aFirst );
157 aSecond = std::abs( aSecond );
158 T largest = aFirst > aSecond ? aFirst : aSecond;
159
160 if( diff <= largest * aEpsilon )
161 {
162 return true;
163 }
164
165 return false;
166}
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:412

References std::abs().

◆ kimathLogDebug()

void kimathLogDebug ( const char *  aFormatString,
  ... 
)

Helper to avoid directly including wx/log.h for the templated functions in kimath.

Definition at line 44 of file util.cpp.

45{
46 if( wxLog::IsLevelEnabled( wxLOG_Debug, wxString::FromAscii( wxLOG_COMPONENT ) ) )
47 {
48 va_list argList;
49 va_start( argList, aFormatString );
50
51 wxVLogWarning( aFormatString, argList );
52
53 va_end( argList );
54 }
55}

Referenced by rescale().

◆ kimathLogOverflow()

void kimathLogOverflow ( double  v,
const char *  aTypeName 
)

Workaround to avoid the empty-string conversion issue in wxWidgets.

Definition at line 58 of file util.cpp.

59{
60 wxString typeName( aTypeName );
61 wxLogWarning( wxString::Format( wxT( "Overflow converting value %f to %s." ), v, typeName ) );
62}
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200

References Format().

Referenced by KiROUND().

◆ KiROUND()

template<typename fp_type , typename ret_type = int>
constexpr ret_type KiROUND ( fp_type  v)
constexpr

Round a floating point number to an integer using "round halfway cases away from zero".

In Debug build an assert fires if will not fit into the return type.

Definition at line 85 of file util.h.

86{
87 using max_ret = long long int;
88 fp_type ret = v < 0 ? v - 0.5 : v + 0.5;
89
90 if( ret > std::numeric_limits<ret_type>::max() )
91 {
92 kimathLogOverflow( double( v ), typeid( ret_type ).name() );
93
94 return std::numeric_limits<ret_type>::max() - 1;
95 }
96 else if( ret < std::numeric_limits<ret_type>::lowest() )
97 {
98 kimathLogOverflow( double( v ), typeid( ret_type ).name() );
99
100 if( std::numeric_limits<ret_type>::is_signed )
101 return std::numeric_limits<ret_type>::lowest() + 1;
102 else
103 return 0;
104 }
105
106 return ret_type( max_ret( ret ) );
107}
const char * name
Definition: DXF_plotter.cpp:56
void kimathLogOverflow(double v, const char *aTypeName)
Workaround to avoid the empty-string conversion issue in wxWidgets.
Definition: util.cpp:58

References kimathLogOverflow(), and name.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), PCAD2KICAD::PCB_POLYGON::AddToBoard(), GRID_HELPER::AlignGrid(), Altium2KiCadUnit(), CADSTAR_PCB_ARCHIVE_LOADER::applyTextCode(), CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings(), CADSTAR_SCH_ARCHIVE_LOADER::applyTransform(), HPGL_PLOTTER::Arc(), PDF_PLOTTER::Arc(), PLOTTER::Arc(), EDA_ANGLE::AsTenthsOfADegree(), SCH_DIRECTIVE_LABEL::AutoplaceFields(), SCH_SHEET::AutoplaceFields(), PCB_GRID_HELPER::BestSnapAnchor(), KIGFX::SCH_PAINTER::bitmapText(), LEGACY_PLUGIN::biuParse(), build45DegLeader(), BuildCornersList_S_Shape(), PAD::BuildEffectivePolygon(), DIRECTION_45::BuildInitialTrace(), ZONE_FILLER::buildThermalSpokes(), CalcArcCenter(), EDA_SHAPE::calcEdit(), PCAD2KICAD::CalculateTextLengthSize(), SHAPE_POLY_SET::chamferFilletPolygon(), EE_INSPECTION_TOOL::CheckSymbol(), CircleToEndSegmentDeltaRadius(), Clamp_Text_PenSize(), EE_SELECTION_TOOL::CollectHits(), SCH_LINE_WIRE_BUS_TOOL::computeBreakPoint(), computeCenter(), ConfigureHPGLPenSizes(), ALTIUM_PCB::ConvertArcs6ToBoardItemOnLayer(), ALTIUM_PCB::ConvertArcs6ToPcbShape(), ConvertArcToPolyline(), AM_PRIMITIVE::ConvertBasicShapeToPolygon(), convertPolygon(), AM_PRIMITIVE::ConvertShapeToPolygon(), ALTIUM_PARSER::ConvertToKicadUnit(), SHAPE_ARC::ConvertToPolyline(), PCAD2KICAD::CorrectTextPosition(), FOOTPRINT::CoverageRatio(), SCH_DIRECTIVE_LABEL::CreateGraphicShape(), MICROWAVE_TOOL::createMicrowaveInductor(), MICROWAVE_TOOL::createPolygonShape(), BOARD_ADAPTER::createTrack(), SCH_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), PCB_CONTROL::DeleteItemCursor(), EDIT_TOOL::DragArcTrack(), KIGFX::SCH_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), KIGFX::OPENGL_GAL::DrawArcSegment(), BITMAP_BASE::DrawBitmap(), KIGFX::OPENGL_GAL::drawBitmapChar(), CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarText(), KIGFX::CAIRO_GAL_BASE::DrawGrid(), KIGFX::OPENGL_GAL::DrawGrid(), GERBER_PLOTTER::emitDcode(), PCB_EXPR_EVALUATOR::Evaluate(), GERBER_FILE_IMAGE::ExecuteRS274XCommand(), PANEL_GALVANIC_CORROSION::fillTable(), EDIT_POINTS::FindPoint(), HPGL_PLOTTER::FlashPadCircle(), HPGL_PLOTTER::FlashPadOval(), HPGL_PLOTTER::FlashPadRect(), HPGL_PLOTTER::FlashPadRoundRect(), FootprintWriteShape(), DS_DATA_MODEL_IO::format(), EDA_TEXT::Format(), STROKE_PARAMS::Format(), formatFill(), BM2CMP_FRAME::FormatOutputSize(), gen_arc(), GENDRILL_WRITER_BASE::genDrillMapFile(), RENDER_3D_OPENGL::generate3dGrid(), WX_HTML_REPORT_BOX::generateHtml(), GERBER_DRAW_ITEM::GetABPosition(), SCH_LINE::GetAngleFrom(), GetArcToSegmentCount(), CADSTAR_SCH_ARCHIVE_LOADER::getCadstarAngle(), GetClampedCoords(), FOOTPRINT::GetCoverageArea(), DIALOG_PAGES_SETTINGS::GetCustomSizeMilsFromDialog(), DS_DATA_ITEM::GetEndPosUi(), GRID_HELPER::GetGrid(), KIGFX::GAL::GetGridPoint(), getGUIFont(), EDA_TEXT::GetInterline(), GetKnockoutTextMargin(), SCH_LABEL_BASE::GetLabelBoxExpansion(), EDA_DRAW_FRAME::GetNearestGridPosition(), EDA_DRAW_FRAME::GetNearestHalfGridPosition(), EE_SELECTION_TOOL::GetNode(), IMAGE_SIZE::GetOutputDPI(), GetPenSizeForBold(), GetPenSizeForNormal(), DS_DATA_ITEM::GetPenSizeUi(), DS_DATA_ITEM_POLYGONS::GetPenSizeUi(), DS_DATA_ITEM_TEXT::GetPenSizeUi(), EDA_SHAPE::GetRadius(), SCH_LINE::GetReverseAngleFrom(), PAD::GetRoundRectCornerRadius(), BITMAP_BASE::GetSize(), PAD::GetSolderPasteMargin(), DS_DATA_ITEM::GetStartPosUi(), KIFONT::OUTLINE_FONT::getTextAsGlyphs(), KIFONT::OUTLINE_FONT::GetTextAsGlyphs(), KIFONT::STROKE_FONT::GetTextAsGlyphs(), EDA_TEXT::GetTextBox(), CADSTAR_SCH_ARCHIVE_LOADER::getTextHeightFromTextCode(), LIB_TEXTBOX::GetTextMargin(), SCH_TEXTBOX::GetTextMargin(), FP_TEXTBOX::GetTextMargin(), PCB_TEXTBOX::GetTextMargin(), SCH_TEXT::GetTextOffset(), DIALOG_POSITION_RELATIVE::getTranslationInIU(), GRID_HELPER::GetVisibleGrid(), GERBER_DRAW_ITEM::GetXYPosition(), GraphicTextWidth(), EE_SELECTION_TOOL::GuessSelectionCandidates(), PCB_SELECTION_TOOL::GuessSelectionCandidates(), ZONE::HatchBorder(), ALTIUM_PCB::HelperParseDimensions6Leader(), HelperShapeLineChainFromAltiumVertices(), DIALOG_PLOT::init_Dialog(), initializePlotter(), GENERAL_COLLECTOR::Inspect(), CIRCLE::Intersect(), CN_ANCHOR::IsDangling(), PCB_TRACK::IsPointOnEnds(), iu_to_d356(), KiScaledBitmap(), EAGLE_PLUGIN::Load(), CADSTAR_SCH_ARCHIVE_LOADER::loadDocumentationSymbols(), SCH_EAGLE_PLUGIN::loadFrame(), CADSTAR_SCH_ARCHIVE_LOADER::loadGraphicStaightSegment(), SCH_EAGLE_PLUGIN::loadLabel(), EAGLE_PLUGIN::loadPlain(), EAGLE_PLUGIN::loadPolygon(), EAGLE_PLUGIN::loadSignals(), CADSTAR_SCH_ARCHIVE_LOADER::loadSymbolFieldAttribute(), PCB_SELECTION_TOOL::Main(), DSN::SPECCTRA_DB::makePADSTACK(), GRAPHICS_IMPORTER_PCBNEW::MapCoordinate(), PLOTTER::markerSquare(), EDA_UNIT_UTILS::Mils2mm(), GERBVIEW_PRINTOUT::milsToIU(), PCBNEW_PRINTOUT::milsToIU(), EDA_UNIT_UTILS::Mm2mils(), ACTION_TOOLBAR::OnCustomRender(), EDA_LIST_DIALOG::onSize(), BM2CMP_FRAME::OpenProjectFiles(), VECTOR2< T >::operator/(), EAGLE_PLUGIN::orientFPText(), EAGLE_PLUGIN::packagePad(), EAGLE_PLUGIN::packagePolygon(), EAGLE_PLUGIN::packageText(), DIALOG_PAD_PROPERTIES::padValuesOK(), PANEL_PACKAGE::PANEL_PACKAGE(), PCAD2KICAD::PCB_ARC::Parse(), SCH_ALTIUM_PLUGIN::ParseArc(), PCB_PARSER::parseBoardUnits(), GPCB_FPL_CACHE::parseFOOTPRINT(), parseInt(), SCH_SEXPR_PARSER::parseInternalUnits(), SCH_TEXT::Plot(), GERBER_PLOTTER::plotArc(), BRDITEMS_PLOTTER::PlotFootprintShape(), PS_PLOTTER::PlotImage(), PDF_PLOTTER::PlotImage(), GERBER_PLOTTER::plotRoundRectAsRegion(), PSLIKE_PLOTTER::postscriptOverlinePositions(), SCH_TEXT::Print(), GERBER_DRAW_ITEM::Print(), FABMASTER::processArc(), FABMASTER::processFootprints(), FABMASTER::processLine(), FABMASTER::processPadStacks(), FABMASTER::processPins(), FABMASTER::processRectangle(), FABMASTER::processText(), FABMASTER::processVias(), GERBER_FILE_IMAGE::ReadIJCoord(), BITMAP_BASE::ReadImageFile(), PARAM_CFG_INT_WITH_SCALE::ReadParam(), EXCELLON_IMAGE::readToolInformation(), GERBER_FILE_IMAGE::ReadXYCoord(), PANEL_SETUP_PINMAP::reBuildMatrixPanel(), VECTOR2< T >::Resize(), PSLIKE_PLOTTER::returnPostscriptTextWidth(), RotatePoint(), rotationFromString(), SCH_SEXPR_PLUGIN::saveJunction(), SCH_SEXPR_PLUGIN::saveSheet(), EDA_SHAPE::scale(), DSN::scale(), scaletoIU(), SCH_JUNCTION::SCH_JUNCTION(), PLOTTER::segmentAsOval(), PNS::SegmentHull(), SegmentIntersectsSegment(), PCB_SELECTION_TOOL::selectionContains(), PL_SELECTION_TOOL::SelectPoint(), DS_DATA_ITEM_TEXT::SetConstrainedTextSize(), PCAD2KICAD::SetTextSizeFromStrokeFontHeight(), PCAD2KICAD::SetTextSizeFromTrueTypeFontHeight(), SHAPE_ARC::SHAPE_ARC(), snapAngle(), PS_PLOTTER::StartPlot(), KIFONT::FONT::StringBoundaryLimits(), STROKE_PARAMS::Stroke(), PCAD2KICAD::StrToInt1Units(), PCAD2KICAD::StrToIntUnits(), KIFONT::OUTLINE_FONT::subscriptSize(), DS_DATA_ITEM_TEXT::SyncDrawItems(), CONNECTIVITY_DATA::TestTrackEndpointDangling(), AR_MATRIX::traceArc(), AR_MATRIX::traceCircle(), AR_MATRIX::TraceFilledRectangle(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow(), PANEL_EESCHEMA_DISPLAY_OPTIONS::TransferDataFromWindow(), DIALOG_MOVE_EXACT::TransferDataFromWindow(), DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform(), TransformOvalToPolygon(), TransformRoundChamferedRectToPolygon(), TransformTrapezoidToPolygon(), SHAPE_ARC::update_bbox(), DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample(), PCB_DIM_ALIGNED::updateGeometry(), PCB_DIM_ORTHOGONAL::updateGeometry(), PCB_DIM_RADIAL::updateGeometry(), TUNER_SLIDER::updateSlider(), PCB_DIM_RADIAL::updateText(), DIALOG_DRC::updateUI(), KIGFX::ORIGIN_VIEWITEM::ViewDraw(), EXCELLON_WRITER::writeCoordinates(), and PCB_SELECTION_TOOL::ZoomFitCrossProbeBBox().

◆ rescale() [1/3]

template<>
int rescale ( int  aNumerator,
int  aValue,
int  aDenominator 
)

Definition at line 66 of file util.cpp.

67{
68 int64_t numerator = (int64_t) aNumerator * (int64_t) aValue;
69
70 // round to nearest
71 if( ( numerator < 0 ) ^ ( aDenominator < 0 ) )
72 return ( numerator - aDenominator / 2 ) / aDenominator;
73 else
74 return ( numerator + aDenominator / 2 ) / aDenominator;
75
76}

◆ rescale() [2/3]

template<>
int64_t rescale ( int64_t  aNumerator,
int64_t  aValue,
int64_t  aDenominator 
)

Definition at line 80 of file util.cpp.

81{
82#if defined( _M_X64 ) && ( _MSC_VER >= 1920 )
83 int64_t productHi;
84 uint64_t productLo = static_cast<uint64_t>( _mul128( aNumerator, aValue, &productHi ) );
85
86 int64_t r = ( ( productHi < 0 ) ^ ( aDenominator < 0 ) ) ? -aDenominator / 2 : aDenominator / 2;
87
88 uint64_t rLo = static_cast<uint64_t>( r );
89 int64_t rHi = r < 0 ? -1ll : 0ll;
90
91 productLo += rLo;
92 productHi += rHi + ( productLo < rLo );
93
94 __try
95 {
96 int64_t remainder;
97 int64_t result = _div128( productHi, productLo, aDenominator, &remainder );
98
99 return result;
100 }
101 __except( ( GetExceptionCode() == EXCEPTION_INT_OVERFLOW ) ? EXCEPTION_EXECUTE_HANDLER
102 : EXCEPTION_CONTINUE_SEARCH )
103 {
104 kimathLogDebug( "Overflow in rescale (%lld * %lld + %lld) / %lld", aNumerator, aValue, r,
105 aDenominator );
106 }
107
108 return 0;
109
110#elif defined( __SIZEOF_INT128__ )
111 __int128_t numerator = (__int128_t) aNumerator * (__int128_t) aValue;
112
113 if( ( numerator < 0 ) ^ ( aDenominator < 0 ) )
114 return ( numerator - aDenominator / 2 ) / aDenominator;
115 else
116 return ( numerator + aDenominator / 2 ) / aDenominator;
117
118#else
119 int64_t r = 0;
120 int64_t sign = ( ( aNumerator < 0 ) ? -1 : 1 ) * ( aDenominator < 0 ? -1 : 1 ) *
121 ( aValue < 0 ? -1 : 1 );
122
123 int64_t a = std::abs( aNumerator );
124 int64_t b = std::abs( aValue );
125 int64_t c = std::abs( aDenominator );
126
127 r = c / 2;
128
129 if( b <= INT_MAX && c <= INT_MAX )
130 {
131 if( a <= INT_MAX )
132 return sign * ( ( a * b + r ) / c );
133 else
134 return sign * ( a / c * b + ( a % c * b + r ) / c);
135 }
136 else
137 {
138 uint64_t a0 = a & 0xFFFFFFFF;
139 uint64_t a1 = a >> 32;
140 uint64_t b0 = b & 0xFFFFFFFF;
141 uint64_t b1 = b >> 32;
142 uint64_t t1 = a0 * b1 + a1 * b0;
143 uint64_t t1a = t1 << 32;
144 int i;
145
146 a0 = a0 * b0 + t1a;
147 a1 = a1 * b1 + ( t1 >> 32 ) + ( a0 < t1a );
148 a0 += r;
149 a1 += a0 < (uint64_t)r;
150
151 for( i = 63; i >= 0; i-- )
152 {
153 a1 += a1 + ( ( a0 >> i ) & 1 );
154 t1 += t1;
155
156 if( (uint64_t) c <= a1 )
157 {
158 a1 -= c;
159 t1++;
160 }
161 }
162
163 return t1 * sign;
164 }
165#endif
166}
void kimathLogDebug(const char *aFormatString,...)
Helper to avoid directly including wx/log.h for the templated functions in kimath.
Definition: util.cpp:44
int sign(T val)
Definition: util.h:124

References std::abs(), kimathLogDebug(), and sign().

◆ rescale() [3/3]

template<typename T >
T rescale ( aNumerator,
aValue,
aDenominator 
)

Scale a number (value) by rational (numerator/denominator).

Numerator must be <= denominator.

Definition at line 118 of file util.h.

119{
120 return aNumerator * aValue / aDenominator;
121}

Referenced by BOOST_AUTO_TEST_CASE(), commonParallelProjection(), PNS::commonParallelProjection(), PAD::GetBestAnchorPosition(), SEG::intersects(), SEG::LineDistance(), SEG::LineProject(), SEG::mutualDistance(), SEG::NearestPoint(), SHAPE_LINE_CHAIN_BASE::PointInside(), processEdge(), SEG::ReflectPoint(), and VECTOR2< T >::Resize().

◆ sign()