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
43namespace ogdf {
44
45// generally used <string> members
46using std::string;
47using 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*/
201class OGDF_EXPORT Configuration {
202public:
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)).
325inline 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)).
332inline 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)).
339inline std::ostream &operator<<(std::ostream &os, Configuration::MemoryManager mm)
340{
341 os << Configuration::toString(mm);
342 return os;
343}
344
345}
346