<commit_before>/*
Copyright libCellML Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "utilities.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
#include <limits>
#include <set>
#include <sstream>
#include <vector>

#include "libcellml/component.h"
#include "libcellml/importsource.h"
#include "libcellml/issue.h"
#include "libcellml/logger.h"
#include "libcellml/model.h"
#include "libcellml/namedentity.h"
#include "libcellml/reset.h"
#include "libcellml/units.h"
#include "libcellml/variable.h"

#include "xmldoc.h"
#include "xmlutils.h"

namespace libcellml {

bool convertToDouble(const std::string &in, double &out)
{
    try {
        out = std::stod(in);
    } catch (...) {
        return false;
    }
    return true;
}

bool hasNonWhitespaceCharacters(const std::string &input)
{
    return input.find_first_not_of(" \t\n\v\f\r") != std::string::npos;
}

std::string convertToString(double value)
{
    std::ostringstream strs;
    strs << std::setprecision(std::numeric_limits<double>::digits10) << value;
    return strs.str();
}

bool convertToInt(const std::string &in, int &out)
{
    try {
        out = std::stoi(in);
    } catch (...) {
        return false;
    }
    return true;
}

std::string convertToString(size_t value)
{
    std::ostringstream strs;
    strs << value;
    return strs.str();
}

std::string convertToString(int value)
{
    std::ostringstream strs;
    strs << value;
    return strs.str();
}

bool isEuropeanNumericCharacter(char c)
{
    const std::set<char> validIntegerCharacters = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    return validIntegerCharacters.find(c) != validIntegerCharacters.end();
}

bool isNonNegativeCellMLInteger(const std::string &candidate)
{
    if (candidate.empty()) {
        return false;
    }
    return std::all_of(candidate.begin(), candidate.end(), isEuropeanNumericCharacter);
}

bool isCellMLInteger(const std::string &candidate)
{
    if (!candidate.empty() && *candidate.begin() == '-') {
        return isNonNegativeCellMLInteger(candidate.substr(1));
    }
    return isNonNegativeCellMLInteger(candidate);
}

bool isCellMLExponent(const std::string &candidate)
{
    if (!candidate.empty() && *candidate.begin() == '+') {
        return isCellMLInteger(candidate.substr(1));
    }
    return isCellMLInteger(candidate);
}

std::vector<size_t> findOccurrences(const std::string &candidate, const std::string &sub)
{
    std::vector<size_t> occurrences;
    size_t pos = candidate.find(sub, 0);
    while (pos != std::string::npos) {
        occurrences.push_back(pos);
        pos = candidate.find(sub, pos + 1);
    }
    return occurrences;
}

bool isCellMLBasicReal(const std::string &candidate)
{
    if (!candidate.empty()) {
        std::vector<size_t> decimalOccurrences = findOccurrences(candidate, ".");
        if (decimalOccurrences.size() < 2) {
            bool beginsMinus = *candidate.begin() == '-';
            std::string numbersOnlyCandidate = candidate;
            if (decimalOccurrences.size() == 1) {
                numbersOnlyCandidate.erase(decimalOccurrences.at(0), 1);
            }
            if (beginsMinus) {
                numbersOnlyCandidate.erase(0, 1);
            }
            return std::all_of(numbersOnlyCandidate.begin(), numbersOnlyCandidate.end(), isEuropeanNumericCharacter);
        }
    }
    return false;
}

bool isCellMLReal(const std::string &candidate)
{
    bool isReal = false;
    if (!candidate.empty()) {
        std::string normalisedCandidate = candidate;
        std::vector<size_t> eOccurrences = findOccurrences(candidate, "E");
        for (const auto &ePos : eOccurrences) {
            normalisedCandidate.replace(ePos, 1, "e");
        }
        std::vector<size_t> lowerEOccurrences = findOccurrences(normalisedCandidate, "e");
        size_t eIndicatorCount = lowerEOccurrences.size();
        if (eIndicatorCount < 2) {
            if (eIndicatorCount == 1) {
                size_t ePos = lowerEOccurrences.at(0);
                std::string significand = normalisedCandidate.substr(0, ePos);
                std::string exponent = normalisedCandidate.substr(ePos + 1, std::string::npos);
                if (isCellMLBasicReal(significand) && isCellMLExponent(exponent)) {
                    isReal = true;
                }
            } else {
                isReal = isCellMLBasicReal(normalisedCandidate);
            }
        }
    }
    return isReal;
}

bool areEqual(double value1, double value2)
{
    return std::abs(value1 - value2) < std::numeric_limits<double>::epsilon();
}

std::vector<ComponentPtr> getImportedComponents(const ComponentEntityConstPtr &componentEntity)
{
    std::vector<ComponentPtr> importedComponents;
    for (size_t i = 0; i < componentEntity->componentCount(); ++i) {
        auto component = componentEntity->component(i);
        if (component->isImport()) {
            importedComponents.push_back(component);
        }

        auto childImportedComponents = getImportedComponents(component);
        importedComponents.reserve(importedComponents.size() + distance(childImportedComponents.begin(),childImportedComponents.end()));
        importedComponents.insert(importedComponents.end(),childImportedComponents.begin(),childImportedComponents.end());
    }<commit_msg>Use size in getImportedComponents reserve vector calculation.<commit_after>/*
Copyright libCellML Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "utilities.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
#include <limits>
#include <set>
#include <sstream>
#include <vector>

#include "libcellml/component.h"
#include "libcellml/importsource.h"
#include "libcellml/issue.h"
#include "libcellml/logger.h"
#include "libcellml/model.h"
#include "libcellml/namedentity.h"
#include "libcellml/reset.h"
#include "libcellml/units.h"
#include "libcellml/variable.h"

#include "xmldoc.h"
#include "xmlutils.h"

namespace libcellml {

bool convertToDouble(const std::string &in, double &out)
{
    try {
        out = std::stod(in);
    } catch (...) {
        return false;
    }
    return true;
}

bool hasNonWhitespaceCharacters(const std::string &input)
{
    return input.find_first_not_of(" \t\n\v\f\r") != std::string::npos;
}

std::string convertToString(double value)
{
    std::ostringstream strs;
    strs << std::setprecision(std::numeric_limits<double>::digits10) << value;
    return strs.str();
}

bool convertToInt(const std::string &in, int &out)
{
    try {
        out = std::stoi(in);
    } catch (...) {
        return false;
    }
    return true;
}

std::string convertToString(size_t value)
{
    std::ostringstream strs;
    strs << value;
    return strs.str();
}

std::string convertToString(int value)
{
    std::ostringstream strs;
    strs << value;
    return strs.str();
}

bool isEuropeanNumericCharacter(char c)
{
    const std::set<char> validIntegerCharacters = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    return validIntegerCharacters.find(c) != validIntegerCharacters.end();
}

bool isNonNegativeCellMLInteger(const std::string &candidate)
{
    if (candidate.empty()) {
        return false;
    }
    return std::all_of(candidate.begin(), candidate.end(), isEuropeanNumericCharacter);
}

bool isCellMLInteger(const std::string &candidate)
{
    if (!candidate.empty() && *candidate.begin() == '-') {
        return isNonNegativeCellMLInteger(candidate.substr(1));
    }
    return isNonNegativeCellMLInteger(candidate);
}

bool isCellMLExponent(const std::string &candidate)
{
    if (!candidate.empty() && *candidate.begin() == '+') {
        return isCellMLInteger(candidate.substr(1));
    }
    return isCellMLInteger(candidate);
}

std::vector<size_t> findOccurrences(const std::string &candidate, const std::string &sub)
{
    std::vector<size_t> occurrences;
    size_t pos = candidate.find(sub, 0);
    while (pos != std::string::npos) {
        occurrences.push_back(pos);
        pos = candidate.find(sub, pos + 1);
    }
    return occurrences;
}

bool isCellMLBasicReal(const std::string &candidate)
{
    if (!candidate.empty()) {
        std::vector<size_t> decimalOccurrences = findOccurrences(candidate, ".");
        if (decimalOccurrences.size() < 2) {
            bool beginsMinus = *candidate.begin() == '-';
            std::string numbersOnlyCandidate = candidate;
            if (decimalOccurrences.size() == 1) {
                numbersOnlyCandidate.erase(decimalOccurrences.at(0), 1);
            }
            if (beginsMinus) {
                numbersOnlyCandidate.erase(0, 1);
            }
            return std::all_of(numbersOnlyCandidate.begin(), numbersOnlyCandidate.end(), isEuropeanNumericCharacter);
        }
    }
    return false;
}

bool isCellMLReal(const std::string &candidate)
{
    bool isReal = false;
    if (!candidate.empty()) {
        std::string normalisedCandidate = candidate;
        std::vector<size_t> eOccurrences = findOccurrences(candidate, "E");
        for (const auto &ePos : eOccurrences) {
            normalisedCandidate.replace(ePos, 1, "e");
        }
        std::vector<size_t> lowerEOccurrences = findOccurrences(normalisedCandidate, "e");
        size_t eIndicatorCount = lowerEOccurrences.size();
        if (eIndicatorCount < 2) {
            if (eIndicatorCount == 1) {
                size_t ePos = lowerEOccurrences.at(0);
                std::string significand = normalisedCandidate.substr(0, ePos);
                std::string exponent = normalisedCandidate.substr(ePos + 1, std::string::npos);
                if (isCellMLBasicReal(significand) && isCellMLExponent(exponent)) {
                    isReal = true;
                }
            } else {
                isReal = isCellMLBasicReal(normalisedCandidate);
            }
        }
    }
    return isReal;
}

bool areEqual(double value1, double value2)
{
    return std::abs(value1 - value2) < std::numeric_limits<double>::epsilon();
}

std::vector<ComponentPtr> getImportedComponents(const ComponentEntityConstPtr &componentEntity)
{
    std::vector<ComponentPtr> importedComponents;
    for (size_t i = 0; i < componentEntity->componentCount(); ++i) {
        auto component = componentEntity->component(i);
        if (component->isImport()) {
            importedComponents.push_back(component);
        }

        auto childImportedComponents = getImportedComponents(component);
        importedComponents.reserve(importedComponents.size() + childImportedComponents.size());
        importedComponents.insert(importedComponents.end(), childImportedComponents.begin(), childImportedComponents.end());
    }
{'fraction_non_alphanumeric': 0.12904610629346613, 'fraction_numerical': 0.00635356744225981, 'mean_word_length': 3.4171406901782326, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3991065', 'n_tokens_mistral': 3673, 'n_tokens_neox': 3575, 'n_words': 788}