A set of benchmarks to compare a new prototype MiniZinc implementation
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3/* 4 * Main authors: 5 * Guido Tack <guido.tack@monash.edu> 6 */ 7 8/* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12#ifndef __MINIZINC_UTILS_H__ 13#define __MINIZINC_UTILS_H__ 14 15#include <minizinc/exception.hh> 16#include <minizinc/timer.hh> 17 18#include <cassert> 19#include <chrono> 20#include <ctime> 21#include <iomanip> 22#include <limits> 23#include <ratio> 24#include <sstream> 25#include <string> 26#include <vector> 27 28#ifdef MZN_HAS_LLROUND 29#include <cmath> 30namespace MiniZinc { 31inline long long int round_to_longlong(double v) { return ::llround(v); } 32} // namespace MiniZinc 33#else 34namespace MiniZinc { 35inline long long int round_to_longlong(double v) { 36 return static_cast<long long int>(v < 0 ? v - 0.5 : v + 0.5); 37} 38} // namespace MiniZinc 39#endif 40 41namespace MiniZinc { 42 43// #define __MZN_PRINTATONCE__ 44#ifdef __MZN_PRINTATONCE__ 45#define __MZN_PRINT_SRCLOC(e1, e2) \ 46 std::cerr << '\n' \ 47 << __FILE__ << ": " << __LINE__ << " (" << __func__ << "): not " << e1 << ": " \ 48 << std::flush; \ 49 std::cerr << e2 << std::endl 50#else 51#define __MZN_PRINT_SRCLOC(e1, e2) 52#endif 53#define MZN_ASSERT_HARD(c) \ 54 do { \ 55 if (!(c)) { \ 56 __MZN_PRINT_SRCLOC(#c, ""); \ 57 throw InternalError(#c); \ 58 } \ 59 } while (0) 60#define MZN_ASSERT_HARD_MSG(c, e) \ 61 do { \ 62 if (!(c)) { \ 63 __MZN_PRINT_SRCLOC(#c, e); \ 64 std::ostringstream oss; \ 65 oss << "not " << #c << ": " << e; \ 66 throw MiniZinc::InternalError(oss.str()); \ 67 } \ 68 } while (0) 69 70inline bool beginswith(std::string s, std::string t) { return s.compare(0, t.length(), t) == 0; } 71 72inline void checkIOStatus(bool fOk, std::string msg, bool fHard = 1) { 73 if (!fOk) { 74#ifdef _MSC_VER 75 char errBuf[1024]; 76 strerror_s(errBuf, sizeof(errBuf), errno); 77#else 78 char* errBuf = strerror(errno); 79#endif 80 std::cerr << "\n " << msg << ": " << errBuf << "." << std::endl; 81 MZN_ASSERT_HARD_MSG(!fHard, msg << ": " << errBuf); 82 } 83} 84 85template <class T> 86inline bool assignStr(T*, const std::string) { 87 return false; 88} 89template <> 90inline bool assignStr(std::string* pS, const std::string s) { 91 *pS = s; 92 return true; 93} 94 95/// A simple per-cmdline option parser 96class CLOParser { 97 int& i; // current item 98 std::vector<std::string>& argv; 99 100public: 101 CLOParser(int& ii, std::vector<std::string>& av) : i(ii), argv(av) {} 102 template <class Value = int> 103 inline bool get(const char* names, // space-separated option list 104 Value* pResult = nullptr, // pointer to value storage 105 bool fValueOptional = false // if pResult, for non-string values 106 ) { 107 return getOption(names, pResult, fValueOptional); 108 } 109 template <class Value = int> 110 inline bool getOption(const char* names, // space-separated option list 111 Value* pResult = nullptr, // pointer to value storage 112 bool fValueOptional = false // if pResult, for non-string values 113 ) { 114 assert(0 == strchr(names, ',')); 115 assert(0 == strchr(names, ';')); 116 if (i >= argv.size()) return false; 117 std::string arg(argv[i]); 118 /// Separate keywords 119 std::string keyword; 120 std::istringstream iss(names); 121 while (iss >> keyword) { 122 if (((2 < keyword.size() || 0 == pResult) && arg != keyword) || // exact cmp 123 (0 != arg.compare(0, keyword.size(), keyword))) // truncated cmp 124 continue; 125 /// Process it 126 bool combinedArg = false; // whether arg and value are combined in one string (like -Ggecode) 127 if (keyword.size() < arg.size()) { 128 if (0 == pResult) continue; 129 combinedArg = true; 130 arg.erase(0, keyword.size()); 131 } else { 132 if (0 == pResult) return true; 133 i++; 134 if (i >= argv.size()) { 135 --i; 136 return fValueOptional; 137 } 138 arg = argv[i]; 139 } 140 assert(pResult); 141 if (assignStr(pResult, arg)) return true; 142 std::istringstream iss(arg); 143 Value tmp; 144 if (!(iss >> tmp)) { 145 if (!combinedArg) --i; 146 if (fValueOptional) { 147 return true; 148 } 149 // Not print because another agent can handle this option 150 // cerr << "\nBad value for " << keyword << ": " << arg << endl; 151 return false; 152 } 153 *pResult = tmp; 154 return true; 155 } 156 return false; 157 } 158}; // class CLOParser 159 160/// This class prints a value if non-0 and adds comma if not 1st time 161class HadOne { 162 bool fHadOne = false; 163 164public: 165 template <class N> 166 std::string operator()(const N& val, const char* descr = 0) { 167 std::ostringstream oss; 168 if (val) { 169 if (fHadOne) oss << ", "; 170 fHadOne = true; 171 oss << val; 172 if (descr) oss << descr; 173 } 174 return oss.str(); 175 } 176 void reset() { fHadOne = false; } 177 operator bool() const { return fHadOne; } 178 bool operator!() const { return !fHadOne; } 179}; 180 181/// Split a string into words 182/// Add the words into the given vector 183inline void split(const std::string& str, std::vector<std::string>& words) { 184 std::istringstream iss(str); 185 std::string buf; 186 while (iss) { 187 iss >> buf; 188 words.push_back(buf); 189 } 190} 191 192/// Puts the strings' c_str()s into the 2nd argument. 193/// The latter is only valid as long as the former isn't changed. 194inline void vecString2vecPChar(const std::vector<std::string>& vS, std::vector<const char*>& vPC) { 195 vPC.resize(vS.size()); 196 for (size_t i = 0; i < vS.size(); ++i) { 197 vPC[i] = vS[i].c_str(); 198 } 199} 200 201} // namespace MiniZinc 202 203#endif // __MINIZINC_UTILS_H__