Files
musrfit/src/include/PStringUtils.h
T
suter_a 07f9c744b3 PStringUtils::IsInt: accept an optional leading sign
IsInt now recognises (possibly signed) integers such as "-5" or "+42",
making it slightly more permissive than TString::IsDigit(). A lone sign,
a double sign, or a sign following a digit are still rejected. strToNum
test expectations updated accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:14:11 +02:00

151 lines
6.3 KiB
C++

/***************************************************************************
PStringUtils.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007-2026 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* 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, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _PSTRINGUTILS_H_
#define _PSTRINGUTILS_H_
#include <string>
#include <vector>
//-------------------------------------------------------------
/**
* \brief Lightweight, dependency-free string utilities (pure C++17).
*
* PStringUtils collects small string helpers used throughout the musrfit
* suite, in particular for tokenizing and parsing the plain-text MSR file
* format. The implementation deliberately relies only on the C++ standard
* library (no ROOT) so that it can be reused freely.
*
* The provided helpers replicate the semantics of the corresponding
* ROOT TString methods that were previously used:
* - Split replaces TString::Tokenize() (+ TObjArray/TObjString)
* - IsInt replaces TString::IsDigit()
* - IsFloat replaces TString::IsFloat()
* - ToInt replaces TString::Atoi()
* - ToDouble replaces TString::Atof()
* - IsEqualNoCase replaces TString::CompareTo(..., TString::kIgnoreCase)
*
* All methods are static; the class is a pure namespace-like utility.
*/
class PStringUtils
{
public:
/**
* <p>Splits a string into tokens on any character contained in
* delimiters, skipping empty tokens. Mirrors TString::Tokenize().
*
* @param str input string to be tokenized
* @param delimiters set of delimiter characters
* @return vector of tokens (without the delimiters)
*/
static std::vector<std::string> Split(const std::string &str, const std::string &delimiters);
/**
* <p>Returns true if the string is a (possibly signed) integer literal,
* i.e. a non-empty sequence of decimal digits with an optional single
* leading sign (+/-). Slightly more permissive than TString::IsDigit(),
* which rejects a sign, so that e.g. "-5" is also recognised.
*
* @param str string to be checked
* @return true if str is a (possibly signed) integer
*/
static bool IsInt(const std::string &str);
/**
* <p>Returns true if the string is a complete integer or floating point
* literal (optionally signed, with decimal point and/or exponent).
* Mirrors TString::IsFloat() for the relevant cases.
*
* @param str string to be checked
* @return true if str is a valid number
*/
static bool IsFloat(const std::string &str);
/**
* <p>Converts the leading part of the string to an int (base 10).
* Mirrors TString::Atoi(). Returns 0 if no conversion is possible.
*
* <p>If \a ok is non-null it is set to true when a valid integer was
* parsed and to false on error (no digits, or value out of int range).
* This allows callers to distinguish a legitimate 0 from a failed
* conversion, which the bare return value cannot express.
*
* @param str string to be converted
* @param ok optional out-parameter signalling conversion success
* @return converted integer value (0 on error)
*/
static int ToInt(const std::string &str, bool *ok = nullptr);
/**
* <p>Converts the leading part of the string to a double.
* Mirrors TString::Atof(). Returns 0.0 if no conversion is possible.
*
* <p>If \a ok is non-null it is set to true when a value was parsed and
* to false on error (no number, or value out of range), allowing callers
* to distinguish a legitimate 0.0 from a failed conversion.
*
* @param str string to be converted
* @param ok optional out-parameter signalling conversion success
* @return converted double value (0.0 on error)
*/
static double ToDouble(const std::string &str, bool *ok = nullptr);
/**
* <p>Case-insensitive full-string equality.
* Mirrors TString::CompareTo(..., TString::kIgnoreCase) == 0.
*
* @param a first string
* @param b second string
* @return true if a and b are equal ignoring case
*/
static bool IsEqualNoCase(const std::string &a, const std::string &b);
/**
* <p>Case-insensitive substring search.
* Mirrors TString::Contains(..., TString::kIgnoreCase).
*
* @param haystack string to be searched in
* @param needle substring to be searched for
* @return true if needle is contained in haystack ignoring case
*/
static bool ContainsNoCase(const std::string &haystack, const std::string &needle);
/**
* <p>Case-insensitive prefix test.
* Mirrors TString::BeginsWith(..., TString::kIgnoreCase).
*
* @param str string to be tested
* @param prefix prefix to be searched for
* @return true if str starts with prefix ignoring case
*/
static bool BeginsWithNoCase(const std::string &str, const std::string &prefix);
};
#endif // _PSTRINGUTILS_H_