Simplify some of the calc engine string logic (#449)

Description of the changes:
Currently Calculator handles strings by defining integers for each type of function that can be performed, this integer will eventually correspond with an index in s_engineStrings which holds the corresponding display string for each function. Some functions such as Sin can have multiple strings (degrees, rads, grads, inverse). Functions like Sin are mapped to another array called "rgUfne" where a new integer is given depending on the output string which will then be given to s_engineStrings. The new integer returned by the "rgUfne" array runs the risk of overlapping with any new functions that may be added in CCommand.h. Furthermore, it is expected that the strings in s_engineStrings and rgUfne are defined in a particular order (not necessarily sequential), otherwise the logic will break. This makes adding new strings for new functions confusing and difficult, since a lot of the logic is not clearly defined.

This PR attempts to make this a bit simpler by changing the s_engineStrings and rgUfne arrays to be unordered_maps instead of arrays. For s_engineStrings the keys will now be strings, allowing the existing logic for indexing to be used by simply converting the number into a string to access the value. This will also allow us to create keys in the future that are not limited to integers but to strings that hold more meaning.

The rgUfne array will also be updated to be a map that will take in an integer and give you the corresponding string that can be passed to s_engineStrings. The UFNE object in the rgUfne array will also be updated to hold all the possible string keys for a function, instead of indexing them on other numbers that may overlap with existing definitions.

Now to add a new string for a new IDC_FOO function, we would just need to add the "FooString" resource keys to the g_sids array and use the updated rgUfne map to link the IDC_FOO value to the corresponding "FooString" resource key. This way the resource key can be a meaningful string, and not an integer that must be in any particular order.

How changes were validated:
Tested each function manually in standard, scientific, and programmer modes.
This commit is contained in:
Pepe Rivera 2019-04-11 15:20:01 -07:00 committed by Daniel Belcher
parent 47a2741218
commit f6f10444f7
5 changed files with 348 additions and 459 deletions

View File

@ -25,13 +25,18 @@ static constexpr wstring_view DEFAULT_NUMBER_STR = L"0";
// Read strings for keys, errors, trig types, etc. // Read strings for keys, errors, trig types, etc.
// These will be copied from the resources to local memory. // These will be copied from the resources to local memory.
array<wstring, CSTRINGSENGMAX> CCalcEngine::s_engineStrings; unordered_map<wstring, wstring> CCalcEngine::s_engineStrings;
void CCalcEngine::LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider) void CCalcEngine::LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider)
{ {
for (size_t i = 0; i < s_engineStrings.size(); i++) for (const auto& sid : g_sids)
{ {
s_engineStrings[i] = resourceProvider.GetCEngineString(g_sids[i]); auto locKey = wstring{ sid };
auto locString = resourceProvider.GetCEngineString(locKey);
if (!locString.empty())
{
s_engineStrings[locKey] = locString;
}
} }
} }
@ -168,7 +173,7 @@ void CCalcEngine::SettingsChanged()
m_HistoryCollector.SetDecimalSymbol(m_decimalSeparator); m_HistoryCollector.SetDecimalSymbol(m_decimalSeparator);
// put the new decimal symbol into the table used to draw the decimal key // put the new decimal symbol into the table used to draw the decimal key
s_engineStrings[IDS_DECIMAL] = m_decimalSeparator; s_engineStrings[SIDS_DECIMAL_SEPARATOR] = m_decimalSeparator;
// we need to redraw to update the decimal point button // we need to redraw to update the decimal point button
numChanged = true; numChanged = true;

View File

