| 25 | |
| 26 | template<typename... Args> |
| 27 | inline std::string fmtstr(const std::string& format, Args... args) |
| 28 | { |
| 29 | // This function came from a code snippet in stackoverflow under cc-by-1.0 |
| 30 | // https://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf |
| 31 | |
| 32 | // Disable format-security warning in this function. |
| 33 | #if defined(_MSC_VER) // for visual studio |
| 34 | #pragma warning(push) |
| 35 | #pragma warning(warning(disable : 4996)) |
| 36 | #elif defined(__GNUC__) || defined(__clang__) // for gcc or clang |
| 37 | #pragma GCC diagnostic push |
| 38 | #pragma GCC diagnostic ignored "-Wformat-security" |
| 39 | #endif |
| 40 | int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' |
| 41 | if (size_s <= 0) { |
| 42 | throw std::runtime_error("Error during formatting."); |
| 43 | } |
| 44 | auto size = static_cast<size_t>(size_s); |
| 45 | auto buf = std::make_unique<char[]>(size); |
| 46 | std::snprintf(buf.get(), size, format.c_str(), args...); |
| 47 | #if defined(_MSC_VER) |
| 48 | #pragma warning(pop) |
| 49 | #elif defined(__GNUC__) || defined(__clang__) |
| 50 | #pragma GCC diagnostic pop |
| 51 | #endif |
| 52 | return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside |
| 53 | } |
| 54 | |
| 55 | template<typename T> |
| 56 | inline std::string vec2str(std::vector<T> vec) |