My programming foundations were formed in Java, but I've decided to only use C++ from now on for my projects as a personal learning experience. Static utility classes are common in Java; but I don't think they work the same as in C++. I'd like the following:
- Code review of the functions to determine potential function-specific improvements
- Analysis of the general architecture/structure to determine if static methods are the way to go. If they are not, what would one recommend to achieve the desired result (which is to have a globally accessible set of utility methods)?
Here's the code:
util.h
#ifndef STDAFX_INCLUDE
#define STDAFX_INCLUDE
#include "stdafx.h"
#endif
#include <sstream>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <random>
// Utility class to manage misc. functions
class Util {
public:
static std::string serialize_http_args(std::map<std::string, std::string>);
static std::string serialize_http_headers(std::map<std::string, std::string>);
static int randrange(int min, int max);
static void trim(std::string&);
static void ltrim(std::string&);
static void rtrim(std::string&);
static std::string trim_copy(std::string);
static std::string ltrim_copy(std::string);
static std::string rtrim_copy(std::string);
static std::string int2str(int);
static std::string lowercase(std::string);
static std::vector<std::string> split(std::string, std::string);
static std::vector<std::string> split_once(std::string, std::string);
};
util.c
#include "util.h"
// returns a random number in range min through max, inclusive.
int Util::randrange(int min, int max) {
std::random_device rd; // obtain a random number from hardware
std::mt19937 eng(rd()); // seed the generator
std::uniform_int_distribution<> distr(min, max); // define the range
return distr(eng);
}
// takes a map of arguments and converts it to a string representation
std::string Util::serialize_http_args(std::map<std::string, std::string> _args) {
if (_args.size() > 0) {
size_t counter = 1;
std::string args_str = "";
for (auto const& arg : _args) {
args_str += arg.first + "=" + arg.second;
if (counter < _args.size())
args_str += "&";
counter++;
}
return args_str;
}
return "";
}
// takes a map of headers and converts it to the string representation
std::string Util::serialize_http_headers(std::map<std::string, std::string> _headers) {
if (_headers.size() > 0) {
std::string headers_ser = "";
for (auto const& header : _headers)
headers_ser += header.first + ": " + header.second + "\r\n";
return (headers_ser + "\r\n");
}
return "";
}
// splits a string infinitely by delimiter until completely tokenized
std::vector<std::string> Util::split(std::string s, std::string delimiter) {
std::vector<std::string> output;
std::string::size_type prev_pos = 0, pos = 0;
while ((pos = s.find(delimiter, pos)) != std::string::npos)
{
std::string substring(s.substr(prev_pos, pos - prev_pos));
output.push_back(substring);
prev_pos = ++pos;
}
output.push_back(s.substr(prev_pos, pos - prev_pos)); // Last word
return output;
}
// splits a string by the first instance of delimiter
std::vector<std::string> Util::split_once(std::string s, std::string delimiter)
{
std::vector<std::string> output;
std::string::size_type pos = 0;
if ((pos = s.find(delimiter, pos)) != std::string::npos) {
output.push_back(std::string(s.substr(0, pos)));
output.push_back(std::string(s.substr(pos + 1)));
}
return output;
}
// trim from start (in place)
void Util::ltrim(std::string & s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
}
// trim from end (in place)
void Util::rtrim(std::string & s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
}
// trim from both ends (in place)
void Util::trim(std::string & s) {
ltrim(s);
rtrim(s);
}
// trim from start (copying)
std::string Util::ltrim_copy(std::string _s) {
std::string s = _s;
ltrim(s);
return s;
}
// trim from end (copying)
std::string Util::rtrim_copy(std::string _s) {
std::string s = _s;
rtrim(s);
return s;
}
// trim from both ends (copying)
std::string Util::trim_copy(std::string _s) {
std::string s = _s;
trim(s);
return s;
}
// convert string to lowercase version of same string
std::string Util::lowercase(std::string _s) {
std::string s = _s;
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
}
//convert type integer to string
std::string Util::int2str(int i) {
std::string out;
std::stringstream ss;
ss << i;
return ss.str();
}
```