PMsrHandler: replace ROOT tokenizer machinery with C++17 PStringUtils
Reduce the ROOT footprint of the MSR parser by removing the pervasive TString::Tokenize / TObjArray / TObjString / dynamic_cast pattern (28 tokenize sites, 14 TObjArray, 106 TObjString) used to split lines into tokens, together with the manual `delete tokens` cleanup. Add a new dependency-free C++17 utility class PStringUtils (Split, IsInt, IsFloat, ToInt, ToDouble, IsEqualNoCase, ContainsNoCase, BeginsWithNoCase) that replicates the relevant TString semantics exactly, so it can be reused elsewhere in the suite. IsInt/IsFloat tolerate surrounding whitespace to match TString::IsDigit/IsFloat (needed for tokens split on ',' / ';' only). The public API and the PMusr.h data structures keep TString unchanged; only the internal tokenizing logic is rewritten. Net -451 lines in PMsrHandler.cpp. All 85 integration tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
/***************************************************************************
|
||||
|
||||
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 non-empty sequence of decimal
|
||||
* digits only. Mirrors TString::IsDigit().
|
||||
*
|
||||
* @param str string to be checked
|
||||
* @return true if str consists of digits only
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param str string to be converted
|
||||
* @return converted integer value
|
||||
*/
|
||||
static int ToInt(const std::string &str);
|
||||
|
||||
/**
|
||||
* <p>Converts the leading part of the string to a double.
|
||||
* Mirrors TString::Atof(). Returns 0.0 if no conversion is possible.
|
||||
*
|
||||
* @param str string to be converted
|
||||
* @return converted double value
|
||||
*/
|
||||
static double ToDouble(const std::string &str);
|
||||
|
||||
/**
|
||||
* <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_
|
||||
Reference in New Issue
Block a user