@ -16,13 +16,6 @@
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h" #include "Header Files/CalcUtils.h"
#define IDC_RADSIN IDC_UNARYLAST+1
#define IDC_RADCOS IDC_UNARYLAST+2
#define IDC_RADTAN IDC_UNARYLAST+3
#define IDC_GRADSIN IDC_UNARYLAST+4
#define IDC_GRADCOS IDC_UNARYLAST+5
#define IDC_GRADTAN IDC_UNARYLAST+6
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
@ -868,155 +861,94 @@ void CCalcEngine::DisplayAnnounceBinaryOperator()
// Unary operator Function Name table Element // Unary operator Function Name table Element
// since unary operators button names aren't exactly friendly for history purpose, // since unary operators button names aren't exactly friendly for history purpose,
// we have this separate table to get its localized name and for its Inv function if it exists. // we have this separate table to get its localized name and for its Inv function if it exists.
typedef struct struct FunctionNameElement
{ {
int idsFunc; // index of string for the unary op function. Can be NULL, in which case it same as button name wstring degreeString; // Used by default if there are no rad or grad specific strings.
int idsFuncInv; // index of string for Inv of unary op. Can be NULL, in case it is same as idsFunc wstring inverseDegreeString; // Will fall back to degreeString if empty
bool fDontUseInExpEval; // true if this cant be used in reverse direction as well, ie. during expression evaluation
} UFNE; wstring radString;
wstring inverseRadString; // Will fall back to radString if empty
wstring gradString;
wstring inverseGradString; // Will fall back to gradString if empty
bool hasAngleStrings = ((!radString.empty()) || (!inverseRadString.empty()) || (!gradString.empty()) || (!inverseGradString.empty()));
};
// Table for each unary operator // Table for each unary operator
static const UFNE rgUfne[] = static const std::unordered_map<int, FunctionNameElement> unaryOperatorStringTable =
{ {
/* IDC_CHOP */{ 0, IDS_FRAC, false }, { IDC_CHOP, { L"", SIDS_FRAC} },
/* IDC_ROL */{ 0, 0, true },
/* IDC_ROR */{ 0, 0, true },
/* IDC_COM */{ 0, 0, true }, { IDC_SIN, { SIDS_SIND, SIDS_ASIND, SIDS_SINR, SIDS_ASINR, SIDS_SING, SIDS_ASING } },
/* IDC_SIN */{ IDS_SIND, IDS_ASIND, false }, // default in this table is degrees for sin,cos & tan { IDC_COS, { SIDS_COSD, SIDS_ACOSD, SIDS_COSR, SIDS_ACOSR, SIDS_COSG, SIDS_ACOSG } },
/* IDC_COS */{ IDS_COSD, IDS_ACOSD, false }, { IDC_TAN, { SIDS_TAND, SIDS_ATAND, SIDS_TANR, SIDS_ATANR, SIDS_TANG, SIDS_ATANG } },
/* IDC_TAN */{ IDS_TAND, IDS_ATAND, false },
/* IDC_SINH */{ 0, IDS_ASINH, false }, { IDC_SINH, { L"", SIDS_ASINH } },
/* IDC_COSH */{ 0, IDS_ACOSH, false }, { IDC_COSH, { L"", SIDS_ACOSH } },
/* IDC_TANH */{ 0, IDS_ATANH, false }, { IDC_TANH, { L"", SIDS_ATANH } },
/* IDC_LN */{ 0, IDS_POWE, false }, { IDC_LN , { L"", SIDS_POWE } },
/* IDC_LOG */{ 0, 0, false }, { IDC_SQR, { SIDS_SQR } },
/* IDC_SQRT */{ 0, 0, false }, { IDC_CUB, { SIDS_CUBE } },
/* IDC_SQR */{ IDS_SQR, 0, false }, { IDC_FAC, { SIDS_FACT } },
/* IDC_CUB */{ IDS_CUBE, 0, false }, { IDC_REC, { SIDS_RECIPROC } },
/* IDC_FAC */{ IDS_FACT, 0, false }, { IDC_DMS, { L"", SIDS_DEGREES } },
/* IDC_REC */{ IDS_REC, 0, false }, { IDC_SIGN, { SIDS_NEGATE } },
/* IDC_DMS */{ 0, IDS_DEGREES, false }, { IDC_DEGREES, { SIDS_DEGREES } }
/* IDC_CUBEROOT */{ 0, 0, false },
/* IDC_POW10 */{ 0, 0, false },
/* IDC_PERCENT */{ 0, 0, false },
/* IDC_RADSIN */{ IDS_SINR, IDS_ASINR, false },
/* IDC_RADCOS */{ IDS_COSR, IDS_ACOSR, false },
/* IDC_RADTAN */{ IDS_TANR, IDS_ATANR, false },
/* IDC_GRADCOS */{ IDS_SING, IDS_ASING, false },
/* IDC_GRADCOS */{ IDS_COSG, IDS_ACOSG, false },
/* IDC_GRADTAN */{ IDS_TANG, IDS_ATANG, false },
}; };
wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype) wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype)
{ {
// Special cases for Sign and Degrees
if (IDC_SIGN == nOpCode)
{
return GetString(IDS_NEGATE);
}
if (IDC_DEGREES == nOpCode)
{
return GetString(IDS_DEGREES);
}
// Correct the trigonometric functions with type of angle argument they take
if (ANGLE_RAD == angletype)
{
switch (nOpCode)
{
case IDC_SIN:
nOpCode = IDC_RADSIN;
break;
case IDC_COS:
nOpCode = IDC_RADCOS;
break;
case IDC_TAN:
nOpCode = IDC_RADTAN;
break;
}
}
else if (ANGLE_GRAD == angletype)
{
switch (nOpCode)
{
case IDC_SIN:
nOpCode = IDC_GRADSIN;
break;
case IDC_COS:
nOpCode = IDC_GRADCOS;
break;
case IDC_TAN:
nOpCode = IDC_GRADTAN;
break;
}
}
// Try to lookup the ID in the UFNE table // Try to lookup the ID in the UFNE table
int ids = 0; wstring ids = L"";
int iufne = nOpCode - IDC_UNARYFIRST;
if (iufne >= 0 && (size_t)iufne < size(rgUfne)) if (auto pair = unaryOperatorStringTable.find(nOpCode); pair != unaryOperatorStringTable.end())
{ {
if (fInv) const FunctionNameElement& element = pair->second;
if (!element.hasAngleStrings || ANGLE_DEG == angletype)
{ {
ids = rgUfne[iufne].idsFuncInv; if (fInv)
{
ids = element.inverseDegreeString;
}
if (ids.empty())
{
ids = element.degreeString;
}
} }
if (0 == ids) else if (ANGLE_RAD == angletype)
{ {
ids = rgUfne[iufne].idsFunc; if (fInv)
{
ids = element.inverseRadString;
}
if (ids.empty())
{
ids = element.radString;
}
} }
else if (ANGLE_GRAD == angletype)
{
if (fInv)
{
ids = element.inverseGradString;
}
if (ids.empty())
{
ids = element.gradString;
}
}
}
if (!ids.empty())
{
return GetString(ids);
} }
// If we didn't find an ID in the table, use the op code. // If we didn't find an ID in the table, use the op code.
if (0 == ids) return OpCodeToString(nOpCode);
{
ids = IdStrFromCmdId(nOpCode);
}
return GetString(ids);
}
//
// Sets the Angle Mode for special unary op IDC's which are used to index to the table rgUfne
// and returns the equivalent plain IDC for trigonometric function. If it isn't a trigonometric function
// returns the passed in idc itself.
int CCalcEngine::IdcSetAngleTypeDecMode(int idc)
{
int idcAngleCmd = IDM_DEG;
switch (idc)
{
case IDC_RADSIN:
idcAngleCmd = IDM_RAD;
idc = IDC_SIN;
break;
case IDC_RADCOS:
idcAngleCmd = IDM_RAD;
idc = IDC_COS;
break;
case IDC_RADTAN:
idcAngleCmd = IDM_RAD;
idc = IDC_TAN;
break;
case IDC_GRADSIN:
idcAngleCmd = IDM_GRAD;
idc = IDC_SIN;
break;
case IDC_GRADCOS:
idcAngleCmd = IDM_GRAD;
idc = IDC_COS;
break;
case IDC_GRADTAN:
idcAngleCmd = IDM_GRAD;
idc = IDC_TAN;
break;
}
ProcessCommand(idcAngleCmd);
return idc;
} }
bool CCalcEngine::IsCurrentTooBigForTrig() bool CCalcEngine::IsCurrentTooBigForTrig()

