ROSE 0.11.145.354
Sawyer.h
1// WARNING: Changes to this file must be contributed back to Sawyer or else they will
2// be clobbered by the next update from Sawyer. The Sawyer repository is at
3// https://gitlab.com/charger7534/sawyer.git.
4
5
6
7
8#ifndef Sawyer_H
9#define Sawyer_H
10
11#include <boost/cstdint.hpp>
12#include <boost/thread/recursive_mutex.hpp>
13#include <cstdio>
14#include <string>
15
301// Version numbers (conditional compiliation is only so we can test version mismatch handling)
302#ifndef SAWYER_VERSION_MAJOR
303#define SAWYER_VERSION_MAJOR 0
304#define SAWYER_VERSION_MINOR 1
305#define SAWYER_VERSION_PATCH 0
306#endif
307
308//--------------------------------------------------------------------------------------------------------------------------------
309// Macros for thread-safety portability. This allows Sawyer to be compiled with or without thread support and not have a huge
310// proliferation of conditional compilation directives in the main body of source code.
311//--------------------------------------------------------------------------------------------------------------------------------
312#ifdef _REENTRANT
313 #define SAWYER_MULTI_THREADED 1
314 #define SAWYER_THREAD_TAG Sawyer::MultiThreadedTag
315#else
316 #define SAWYER_MULTI_THREADED 0
317 #define SAWYER_THREAD_TAG Sawyer::SingleThreadedTag
318#endif
319#define SAWYER_THREAD_TRAITS Sawyer::SynchronizationTraits<SAWYER_THREAD_TAG>
320
321#ifdef _REENTRANT
322 #if __cplusplus >= 201103L
323 #define SAWYER_THREAD_LOCAL thread_local
324 #elif defined(_MSC_VER)
325 // Visual C++, Intel (Windows), C++ Builder, Digital Mars C++
326 #define SAWYER_THREAD_LOCAL __declspec(thread)
327 #else
328 // Solaris Studio, IBM XL, GNU, LLVM, Intel (linux)
329 #define SAWYER_THREAD_LOCAL __thread
330 #endif
331#else
332 #define SAWYER_THREAD_LOCAL /*void*/
333#endif
334
335// SAWYER_EXPORT -- Workarounds for Microsoft compilers, otherwise non-static functions won't be callable in shared libraries.
336#ifdef BOOST_WINDOWS
337 // FIXME[Robb Matzke 2014-06-18]: get rid of ROSE_UTIL_EXPORTS; cmake can only have one DEFINE_SYMBOL
338 #if defined(SAWYER_DO_EXPORTS) || defined(ROSE_UTIL_EXPORTS) // defined in CMake when compiling libsawyer
339 #define SAWYER_EXPORT __declspec(dllexport)
340 #else
341 #define SAWYER_EXPORT __declspec(dllimport)
342 #endif
343#else
344 #define SAWYER_EXPORT /*void*/
345#endif
346
347
348#define SAWYER_LINKAGE_INFO SAWYER_VERSION_MAJOR, SAWYER_VERSION_MINOR, SAWYER_VERSION_PATCH, SAWYER_MULTI_THREADED
349#define SAWYER_CHECK_LINKAGE Sawyer::initializeLibrary(SAWYER_LINKAGE_INFO)
350
351
358namespace Sawyer {
359
365SAWYER_EXPORT bool initializeLibrary(size_t vmajor=SAWYER_VERSION_MAJOR,
366 size_t vminor=SAWYER_VERSION_MINOR,
367 size_t vpatch=SAWYER_VERSION_PATCH,
368 bool withThreads=SAWYER_MULTI_THREADED);
369
373SAWYER_EXPORT boost::int64_t strtoll(const char*, char**, int);
374
378SAWYER_EXPORT boost::uint64_t strtoull(const char*, char**, int);
379
383SAWYER_EXPORT std::string readOneLine(FILE*);
384
386SAWYER_EXPORT FILE *popen(const std::string&, const char *how);
387
389SAWYER_EXPORT int pclose(FILE*);
390
394SAWYER_EXPORT std::string generateSequentialName(size_t length=3);
395
397SAWYER_EXPORT void checkBoost();
398
400SAWYER_EXPORT std::string thisExecutableName();
401
403SAWYER_EXPORT std::string thisExecutablePath();
404
405} // namespace
406
407// Define only when we have the Boost Chrono library, which was first available in boost-1.47.
408//#define SAWYER_HAVE_BOOST_CHRONO
409
411// Boost serialization
413#define SAWYER_HAVE_BOOST_SERIALIZATION
414#ifdef SAWYER_HAVE_BOOST_SERIALIZATION
415 #include <boost/serialization/access.hpp>
416 #include <boost/serialization/nvp.hpp>
417 #include <boost/serialization/split_member.hpp>
418#endif
419
421// Cereal serialization
423
424#if defined(CEREAL_SAVE_FUNCTION_NAME) && defined(CEREAL_LOAD_FUNCTION_NAME) && defined(CEREAL_SERIALIZE_FUNCTION_NAME)
425 #define SAWYER_HAVE_CEREAL
426 #include <cereal/cereal.hpp>
427#endif
428
430// Compiler portability issues
431//
432// The following macros are used to distinguish between different compilers:
433// _MSC_VER Defined only when compiled by Microsoft's MVC C++ compiler. This macro is predefined by Microsoft's
434// preprocessor.
435//
436// The following macros are used to distinguish between different target environments, regardless of what compiler is being
437// used or the environment which is doing the compiling. For instance, BOOST_WINDOWS will be defined when using the MinGW
438// compiler on Linux to target a Windows environment.
439// BOOST_WINDOWS The Windows API is present. This is defined (or not) by including <boost/config.hpp>.
440//
442
443// Suppress warnings about unused function formal arguments. Most of the time you can simply omit the argument name, but that's
444// not possible if the argument is integral to the documentation. In those cases, mention the argument with this macro.
445# define SAWYER_ARGUSED(X) (void)(X)
446
447#ifdef _MSC_VER
448//--------------------------
449// Microsoft Windows
450//--------------------------
451
452# define SAWYER_ATTR_UNUSED /*void*/
453# define SAWYER_PRETTY_FUNCTION __FUNCSIG__
454# define SAWYER_MAY_ALIAS /*void*/
455# define SAWYER_STATIC_INIT /*void*/
456# define SAWYER_DEPRECATED(WHY) /*void*/
457
458// Microsoft compiler doesn't support stack arrays whose size is not known at compile time. We fudge by using an STL vector,
459// which will be cleaned up propertly at end of scope or exceptions.
460# define SAWYER_VARIABLE_LENGTH_ARRAY(TYPE, NAME, SIZE) \
461 std::vector<TYPE> NAME##Vec_(SIZE); \
462 TYPE *NAME = &(NAME##Vec_[0]);
463
464#elif defined(__sun)
465//--------------------------
466// Sun Solaris
467//--------------------------
468
469# define SAWYER_ATTR_UNUSED /*void*/
470# define SAWYER_PRETTY_FUNCTION __PRETTY_FUNCTION__
471# define SAWYER_MAY_ALIAS /*void*/
472# define SAWYER_STATIC_INIT /*void*/
473# define SAWYER_DEPRECATED(WHY) /*void*/
474
475# define SAWYER_VARIABLE_LENGTH_ARRAY(TYPE, NAME, SIZE) \
476 TYPE NAME[SIZE]; memset(NAME, 0, (SIZE)*sizeof(TYPE))
477
478#elif defined(__APPLE__) && defined(__MACH__)
479//--------------------------
480// Apple OSX, iOS, Darwin
481//--------------------------
482
483# define SAWYER_ATTR_UNUSED /*void*/
484# define SAWYER_PRETTY_FUNCTION __PRETTY_FUNCTION__
485# define SAWYER_MAY_ALIAS /*void*/
486# define SAWYER_STATIC_INIT /*void*/
487# define SAWYER_DEPRECATED(WHY) /*void*/
488
489// Apple compilers don't support stack arrays whose size is not known at compile time. We fudge by using an STL vector,
490// which will be cleaned up propertly at end of scope or exceptions.
491# define SAWYER_VARIABLE_LENGTH_ARRAY(TYPE, NAME, SIZE) \
492 std::vector<TYPE> NAME##Vec_(SIZE); \
493 TYPE *NAME = &(NAME##Vec_[0]);
494
495
496#else
497//--------------------------
498// Other, GCC-based
499//--------------------------
500
501# define SAWYER_ATTR_UNUSED __attribute__((unused))
502# define SAWYER_PRETTY_FUNCTION __PRETTY_FUNCTION__
503# define SAWYER_MAY_ALIAS __attribute__((may_alias))
504# define SAWYER_DEPRECATED(WHY) __attribute__((deprecated))
505
506// Sawyer globals need to be initialized after the C++ standard runtime, but before other user-level stuff. The constant 101
507// causes the initialization to happen as early as possible after the C++ runtime.
508# define SAWYER_STATIC_INIT __attribute__((init_priority(101)))
509
510# define SAWYER_VARIABLE_LENGTH_ARRAY(TYPE, NAME, SIZE) \
511 TYPE *NAME = (TYPE*)alloca((SIZE) * sizeof(TYPE)); memset(NAME, 0, (SIZE)*sizeof(TYPE))
512
513#endif
514
515#define SAWYER_CONFIGURED /*void*/
516
517#endif
518
519// Clean up namespace pollution (shame on Qt for attempting to unilaterally change the language!)
520// These need to be outside the #ifndef Sawyer_H that protects the rest of this file, otherwise the following
521// is possible:
522// #include "foo.h" // which includes Saywer.h"
523// #include "bar.h" // which includes #define emit...
524// #include "baz.h" // which has "emit" symbols clobbered by the pollution
525//
526// I decided it's better to fail early/fail often, therefore these are always deleted.
527// Please fix your Qt headers. Qt's "moc" tool has a command-line switch that prevents the pollution.
528#undef slot
529#undef emit
530
Sawyer support library.
std::string thisExecutablePath()
Return the full path of this program obtained from the operating system.
int pclose(FILE *)
Semi-portable replacement for pclose.
std::string generateSequentialName(size_t length=3)
Generate a sequential name.
boost::int64_t strtoll(const char *, char **, int)
Portable replacement for strtoll.
std::string thisExecutableName()
Return the name of this program obtained from the operating system.
bool initializeLibrary(size_t vmajor=0, size_t vminor=1, size_t vpatch=0, bool withThreads=0)
Explicitly initialize the library.
std::string readOneLine(FILE *)
Reads one line of input from a file.
void checkBoost()
Check for valid boost version or abort.
boost::uint64_t strtoull(const char *, char **, int)
Portable replacement for strtoull.
FILE * popen(const std::string &, const char *how)
Semi-portable replacement for popen.