Arrays: isolate axis code in a new class

Remove the axis numbering code from ARRAY_OPTIONS
and place in a new class, ARRAY_AXIS. This keeps
the logic for the array item numbering separate from
the logic for the array item geometry.

This simplifies the logic in the ARRAY_OPTIONS class, which
no longer has to deal with the numbering of each axis.
This commit is contained in:
John Beard 2019-05-15 11:47:45 +01:00
parent dfc3a11185
commit 2c1b970027
10 changed files with 531 additions and 178 deletions

View File

@ -280,6 +280,7 @@ set( COMMON_SRCS
${COMMON_PREVIEW_ITEMS_SRCS} ${COMMON_PREVIEW_ITEMS_SRCS}
${PLOTTERS_CONTROL_SRCS} ${PLOTTERS_CONTROL_SRCS}
advanced_config.cpp advanced_config.cpp
array_axis.cpp
array_options.cpp array_options.cpp
base_struct.cpp base_struct.cpp
bezier_curves.cpp bezier_curves.cpp

153
common/array_axis.cpp Normal file
View File

@ -0,0 +1,153 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <array_axis.h>
/**
* @return False for schemes like 0,1...9,10
* True for schemes like A,B..Z,AA (where the tens column starts with char 0)
*/
static bool schemeNonUnitColsStartAt0( ARRAY_AXIS::NUMBERING_TYPE type )
{
return type == ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL
|| type == ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_NO_IOSQXZ;
}
ARRAY_AXIS::ARRAY_AXIS() : m_type( NUMBERING_TYPE::NUMBERING_NUMERIC ), m_offset( 0 )
{
}
const wxString& ARRAY_AXIS::GetAlphabet() const
{
static const wxString alphaNumeric = "0123456789";
static const wxString alphaHex = "0123456789ABCDEF";
static const wxString alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const wxString alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY";
switch( m_type )
{
default:
case NUMBERING_NUMERIC:
return alphaNumeric;
case NUMBERING_HEX:
return alphaHex;
case NUMBERING_ALPHA_NO_IOSQXZ:
return alphaNoIOSQXZ;
case NUMBERING_ALPHA_FULL:
return alphaFull;
}
}
OPT<int> ARRAY_AXIS::getNumberingOffset( const wxString& str ) const
{
if( str.length() == 0 )
return OPT<int>{};
const wxString& alphabet = GetAlphabet();
int offset = 0;
const int radix = alphabet.length();
for( unsigned i = 0; i < str.length(); i++ )
{
int chIndex = alphabet.Find( str[i], false );
if( chIndex == wxNOT_FOUND )
return OPT<int>{};
const bool start0 = schemeNonUnitColsStartAt0( m_type );
// eg "AA" is actually index 27, not 26
if( start0 && i < str.length() - 1 )
chIndex++;
offset *= radix;
offset += chIndex;
}
return OPT<int>{ offset };
}
void ARRAY_AXIS::SetAxisType( NUMBERING_TYPE aType )
{
m_type = aType;
}
bool ARRAY_AXIS::SetOffset( const wxString& aOffsetName )
{
OPT<int> offset = getNumberingOffset( aOffsetName );
// The string does not decode to a valid offset
if( !offset )
return false;
SetOffset( *offset );
return true;
}
void ARRAY_AXIS::SetOffset( int aOffset )
{
m_offset = aOffset;
}
int ARRAY_AXIS::GetOffset() const
{
return m_offset;
}
wxString ARRAY_AXIS::GetItemNumber( int n ) const
{
wxString itemNum;
const wxString& alphabet = GetAlphabet();
const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( m_type );
bool firstRound = true;
int radix = alphabet.Length();
n += m_offset;
do
{
int modN = n % radix;
if( nonUnitColsStartAt0 && !firstRound )
modN--; // Start the "tens/hundreds/etc column" at "Ax", not "Bx"
itemNum.insert( 0, 1, alphabet[modN] );
n /= radix;
firstRound = false;
} while( n );
return itemNum;
}

View File

@ -25,86 +25,6 @@
#include <trigo.h> #include <trigo.h>
const wxString& ARRAY_OPTIONS::AlphabetFromNumberingScheme( NUMBERING_TYPE_T type )
{
static const wxString alphaNumeric = "0123456789";
static const wxString alphaHex = "0123456789ABCDEF";
static const wxString alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const wxString alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY";
switch( type )
{
default:
case NUMBERING_NUMERIC: return alphaNumeric;
case NUMBERING_HEX: return alphaHex;
case NUMBERING_ALPHA_NO_IOSQXZ: return alphaNoIOSQXZ;
case NUMBERING_ALPHA_FULL: return alphaFull;
}
}
bool ARRAY_OPTIONS::SchemeNonUnitColsStartAt0( NUMBERING_TYPE_T type )
{
return type == NUMBERING_ALPHA_FULL || type == NUMBERING_ALPHA_NO_IOSQXZ;
}
bool ARRAY_OPTIONS::GetNumberingOffset(
const wxString& str, ARRAY_OPTIONS::NUMBERING_TYPE_T type, int& offsetToFill )
{
const wxString& alphabet = ARRAY_OPTIONS::AlphabetFromNumberingScheme( type );
int offset = 0;
const int radix = alphabet.length();
for( unsigned i = 0; i < str.length(); i++ )
{
int chIndex = alphabet.Find( str[i], false );
if( chIndex == wxNOT_FOUND )
return false;
const bool start0 = ARRAY_OPTIONS::SchemeNonUnitColsStartAt0( type );
// eg "AA" is actually index 27, not 26
if( start0 && i < str.length() - 1 )
chIndex++;
offset *= radix;
offset += chIndex;
}
offsetToFill = offset;
return true;
}
wxString ARRAY_OPTIONS::getCoordinateNumber( int n, NUMBERING_TYPE_T type )
{
wxString itemNum;
const wxString& alphabet = AlphabetFromNumberingScheme( type );
const bool nonUnitColsStartAt0 = SchemeNonUnitColsStartAt0( type );
bool firstRound = true;
int radix = alphabet.Length();
do
{
int modN = n % radix;
if( nonUnitColsStartAt0 && !firstRound )
modN--; // Start the "tens/hundreds/etc column" at "Ax", not "Bx"
itemNum.insert( 0, 1, alphabet[modN] );
n /= radix;
firstRound = false;
} while( n );
return itemNum;
}
int ARRAY_GRID_OPTIONS::GetArraySize() const int ARRAY_GRID_OPTIONS::GetArraySize() const
{ {
@ -167,12 +87,12 @@ wxString ARRAY_GRID_OPTIONS::GetItemNumber( int n ) const
{ {
VECTOR2I coords = getGridCoords( n ); VECTOR2I coords = getGridCoords( n );
itemNum += getCoordinateNumber( coords.x + m_numberingOffsetX, m_priAxisNumType ); itemNum << m_pri_axis.GetItemNumber( coords.x );
itemNum += getCoordinateNumber( coords.y + m_numberingOffsetY, m_secAxisNumType ); itemNum << m_sec_axis.GetItemNumber( coords.y );
} }
else else
{ {
itemNum += getCoordinateNumber( n + m_numberingOffsetX, m_priAxisNumType ); itemNum << m_pri_axis.GetItemNumber( n );
} }
return itemNum; return itemNum;
@ -209,5 +129,5 @@ ARRAY_OPTIONS::TRANSFORM ARRAY_CIRCULAR_OPTIONS::GetTransform( int n, const VECT
wxString ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const wxString ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const
{ {
return getCoordinateNumber( aN + m_numberingOffset, m_numberingType ); return m_axis.GetItemNumber( aN );
} }

110
include/array_axis.h Normal file
View File

@ -0,0 +1,110 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef ARRAY_AXIS__H
#define ARRAY_AXIS__H
#include <core/optional.h>
#include <wx/string.h>
/**
* Class that contains information about a single array axis and the numbering
* of items along that axis.
*
* For example, a rectangular grid has two axes, X and Y, but a circular array
* has only one, that runs around the circle.
*/
class ARRAY_AXIS
{
public:
enum NUMBERING_TYPE
{
NUMBERING_NUMERIC = 0, ///< Arabic numerals: 0,1,2,3,4,5,6,7,8,9,10,11...
NUMBERING_HEX,
NUMBERING_ALPHA_NO_IOSQXZ, /*!< Alphabet, excluding IOSQXZ
*
* Per ASME Y14.35M-1997 sec. 5.2 (previously MIL-STD-100 sec. 406.5)
* as these can be confused with numerals and are often not used
* for pin numbering on BGAs, etc
*/
NUMBERING_ALPHA_FULL, ///< Full 26-character alphabet
};
ARRAY_AXIS();
/**
* Get the alphabet for the current numbering scheme.
* @param type the numbering scheme
* @return the alphabet (as a string)
*/
const wxString& GetAlphabet() const;
/**
* Set the axis numbering type
*/
void SetAxisType( NUMBERING_TYPE aType );
/**
* Set the axis start (as a string, which should decode to a valid index
* in the alphabet)
*/
bool SetOffset( const wxString& aOffsetName );
/**
* Set the start offset for the series (e.g. 0 to start at 0/A, 4 to start
* at 4/E).
*
* @param aOffset offset of the first item in the
*/
void SetOffset( int aOffset );
/**
* Get the numbering offset for the axis
*
* @return the current offset
*/
int GetOffset() const;
/**
* Get the position number (name) for the n'th axis point
*
* @param n array point index, from 0
* @return the point's name
*/
wxString GetItemNumber( int n ) const;
private:
/**
* Get the numbering offset for a given numbering string
*
* @param str a numbering string, say "B" or "5"
* @return the offset, if found, else empty
*/
OPT<int> getNumberingOffset( const wxString& str ) const;
NUMBERING_TYPE m_type;
int m_offset;
};
#endif // ARRAY_AXIS__H

View File

@ -26,6 +26,8 @@
#include <math/vector2d.h> #include <math/vector2d.h>
#include <array_axis.h>
/** /**
* Options that govern the setup of an "array" of multiple item. * Options that govern the setup of an "array" of multiple item.
* The base #ARRAY_OPTIONS do not encode a specific geometry or numbering * The base #ARRAY_OPTIONS do not encode a specific geometry or numbering
@ -40,20 +42,6 @@ public:
ARRAY_CIRCULAR, ///< A circular array ARRAY_CIRCULAR, ///< A circular array
}; };
// NOTE: do not change order relative to charSetDescriptions
enum NUMBERING_TYPE_T
{
NUMBERING_NUMERIC = 0, ///< Arabic numerals: 0,1,2,3,4,5,6,7,8,9,10,11...
NUMBERING_HEX,
NUMBERING_ALPHA_NO_IOSQXZ, /*!< Alphabet, excluding IOSQXZ
*
* Per ASME Y14.35M-1997 sec. 5.2 (previously MIL-STD-100 sec. 406.5)
* as these can be confused with numerals and are often not used
* for pin numbering on BGAs, etc
*/
NUMBERING_ALPHA_FULL, ///< Full 26-character alphabet
};
ARRAY_OPTIONS( ARRAY_TYPE_T aType ) ARRAY_OPTIONS( ARRAY_TYPE_T aType )
: m_type( aType ), m_shouldNumber( false ), m_numberingStartIsSpecified( false ) : m_type( aType ), m_shouldNumber( false ), m_numberingStartIsSpecified( false )
{ {
@ -61,29 +49,6 @@ public:
virtual ~ARRAY_OPTIONS(){}; virtual ~ARRAY_OPTIONS(){};
/**
* Get the alphabet for a particular numbering scheme.
* @param type the numbering scheme
* @return the alphabet (as a string)
*/
static const wxString& AlphabetFromNumberingScheme( NUMBERING_TYPE_T type );
/**
* @return False for schemes like 0,1...9,10
* True for schemes like A,B..Z,AA (where the tens column starts with char 0)
*/
static bool SchemeNonUnitColsStartAt0( NUMBERING_TYPE_T type );
/**
* Get the numbering offset for a given numbering string
* @param str a numbering string, say "B" or "5"
* @param type the type this string should be
* @param offsetToFill the offset to set, if found
* @return true if the string is a valid offset of this type
*/
static bool GetNumberingOffset(
const wxString& str, ARRAY_OPTIONS::NUMBERING_TYPE_T type, int& offsetToFill );
/** /**
* Transform applied to an object by this array * Transform applied to an object by this array
*/ */
@ -143,7 +108,6 @@ public:
} }
protected: protected:
static wxString getCoordinateNumber( int n, NUMBERING_TYPE_T type );
ARRAY_TYPE_T m_type; ARRAY_TYPE_T m_type;
@ -166,11 +130,7 @@ struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS
m_reverseNumberingAlternate( false ), m_reverseNumberingAlternate( false ),
m_stagger( 0 ), m_stagger( 0 ),
m_stagger_rows( true ), m_stagger_rows( true ),
m_2dArrayNumbering( false ), m_2dArrayNumbering( false )
m_numberingOffsetX( 0 ),
m_numberingOffsetY( 0 ),
m_priAxisNumType( NUMBERING_NUMERIC ),
m_secAxisNumType( NUMBERING_NUMERIC )
{ {
} }
@ -181,8 +141,7 @@ struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS
long m_stagger; long m_stagger;
bool m_stagger_rows; bool m_stagger_rows;
bool m_2dArrayNumbering; bool m_2dArrayNumbering;
int m_numberingOffsetX, m_numberingOffsetY; ARRAY_AXIS m_pri_axis, m_sec_axis;
NUMBERING_TYPE_T m_priAxisNumType, m_secAxisNumType;
TRANSFORM GetTransform( int aN, const VECTOR2I& aPos ) const override; TRANSFORM GetTransform( int aN, const VECTOR2I& aPos ) const override;
int GetArraySize() const override; int GetArraySize() const override;
@ -199,9 +158,7 @@ struct ARRAY_CIRCULAR_OPTIONS : public ARRAY_OPTIONS
: ARRAY_OPTIONS( ARRAY_CIRCULAR ), : ARRAY_OPTIONS( ARRAY_CIRCULAR ),
m_nPts( 0 ), m_nPts( 0 ),
m_angle( 0.0f ), m_angle( 0.0f ),
m_rotateItems( false ), m_rotateItems( false )
m_numberingType( NUMBERING_NUMERIC ),
m_numberingOffset( 0 )
{ {
} }
@ -211,8 +168,7 @@ struct ARRAY_CIRCULAR_OPTIONS : public ARRAY_OPTIONS
double m_angle; double m_angle;
VECTOR2I m_centre; VECTOR2I m_centre;
bool m_rotateItems; bool m_rotateItems;
NUMBERING_TYPE_T m_numberingType; ARRAY_AXIS m_axis;
long m_numberingOffset;
TRANSFORM GetTransform( int aN, const VECTOR2I& aPos ) const override; TRANSFORM GetTransform( int aN, const VECTOR2I& aPos ) const override;
int GetArraySize() const override; int GetArraySize() const override;

View File

@ -114,7 +114,7 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY(
// Set up numbering scheme drop downs // Set up numbering scheme drop downs
// //
// character set // character set
// NOTE: do not change the order of this relative to the NUMBERING_TYPE_T enum // NOTE: do not change the order of this relative to the NUMBERING_TYPE enum
const wxString charSetDescriptions[] = const wxString charSetDescriptions[] =
{ {
_( "Numerals (0,1,2,...,9,10)" ), _( "Numerals (0,1,2,...,9,10)" ),
@ -206,17 +206,15 @@ void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
* @return if all valid * @return if all valid
*/ */
static bool validateNumberingTypeAndOffset( const wxTextCtrl& offsetEntry, static bool validateNumberingTypeAndOffset( const wxTextCtrl& offsetEntry,
const wxChoice& typeEntry, const wxChoice& typeEntry, ARRAY_AXIS& aAxis, wxArrayString& errors )
ARRAY_OPTIONS::NUMBERING_TYPE_T& type,
int& offset, wxArrayString& errors )
{ {
const int typeVal = typeEntry.GetSelection(); const int typeVal = typeEntry.GetSelection();
// mind undefined casts to enums (should not be able to happen) // mind undefined casts to enums (should not be able to happen)
bool ok = typeVal <= ARRAY_OPTIONS::NUMBERING_TYPE_MAX; bool ok = typeVal <= ARRAY_AXIS::NUMBERING_TYPE_MAX;
if( ok ) if( ok )
{ {
type = (ARRAY_OPTIONS::NUMBERING_TYPE_T) typeVal; aAxis.SetAxisType( static_cast<ARRAY_AXIS::NUMBERING_TYPE>( typeVal ) );
} }
else else
{ {
@ -228,17 +226,19 @@ static bool validateNumberingTypeAndOffset( const wxTextCtrl& offsetEntry,
} }
const wxString text = offsetEntry.GetValue(); const wxString text = offsetEntry.GetValue();
ok = ARRAY_OPTIONS::GetNumberingOffset( text, type, offset );
ok = aAxis.SetOffset( text );
if( !ok ) if( !ok )
{ {
const wxString& alphabet = ARRAY_OPTIONS::AlphabetFromNumberingScheme( type ); const wxString& alphabet = aAxis.GetAlphabet();
wxString err; wxString err;
err.Printf( _( "Could not determine numbering start from \"%s\": " err.Printf( _( "Could not determine numbering start from \"%s\": "
"expected value consistent with alphabet \"%s\"" ), "expected value consistent with alphabet \"%s\"" ),
text, alphabet ); text, alphabet );
errors.Add(err); errors.Add(err);
return false;
} }
return ok; return ok;
@ -311,14 +311,12 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
// validate from the input fields // validate from the input fields
bool numOk = validateNumberingTypeAndOffset( *m_entryGridPriNumberingOffset, bool numOk = validateNumberingTypeAndOffset( *m_entryGridPriNumberingOffset,
*m_choicePriAxisNumbering, newGrid->m_priAxisNumType, *m_choicePriAxisNumbering, newGrid->m_pri_axis, errors );
newGrid->m_numberingOffsetX, errors );
if( newGrid->m_2dArrayNumbering ) if( newGrid->m_2dArrayNumbering )
{ {
numOk = validateNumberingTypeAndOffset( *m_entryGridSecNumberingOffset, numOk = validateNumberingTypeAndOffset( *m_entryGridSecNumberingOffset,
*m_choiceSecAxisNumbering, newGrid->m_secAxisNumType, *m_choiceSecAxisNumbering, newGrid->m_sec_axis, errors )
newGrid->m_numberingOffsetY, errors )
&& numOk; && numOk;
} }
@ -328,8 +326,8 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
{ {
// artificial linear numeric scheme from 1 // artificial linear numeric scheme from 1
newGrid->m_2dArrayNumbering = false; newGrid->m_2dArrayNumbering = false;
newGrid->m_priAxisNumType = ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC; newGrid->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC );
newGrid->m_numberingOffsetX = 1; // Start at "1" newGrid->m_pri_axis.SetOffset( 1 );
} }
} }
@ -359,16 +357,23 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
if( newCirc->GetNumberingStartIsSpecified() ) if( newCirc->GetNumberingStartIsSpecified() )
{ {
newCirc->m_numberingType = ARRAY_OPTIONS::NUMBERING_NUMERIC; newCirc->m_axis.SetAxisType( ARRAY_AXIS::NUMBERING_NUMERIC );
long offset;
ok = ok ok = ok
&& validateLongEntry( *m_entryCircNumberingStart, newCirc->m_numberingOffset, && validateLongEntry(
_( "numbering start" ), errors ); *m_entryCircNumberingStart, offset, _( "numbering start" ), errors );
if( ok )
{
newCirc->m_axis.SetOffset( offset );
}
} }
else else
{ {
// artificial linear numeric scheme from 1 // artificial linear numeric scheme from 1
newCirc->m_numberingOffset = 1; // Start at "1" newCirc->m_axis.SetOffset( 1 ); // Start at "1"
} }
} }

View File

@ -36,6 +36,7 @@ set( common_srcs
../../common/colors.cpp ../../common/colors.cpp
../../common/observable.cpp ../../common/observable.cpp
test_array_axis.cpp
test_array_options.cpp test_array_options.cpp
test_color4d.cpp test_color4d.cpp
test_coroutine.cpp test_coroutine.cpp

View File

@ -0,0 +1,209 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 KiCad Developers, see CHANGELOG.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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file
* Test suite for #ARRAY_AXIS
*/
#include <unit_test_utils/unit_test_utils.h>
#include <array_axis.h>
/**
* Declare the test suite
*/
BOOST_AUTO_TEST_SUITE( ArrayAxis )
struct VALID_OFFSET_CASE
{
ARRAY_AXIS::NUMBERING_TYPE m_axis_type;
std::string m_offset_str;
bool m_exp_valid;
int m_exp_offset;
};
/**
* Check we can get valid (or invalid) offsets as expected
*/
BOOST_AUTO_TEST_CASE( ValidOffsets )
{
// clang-format off
const std::vector<VALID_OFFSET_CASE> cases = {
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"0",
true,
0,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"1",
true,
1,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"1234",
true,
1234,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"",
false,
0,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"www",
false,
0,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL,
"A",
true,
0,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL,
"XY",
true,
648,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_HEX,
"A0",
true,
160,
},
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_HEX,
"G0",
false,
0,
},
};
// clang-format on
for( const auto& c : cases )
{
ARRAY_AXIS axis;
axis.SetAxisType( c.m_axis_type );
bool offset_ok = axis.SetOffset( c.m_offset_str );
BOOST_CHECK_EQUAL( offset_ok, c.m_exp_valid );
if( c.m_exp_valid )
{
BOOST_CHECK_EQUAL( axis.GetOffset(), c.m_exp_offset );
}
}
}
/**
* Data for testing a single array axis
*/
struct ARRAY_AXIS_NAMING_PARAMS
{
ARRAY_AXIS::NUMBERING_TYPE m_axis_type;
std::string m_start_at;
};
struct ARRAY_AXIS_NAMING_CASE
{
std::string m_case_name;
ARRAY_AXIS_NAMING_PARAMS m_prms;
int m_num;
std::vector<std::string> m_exp_names;
};
// clang-format off
static const std::vector<ARRAY_AXIS_NAMING_CASE> axis_name_cases = {
{
"Linear",
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"1",
},
6,
{ "1", "2", "3", "4", "5", "6" },
},
{
// Test alphabetical
"Alpha",
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL,
"A",
},
3,
{ "A", "B", "C" },
},
{
// Test alphabetical with 2nd col
"Alpha 2nd col",
{
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL,
"Y",
},
4,
{ "Y", "Z", "AA", "AB" },
},
};
// clang-format on
/**
* Test of the naming cases
*/
BOOST_AUTO_TEST_CASE( Numbering )
{
for( const auto& c : axis_name_cases )
{
BOOST_TEST_CONTEXT( c.m_case_name )
{
ARRAY_AXIS axis;
axis.SetAxisType( c.m_prms.m_axis_type );
bool start_ok = axis.SetOffset( c.m_prms.m_start_at );
// All these examples have valid start offsets
BOOST_CHECK( start_ok );
std::vector<std::string> names;
for( int i = 0; i < c.m_num; i++ )
{
names.push_back( axis.GetItemNumber( i ).ToStdString() );
}
BOOST_CHECK_EQUAL_COLLECTIONS(
names.begin(), names.end(), c.m_exp_names.begin(), c.m_exp_names.end() );
}
}
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -392,14 +392,14 @@ void CheckArrayNumbering( const ARRAY_OPTIONS& aOpts, const std::vector<std::str
struct GRID_ARRAY_NAMING_PARAMS struct GRID_ARRAY_NAMING_PARAMS
{ {
ARRAY_OPTIONS::NUMBERING_TYPE_T m_pri_type; ARRAY_AXIS::NUMBERING_TYPE m_pri_type;
ARRAY_OPTIONS::NUMBERING_TYPE_T m_sec_type; ARRAY_AXIS::NUMBERING_TYPE m_sec_type;
std::string m_start_at_x; std::string m_start_at_x;
std::string m_start_at_y; std::string m_start_at_y;
bool m_2d_numbering; bool m_2d_numbering;
bool m_h_then_v; bool m_h_then_v;
int m_nx; int m_nx;
int m_ny; int m_ny;
}; };
@ -416,8 +416,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = {
{ {
"Linear grid", "Linear grid",
{ {
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, // doesn't matter here ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, // doesn't matter here
"1", "1",
"2", "2",
false, false,
@ -431,8 +431,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = {
// Tests a 2d grid // Tests a 2d grid
"2D grid A1", "2D grid A1",
{ {
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_ALPHA_FULL, ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL,
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"A", "A",
"1", "1",
true, true,
@ -446,8 +446,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = {
// Tests a 2d grid // Tests a 2d grid
"2D grid 11", "2D grid 11",
{ {
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
"1", "1",
"1", "1",
true, true,
@ -463,8 +463,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = {
// Tests a 2d grid, with different types and offsets (and alphabet wrap) // Tests a 2d grid, with different types and offsets (and alphabet wrap)
"2D grid offsets", "2D grid offsets",
{ {
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_ALPHA_FULL, ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL,
"5", "5",
"Z", "Z",
true, true,
@ -494,13 +494,11 @@ BOOST_AUTO_TEST_CASE( GridNaming )
grid_opts.m_horizontalThenVertical = c.m_prms.m_h_then_v; grid_opts.m_horizontalThenVertical = c.m_prms.m_h_then_v;
ARRAY_OPTIONS::GetNumberingOffset( grid_opts.m_pri_axis.SetAxisType( c.m_prms.m_pri_type );
c.m_prms.m_start_at_x, c.m_prms.m_pri_type, grid_opts.m_numberingOffsetX ); grid_opts.m_sec_axis.SetAxisType( c.m_prms.m_sec_type );
ARRAY_OPTIONS::GetNumberingOffset(
c.m_prms.m_start_at_y, c.m_prms.m_sec_type, grid_opts.m_numberingOffsetY );
grid_opts.m_priAxisNumType = c.m_prms.m_pri_type; grid_opts.m_pri_axis.SetOffset( c.m_prms.m_start_at_x );
grid_opts.m_secAxisNumType = c.m_prms.m_sec_type; grid_opts.m_sec_axis.SetOffset( c.m_prms.m_start_at_y );
grid_opts.m_2dArrayNumbering = c.m_prms.m_2d_numbering; grid_opts.m_2dArrayNumbering = c.m_prms.m_2d_numbering;

View File

@ -82,8 +82,8 @@ std::vector<APNP_CASE> GetModuleAPNPCases()
// simple linear numbering // simple linear numbering
opts->m_2dArrayNumbering = false; opts->m_2dArrayNumbering = false;
opts->m_numberingOffsetX = 1; opts->m_pri_axis.SetOffset( 1 );
opts->m_priAxisNumType = ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC; opts->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC );
cases.push_back( { cases.push_back( {
"Simple linear, skip some", "Simple linear, skip some",
@ -98,8 +98,8 @@ std::vector<APNP_CASE> GetModuleAPNPCases()
// simple linear numbering (again) // simple linear numbering (again)
opts->m_2dArrayNumbering = false; opts->m_2dArrayNumbering = false;
opts->m_numberingOffsetX = 1; opts->m_pri_axis.SetOffset( 1 );
opts->m_priAxisNumType = ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC; opts->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC );
cases.push_back( { cases.push_back( {
"Simple linear, no module", "Simple linear, no module",