View File

@ -72,7 +72,8 @@ public:
// Static methods for the instance // Static methods for the instance
static void InitialOneTimeOnlySetup(CalculationManager::IResourceProvider& resourceProvider); // Once per load time to call to initialize all shared global variables static void InitialOneTimeOnlySetup(CalculationManager::IResourceProvider& resourceProvider); // Once per load time to call to initialize all shared global variables
// returns the ptr to string representing the operator. Mostly same as the button, but few special cases for x^y etc. // returns the ptr to string representing the operator. Mostly same as the button, but few special cases for x^y etc.
static std::wstring_view GetString(int ids) { return s_engineStrings[ids]; } static std::wstring_view GetString(int ids) { return s_engineStrings[std::to_wstring(ids)]; }
static std::wstring_view GetString(std::wstring ids) { return s_engineStrings[ids]; }
static std::wstring_view OpCodeToString(int nOpCode) { return GetString(IdStrFromCmdId(nOpCode)); } static std::wstring_view OpCodeToString(int nOpCode) { return GetString(IdStrFromCmdId(nOpCode)); }
static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype); static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype);
@ -123,7 +124,7 @@ private:
std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement
std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers
static std::array<std::wstring, CSTRINGSENGMAX> s_engineStrings; // the string table shared across all instances static std::unordered_map<std::wstring, std::wstring> s_engineStrings; // the string table shared across all instances
wchar_t m_decimalSeparator; wchar_t m_decimalSeparator;
wchar_t m_groupSeparator; wchar_t m_groupSeparator;
@ -146,12 +147,11 @@ private:
bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno); bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno);
void CheckAndAddLastBinOpToHistory(bool addToHistory = true); void CheckAndAddLastBinOpToHistory(bool addToHistory = true);
int IdcSetAngleTypeDecMode(int idc);
void InitChopNumbers(); void InitChopNumbers();
static void LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider); static void LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider);
static int IdStrFromCmdId(int id) { return id - IDC_FIRSTCONTROL + IDS_FIRSTENGSTR; } static int IdStrFromCmdId(int id) { return id - IDC_FIRSTCONTROL + IDS_ENGINESTR_FIRST; }
static std::vector<uint32_t> DigitGroupingStringToGroupingVector(std::wstring_view groupingString); static std::vector<uint32_t> DigitGroupingStringToGroupingVector(std::wstring_view groupingString);
std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false); std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false);

View File

