UCommon
platform.h
Go to the documentation of this file.
1// Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2// Copyright (C) 2015-2020 Cherokees of Idaho.
3//
4// This file is part of GNU uCommon C++.
5//
6// GNU uCommon C++ is free software: you can redistribute it and/or modify
7// it under the terms of the GNU Lesser General Public License as published
8// by the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// GNU uCommon C++ is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU Lesser General Public License for more details.
15//
16// You should have received a copy of the GNU Lesser General Public License
17// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18
28#ifdef __clang__
29#pragma clang diagnostic ignored "-Wpadded"
30#pragma clang diagnostic ignored "-Wswitch-enum"
31#pragma clang diagnostic ignored "-Wmissing-noreturn"
32#pragma clang diagnostic ignored "-Wold-style-cast"
33#pragma clang diagnostic ignored "-Wcast-qual"
34#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
35#endif
36
37#ifdef __GNUC__
38#pragma GCC diagnostic ignored "-Wunused-result"
39#pragma GCC diagnostic ignored "-Wold-style-cast"
40#pragma GCC diagnostic ignored "-Wcast-qual"
41#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
42#endif
43
44#include <cstdlib>
45#include <cstddef>
46#if __cplusplus >= 201103L
47#include <memory>
48#endif
49
50#if defined(sun) && defined(unix)
51#include <malloc.h>
52#endif
53
54#ifndef _UCOMMON_PLATFORM_H_
55#define _UCOMMON_PLATFORM_H_
56#define UCOMMON_ABI 7
57
58#ifndef UCOMMON_SYSRUNTIME
59#ifndef NEW_STDCPP
60#define NEW_STDCPP
61#endif
62#define _UCOMMON_EXTENDED_
63#include <stdexcept>
64#define __THROW_SIZE(x) throw std::length_error(x)
65#define __THROW_RANGE(x) throw std::out_of_range(x)
66#define __THROW_RUNTIME(x) throw std::runtime_error(x)
67#define __THROW_ALLOC() throw std::bad_alloc()
68#define __THROW_DEREF(v) if(v == nullptr) \
69 throw std::runtime_error("Dereference NULL")
70#define __THROW_UNDEF(v,x) if(v == nullptr) throw std::runtime_error(x)
71#else
72#define __THROW_RANGE(x) abort()
73#define __THROW_SIZE(x) abort()
74#define __THROW_RUNTIME(x) abort()
75#define __THROW_ALLOC() abort()
76#define __THROW_DEREF(v) if(v == nullptr) abort()
77#define __THROW_UNDEF(v,x) if(v == nullptr) abort()
78#endif
79
90#define UCOMMON_NAMESPACE ucommon
91#define NAMESPACE_UCOMMON namespace ucommon {
92#define END_NAMESPACE }
93
94#ifndef _REENTRANT
95#define _REENTRANT 1
96#endif
97
98#ifndef __PTH__
99#ifndef _THREADSAFE
100#define _THREADSAFE 1
101#endif
102
103#ifndef _POSIX_PTHREAD_SEMANTICS
104#define _POSIX_PTHREAD_SEMANTICS
105#endif
106#endif
107
108#if !defined(__GNUC__) && !defined(__has_feature) && !defined(_MSC_VER)
109#define UCOMMON_RTTI 1
110#endif
111
112#if __GNUC__ > 3 && defined(__GXX_RTTI)
113#define UCOMMON_RTTI 1
114#endif
115
116#if defined(_MSC_VER) && defined(_CPPRTTI)
117#define UCOMMON_RTTI 1
118#endif
119
120#if defined(__has_feature)
121#if __has_feature(cxx_rtti)
122#define UCOMMON_RTTI 1
123#endif
124#endif
125
126#ifdef UCOMMON_RTTI
127#define __PROTOCOL virtual
128template<typename T, typename S>
129T protocol_cast(S *s) {
130 return dynamic_cast<T>(s);
131}
132#else
133#define __PROTOCOL
134template<typename T, typename S>
135T protocol_cast(S *s) {
136 return static_cast<T>(s);
137}
138#endif
139
140#if defined(__GNUC__) && (__GNUC < 3) && !defined(_GNU_SOURCE)
141#define _GNU_SOURCE
142#endif
143
144#if !defined(__GNUC_PREREQ__)
145#if defined(__GNUC__) && defined(__GNUC_MINOR__)
146#define __GNUC_PREREQ__(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
147#else
148#define __GNUC_PREREQ__(maj, min) 0
149#endif
150#endif
151
152#if __GNUC_PREREQ__(3,3)
153#define __PRINTF(x,y) __attribute__ ((format (printf, x, y)))
154#define __SCANF(x, y) __attribute__ ((format (scanf, x, y)))
155#define __MALLOC __attribute__ ((malloc))
156#define __NORETURN __attribute__ ((__noreturn__))
157#endif
158
159#define __UNUSED(x) (void)x
160
161#if __cplusplus >= 201103L
162#define __ALIGNED(x) alignas(x)
163#else
164#ifdef _MSC_VER
165#define __ALIGNED(x) __declspec(align(x))
166#else
167#define __ALIGNED(x) __attribute__(align(x))
168#endif
169#endif
170
171#if __cplusplus < 201103L
172#define __FINAL
173#define __OVERRIDE
174#define __DELETED
175#define __DELETE_COPY(x) inline x(const x&);\
176 inline x& operator=(const x&)
177#define __DELETE_DEFAULTS(x) inline x();\
178 __DELETE_COPY(x)
179#else
180#define __FINAL final
181#define __OVERRIDE override
182#define __DELETED =delete
183#define __DELETE_COPY(x) inline x(const x&) =delete;\
184 inline x& operator=(const x&) =delete
185#define __DELETE_DEFAULTS(x) inline x() =delete;\
186 __DELETE_COPY(x)
187#endif
188
189#if __cplusplus <= 199711L && !defined(_MSC_VER)
190#if defined(__GNUC_MINOR__) && !defined(__clang__)
191#define nullptr __null
192#elif !defined(__clang__) || (defined(__clang__) && defined(__linux__))
193const class nullptr_t
194{
195public:
196 template<class T>
197 inline operator T*() const {
198 return 0;
199 }
200
201 template<class C, class T>
202 inline operator T C::*() const {
203 return 0;
204 }
205
206private:
207 void operator&() const;
208
209} nullptr = {};
210#endif
211#endif
212
213#ifndef __MALLOC
214#define __PRINTF(x, y)
215#define __SCANF(x, y)
216#define __MALLOC
217#endif
218
219#ifndef DEBUG
220#ifndef NDEBUG
221#define NDEBUG
222#endif
223#endif
224
225#ifdef DEBUG
226#ifdef NDEBUG
227#undef NDEBUG
228#endif
229#endif
230
231// see if targeting legacy Microsoft windows platform
232
233#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
234#define _MSWINDOWS_
235
236#if defined(_MSC_VER)
237#define NOMINMAX
238#if _MSC_VER < 1500
239#warning "Probably won't build, need VS >= 2010 or later"
240#endif
241#endif
242
243// minimum required version requires conditional
244#ifdef _WIN32_WINNT
245#if _WIN32_WINNT < 0x0600
246#undef _WIN32_WINNT
247#undef WINVER
248#endif
249#endif
250
251#ifndef _WIN32_WINNT
252#define _WIN32_WINNT 0x0600
253#endif
254
255#ifdef _MSC_VER
256#pragma warning(disable: 4251)
257#pragma warning(disable: 4996)
258#pragma warning(disable: 4355)
259#pragma warning(disable: 4290)
260#pragma warning(disable: 4291)
261#endif
262
263#if defined(__BORLANDC__) && !defined(__MT__)
264#error Please enable multithreading
265#endif
266
267#if defined(_MSC_VER) && !defined(_MT)
268#error Please enable multithreading (Project -> Settings -> C/C++ -> Code Generation -> Use Runtime Library)
269#endif
270
271// Make sure we're consistent with _WIN32_WINNT
272#ifndef WINVER
273#define WINVER _WIN32_WINNT
274#endif
275
276#ifndef WIN32_LEAN_AND_MEAN
277#define WIN32_LEAN_AND_MEAN
278#endif
279
280#include <winsock2.h>
281#include <ws2tcpip.h>
282
283#if defined(_MSC_VER)
284typedef int socksize_t;
285typedef int socklen_t;
286typedef signed long ssize_t;
287typedef int pid_t;
288#else
289typedef size_t sockword_t;
290typedef size_t socksize_t;
291#endif
292
293#include <process.h>
294#ifndef __EXPORT
295#ifdef UCOMMON_STATIC
296#define __EXPORT
297#else
298#define __EXPORT __declspec(dllimport)
299#endif
300#endif
301#define __LOCAL
302
303// if runtime mode then non-runtime libraries are static on windows...
304#if defined(UCOMMON_RUNTIME) || defined(UCOMMON_STATIC)
305#define __SHARED
306#else
307#define __SHARED __declspec(dllimport)
308#endif
309
310#else
311typedef size_t socksize_t;
312#define __EXPORT __attribute__ ((visibility("default")))
313#define __LOCAL __attribute__ ((visibility("hidden")))
314#define __SHARED __attribute__ ((visibility("default")))
315#endif
316
317#ifdef _MSWINDOWS_
318
319#define _UWIN
320
321#include <sys/stat.h>
322#include <io.h>
323
324// gcc mingw can do native high performance win32 conditionals...
325#if defined(UCOMMON_WINPTHREAD) && __GNUC_PREREQ__(4, 8) && !defined(UCOMMON_SYSRUNTIME)
326#define __MINGW_WINPTHREAD__
327#include <pthread.h> // gnu libstdc++ now requires a win pthread
328typedef size_t stacksize_t;
329#else
330#define _MSTHREADS_
331typedef DWORD pthread_t;
332typedef DWORD pthread_key_t;
333typedef unsigned stacksize_t;
334typedef CRITICAL_SECTION pthread_mutex_t;
335#endif
336typedef char *caddr_t;
337typedef HANDLE fd_t;
338typedef SOCKET socket_t;
339
340#if defined(_MSC_VER) && defined(_CRT_NO_TIME_T)
341typedef struct timespec {
342 time_t tv_sec;
343 long tv_nsec;
344} timespec_t;
345#endif
346
347inline void sleep(int seconds)
348 {::Sleep((seconds * 1000l));}
349
350extern "C" {
351
352 #define __SERVICE(id, argc, argv) void WINAPI service_##id(DWORD argc, LPSTR *argv)
353 #define SERVICE_MAIN(id, argc, argv) void WINAPI service_##id(DWORD argc, LPSTR *argv)
354
355 typedef LPSERVICE_MAIN_FUNCTION cpr_service_t;
356
357#ifdef _MSTHREADS_
358 inline void pthread_exit(void *p)
359 {_endthreadex((DWORD)0);}
360
361 inline pthread_t pthread_self(void)
362 {return (pthread_t)GetCurrentThreadId();}
363
364 inline int pthread_mutex_init(pthread_mutex_t *mutex, void *x)
365 {InitializeCriticalSection(mutex); return 0;}
366
367 inline void pthread_mutex_destroy(pthread_mutex_t *mutex)
368 {DeleteCriticalSection(mutex);}
369
370 inline void pthread_mutex_lock(pthread_mutex_t *mutex)
371 {EnterCriticalSection(mutex);}
372
373 inline void pthread_mutex_unlock(pthread_mutex_t *mutex)
374 {LeaveCriticalSection(mutex);}
375#endif
376}
377
378#elif defined(__PTH__)
379
380#include <pth.h>
381#include <sys/wait.h>
382
383typedef size_t stacksize_t;
384typedef int socket_t;
385typedef int fd_t;
386#define INVALID_SOCKET -1
387#define INVALID_HANDLE_VALUE -1
388#include <signal.h>
389
390#define pthread_mutex_t pth_mutex_t
391#define pthread_cond_t pth_cond_t
392#define pthread_t pth_t
393
394inline int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
395 {return pth_sigmask(how, set, oset);};
396
397inline void pthread_exit(void *p)
398 {pth_exit(p);};
399
400inline void pthread_kill(pthread_t tid, int sig)
401 {pth_raise(tid, sig);};
402
403inline int pthread_mutex_init(pthread_mutex_t *mutex, void *x)
404 {return pth_mutex_init(mutex) != 0;};
405
406inline void pthread_mutex_destroy(pthread_mutex_t *mutex)
407 {};
408
409inline void pthread_mutex_lock(pthread_mutex_t *mutex)
410 {pth_mutex_acquire(mutex, 0, nullptr);};
411
412inline void pthread_mutex_unlock(pthread_mutex_t *mutex)
413 {pth_mutex_release(mutex);};
414
415inline void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
416 {pth_cond_await(cond, mutex, nullptr);};
417
418inline void pthread_cond_signal(pthread_cond_t *cond)
419 {pth_cond_notify(cond, FALSE);};
420
421inline void pthread_cond_broadcast(pthread_cond_t *cond)
422 {pth_cond_notify(cond, TRUE);};
423
424#else
425
426#include <pthread.h>
427
428typedef size_t stacksize_t;
429typedef int socket_t;
430typedef int fd_t;
431#define INVALID_SOCKET -1
432#define INVALID_HANDLE_VALUE -1
433#include <signal.h>
434
435#endif
436
437#ifdef _MSC_VER
438typedef signed __int8 int8_t;
439typedef unsigned __int8 uint8_t;
440typedef signed __int16 int16_t;
441typedef unsigned __int16 uint16_t;
442typedef signed __int32 int32_t;
443typedef unsigned __int32 uint32_t;
444typedef signed __int64 int64_t;
445typedef unsigned __int64 uint64_t;
446typedef char *caddr_t;
447
448#include <stdio.h>
449#define snprintf(p, s, f, ...) _snprintf_s(p, s, _TRUNCATE, f, __VA_ARGS__)
450#define vsnprintf(p, s, f, a) _vsnprintf_s(p, s, _TRUNCATE, f, a)
451
452#else
453
454#include <sys/stat.h>
455#include <sys/types.h>
456#include <stdint.h>
457#include <unistd.h>
458#include <stdio.h>
459
460#endif
461
462#undef getchar
463#undef putchar
464
465#ifndef _GNU_SOURCE
466typedef void (*sighandler_t)(int);
467#endif
468typedef unsigned long timeout_t;
469
470#include <cctype>
471#include <climits>
472#include <cerrno>
473#ifndef UCOMMON_RUNTIME
474#include <new>
475#endif
476
477#ifdef _MSWINDOWS_
478#ifndef ENETDOWN
479#define ENETDOWN ((int)(WSAENETDOWN))
480#endif
481#ifndef EINPROGRESS
482#define EINPROGRESS ((int)(WSAEINPROGRESS))
483#endif
484#ifndef ENOPROTOOPT
485#define ENOPROTOOPT ((int)(WSAENOPROTOOPT))
486#endif
487#ifndef EADDRINUSE
488#define EADDRINUSE ((int)(WSAEADDRINUSE))
489#endif
490#ifndef EADDRNOTAVAIL
491#define EADDRNOTAVAIL ((int)(WSAEADDRNOTAVAIL))
492#endif
493#ifndef ENETUNREACH
494#define ENETUNREACH ((int)(WSAENETUNREACH))
495#endif
496#ifndef EHOSTUNREACH
497#define EHOSTUNREACH ((int)(WSAEHOSTUNREACH))
498#endif
499#ifndef EHOSTDOWN
500#define EHOSTDOWN ((int)(WSAEHOSTDOWN))
501#endif
502#ifndef ENETRESET
503#define ENETRESET ((int)(WSAENETRESET))
504#endif
505#ifndef ECONNABORTED
506#define ECONNABORTED ((int)(WSAECONNABORTED))
507#endif
508#ifndef ECONNRESET
509#define ECONNRESET ((int)(WSAECONNRESET))
510#endif
511#ifndef EISCONN
512#define EISCONN ((int)(WSAEISCONN))
513#endif
514#ifndef ENOTCONN
515#define ENOTCONN ((int)(WSAENOTCONN))
516#endif
517#ifndef ESHUTDOWN
518#define ESHUTDOWN ((int)(WSAESHUTDOWN))
519#endif
520#ifndef ETIMEDOUT
521#define ETIMEDOUT ((int)(WSAETIMEDOUT))
522#endif
523#ifndef ECONNREFUSED
524#define ECONNREFUSED ((int)(WSAECONNREFUSED))
525#endif
526#endif
527
528#ifndef DEBUG
529#ifndef NDEBUG
530#define NDEBUG
531#endif
532#endif
533
534#ifdef DEBUG
535#ifdef NDEBUG
536#undef NDEBUG
537#endif
538#endif
539
540#ifndef __PROGRAM
541#define __PROGRAM(c,v) extern "C" int main(int c, char **v)
542#define PROGRAM_MAIN(argc, argv) extern "C" int main(int argc, char **argv)
543#define PROGRAM_EXIT(code) return code
544#endif
545
546#ifndef __SERVICE
547#define __SERVICE(id, c, v) void service_##id(int c, char **v)
548#define SERVICE_MAIN(id, argc, argv) void service_##id(int argc, char **argv)
549typedef void (*cpr_service_t)(int argc, char **argv);
550#endif
551
552#include <assert.h>
553#ifdef DEBUG
554#define crit(x, text) assert(x)
555#else
556#define crit(x, text) if(!(x)) cpr_runtime_error(text)
557#endif
558
565template<class T>
566inline T *init(T *memory)
567 {return ((memory) ? new(((void *)memory)) T : nullptr);}
568
569typedef long Integer;
570typedef unsigned long Unsigned;
571typedef double Real;
572typedef uint8_t ubyte_t;
573
578inline void strfree(char *str)
579 {::free(str);}
580
581template<class T, class S>
582inline T polypointer_cast(S *s)
583{
584#if defined(DEBUG) && defined(UCOMMON_RTTI)
585 if(s == nullptr)
586 return nullptr;
587 T ptr = dynamic_cast<T>(s);
588 __THROW_DEREF(ptr);
589 return ptr;
590#else
591 return static_cast<T>(s);
592#endif
593}
594
595template<class T, class S>
596inline T polyconst_cast(S *s)
597{
598 return const_cast<T>(polypointer_cast<T>(s));
599}
600
601template<class T, class S>
602inline T polystatic_cast(S *s)
603{
604 return static_cast<T>(s);
605}
606
607template<class T, class S>
608inline T polydynamic_cast(S *s)
609{
610#if defined(UCOMMON_RTTI)
611 return dynamic_cast<T>(s);
612#else
613 return static_cast<T>(s);
614#endif
615}
616
617template<class T, class S>
618inline T& polyreference_cast(S *s)
619{
620 __THROW_DEREF(s);
621 return *(static_cast<T*>(s));
622}
623
624template<typename T>
625inline T& reference_cast(T *pointer) {
626 __THROW_DEREF(pointer);
627 return *pointer;
628}
629
630template<typename T>
631inline const T immutable_cast(T p)
632{
633 return static_cast<const T>(p);
634}
635
636#endif
void(* sighandler_t)(int)
Convenient typedef for signal handlers.
Definition platform.h:466
T * init(T *memory)
Template function to initialize memory by invoking default constructor.
Definition platform.h:566
void strfree(char *str)
Matching function for strdup().
Definition platform.h:578
Process services.