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 | |