@ -13,327 +13,279 @@
* Created: 13-Feb-2008 * Created: 13-Feb-2008
* *
\****************************************************************************/ \****************************************************************************/
#define IDS_FIRSTENGSTR IDS_ENGINESTR_FIRST inline constexpr auto IDS_ERRORS_FIRST = 99;
#define IDS_DECIMAL 4
// All unary op function names for easy history reading
// This is where the first string after all the commands in order have been placed, should be placed
// keeping in consecutive helps us to allocate 1 string table and index them
#define IDS_FNSZFIRST (IDC_F -IDC_FIRSTCONTROL)+1
#define IDS_FRAC IDS_FNSZFIRST
#define IDS_SIND IDS_FNSZFIRST+1
#define IDS_COSD IDS_FNSZFIRST+2
#define IDS_TAND IDS_FNSZFIRST+3
#define IDS_ASIND IDS_FNSZFIRST+4
#define IDS_ACOSD IDS_FNSZFIRST+5
#define IDS_ATAND IDS_FNSZFIRST+6
#define IDS_SINR IDS_FNSZFIRST+7
#define IDS_COSR IDS_FNSZFIRST+8
#define IDS_TANR IDS_FNSZFIRST+9
#define IDS_ASINR IDS_FNSZFIRST+10
#define IDS_ACOSR IDS_FNSZFIRST+11
#define IDS_ATANR IDS_FNSZFIRST+12
#define IDS_SING IDS_FNSZFIRST+13
#define IDS_COSG IDS_FNSZFIRST+14
#define IDS_TANG IDS_FNSZFIRST+15
#define IDS_ASING IDS_FNSZFIRST+16
#define IDS_ACOSG IDS_FNSZFIRST+17
#define IDS_ATANG IDS_FNSZFIRST+18
#define IDS_ASINH IDS_FNSZFIRST+19
#define IDS_ACOSH IDS_FNSZFIRST+20
#define IDS_ATANH IDS_FNSZFIRST+21
#define IDS_POWE IDS_FNSZFIRST+22
#define IDS_POW10 IDS_FNSZFIRST+23
#define IDS_SQRT IDS_FNSZFIRST+24
#define IDS_SQR IDS_FNSZFIRST+25
#define IDS_CUBE IDS_FNSZFIRST+26
#define IDS_CUBERT IDS_FNSZFIRST+27
#define IDS_FACT IDS_FNSZFIRST+28
#define IDS_REC IDS_FNSZFIRST+29
#define IDS_DEGREES IDS_FNSZFIRST+30
#define IDS_NEGATE IDS_FNSZFIRST+31
#define IDS_RSH IDS_FNSZFIRST+32
#define IDS_FNSZLAST IDS_RSH
#define IDS_ERRORS_FIRST IDS_FNSZLAST+1
// This is the list of error strings corresponding to SCERR_DIVIDEZERO.. // This is the list of error strings corresponding to SCERR_DIVIDEZERO..
#define IDS_DIVBYZERO IDS_ERRORS_FIRST inline constexpr auto IDS_DIVBYZERO = IDS_ERRORS_FIRST;
#define IDS_DOMAIN IDS_ERRORS_FIRST+1 inline constexpr auto IDS_DOMAIN = IDS_ERRORS_FIRST + 1;
#define IDS_UNDEFINED IDS_ERRORS_FIRST+2 inline constexpr auto IDS_UNDEFINED = IDS_ERRORS_FIRST + 2;
#define IDS_POS_INFINITY IDS_ERRORS_FIRST+3 inline constexpr auto IDS_POS_INFINITY = IDS_ERRORS_FIRST + 3;
#define IDS_NEG_INFINITY IDS_ERRORS_FIRST+4 inline constexpr auto IDS_NEG_INFINITY = IDS_ERRORS_FIRST + 4;
#define IDS_NOMEM IDS_ERRORS_FIRST+6 inline constexpr auto IDS_NOMEM = IDS_ERRORS_FIRST + 6;
#define IDS_TOOMANY IDS_ERRORS_FIRST+7 inline constexpr auto IDS_TOOMANY = IDS_ERRORS_FIRST + 7;
#define IDS_OVERFLOW IDS_ERRORS_FIRST+8 inline constexpr auto IDS_OVERFLOW = IDS_ERRORS_FIRST + 8;
#define IDS_NORESULT IDS_ERRORS_FIRST+9 inline constexpr auto IDS_NORESULT = IDS_ERRORS_FIRST + 9;
#define IDS_INSUFFICIENT_DATA IDS_ERRORS_FIRST+10 inline constexpr auto IDS_INSUFFICIENT_DATA = IDS_ERRORS_FIRST + 10;
#define CSTRINGSENGMAX IDS_INSUFFICIENT_DATA+1 inline constexpr auto CSTRINGSENGMAX = IDS_INSUFFICIENT_DATA + 1;
// Arithmetic expression evaluator error strings // Arithmetic expression evaluator error strings
#define IDS_ERR_UNK_CH CSTRINGSENGMAX+1 inline constexpr auto IDS_ERR_UNK_CH = CSTRINGSENGMAX + 1;
#define IDS_ERR_UNK_FN CSTRINGSENGMAX+2 inline constexpr auto IDS_ERR_UNK_FN = CSTRINGSENGMAX + 2;
#define IDS_ERR_UNEX_NUM CSTRINGSENGMAX+3 inline constexpr auto IDS_ERR_UNEX_NUM = CSTRINGSENGMAX + 3;
#define IDS_ERR_UNEX_CH CSTRINGSENGMAX+4 inline constexpr auto IDS_ERR_UNEX_CH = CSTRINGSENGMAX + 4;
#define IDS_ERR_UNEX_SZ CSTRINGSENGMAX+5 inline constexpr auto IDS_ERR_UNEX_SZ = CSTRINGSENGMAX + 5;
#define IDS_ERR_MISMATCH_CLOSE CSTRINGSENGMAX+6 inline constexpr auto IDS_ERR_MISMATCH_CLOSE = CSTRINGSENGMAX + 6;
#define IDS_ERR_UNEX_END CSTRINGSENGMAX+7 inline constexpr auto IDS_ERR_UNEX_END = CSTRINGSENGMAX + 7;
#define IDS_ERR_SG_INV_ERROR CSTRINGSENGMAX+8 inline constexpr auto IDS_ERR_SG_INV_ERROR = CSTRINGSENGMAX + 8;
#define IDS_ERR_INPUT_OVERFLOW CSTRINGSENGMAX+9 inline constexpr auto IDS_ERR_INPUT_OVERFLOW = CSTRINGSENGMAX + 9;
#define IDS_ERR_OUTPUT_OVERFLOW CSTRINGSENGMAX+10 inline constexpr auto IDS_ERR_OUTPUT_OVERFLOW = CSTRINGSENGMAX + 10;
// Resource keys for CEngineStrings.resw
#define SIDS_PLUS_MINUS L"0" inline constexpr auto SIDS_PLUS_MINUS = L"0";
#define SIDS_CLEAR L"1" inline constexpr auto SIDS_CLEAR = L"1";
#define SIDS_CE L"2" inline constexpr auto SIDS_CE = L"2";
#define SIDS_BACKSPACE L"3" inline constexpr auto SIDS_BACKSPACE = L"3";
#define SIDS_DECIMAL_SEPARATOR L"4" inline constexpr auto SIDS_DECIMAL_SEPARATOR = L"4";
#define SIDS_EMPTY_STRING L"5" inline constexpr auto SIDS_EMPTY_STRING = L"5";
#define SIDS_AND L"6" inline constexpr auto SIDS_AND = L"6";
#define SIDS_OR L"7" inline constexpr auto SIDS_OR = L"7";
#define SIDS_XOR L"8" inline constexpr auto SIDS_XOR = L"8";
#define SIDS_LSH L"9" inline constexpr auto SIDS_LSH = L"9";
#define SIDS_RSH L"10" inline constexpr auto SIDS_RSH = L"10";
#define SIDS_DIVIDE L"11" inline constexpr auto SIDS_DIVIDE = L"11";
#define SIDS_MULTIPLY L"12" inline constexpr auto SIDS_MULTIPLY = L"12";
#define SIDS_PLUS L"13" inline constexpr auto SIDS_PLUS = L"13";
#define SIDS_MINUS L"14" inline constexpr auto SIDS_MINUS = L"14";
#define SIDS_MOD L"15" inline constexpr auto SIDS_MOD = L"15";
#define SIDS_YROOT L"16" inline constexpr auto SIDS_YROOT = L"16";
#define SIDS_POW_HAT L"17" inline constexpr auto SIDS_POW_HAT = L"17";
#define SIDS_INT L"18" inline constexpr auto SIDS_INT = L"18";
#define SIDS_ROL L"19" inline constexpr auto SIDS_ROL = L"19";
#define SIDS_ROR L"20" inline constexpr auto SIDS_ROR = L"20";
#define SIDS_NOT L"21" inline constexpr auto SIDS_NOT = L"21";
#define SIDS_SIN L"22" inline constexpr auto SIDS_SIN = L"22";
#define SIDS_COS L"23" inline constexpr auto SIDS_COS = L"23";
#define SIDS_TAN L"24" inline constexpr auto SIDS_TAN = L"24";
#define SIDS_SINH L"25" inline constexpr auto SIDS_SINH = L"25";
#define SIDS_COSH L"26" inline constexpr auto SIDS_COSH = L"26";
#define SIDS_TANH L"27" inline constexpr auto SIDS_TANH = L"27";
#define SIDS_LN L"28" inline constexpr auto SIDS_LN = L"28";
#define SIDS_LOG L"29" inline constexpr auto SIDS_LOG = L"29";
#define SIDS_SQRT L"30" inline constexpr auto SIDS_SQRT = L"30";
#define SIDS_XPOW2 L"31" inline constexpr auto SIDS_XPOW2 = L"31";
#define SIDS_XPOW3 L"32" inline constexpr auto SIDS_XPOW3 = L"32";
#define SIDS_NFACTORIAL L"33" inline constexpr auto SIDS_NFACTORIAL = L"33";
#define SIDS_RECIPROCAL L"34" inline constexpr auto SIDS_RECIPROCAL = L"34";
#define SIDS_DMS L"35" inline constexpr auto SIDS_DMS = L"35";
#define SIDS_CUBEROOT L"36" inline constexpr auto SIDS_CUBEROOT = L"36";
#define SIDS_POWTEN L"37" inline constexpr auto SIDS_POWTEN = L"37";
#define SIDS_PERCENT L"38" inline constexpr auto SIDS_PERCENT = L"38";
#define SIDS_SCIENTIFIC_NOTATION L"39" inline constexpr auto SIDS_SCIENTIFIC_NOTATION = L"39";
#define SIDS_PI L"40" inline constexpr auto SIDS_PI = L"40";
#define SIDS_EQUAL L"41" inline constexpr auto SIDS_EQUAL = L"41";
#define SIDS_MC L"42" inline constexpr auto SIDS_MC = L"42";
#define SIDS_MR L"43" inline constexpr auto SIDS_MR = L"43";
#define SIDS_MS L"44" inline constexpr auto SIDS_MS = L"44";
#define SIDS_MPLUS L"45" inline constexpr auto SIDS_MPLUS = L"45";
#define SIDS_MMINUS L"46" inline constexpr auto SIDS_MMINUS = L"46";
#define SIDS_EXP L"47" inline constexpr auto SIDS_EXP = L"47";
#define SIDS_OPEN_PAREN L"48" inline constexpr auto SIDS_OPEN_PAREN = L"48";
#define SIDS_CLOSE_PAREN L"49" inline constexpr auto SIDS_CLOSE_PAREN = L"49";
#define SIDS_0 L"50" inline constexpr auto SIDS_0 = L"50";
#define SIDS_1 L"51" inline constexpr auto SIDS_1 = L"51";
#define SIDS_2 L"52" inline constexpr auto SIDS_2 = L"52";
#define SIDS_3 L"53" inline constexpr auto SIDS_3 = L"53";
#define SIDS_4 L"54" inline constexpr auto SIDS_4 = L"54";
#define SIDS_5 L"55" inline constexpr auto SIDS_5 = L"55";
#define SIDS_6 L"56" inline constexpr auto SIDS_6 = L"56";
#define SIDS_7 L"57" inline constexpr auto SIDS_7 = L"57";
#define SIDS_8 L"58" inline constexpr auto SIDS_8 = L"58";
#define SIDS_9 L"59" inline constexpr auto SIDS_9 = L"59";
#define SIDS_A L"60" inline constexpr auto SIDS_A = L"60";
#define SIDS_B L"61" inline constexpr auto SIDS_B = L"61";
#define SIDS_C L"62" inline constexpr auto SIDS_C = L"62";
#define SIDS_D L"63" inline constexpr auto SIDS_D = L"63";
#define SIDS_E L"64" inline constexpr auto SIDS_E = L"64";
#define SIDS_F L"65" inline constexpr auto SIDS_F = L"65";
#define SIDS_FRAC L"66" inline constexpr auto SIDS_FRAC = L"66";
#define SIDS_SIND L"67" inline constexpr auto SIDS_SIND = L"67";
#define SIDS_COSD L"68" inline constexpr auto SIDS_COSD = L"68";
#define SIDS_TAND L"69" inline constexpr auto SIDS_TAND = L"69";
#define SIDS_ASIND L"70" inline constexpr auto SIDS_ASIND = L"70";
#define SIDS_ACOSD L"71" inline constexpr auto SIDS_ACOSD = L"71";
#define SIDS_ATAND L"72" inline constexpr auto SIDS_ATAND = L"72";
#define SIDS_SINR L"73" inline constexpr auto SIDS_SINR = L"73";
#define SIDS_COSR L"74" inline constexpr auto SIDS_COSR = L"74";
#define SIDS_TANR L"75" inline constexpr auto SIDS_TANR = L"75";
#define SIDS_ASINR L"76" inline constexpr auto SIDS_ASINR = L"76";
#define SIDS_ACOSR L"77" inline constexpr auto SIDS_ACOSR = L"77";
#define SIDS_ATANR L"78" inline constexpr auto SIDS_ATANR = L"78";
#define SIDS_SING L"79" inline constexpr auto SIDS_SING = L"79";
#define SIDS_COSG L"80" inline constexpr auto SIDS_COSG = L"80";
#define SIDS_TANG L"81" inline constexpr auto SIDS_TANG = L"81";
#define SIDS_ASING L"82" inline constexpr auto SIDS_ASING = L"82";
#define SIDS_ACOSG L"83" inline constexpr auto SIDS_ACOSG = L"83";
#define SIDS_ATANG L"84" inline constexpr auto SIDS_ATANG = L"84";
#define SIDS_ASINH L"85" inline constexpr auto SIDS_ASINH = L"85";
#define SIDS_ACOSH L"86" inline constexpr auto SIDS_ACOSH = L"86";
#define SIDS_ATANH L"87" inline constexpr auto SIDS_ATANH = L"87";
#define SIDS_POWE L"88" inline constexpr auto SIDS_POWE = L"88";
#define SIDS_POWTEN2 L"89" inline constexpr auto SIDS_POWTEN2 = L"89";
#define SIDS_SQRT2 L"90" inline constexpr auto SIDS_SQRT2 = L"90";
#define SIDS_SQR L"91" inline constexpr auto SIDS_SQR = L"91";
#define SIDS_CUBE L"92" inline constexpr auto SIDS_CUBE = L"92";
#define SIDS_CUBERT L"93" inline constexpr auto SIDS_CUBERT = L"93";
#define SIDS_FACT L"94" inline constexpr auto SIDS_FACT = L"94";
#define SIDS_RECIPROC L"95" inline constexpr auto SIDS_RECIPROC = L"95";
#define SIDS_DEGREES L"96" inline constexpr auto SIDS_DEGREES = L"96";
#define SIDS_NEGATE L"97" inline constexpr auto SIDS_NEGATE = L"97";
#define SIDS_RSH2 L"98" inline constexpr auto SIDS_RSH2 = L"98";
#define SIDS_DIVIDEBYZERO L"99" inline constexpr auto SIDS_DIVIDEBYZERO = L"99";
#define SIDS_DOMAIN L"100" inline constexpr auto SIDS_DOMAIN = L"100";
#define SIDS_UNDEFINED L"101" inline constexpr auto SIDS_UNDEFINED = L"101";
#define SIDS_POS_INFINITY L"102" inline constexpr auto SIDS_POS_INFINITY = L"102";
#define SIDS_NEG_INFINITY L"103" inline constexpr auto SIDS_NEG_INFINITY = L"103";
#define SIDS_ABORTED L"104" inline constexpr auto SIDS_ABORTED = L"104";
#define SIDS_NOMEM L"105" inline constexpr auto SIDS_NOMEM = L"105";
#define SIDS_TOOMANY L"106" inline constexpr auto SIDS_TOOMANY = L"106";
#define SIDS_OVERFLOW L"107" inline constexpr auto SIDS_OVERFLOW = L"107";
#define SIDS_NORESULT L"108" inline constexpr auto SIDS_NORESULT = L"108";
#define SIDS_INSUFFICIENT_DATA L"109" inline constexpr auto SIDS_INSUFFICIENT_DATA = L"109";
// 110 is skipped by CSTRINGSENGMAX // 110 is skipped by CSTRINGSENGMAX
#define SIDS_ERR_UNK_CH L"111" inline constexpr auto SIDS_ERR_UNK_CH = L"111";
#define SIDS_ERR_UNK_FN L"112" inline constexpr auto SIDS_ERR_UNK_FN = L"112";
#define SIDS_ERR_UNEX_NUM L"113" inline constexpr auto SIDS_ERR_UNEX_NUM = L"113";
#define SIDS_ERR_UNEX_CH L"114" inline constexpr auto SIDS_ERR_UNEX_CH = L"114";
#define SIDS_ERR_UNEX_SZ L"115" inline constexpr auto SIDS_ERR_UNEX_SZ = L"115";
#define SIDS_ERR_MISMATCH_CLOSE L"116" inline constexpr auto SIDS_ERR_MISMATCH_CLOSE = L"116";
#define SIDS_ERR_UNEX_END L"117" inline constexpr auto SIDS_ERR_UNEX_END = L"117";
#define SIDS_ERR_SG_INV_ERROR L"118" inline constexpr auto SIDS_ERR_SG_INV_ERROR = L"118";
#define SIDS_ERR_INPUT_OVERFLOW L"119" inline constexpr auto SIDS_ERR_INPUT_OVERFLOW = L"119";
#define SIDS_ERR_OUTPUT_OVERFLOW L"120" inline constexpr auto SIDS_ERR_OUTPUT_OVERFLOW = L"120";
__declspec(selectany) std::wstring g_sids[] = // Include the resource key ID from above into this vector to load it into memory for the engine to use
inline constexpr std::array<std::wstring_view, 120> g_sids =
{ {
std::wstring(SIDS_PLUS_MINUS), SIDS_PLUS_MINUS,
std::wstring(SIDS_C), SIDS_C,
std::wstring(SIDS_CE), SIDS_CE,
std::wstring(SIDS_BACKSPACE), SIDS_BACKSPACE,
std::wstring(SIDS_DECIMAL_SEPARATOR), SIDS_DECIMAL_SEPARATOR,
std::wstring(SIDS_EMPTY_STRING), SIDS_EMPTY_STRING,
std::wstring(SIDS_AND), SIDS_AND,
std::wstring(SIDS_OR), SIDS_OR,
std::wstring(SIDS_XOR), SIDS_XOR,
std::wstring(SIDS_LSH), SIDS_LSH,
std::wstring(SIDS_RSH), SIDS_RSH,
std::wstring(SIDS_DIVIDE), SIDS_DIVIDE,
std::wstring(SIDS_MULTIPLY), SIDS_MULTIPLY,
std::wstring(SIDS_PLUS), SIDS_PLUS,
std::wstring(SIDS_MINUS), SIDS_MINUS,
std::wstring(SIDS_MOD), SIDS_MOD,
std::wstring(SIDS_YROOT), SIDS_YROOT,
std::wstring(SIDS_POW_HAT), SIDS_POW_HAT,
std::wstring(SIDS_INT), SIDS_INT,
std::wstring(SIDS_ROL), SIDS_ROL,
std::wstring(SIDS_ROR), SIDS_ROR,
std::wstring(SIDS_NOT), SIDS_NOT,
std::wstring(SIDS_SIN), SIDS_SIN,
std::wstring(SIDS_COS), SIDS_COS,
std::wstring(SIDS_TAN), SIDS_TAN,
std::wstring(SIDS_SINH), SIDS_SINH,
std::wstring(SIDS_COSH), SIDS_COSH,
std::wstring(SIDS_TANH), SIDS_TANH,
std::wstring(SIDS_LN), SIDS_LN,
std::wstring(SIDS_LOG), SIDS_LOG,
std::wstring(SIDS_SQRT), SIDS_SQRT,
std::wstring(SIDS_XPOW2), SIDS_XPOW2,
std::wstring(SIDS_XPOW3), SIDS_XPOW3,
std::wstring(SIDS_NFACTORIAL), SIDS_NFACTORIAL,
std::wstring(SIDS_RECIPROCAL), SIDS_RECIPROCAL,
std::wstring(SIDS_DMS), SIDS_DMS,
std::wstring(SIDS_CUBEROOT), SIDS_CUBEROOT,
std::wstring(SIDS_POWTEN), SIDS_POWTEN,
std::wstring(SIDS_PERCENT), SIDS_PERCENT,
std::wstring(SIDS_SCIENTIFIC_NOTATION), SIDS_SCIENTIFIC_NOTATION,
std::wstring(SIDS_PI), SIDS_PI,
std::wstring(SIDS_EQUAL), SIDS_EQUAL,
std::wstring(SIDS_MC), SIDS_MC,
std::wstring(SIDS_MR), SIDS_MR,
std::wstring(SIDS_MS), SIDS_MS,
std::wstring(SIDS_MPLUS), SIDS_MPLUS,
std::wstring(SIDS_MMINUS), SIDS_MMINUS,
std::wstring(SIDS_EXP), SIDS_EXP,
std::wstring(SIDS_OPEN_PAREN), SIDS_OPEN_PAREN,
std::wstring(SIDS_CLOSE_PAREN), SIDS_CLOSE_PAREN,
std::wstring(SIDS_0), SIDS_0,
std::wstring(SIDS_1), SIDS_1,
std::wstring(SIDS_2), SIDS_2,
std::wstring(SIDS_3), SIDS_3,
std::wstring(SIDS_4), SIDS_4,
std::wstring(SIDS_5), SIDS_5,
std::wstring(SIDS_6), SIDS_6,
std::wstring(SIDS_7), SIDS_7,
std::wstring(SIDS_8), SIDS_8,
std::wstring(SIDS_9), SIDS_9,
std::wstring(SIDS_A), SIDS_A,
std::wstring(SIDS_B), SIDS_B,
std::wstring(SIDS_C), SIDS_C,
std::wstring(SIDS_D), SIDS_D,
std::wstring(SIDS_E), SIDS_E,
std::wstring(SIDS_F), SIDS_F,
std::wstring(SIDS_FRAC), SIDS_FRAC,
std::wstring(SIDS_SIND), SIDS_SIND,
std::wstring(SIDS_COSD), SIDS_COSD,
std::wstring(SIDS_TAND), SIDS_TAND,
std::wstring(SIDS_ASIND), SIDS_ASIND,
std::wstring(SIDS_ACOSD), SIDS_ACOSD,
std::wstring(SIDS_ATAND), SIDS_ATAND,
std::wstring(SIDS_SINR), SIDS_SINR,
std::wstring(SIDS_COSR), SIDS_COSR,
std::wstring(SIDS_TANR), SIDS_TANR,
std::wstring(SIDS_ASINR), SIDS_ASINR,
std::wstring(SIDS_ACOSR), SIDS_ACOSR,
std::wstring(SIDS_ATANR), SIDS_ATANR,
std::wstring(SIDS_SING), SIDS_SING,
std::wstring(SIDS_COSG), SIDS_COSG,
std::wstring(SIDS_TANG), SIDS_TANG,
std::wstring(SIDS_ASING), SIDS_ASING,
std::wstring(SIDS_ACOSG), SIDS_ACOSG,
std::wstring(SIDS_ATANG), SIDS_ATANG,
std::wstring(SIDS_ASINH), SIDS_ASINH,
std::wstring(SIDS_ACOSH), SIDS_ACOSH,
std::wstring(SIDS_ATANH), SIDS_ATANH,
std::wstring(SIDS_POWE), SIDS_POWE,
std::wstring(SIDS_POWTEN2), SIDS_POWTEN2,
std::wstring(SIDS_SQRT2), SIDS_SQRT2,
std::wstring(SIDS_SQR), SIDS_SQR,
std::wstring(SIDS_CUBE), SIDS_CUBE,
std::wstring(SIDS_CUBERT), SIDS_CUBERT,
std::wstring(SIDS_FACT), SIDS_FACT,
std::wstring(SIDS_RECIPROC), SIDS_RECIPROC,
std::wstring(SIDS_DEGREES), SIDS_DEGREES,
std::wstring(SIDS_NEGATE), SIDS_NEGATE,
std::wstring(SIDS_RSH), SIDS_RSH,
std::wstring(SIDS_DIVIDEBYZERO), SIDS_DIVIDEBYZERO,
std::wstring(SIDS_DOMAIN), SIDS_DOMAIN,
std::wstring(SIDS_UNDEFINED), SIDS_UNDEFINED,
std::wstring(SIDS_POS_INFINITY), SIDS_POS_INFINITY,
std::wstring(SIDS_NEG_INFINITY), SIDS_NEG_INFINITY,
std::wstring(SIDS_ABORTED), SIDS_ABORTED,
std::wstring(SIDS_NOMEM), SIDS_NOMEM,
std::wstring(SIDS_TOOMANY), SIDS_TOOMANY,
std::wstring(SIDS_OVERFLOW), SIDS_OVERFLOW,
std::wstring(SIDS_NORESULT), SIDS_NORESULT,
std::wstring(SIDS_INSUFFICIENT_DATA), SIDS_INSUFFICIENT_DATA,
std::wstring(SIDS_ERR_UNK_CH), SIDS_ERR_UNK_CH,
std::wstring(SIDS_ERR_UNK_FN), SIDS_ERR_UNK_FN,
std::wstring(SIDS_ERR_UNEX_NUM), SIDS_ERR_UNEX_NUM,
std::wstring(SIDS_ERR_UNEX_CH), SIDS_ERR_UNEX_CH,
std::wstring(SIDS_ERR_UNEX_SZ), SIDS_ERR_UNEX_SZ,
std::wstring(SIDS_ERR_MISMATCH_CLOSE), SIDS_ERR_MISMATCH_CLOSE,
std::wstring(SIDS_ERR_UNEX_END), SIDS_ERR_UNEX_END,
std::wstring(SIDS_ERR_SG_INV_ERROR), SIDS_ERR_SG_INV_ERROR,
std::wstring(SIDS_ERR_INPUT_OVERFLOW), SIDS_ERR_INPUT_OVERFLOW,
std::wstring(SIDS_ERR_OUTPUT_OVERFLOW) SIDS_ERR_OUTPUT_OVERFLOW
}; };

View File

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
@ -394,7 +394,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
void UnitConverterViewModel::DisplayPasteError() void UnitConverterViewModel::DisplayPasteError()
{ {
String^ errorMsg = AppResourceProvider::GetInstance().GetCEngineString(SIDS_DOMAIN); /*SIDS_DOMAIN is for "invalid input"*/ String^ errorMsg = AppResourceProvider::GetInstance().GetCEngineString(StringReference(SIDS_DOMAIN)); /*SIDS_DOMAIN is for "invalid input"*/
Value1 = errorMsg; Value1 = errorMsg;
Value2 = errorMsg; Value2 = errorMsg;
m_relocalizeStringOnSwitch = false; m_relocalizeStringOnSwitch = false;