// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html #include #include #include #include #include #include #include #include "general_functions.h" using namespace std; bool is_natural_number(const char* c_str) { bool answer = false; if (is_whole_number(c_str)) { if (stoi(c_str) > 0) { answer = true; } } return answer; } bool is_whole_number(const char* c_str) { bool answer = false; int c_str_length = strlen(c_str); if (c_str_length < 1) { // nothing needs to be done } else if (! isdigit(c_str[0])) { // nothing needs to be done } else { answer = true; // c_str[0] is checked in else if statement. for (int i=1; i < (c_str_length-1); i++) if (! isdigit(c_str[i])) { answer = false; } } return answer; } void get_textfile_lines(string filename, vector &file_lines) { ifstream file(filename); if (! file.good()) { cerr << "Failed to open/read file: " << filename\ << ". Non-exhaustive list of possible reasons:\n"\ << "1. File does not exist.\n"\ << "2. Unable to read file due to:\n"\ << "2.1 Don't have read access to file\n"\ << "2.2 File is opened elsewhere and some program have a "\ << "lock on file.\n"; exit(2); } // cout << "Reading file: " << filename << endl; int i=0; while (file.good()) { file_lines.push_back(""); getline(file, file_lines[i]); i++; } file.close(); } int random_int(int minimum, int maximum) { static random_device seed; static mt19937 random_number_generator(seed()); uniform_int_distribution range( minimum, maximum); return range(random_number_generator); } // SOURCE: cppreference.com float random_float(float minimum, float maximum) { static random_device seed; static mt19937 random_number_generator(seed()); uniform_real_distribution<> range( minimum, maximum); return range(random_number_generator); } void string_to_vector( string &a_string, vector &str_vector, char delimeter) { stringstream str_stream(a_string); string str = ""; while(getline(str_stream, str, delimeter)) { if (str.length() > 1 and str != "\n") { str_vector.push_back(str); } } } void pick_random_string( string &str, const vector &str_vector) { int vector_size = str_vector.size(); if (vector_size < 1) { str = ""; } else { int i = random_int(0, vector_size-1); str = str_vector[i]; } } int modulate(int number, int modulus) { int after_modulation; if (number >= 0) { after_modulation = number % modulus; } else if (number < 0) { after_modulation = ( modulus - (absolute_number(number)%modulus)); } else { // OK, I know this is too much cerr_and_exit( 2, "internal", __FILE__, __func__, __LINE__, "argument 1 'number' is neither >=0 nor < 0. " "NOTE: this is just hypothetical situation following " "defensive programming and should never happen in practice" ); } return after_modulation; } void cerr_and_exit( int exit_code, string error_name, string file_name, string function_name, int line_number, string additional_message) { cerr_only( error_name, file_name, function_name, line_number, additional_message); exit(exit_code); } void cerr_only( string error_name, string file_name, string function_name, int line_number, string additional_message) { if (error_name.size() > 0) { error_name[0] = toupper(error_name[0]); if (error_name[-1] != ' ') { error_name += ' '; } } cerr << error_name << "error occured at:\n" << "Source code file name: " << file_name << "\n" << "Function name: " << function_name << "\n" << "Line number: " << line_number << "\n" << additional_message; if (additional_message != "") { if (additional_message[-1] != '\n') { cerr << '\n'; } } }