Files
rdkit/External/GA/util/Util.h
Ricardo Rodriguez 7b7a8a4e17 Refactor iostreams includes (#8846)
* refactor iostreams includes

* restore ostream to MonomerInfo.cpp
2025-10-08 16:08:01 +02:00

420 lines
9.5 KiB
C++

//
// Copyright (C) 2020 Gareth Jones, Glysade LLC
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
#ifndef UTIL_H_
#define UTIL_H_
#include <cmath>
#include <limits>
#include <cstdio>
#include <ctime>
#include <string>
#include <iterator>
#include <fstream>
#include <sstream>
#include <vector>
#include <memory>
#include <map>
#include <algorithm>
#include <boost/optional.hpp>
#include "export.h"
/*
* Utility methods
*/
namespace GarethUtil {
using namespace std;
/*
* Return current time as string
*/
string currentTime();
/**
*
* @param str
* @param prefix
* @return true id str starts with prefix
*/
GA_EXPORT bool startsWith(string str, string prefix);
/**
*
* @return current user name
*/
GA_EXPORT string getUserName();
/**
* Template function to convert a string to a type. Can optionally process a
* substring
*
* @param str
* @param ok optional boolean reference to indicate success or failure
* @param start optional start position
* @param end optional end position
* @return
*/
template <typename T>
T convertString(const string &str, bool *const ok = nullptr, size_t start = 0,
size_t noChars = 0) {
if (ok != nullptr) {
*ok = false;
}
T rtn;
if (str.empty()) {
return rtn;
}
if (start >= str.length()) {
return rtn;
}
if (noChars == 0) {
noChars = str.length() - start;
}
string field = str.substr(start, noChars);
stringstream ss(field);
ss >> rtn;
if (!ss.fail()) {
if (ok != nullptr) {
*ok = true;
}
}
return rtn;
}
/**
* Template function to write all elements of a vector to a string
*
* @param vec
* @param seperator
* @return
*/
template <typename T>
string collectionToString(const T &vec, const string &seperator = ", ") {
stringstream ss;
std::copy(vec.begin(), vec.end(),
ostream_iterator<typename T::value_type>(ss, seperator.c_str()));
// erase trailing separator
string rtn = ss.str();
if (!rtn.empty()) {
rtn.erase(rtn.length() - seperator.length(), seperator.length());
}
return rtn;
}
/**
* Removes any trailing linefeed (\r) from a string
* @param line
* @return
*/
GA_EXPORT string &removeTrailingLF(string &line);
/**
* Determines if a key is present in a map
*
* @param key
* @param map
* @param value optionally set the value for the key
* @return
*/
template <typename K, typename V>
bool isKeyPresent(const K key, const map<K, V> &map, V *const value = nullptr) {
auto iter = map.find(key);
if (iter != map.end()) {
if (value != nullptr) {
*value = iter->second;
}
return true;
}
return false;
}
/**
* Bs whitespace from beginning and end of string. Original argument is
* modified and returned.
* @param str
* @return
*/
GA_EXPORT string &trim(string &str);
/**
* Converts string to upper case. Original argument is modified and returned.
* @param str
* @return
*/
GA_EXPORT string &toUpperCase(string &str);
/**
* Converts string to lower case. Original argument is modified and returned.
* @param str
* @return
*/
GA_EXPORT string &toLowerCase(string &str);
/**
* @param str1
* @param str2
* @return true if the two strings are equal
*/
GA_EXPORT bool equals(const string &str1, const string &str2);
/**
* @param str1
* @param str2
* @return true if the two strings are equal (case insensitive)
*/
GA_EXPORT bool equalsIgnoreCase(const string &str1, const string &str2);
/**
*
* @param str
* @param suffix
* @return true if str ends with suffix
*/
GA_EXPORT bool endsWith(const string &str, const string &suffix);
/**
*
* @param vector
* @param value
* @return true if vector contains value
*/
template <typename T>
bool contains(std::vector<T> vector, T value) {
return std::find(vector.begin(), vector.end(), value) != vector.end();
}
/**
* Determines if two double numbers are equal within multiples of machine
* precision
*
* @param d1
* @param d2
* @param ulp machine precision (units in the last place)
* @return
*/
GA_EXPORT bool equals(const double d1, const double d2, const int ulp);
/**
* Returns true if the two numbers are within epsilon of each other
*
* @param d1
* @param d2
* @param epsilon
* @return
*/
GA_EXPORT bool equals(const double d1, const double d2, const double epsilon);
/**
* Determines if two double numbers are within one unit of the last place.
*
* @param d1
* @param d2
* @return
*/
GA_EXPORT bool equals(const double d1, const double d2);
/**
* Finds the first occurrence of an matching item in a list
*
* @param values
* @param matcher
* @return
*/
template <typename T>
boost::optional<T> findFirstInList(const std::vector<T> &values,
const function<bool(T)> &matcher) {
auto iter = std::find_if(values.cbegin(), values.cend(), matcher);
if (iter != values.cend()) {
return *iter;
}
return boost::none;
}
/**
* Finds the first occurrence of an matching item in a list of unique pointers
*
* @param values
* @param matcher
* @return
*/
template <typename T>
boost::optional<T *> findFirstInUniquePtrList(
const std::vector<unique_ptr<T>> &values,
const function<bool(const unique_ptr<T> &)> &matcher) {
auto iter = std::find_if(values.cbegin(), values.cend(), matcher);
if (iter != values.cend()) {
return iter->get();
}
return boost::none;
}
/**
* Removes all items from a list that DON'T match the filter. Alters and
* returns the original list.
*
* @param values
* @param filter
* @return
*/
template <typename T>
std::vector<T> &filterList(std::vector<T> &values,
const function<bool(T &)> &filter) {
auto iter = remove_if(values.begin(), values.end(), not1(filter));
values.erase(iter, values.end());
return values;
}
/**
* Creates a new vector of items in the input vector that match the filter
* @param values
* @param filter
* @return
*/
template <typename T>
std::vector<T> filterListToNewList(const std::vector<T> &values,
const function<bool(const T &)> &filter) {
std::vector<T> newValues;
newValues.reserve(values.size());
copy_if(values.begin(), values.end(), back_inserter(newValues), filter);
return newValues;
}
/**
* Creates a new vector of items in the input vector that match the filter.
* This method is specialized for an input list of unique pointers.
* A list of raw pointers is returned. It is assumed that the input list will
* outlast the filtered list.
*
* @param values
* @param filter
* @return
*/
template <typename T>
std::vector<T *> filterUniquePtrListToRawPtrList(
const std::vector<unique_ptr<T>> &values,
const function<bool(T &)> &filter) {
std::vector<T *> newValues;
newValues.reserve(values.size());
for (const auto &value : values) {
if (filter(*value)) {
newValues.push_back(value.get());
}
}
return newValues;
}
/**
* Specialization of the above for filtering non-const unique_ptrs to const raw
* pointer filtered list
* @param values
* @param filter
* @return
*/
template <typename T>
std::vector<const T *> filterUniquePtrListToConstRawPtrList(
const std::vector<unique_ptr<T>> &values,
const function<bool(T &)> &filter) {
std::vector<const T *> newValues;
newValues.reserve(values.size());
for (const auto &value : values) {
if (filter(*value)) {
newValues.push_back(value.get());
}
}
return newValues;
}
/**
* Creates a new list from an existing list by applying the mapping function.
*
* @param values
* @param map
* @return
*/
template <typename T, typename V>
std::vector<V> mapToNewList(const std::vector<T> &values,
const function<V(const T &)> &map) {
std::vector<V> mappedValues;
mappedValues.reserve(values.size());
std::transform(values.cbegin(), values.cend(), back_inserter(mappedValues),
map);
return mappedValues;
}
/**
* Creates a new list from an existing list by applying the mapping function.
*
* @param values
* @param map
* @return
*/
template <typename T>
std::vector<T> mapToNewList(const std::vector<T> &values,
const function<T(const T &)> &map) {
return mapToNewList<T, T>(values, map);
}
/**
* Applies a function to every value in a list.
*
* @param values
* @param func
*/
template <typename T>
void forEach(const std::vector<T> &values, const function<void(T &)> &func) {
for (const auto &v : values) {
func(v);
}
}
/**
* Reduces a vector to a single value of a different type using the accumulator
* function.
*
* @param startingValue
* @param accumulator function takes accumulating value as first argument and
* current list value as second.
* @return
*/
template <typename T, typename R>
R reduce(const std::vector<T> &values, const R &startingValue,
const function<R(R &, const T &)> accumulator) {
R currentValue = startingValue;
for (auto iter = values.cbegin(); iter != values.cend(); ++iter) {
currentValue = accumulator(currentValue, *iter);
}
return currentValue;
}
/**
* Writes an object to a string using the stream << operator.
*
* @param obj
* @return
*/
template <typename T>
string printToString(T obj) {
stringstream ss;
ss << obj;
return ss.str();
}
/**
* Retrieve an environment variable value, or none if it is not set.
*
* @param name
* @return
*/
GA_EXPORT boost::optional<string> getEnv(const string &name);
} // namespace GarethUtil
#endif /* UTIL_H_ */