| 1 | /** \file |
| 2 | * \brief Basic configuration file |
| 3 | * |
| 4 | * \author Carsten Gutwenger |
| 5 | * |
| 6 | * \par License: |
| 7 | * This file is part of the Open Graph Drawing Framework (OGDF). |
| 8 | * |
| 9 | * \par |
| 10 | * Copyright (C)<br> |
| 11 | * See README.md in the OGDF root directory for details. |
| 12 | * |
| 13 | * \par |
| 14 | * This program is free software; you can redistribute it and/or |
| 15 | * modify it under the terms of the GNU General Public License |
| 16 | * Version 2 or 3 as published by the Free Software Foundation; |
| 17 | * see the file LICENSE.txt included in the packaging of this file |
| 18 | * for details. |
| 19 | * |
| 20 | * \par |
| 21 | * This program is distributed in the hope that it will be useful, |
| 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 24 | * GNU General Public License for more details. |
| 25 | * |
| 26 | * \par |
| 27 | * You should have received a copy of the GNU General Public |
| 28 | * License along with this program; if not, see |
| 29 | * http://www.gnu.org/copyleft/gpl.html |
| 30 | */ |
| 31 | |
| 32 | #pragma once |
| 33 | |
| 34 | #include <ogdf/basic/internal/version.h> |
| 35 | #include <ogdf/basic/internal/config_autogen.h> |
| 36 | #include <iostream> |
| 37 | #include <string> |
| 38 | |
| 39 | #if defined(OGDF_DEBUG) && defined(NDEBUG) |
| 40 | # error "Contradicting configuration: Macros OGDF_DEBUG and NDEBUG are defined." |
| 41 | #endif |
| 42 | |
| 43 | namespace ogdf { |
| 44 | |
| 45 | // generally used <string> members |
| 46 | using std::string; |
| 47 | using std::to_string; |
| 48 | |
| 49 | // detection of the system |
| 50 | |
| 51 | #if defined(unix) || defined(__unix__) || defined(__unix) || defined(_AIX) || defined(__APPLE__) |
| 52 | #define OGDF_SYSTEM_UNIX |
| 53 | #endif |
| 54 | |
| 55 | #if defined(__WIN32__) || defined(_WIN32) || defined(__NT__) |
| 56 | #define OGDF_SYSTEM_WINDOWS |
| 57 | #endif |
| 58 | |
| 59 | // Note: Apple OS X machines will be both OGDF_SYSTEM_UNIX and OGDF_SYSTEM_OSX |
| 60 | #if defined(__APPLE__) |
| 61 | #define OGDF_SYSTEM_OSX |
| 62 | #endif |
| 63 | |
| 64 | // C++11 standard |
| 65 | |
| 66 | #if __cplusplus < 201103 |
| 67 | |
| 68 | #if defined(_MSC_VER) |
| 69 | #if _MSC_VER < 1700 |
| 70 | #error "Compiling OGDF requires Visual C++ 11 (Visual Studio 2012) or higher!" |
| 71 | #endif |
| 72 | |
| 73 | #elif defined(__GNUC__) |
| 74 | #ifndef __GXX_EXPERIMENTAL_CXX0X__ |
| 75 | #error "No C++11 support activated for g++ (compile with -std=c++0x or -std=c++11)!" |
| 76 | #endif |
| 77 | |
| 78 | #else |
| 79 | #error "Compiling OGDF requires a C++11 compliant compiler!" |
| 80 | #endif |
| 81 | |
| 82 | #endif |
| 83 | |
| 84 | #ifdef __has_cpp_attribute |
| 85 | # define OGDF_HAS_CPP_ATTRIBUTE(x) (__has_cpp_attribute(x) && __cplusplus >= __has_cpp_attribute(x)) |
| 86 | #else |
| 87 | # define OGDF_HAS_CPP_ATTRIBUTE(x) 0 |
| 88 | #endif |
| 89 | |
| 90 | //! @name Important when compiling OGDF as DLL |
| 91 | //! @ingroup macros |
| 92 | //! @{ |
| 93 | |
| 94 | /** |
| 95 | * Specifies that a function or class is exported by the OGDF DLL. |
| 96 | * It is set according to the definition of OGDF_INSTALL (OGDF is build as DLL) and OGDF_DLL (OGDF is used as DLL). |
| 97 | * If none of these are defined (OGDF is build or used as static library), the define expands to nothing. |
| 98 | */ |
| 99 | #define OGDF_EXPORT |
| 100 | |
| 101 | #ifdef OGDF_SYSTEM_WINDOWS |
| 102 | # ifdef OGDF_DLL |
| 103 | # undef OGDF_EXPORT |
| 104 | # ifdef OGDF_INSTALL |
| 105 | # define OGDF_EXPORT __declspec(dllexport) |
| 106 | # else |
| 107 | # define OGDF_EXPORT __declspec(dllimport) |
| 108 | # endif |
| 109 | # endif |
| 110 | #endif |
| 111 | |
| 112 | //! @} |
| 113 | //! @name Deprecation |
| 114 | //! @{ |
| 115 | |
| 116 | //! Mark a class / member / function as deprecated |
| 117 | //! @ingroup macros |
| 118 | #define OGDF_DEPRECATED(reason) |
| 119 | |
| 120 | #if OGDF_HAS_CPP_ATTRIBUTE(deprecated) |
| 121 | # undef OGDF_DEPRECATED |
| 122 | # define OGDF_DEPRECATED(reason) [[deprecated(reason)]] |
| 123 | #elif defined(_MSC_VER) |
| 124 | # undef OGDF_DEPRECATED |
| 125 | # define OGDF_DEPRECATED(reason) __declspec(deprecated(reason)) |
| 126 | #elif defined(__GNUC__) |
| 127 | # undef OGDF_DEPRECATED |
| 128 | # define OGDF_DEPRECATED(reason) __attribute__((deprecated(reason))) |
| 129 | #endif |
| 130 | |
| 131 | //! @} |
| 132 | |
| 133 | //! @name Optimization |
| 134 | //! @{ |
| 135 | |
| 136 | /** |
| 137 | * Specify the likely branch in a condition. |
| 138 | * Usage: \code if (OGDF_LIKELY(i >= 0)) { likely branch } else { unlikely branch } \endcode |
| 139 | * @ingroup macros |
| 140 | */ |
| 141 | #define OGDF_LIKELY(x) (x) |
| 142 | |
| 143 | /** |
| 144 | * Specify the unlikely branch in a condition. |
| 145 | * Usage: \code if (OGDF_UNLIKELY(set.empty())) { unlikely branch } else { likely branch } \endcode |
| 146 | * @ingroup macros |
| 147 | */ |
| 148 | #define OGDF_UNLIKELY(x) (x) |
| 149 | |
| 150 | //! Specify the minimum alignment (in bytes) of a type to be \p b. This is used in type declarations. |
| 151 | //! @ingroup macros |
| 152 | #define OGDF_DECL_ALIGN(b) |
| 153 | |
| 154 | #ifdef _MSC_VER // Visual C++ compiler |
| 155 | # undef OGDF_DECL_ALIGN |
| 156 | # define OGDF_DECL_ALIGN(b) __declspec(align(b)) |
| 157 | #elif defined(__GNUC__) // GNU gcc compiler (also Intel compiler) |
| 158 | # undef OGDF_LIKELY |
| 159 | # define OGDF_LIKELY(x) __builtin_expect((x),1) |
| 160 | # undef OGDF_UNLIKELY |
| 161 | # define OGDF_UNLIKELY(x) __builtin_expect((x),0) |
| 162 | # undef OGDF_DECL_ALIGN |
| 163 | # define OGDF_DECL_ALIGN(b) __attribute__ ((aligned(b))) |
| 164 | #endif |
| 165 | |
| 166 | //! @} |
| 167 | |
| 168 | //! An attribute to mark cases (in switch) that fall through to the next case |
| 169 | #define OGDF_CASE_FALLTHROUGH |
| 170 | #if OGDF_HAS_CPP_ATTRIBUTE(fallthrough) |
| 171 | # undef OGDF_CASE_FALLTHROUGH |
| 172 | # define OGDF_CASE_FALLTHROUGH [[fallthrough]] |
| 173 | #elif defined(__GNUC__) && __GNUC__ >= 7 |
| 174 | # undef OGDF_CASE_FALLTHROUGH |
| 175 | # define OGDF_CASE_FALLTHROUGH __attribute__((fallthrough)) |
| 176 | #endif |
| 177 | |
| 178 | // compiler adaptions |
| 179 | |
| 180 | #ifdef _MSC_VER |
| 181 | |
| 182 | #ifdef OGDF_DLL |
| 183 | // disable useless warnings |
| 184 | // missing dll-interface |
| 185 | |
| 186 | // warning C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' |
| 187 | #pragma warning(disable : 4251) |
| 188 | // warning C4275: non-DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier' |
| 189 | #pragma warning(disable : 4275) |
| 190 | #endif |
| 191 | |
| 192 | // warning C4355: 'this' : used in base member initializer list |
| 193 | #pragma warning (disable : 4355) |
| 194 | |
| 195 | #endif |
| 196 | |
| 197 | //! Provides information about how OGDF has been configured. |
| 198 | /** |
| 199 | * @ingroup system |
| 200 | */ |
| 201 | class OGDF_EXPORT Configuration { |
| 202 | public: |
| 203 | //! Specifies the operating system for which OGDF has been configured/built. |
| 204 | enum class System { |
| 205 | Unknown, //!< not known (inproper configuration) |
| 206 | Windows, //!< Windows |
| 207 | Unix, //!< Unix/Linux |
| 208 | OSX, //!< Apple OSX |
| 209 | STOP |
| 210 | }; |
| 211 | |
| 212 | //! Specifies the LP-solver used by OGDF. |
| 213 | enum class LPSolver { |
| 214 | None, //!< no LP-solver available |
| 215 | Clp, //!< COIN-OR LP-solver (Clp) |
| 216 | Symphony, //!< Symphony |
| 217 | CPLEX, //!< CPLEX (commercial) |
| 218 | Gurobi, //!< Gurobi (commercial) |
| 219 | STOP |
| 220 | }; |
| 221 | |
| 222 | //! Specifies the memory-manager used by OGDF. |
| 223 | enum class MemoryManager { |
| 224 | PoolTS, //!< thread-safe pool allocator |
| 225 | PoolNTS, //!< non-thread-safe pool allocator |
| 226 | Malloc, //!< malloc/free allocator |
| 227 | STOP |
| 228 | }; |
| 229 | |
| 230 | //! Returns the operating system for which OGDF has been configured. |
| 231 | static constexpr System whichSystem() { |
| 232 | #ifdef OGDF_SYSTEM_WINDOWS |
| 233 | return System::Windows; |
| 234 | #elif defined(OGDF_SYSTEM_OSX) |
| 235 | return System::OSX; |
| 236 | #elif defined(OGDF_SYSTEM_UNIX) |
| 237 | return System::Unix; |
| 238 | #else |
| 239 | return System::Unknown |
| 240 | #endif |
| 241 | } |
| 242 | |
| 243 | //! Returns whether OGDF has been configured with LP-solver support. |
| 244 | /** |
| 245 | * Since COIN and ABACUS are required and shipped, this function |
| 246 | * always returns true. |
| 247 | */ |
| 248 | OGDF_DEPRECATED("OGDF always has LP solver support since 2015.05" ) |
| 249 | static constexpr bool haveLPSolver() { |
| 250 | return true; |
| 251 | } |
| 252 | |
| 253 | //! Returns the LP-solver used by OGDF. |
| 254 | static constexpr LPSolver whichLPSolver() { |
| 255 | #if defined(COIN_OSI_CLP) |
| 256 | return LPSolver::Clp; |
| 257 | #elif defined(COIN_OSI_SYM) |
| 258 | return LPSolver::Symphony; |
| 259 | #elif defined(COIN_OSI_CPX) |
| 260 | return LPSolver::CPLEX; |
| 261 | #elif defined(COIN_OSI_GRB) |
| 262 | return LPSolver::Gurobi; |
| 263 | #else |
| 264 | # error "OGDF is compiled without LP solver. Check your build configuration." |
| 265 | #endif |
| 266 | } |
| 267 | |
| 268 | //! Returns whether OGDF has been configured with COIN support. |
| 269 | /** |
| 270 | * COIN is used as LP solver by some OGDF algorithms. |
| 271 | * In former versions, OGDF could be configured without COIN support, |
| 272 | * so this functionality was not available. |
| 273 | * Now this function always returns true. |
| 274 | */ |
| 275 | OGDF_DEPRECATED("OGDF always has COIN-OR since 2015.05" ) |
| 276 | static constexpr bool haveCoin() { |
| 277 | return true; |
| 278 | } |
| 279 | |
| 280 | //! Returns whether OGDF has been configured with ABACUS support. |
| 281 | /** |
| 282 | * ABACUS is used as branch-and-cut-solver by some OGDF algorithms. |
| 283 | * In former versions, OGDF could be configured without ABACUS support, |
| 284 | * so this functionality was not available. |
| 285 | * Now this function always returns true. |
| 286 | */ |
| 287 | OGDF_DEPRECATED("OGDF always has ABACUS since 2015.05" ) |
| 288 | static constexpr bool haveAbacus() { |
| 289 | return true; |
| 290 | } |
| 291 | |
| 292 | /** |
| 293 | * Returns the memory manager used by OGDF. |
| 294 | * |
| 295 | * The memory manager is configured using the build configuration. |
| 296 | * Depending on that, the following macros are set: |
| 297 | * - OGDF_MEMORY_POOL_TS: buffered-pool allocator per thread pool (thread-safe) |
| 298 | * - OGDF_MEMORY_POOL_NTS: pool allocator (not thread-safe) |
| 299 | * - OGDF_MEMORY_MALLOC_TS: just using malloc/free (thread-safe) |
| 300 | */ |
| 301 | static constexpr MemoryManager whichMemoryManager() { |
| 302 | #if defined(OGDF_MEMORY_POOL_TS) |
| 303 | return MemoryManager::PoolTS; |
| 304 | #elif defined(OGDF_MEMORY_POOL_NTS) |
| 305 | return MemoryManager::PoolNTS; |
| 306 | #elif defined(OGDF_MEMORY_MALLOC_TS) |
| 307 | return MemoryManager::Malloc; |
| 308 | #else |
| 309 | # error "OGDF is compiled without memory manager. Check your build configuration." |
| 310 | #endif |
| 311 | } |
| 312 | |
| 313 | //! Converts \p sys to a (readable) string. |
| 314 | static const string &toString(System sys); |
| 315 | |
| 316 | //! Converts \p lps to a (readable) string. |
| 317 | static const string &toString(LPSolver lps); |
| 318 | |
| 319 | //! Converts \p mm to a (readable) string. |
| 320 | static const string &toString(MemoryManager mm); |
| 321 | }; |
| 322 | |
| 323 | |
| 324 | //! Output operator for Configuration::System (uses Configuration::toString(Configuration::System)). |
| 325 | inline std::ostream &operator<<(std::ostream &os, Configuration::System sys) |
| 326 | { |
| 327 | os << Configuration::toString(sys); |
| 328 | return os; |
| 329 | } |
| 330 | |
| 331 | //! Output operator for Configuration::LPSolver (uses Configuration::toString(Configuration::LPSolver)). |
| 332 | inline std::ostream &operator<<(std::ostream &os, Configuration::LPSolver lps) |
| 333 | { |
| 334 | os << Configuration::toString(lps); |
| 335 | return os; |
| 336 | } |
| 337 | |
| 338 | //! Output operator for Configuration::MemoryManager (uses Configuration::toString(Configuration::MemoryManager)). |
| 339 | inline std::ostream &operator<<(std::ostream &os, Configuration::MemoryManager mm) |
| 340 | { |
| 341 | os << Configuration::toString(mm); |
| 342 | return os; |
| 343 | } |
| 344 | |
| 345 | } |
| 346 | |